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,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
@@ -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 />