Commit 2290803dba73b806dfb492d8df0396dceeaff342

Authored by Miguel Barao
1 parent c74f28c0
Exists in master and in 1 other branch dev

- added demo questions, test and scripts

- changed default question type to 'information'.
MANUAL.md
... ... @@ -260,7 +260,6 @@ A generator question will run an external program that is expected to print a qu
260 260  
261 261 An example of a question generator is the following
262 262  
263   - :::python linenums="True"
264 263 #!/usr/bin/env python3.4
265 264 from random import randint
266 265  
... ...
demo/correct-question.py 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +#!/usr/bin/env python3.4
  2 +
  3 +import sys
  4 +s = sys.stdin.read()
  5 +
  6 +# set of words converted to lowercase lowercase
  7 +answer = set(re.findall(r'[\w]+', s.lower()))
  8 +
  9 +# correct set of colors
  10 +rgb_colors = set(['red', 'green', 'blue'])
  11 +
  12 +if answer == rgb_colors:
  13 + print(1.0)
  14 +else:
  15 + print(0.0)
  16 +exit(0)
0 17 \ No newline at end of file
... ...
demo/generate-question.py 0 → 100755
... ... @@ -0,0 +1,21 @@
  1 +#!/usr/bin/env python3.4
  2 +
  3 +from random import randint
  4 +
  5 +
  6 +q = '''
  7 +type: checkbox
  8 +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.
  9 +options:
  10 +'''
  11 +
  12 +correct = []
  13 +for i in range(5):
  14 + x = randint(11,120)
  15 + y = randint(11,120)
  16 + q += '- "`{} + {}`"\n'.format(x, y)
  17 + correct.append(1 if x + y > 127 else -1)
  18 +
  19 +q += 'correct: ' + str(correct)
  20 +
  21 +print(q)
... ...
demo/questions.yaml 0 → 100644
... ... @@ -0,0 +1,72 @@
  1 +-
  2 + ref: solar-system-mars
  3 + type: radio
  4 + text: Choose the correct answer
  5 + options:
  6 + - This one is correct
  7 + - Wrong
  8 + - Very wrong!
  9 + # optional
  10 + correct: 0
  11 + shuffle: True
  12 + discount: True
  13 + hint: Just don't choose the wrong ones
  14 +# ---------------------------------------------------------------------------
  15 +-
  16 + ref: solar-system-jupiter
  17 + type: checkbox
  18 + text: Which ones are correct?
  19 + options:
  20 + - Yes
  21 + - No
  22 + - Yes
  23 + - Obvious one, not very important
  24 + correct: [1, -1, 1, 0.5]
  25 + hint: There are three.
  26 +# ---------------------------------------------------------------------------
  27 +-
  28 + ref: solar-system-venus
  29 + type: text
  30 + text: What's your favorite basic color?
  31 + correct: ['blue', 'green']
  32 + hint: It's not red.
  33 +# ---------------------------------------------------------------------------
  34 +-
  35 + ref: question-v1
  36 + type: text_regex
  37 + text: What's your favorite basic color?
  38 + correct: '[bB]lue'
  39 + hint: It's not red.
  40 +# ---------------------------------------------------------------------------
  41 +-
  42 + ref: question-v2
  43 + type: textarea
  44 + text: Write names of the three basic colors.
  45 + correct: demo/correct-question.py
  46 + hint: They start by RGB and order does not matter.
  47 +# ---------------------------------------------------------------------------
  48 +-
  49 + ref: question-v3
  50 + type: generator
  51 + script: demo/generate-question.py
  52 + # the script should print a question in yaml format like the ones above.
  53 + # Print only the dictionary, not the list (hiffen).
  54 +# ---------------------------------------------------------------------------
  55 +-
  56 + ref: one-question
  57 + type: information
  58 + text: Please do not cheat.
  59 +# ---------------------------------------------------------------------------
  60 +-
  61 + ref: another-question
  62 + # type: information (default)
  63 + text: |
  64 + The text of questions is parsed as __markdown__ and can include
  65 + LaTeX formulas $\sqrt{2\pi}$ and pretty code
  66 +
  67 + ```.C
  68 + int main() {
  69 + return 0;
  70 + }
  71 + ```
  72 +
