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 | 67 | type: text_regex |
| 68 | 68 | text: O nosso planeta chama-se planeta... |
| 69 | 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 | 78 | ref: basic-colors | ... | ... |
demo/test.yaml
| ... | ... | @@ -40,30 +40,32 @@ files: |
| 40 | 40 | # The order is preserved. |
| 41 | 41 | # There are several ways to define each question (explained below). |
| 42 | 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 | 122 | 'checkbox' : QuestionCheckbox, |
| 123 | 123 | 'text' : QuestionText, |
| 124 | 124 | 'text_regex': QuestionTextRegex, |
| 125 | + 'text_numeric': QuestionTextNumeric, | |
| 125 | 126 | 'textarea' : QuestionTextArea, |
| 126 | 127 | # informative panels |
| 127 | 128 | 'information': QuestionInformation, |
| ... | ... | @@ -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 | 423 | class QuestionTextArea(Question): |
| 387 | 424 | '''An instance of QuestionTextArea will always have the keys: |
| 388 | 425 | type (str) | ... | ... |
templates/review.html
| ... | ... | @@ -207,7 +207,7 @@ |
| 207 | 207 | </li> |
| 208 | 208 | % endfor |
| 209 | 209 | </ul> |
| 210 | - % elif q['type'] in ('text', 'text_regex', 'textarea'): | |
| 210 | + % elif q['type'] in ('text', 'text_regex', 'text_numeric', 'textarea'): | |
| 211 | 211 | <pre>${q['answer'] if q['answer'] is not None else ''}</pre> |
| 212 | 212 | % endif |
| 213 | 213 | ... | ... |
templates/test.html
| ... | ... | @@ -157,7 +157,7 @@ |
| 157 | 157 | </a> |
| 158 | 158 | % endfor |
| 159 | 159 | </div> |
| 160 | - % elif q['type'] in ('text', 'text_regex'): | |
| 160 | + % elif q['type'] in ('text', 'text_regex', 'text_numeric'): | |
| 161 | 161 | <input type="text" name="${i}" class="form-control" value="${q['answer'] if q['answer'] is not None else ''}"> |
| 162 | 162 | % elif q['type'] == 'textarea': |
| 163 | 163 | <textarea class="form-control" rows="${q['lines']}" name="${i}">${q['answer'] if q['answer'] is not None else ''}</textarea><br /> | ... | ... |