Commit c186f48fc1632e263e11a326ff6dd2a1ae37101a

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

text-regex questions now accept also a list of regular expressions to

match. It's considered correct if any match is found.
Showing 1 changed file with 23 additions and 10 deletions   Show diff stats
aprendizations/questions.py
@@ -257,8 +257,11 @@ class QuestionTextRegex(Question): @@ -257,8 +257,11 @@ class QuestionTextRegex(Question):
257 '''An instance of QuestionTextRegex will always have the keys: 257 '''An instance of QuestionTextRegex will always have the keys:
258 type (str) 258 type (str)
259 text (str) 259 text (str)
260 - correct (str with regex) 260 + correct (str or list[str])
261 answer (None or an actual answer) 261 answer (None or an actual answer)
  262 +
  263 + The correct strings are python standard regular expressions.
  264 + Grade is 1.0 when the answer matches any of the regex in the list.
262 ''' 265 '''
263 266
264 # ------------------------------------------------------------------------ 267 # ------------------------------------------------------------------------
@@ -267,19 +270,29 @@ class QuestionTextRegex(Question): @@ -267,19 +270,29 @@ class QuestionTextRegex(Question):
267 270
268 self.set_defaults(QDict({ 271 self.set_defaults(QDict({
269 'text': '', 272 'text': '',
270 - 'correct': '$.^', # will always return false 273 + 'correct': ['$.^'], # will always return false
271 })) 274 }))
272 275
  276 + # make sure its always a list of regular expressions
  277 + if not isinstance(self['correct'], list):
  278 + self['correct'] = [self['correct']]
  279 +
  280 + # make sure all elements of the list are strings
  281 + self['correct'] = [str(a) for a in self['correct']]
  282 +
273 # ------------------------------------------------------------------------ 283 # ------------------------------------------------------------------------
274 def correct(self) -> None: 284 def correct(self) -> None:
275 super().correct() 285 super().correct()
276 if self['answer'] is not None: 286 if self['answer'] is not None:
277 - try:  
278 - ok = re.match(self['correct'], self['answer'])  
279 - except TypeError:  
280 - logger.error(f'While matching regex {self["correct"]} with '  
281 - f'answer {self["answer"]}.')  
282 - self['grade'] = 1.0 if ok else 0.0 287 + self['grade'] = 0.0
  288 + for r in self['correct']:
  289 + try:
  290 + if re.match(r, self['answer']):
  291 + self['grade'] = 1.0
  292 + return
  293 + except TypeError:
  294 + logger.error(f'While matching regex {self["correct"]} with'
  295 + f' answer "{self["answer"]}".')
283 296
284 297
285 # ============================================================================ 298 # ============================================================================
@@ -421,8 +434,8 @@ class QuestionInformation(Question): @@ -421,8 +434,8 @@ class QuestionInformation(Question):
421 # To generate an instance of a question we use the method generate(). 434 # To generate an instance of a question we use the method generate().
422 # It returns a question instance of the correct class. 435 # It returns a question instance of the correct class.
423 # There is also an asynchronous version called gen_async(). This version is 436 # There is also an asynchronous version called gen_async(). This version is
424 -# synchronous for all question types (radio, checkbox, etc) except for generator  
425 -# types which run asynchronously. 437 +# synchronous for all question types (radio, checkbox, etc) except for
  438 +# generator types which run asynchronously.
426 # 439 #
427 # Example: 440 # Example:
428 # 441 #