diff --git a/MANUAL.md b/MANUAL.md index 14be2ee..474487c 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -260,7 +260,6 @@ A generator question will run an external program that is expected to print a qu An example of a question generator is the following - :::python linenums="True" #!/usr/bin/env python3.4 from random import randint diff --git a/demo/correct-question.py b/demo/correct-question.py new file mode 100644 index 0000000..c5ff284 --- /dev/null +++ b/demo/correct-question.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3.4 + +import sys +s = sys.stdin.read() + +# set of words converted to lowercase lowercase +answer = set(re.findall(r'[\w]+', s.lower())) + +# correct set of colors +rgb_colors = set(['red', 'green', 'blue']) + +if answer == rgb_colors: + print(1.0) +else: + print(0.0) +exit(0) \ No newline at end of file diff --git a/demo/generate-question.py b/demo/generate-question.py new file mode 100755 index 0000000..f3a1bbd --- /dev/null +++ b/demo/generate-question.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3.4 + +from random import randint + + +q = ''' +type: checkbox +text: Indique quais das seguintes adições resultam em overflow quando se considera a adição de números com sinal (complemento para 2) em registos de 8 bits. +options: +''' + +correct = [] +for i in range(5): + x = randint(11,120) + y = randint(11,120) + q += '- "`{} + {}`"\n'.format(x, y) + correct.append(1 if x + y > 127 else -1) + +q += 'correct: ' + str(correct) + +print(q) diff --git a/demo/questions.yaml b/demo/questions.yaml new file mode 100644 index 0000000..e760d87 --- /dev/null +++ b/demo/questions.yaml @@ -0,0 +1,72 @@ +- + ref: solar-system-mars + type: radio + text: Choose the correct answer + options: + - This one is correct + - Wrong + - Very wrong! + # optional + correct: 0 + shuffle: True + discount: True + hint: Just don't choose the wrong ones +# --------------------------------------------------------------------------- +- + ref: solar-system-jupiter + type: checkbox + text: Which ones are correct? + options: + - Yes + - No + - Yes + - Obvious one, not very important + correct: [1, -1, 1, 0.5] + hint: There are three. +# --------------------------------------------------------------------------- +- + ref: solar-system-venus + type: text + text: What's your favorite basic color? + correct: ['blue', 'green'] + hint: It's not red. +# --------------------------------------------------------------------------- +- + ref: question-v1 + type: text_regex + text: What's your favorite basic color? + correct: '[bB]lue' + hint: It's not red. +# --------------------------------------------------------------------------- +- + ref: question-v2 + type: textarea + text: Write names of the three basic colors. + correct: demo/correct-question.py + hint: They start by RGB and order does not matter. +# --------------------------------------------------------------------------- +- + ref: question-v3 + type: generator + script: demo/generate-question.py + # the script should print a question in yaml format like the ones above. + # Print only the dictionary, not the list (hiffen). +# --------------------------------------------------------------------------- +- + ref: one-question + type: information + text: Please do not cheat. +# --------------------------------------------------------------------------- +- + ref: another-question + # type: information (default) + text: | + The text of questions is parsed as __markdown__ and can include + LaTeX formulas $\sqrt{2\pi}$ and pretty code + + ```.C + int main() { + return 0; + } + ``` + diff --git a/demo/test.yaml b/demo/test.yaml new file mode 100644 index 0000000..a5e61ac --- /dev/null +++ b/demo/test.yaml @@ -0,0 +1,56 @@ +#============================================================================= +ref: demo +title: Teste de Demonstração + +# database contains students+passwords, final results of the tests, and questions done +# database: path/to/students.db +database: db/asc1-students.db + +# this will generate a file for each test done. The file is like a replacement +# for a test done in paper. +save_answers: False +# answers_dir: path/to/directory + +show_points: True +show_hints: True +practice: True +# debug: False + +# When in practice mode and an answer is wrong (i.e. less that 0.5 correct), +# an insult is chosen from the list (optional) +offensive: + - Ó meu grande asno, então não sabes esta? + - Pois, pois... não estudes não... + - E eu sou o Elvis Presley... + - Pois, e bróculos também. + +#----------------------------------------------------------------------------- +# List of files containing questions in yaml format. +# Selected questions will be obtained from these files. +files: + - demo/questions.yaml +#----------------------------------------------------------------------------- +# This is the list of questions. If a "ref:" has a list of keys, then +# one question is selected from the list. +# The following example will generate a test with 3 questions. +questions: + # first + - ref: + # choose 1 from the following 3 questions + - solar-system-mars + - solar-system-jupiter + - solar-system-venus + points: 0.5 + + # second + - ref: + - question-v1 + - question-v2 + - question-v3 + # points: 1.0 is the default, if not defined here. + + # third + - ref: one-question + + # fourth + - another-question diff --git a/questions.py b/questions.py index c8fdef8..f920323 100644 --- a/questions.py +++ b/questions.py @@ -3,6 +3,7 @@ import yaml import random import re import subprocess +import os # Example usage: # @@ -29,8 +30,8 @@ class QuestionsPool(dict): with open(filename, 'r') as f: questions = yaml.load(f) except(FileNotFoundError): - print(' * Questions file "%s" not found. Ignoring...' % filename) - return + print(' * Questions file "%s" not found. Aborting...' % filename) + os.sys.exit(1) # add defaults if missing from sources for i, q in enumerate(questions): @@ -45,8 +46,8 @@ class QuestionsPool(dict): # ref (if missing, add 'filename.yaml:3') q['ref'] = str(q.get('ref', filename + ':' + str(i))) - # type (default type is just '') - q['type'] = str(q.get('type', '')) + # type (default type is 'information') + q['type'] = str(q.get('type', 'information')) # add question to the pool self[q['ref']] = q @@ -78,19 +79,19 @@ def create_question(q): 'checkbox' : QuestionCheckbox, 'text' : QuestionText, 'text_regex': QuestionTextRegex, - 'text-regex': QuestionTextRegex, - 'regex' : QuestionTextRegex, + # 'text-regex': QuestionTextRegex, + # 'regex' : QuestionTextRegex, 'textarea' : QuestionTextArea, 'information': QuestionInformation, - 'info' : QuestionInformation, - '' : QuestionInformation, # default + # 'info' : QuestionInformation, + # '' : QuestionInformation, # default } # create instance of given type try: questiontype = types[q['type']] except KeyError: - print(' * unsupported question type in "%s:%s".' % (q['filename'], q['ref'])) + print(' * unsupported question type "{0}" in "{1}:{2}".'.format(q['type'], q['filename'], q['ref'])) questiontype = Question # create question instance and return diff --git a/test.py b/test.py index 77b9eb0..41ad5dc 100644 --- a/test.py +++ b/test.py @@ -8,7 +8,7 @@ from datetime import datetime import questions import database -# ============================================================================ +# =========================================================================== def read_configuration(filename, debug=False, show_points=False, show_hints=False, practice=False, save_answers=False): # FIXME validar se ficheiros e directorios existem??? if not os.path.isfile(filename): @@ -35,7 +35,7 @@ def read_configuration(filename, debug=False, show_points=False, show_hints=Fals if 'database' not in test: print(' * Missing database in the test configuration.') - sys.exit(1) + os.sys.exit(1) if isinstance(test['files'], str): test['files'] = [test['files']] @@ -67,7 +67,7 @@ def read_configuration(filename, debug=False, show_points=False, show_hints=Fals return test -# ============================================================================ +# =========================================================================== class Test(dict): # ----------------------------------------------------------------------- def __init__(self, d): -- libgit2 0.21.2