Commit d5ac4a8b612e977d9b6102f0e73de16a1fc1cb96

Authored by Miguel Barão
1 parent 3cd9487a
Exists in master and in 1 other branch dev

- Added new question type text_numeric. Expects a numerical answer and checks if…

… it's in a given interval.
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 />
... ...