Commit d5ac4a8b612e977d9b6102f0e73de16a1fc1cb96
1 parent
3cd9487a
Exists in
master
and in
1 other branch
- Added new question type text_numeric. Expects a numerical answer and checks if…
… it's in a given interval.
Showing
5 changed files
with
67 additions
and
22 deletions
Show diff stats
demo/questions/questions.yaml
@@ -67,6 +67,12 @@ | @@ -67,6 +67,12 @@ | ||
67 | type: text_regex | 67 | type: text_regex |
68 | text: O nosso planeta chama-se planeta... | 68 | text: O nosso planeta chama-se planeta... |
69 | correct: !regex '[Tt]erra' | 69 | correct: !regex '[Tt]erra' |
70 | + # --------------------------------------------------------------------------- | ||
71 | +- | ||
72 | + ref: fractions | ||
73 | + type: text_numeric | ||
74 | + text: Quanto é 1/4? | ||
75 | + correct: [0.249, 0.251] | ||
70 | # --------------------------------------------------------------------------- | 76 | # --------------------------------------------------------------------------- |
71 | - | 77 | - |
72 | ref: basic-colors | 78 | ref: basic-colors |
demo/test.yaml
@@ -40,30 +40,32 @@ files: | @@ -40,30 +40,32 @@ files: | ||
40 | # The order is preserved. | 40 | # The order is preserved. |
41 | # There are several ways to define each question (explained below). | 41 | # There are several ways to define each question (explained below). |
42 | questions: | 42 | questions: |
43 | - # show question where ref=instructions | ||
44 | - - ref: instructions | 43 | + # # show question where ref=instructions |
44 | + # - ref: instructions | ||
45 | 45 | ||
46 | - # show question where ref=flags and assigns 0.5 points (unnormalized) | ||
47 | - - ref: flags | ||
48 | - points: 0.5 | 46 | + # # show question where ref=flags and assigns 0.5 points (unnormalized) |
47 | + # - ref: flags | ||
48 | + # points: 0.5 | ||
49 | 49 | ||
50 | - # idem | ||
51 | - - ref: math-expressions | ||
52 | - points: 2.0 | 50 | + # # idem |
51 | + # - ref: math-expressions | ||
52 | + # points: 2.0 | ||
53 | 53 | ||
54 | - # show question where ref=solar-system and assign the default of 1.0 point (unnormalized) | ||
55 | - - ref: solar-system | 54 | + # # show question where ref=solar-system and assign the default of 1.0 point (unnormalized) |
55 | + # - ref: solar-system | ||
56 | 56 | ||
57 | - # select one questions from the list [our_planet1, our_planet2] | ||
58 | - # and assign 0.75 points (unnormalized) | ||
59 | - - ref: | ||
60 | - - our_planet1 | ||
61 | - - our_planet2 | ||
62 | - points: 0.75 | 57 | + # # select one questions from the list [our_planet1, our_planet2] |
58 | + # # and assign 0.75 points (unnormalized) | ||
59 | + # - ref: | ||
60 | + # - our_planet1 | ||
61 | + # - our_planet2 | ||
62 | + # points: 0.75 | ||
63 | 63 | ||
64 | - # the key 'ref:' can be omitted, a default of 1.0 points is assigned | ||
65 | - - basic-colors | 64 | + # # the key 'ref:' can be omitted, a default of 1.0 points is assigned |
65 | + # - basic-colors | ||
66 | 66 | ||
67 | - - question-whatever | 67 | + - fractions |
68 | 68 | ||
69 | - - markdown_instructions | 69 | + # - question-whatever |
70 | + | ||
71 | + # - markdown_instructions |
questions.py
@@ -122,6 +122,7 @@ class QuestionFactory(dict): | @@ -122,6 +122,7 @@ class QuestionFactory(dict): | ||
122 | 'checkbox' : QuestionCheckbox, | 122 | 'checkbox' : QuestionCheckbox, |
123 | 'text' : QuestionText, | 123 | 'text' : QuestionText, |
124 | 'text_regex': QuestionTextRegex, | 124 | 'text_regex': QuestionTextRegex, |
125 | + 'text_numeric': QuestionTextNumeric, | ||
125 | 'textarea' : QuestionTextArea, | 126 | 'textarea' : QuestionTextArea, |
126 | # informative panels | 127 | # informative panels |
127 | 'information': QuestionInformation, | 128 | 'information': QuestionInformation, |
@@ -383,6 +384,42 @@ class QuestionTextRegex(Question): | @@ -383,6 +384,42 @@ class QuestionTextRegex(Question): | ||
383 | 384 | ||
384 | 385 | ||
385 | # =========================================================================== | 386 | # =========================================================================== |
387 | +class QuestionTextNumeric(Question): | ||
388 | + '''An instance of QuestionTextNumeric will always have the keys: | ||
389 | + type (str) | ||
390 | + text (str) | ||
391 | + correct (list [lower bound, upper bound]) | ||
392 | + answer (None or an actual answer) | ||
393 | + An answer is correct if it's in the closed interval. | ||
394 | + ''' | ||
395 | + | ||
396 | + #------------------------------------------------------------------------ | ||
397 | + def __init__(self, q): | ||
398 | + super().__init__(q) | ||
399 | + | ||
400 | + self.set_defaults({ | ||
401 | + 'text': '', | ||
402 | + 'correct': [1.0, -1.0], # will always return false | ||
403 | + }) | ||
404 | + | ||
405 | + #------------------------------------------------------------------------ | ||
406 | + # can return negative values for wrong answers | ||
407 | + def correct(self): | ||
408 | + super().correct() | ||
409 | + if self['answer'] is not None: | ||
410 | + lower, upper = self['correct'] | ||
411 | + print(lower) | ||
412 | + print(upper) | ||
413 | + try: | ||
414 | + self['grade'] = 1.0 if lower <= float(self['answer']) <= upper else 0.0 | ||
415 | + except TypeError: | ||
416 | + logger.error('While matching regex {0} with answer {1}.'.format(self['correct'], self['answer'])) | ||
417 | + except ValueError: | ||
418 | + self['comments'] = f'A resposta "{self["answer"]}" não é numérica.' | ||
419 | + return self['grade'] | ||
420 | + | ||
421 | + | ||
422 | +# =========================================================================== | ||
386 | class QuestionTextArea(Question): | 423 | class QuestionTextArea(Question): |
387 | '''An instance of QuestionTextArea will always have the keys: | 424 | '''An instance of QuestionTextArea will always have the keys: |
388 | type (str) | 425 | type (str) |
templates/review.html
@@ -207,7 +207,7 @@ | @@ -207,7 +207,7 @@ | ||
207 | </li> | 207 | </li> |
208 | % endfor | 208 | % endfor |
209 | </ul> | 209 | </ul> |
210 | - % elif q['type'] in ('text', 'text_regex', 'textarea'): | 210 | + % elif q['type'] in ('text', 'text_regex', 'text_numeric', 'textarea'): |
211 | <pre>${q['answer'] if q['answer'] is not None else ''}</pre> | 211 | <pre>${q['answer'] if q['answer'] is not None else ''}</pre> |
212 | % endif | 212 | % endif |
213 | 213 |
templates/test.html
@@ -157,7 +157,7 @@ | @@ -157,7 +157,7 @@ | ||
157 | </a> | 157 | </a> |
158 | % endfor | 158 | % endfor |
159 | </div> | 159 | </div> |
160 | - % elif q['type'] in ('text', 'text_regex'): | 160 | + % elif q['type'] in ('text', 'text_regex', 'text_numeric'): |
161 | <input type="text" name="${i}" class="form-control" value="${q['answer'] if q['answer'] is not None else ''}"> | 161 | <input type="text" name="${i}" class="form-control" value="${q['answer'] if q['answer'] is not None else ''}"> |
162 | % elif q['type'] == 'textarea': | 162 | % elif q['type'] == 'textarea': |
163 | <textarea class="form-control" rows="${q['lines']}" name="${i}">${q['answer'] if q['answer'] is not None else ''}</textarea><br /> | 163 | <textarea class="form-control" rows="${q['lines']}" name="${i}">${q['answer'] if q['answer'] is not None else ''}</textarea><br /> |