... ...
demo/test.yaml 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +#=============================================================================
  2 +ref: demo
  3 +title: Teste de Demonstração
  4 +
  5 +# database contains students+passwords, final results of the tests, and questions done
  6 +# database: path/to/students.db
  7 +database: db/asc1-students.db
  8 +
  9 +# this will generate a file for each test done. The file is like a replacement
  10 +# for a test done in paper.
  11 +save_answers: False
  12 +# answers_dir: path/to/directory
  13 +
  14 +show_points: True
  15 +show_hints: True
  16 +practice: True
  17 +# debug: False
  18 +
  19 +# When in practice mode and an answer is wrong (i.e. less that 0.5 correct),
  20 +# an insult is chosen from the list (optional)
  21 +offensive:
  22 + - Ó meu grande asno, então não sabes esta?
  23 + - Pois, pois... não estudes não...
  24 + - E eu sou o Elvis Presley...
  25 + - Pois, e bróculos também.
  26 +
  27 +#-----------------------------------------------------------------------------
  28 +# List of files containing questions in yaml format.
  29 +# Selected questions will be obtained from these files.
  30 +files:
  31 + - demo/questions.yaml
  32 +#-----------------------------------------------------------------------------
  33 +# This is the list of questions. If a "ref:" has a list of keys, then
  34 +# one question is selected from the list.
  35 +# The following example will generate a test with 3 questions.
  36 +questions:
  37 + # first
  38 + - ref:
  39 + # choose 1 from the following 3 questions
  40 + - solar-system-mars
  41 + - solar-system-jupiter
  42 + - solar-system-venus
  43 + points: 0.5
  44 +
  45 + # second
  46 + - ref:
  47 + - question-v1
  48 + - question-v2
  49 + - question-v3
  50 + # points: 1.0 is the default, if not defined here.
  51 +
  52 + # third
  53 + - ref: one-question
  54 +
  55 + # fourth
  56 + - another-question
... ...
questions.py
... ... @@ -3,6 +3,7 @@ import yaml
3 3 import random
4 4 import re
5 5 import subprocess
  6 +import os
6 7  
7 8 # Example usage:
8 9 #
... ... @@ -29,8 +30,8 @@ class QuestionsPool(dict):
29 30 with open(filename, 'r') as f:
30 31 questions = yaml.load(f)
31 32 except(FileNotFoundError):
32   - print(' * Questions file "%s" not found. Ignoring...' % filename)
33   - return
  33 + print(' * Questions file "%s" not found. Aborting...' % filename)
  34 + os.sys.exit(1)
34 35  
35 36 # add defaults if missing from sources
36 37 for i, q in enumerate(questions):
... ... @@ -45,8 +46,8 @@ class QuestionsPool(dict):
45 46 # ref (if missing, add 'filename.yaml:3')
46 47 q['ref'] = str(q.get('ref', filename + ':' + str(i)))
47 48  
48   - # type (default type is just '')
49   - q['type'] = str(q.get('type', ''))
  49 + # type (default type is 'information')
  50 + q['type'] = str(q.get('type', 'information'))
50 51  
51 52 # add question to the pool
52 53 self[q['ref']] = q
... ... @@ -78,19 +79,19 @@ def create_question(q):
78 79 'checkbox' : QuestionCheckbox,
79 80 'text' : QuestionText,
80 81 'text_regex': QuestionTextRegex,
81   - 'text-regex': QuestionTextRegex,
82   - 'regex' : QuestionTextRegex,
  82 + # 'text-regex': QuestionTextRegex,
  83 + # 'regex' : QuestionTextRegex,
83 84 'textarea' : QuestionTextArea,
84 85 'information': QuestionInformation,
85   - 'info' : QuestionInformation,
86   - '' : QuestionInformation, # default
  86 + # 'info' : QuestionInformation,
  87 + # '' : QuestionInformation, # default
87 88 }
88 89  
89 90 # create instance of given type
90 91 try:
91 92 questiontype = types[q['type']]
92 93 except KeyError:
93   - print(' * unsupported question type in "%s:%s".' % (q['filename'], q['ref']))
  94 + print(' * unsupported question type "{0}" in "{1}:{2}".'.format(q['type'], q['filename'], q['ref']))
94 95 questiontype = Question
95 96  
96 97 # create question instance and return
... ...
test.py
... ... @@ -8,7 +8,7 @@ from datetime import datetime
8 8 import questions
9 9 import database
10 10  
11   -# ============================================================================
  11 +# ===========================================================================
12 12 def read_configuration(filename, debug=False, show_points=False, show_hints=False, practice=False, save_answers=False):
13 13 # FIXME validar se ficheiros e directorios existem???
14 14 if not os.path.isfile(filename):
... ... @@ -35,7 +35,7 @@ def read_configuration(filename, debug=False, show_points=False, show_hints=Fals
35 35  
36 36 if 'database' not in test:
37 37 print(' * Missing database in the test configuration.')
38   - sys.exit(1)
  38 + os.sys.exit(1)
39 39  
40 40 if isinstance(test['files'], str):
41 41 test['files'] = [test['files']]
... ... @@ -67,7 +67,7 @@ def read_configuration(filename, debug=False, show_points=False, show_hints=Fals
67 67  
68 68 return test
69 69  
70   -# ============================================================================
  70 +# ===========================================================================
71 71 class Test(dict):
72 72 # -----------------------------------------------------------------------
73 73 def __init__(self, d):
... ...