Commit c186f48fc1632e263e11a326ff6dd2a1ae37101a
1 parent
f4809e6f
Exists in
master
and in
1 other branch
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 | # |