Commit 94b0dd76345d616bd319a464778ad836923185ec
1 parent
f23c0e87
Exists in
master
and in
1 other branch
fixes error in checkbox questions when shuffle=false.
Showing
3 changed files
with
20 additions
and
15 deletions
Show diff stats
aprendizations/learnapp.py
@@ -44,8 +44,8 @@ class LearnApp(object): | @@ -44,8 +44,8 @@ class LearnApp(object): | ||
44 | yield session | 44 | yield session |
45 | session.commit() | 45 | session.commit() |
46 | except Exception: | 46 | except Exception: |
47 | - session.rollback() | ||
48 | logger.error('DB rollback!!!') | 47 | logger.error('DB rollback!!!') |
48 | + session.rollback() | ||
49 | finally: | 49 | finally: |
50 | session.close() | 50 | session.close() |
51 | 51 |
aprendizations/questions.py
@@ -50,8 +50,6 @@ class Question(dict): | @@ -50,8 +50,6 @@ class Question(dict): | ||
50 | 50 | ||
51 | async def correct_async(self) -> None: | 51 | async def correct_async(self) -> None: |
52 | self.correct() | 52 | self.correct() |
53 | - # loop = asyncio.get_running_loop() | ||
54 | - # await loop.run_in_executor(None, self.correct) | ||
55 | 53 | ||
56 | def set_defaults(self, d: QDict) -> None: | 54 | def set_defaults(self, d: QDict) -> None: |
57 | 'Add k:v pairs from default dict d for nonexistent keys' | 55 | 'Add k:v pairs from default dict d for nonexistent keys' |
@@ -94,7 +92,9 @@ class QuestionRadio(Question): | @@ -94,7 +92,9 @@ class QuestionRadio(Question): | ||
94 | for x in range(n)] | 92 | for x in range(n)] |
95 | 93 | ||
96 | if len(self['correct']) != n: | 94 | if len(self['correct']) != n: |
97 | - msg = f'Options and correct mismatch in "{self["ref"]}"' | 95 | + msg = (f'Options and correct mismatch in ' |
96 | + f'"{self["ref"]}", file "{self["filename"]}".') | ||
97 | + logger.error(msg) | ||
98 | raise QuestionException(msg) | 98 | raise QuestionException(msg) |
99 | 99 | ||
100 | if self['shuffle']: | 100 | if self['shuffle']: |
@@ -168,18 +168,20 @@ class QuestionCheckbox(Question): | @@ -168,18 +168,20 @@ class QuestionCheckbox(Question): | ||
168 | })) | 168 | })) |
169 | 169 | ||
170 | if len(self['correct']) != n: | 170 | if len(self['correct']) != n: |
171 | - msg = f'Options and correct mismatch in "{self["ref"]}"' | 171 | + msg = (f'Options and correct size mismatch in ' |
172 | + f'"{self["ref"]}", file "{self["filename"]}".') | ||
173 | + logger.error(msg) | ||
172 | raise QuestionException(msg) | 174 | raise QuestionException(msg) |
173 | 175 | ||
174 | # if an option is a list of (right, wrong), pick one | 176 | # if an option is a list of (right, wrong), pick one |
175 | - # FIXME it's possible that all options are chosen wrong | ||
176 | options = [] | 177 | options = [] |
177 | correct = [] | 178 | correct = [] |
178 | for o, c in zip(self['options'], self['correct']): | 179 | for o, c in zip(self['options'], self['correct']): |
179 | if isinstance(o, list): | 180 | if isinstance(o, list): |
180 | r = random.randint(0, 1) | 181 | r = random.randint(0, 1) |
181 | o = o[r] | 182 | o = o[r] |
182 | - c = c if r == 0 else -c | 183 | + if r == 1: |
184 | + c = -c | ||
183 | options.append(str(o)) | 185 | options.append(str(o)) |
184 | correct.append(float(c)) | 186 | correct.append(float(c)) |
185 | 187 | ||
@@ -187,8 +189,11 @@ class QuestionCheckbox(Question): | @@ -187,8 +189,11 @@ class QuestionCheckbox(Question): | ||
187 | # and apply to `options` and `correct` | 189 | # and apply to `options` and `correct` |
188 | if self['shuffle']: | 190 | if self['shuffle']: |
189 | perm = random.sample(range(n), k=self['choose']) | 191 | perm = random.sample(range(n), k=self['choose']) |
190 | - self['options'] = [str(options[i]) for i in perm] | ||
191 | - self['correct'] = [float(correct[i]) for i in perm] | 192 | + self['options'] = [options[i] for i in perm] |
193 | + self['correct'] = [correct[i] for i in perm] | ||
194 | + else: | ||
195 | + self['options'] = options[:self['choose']] | ||
196 | + self['correct'] = correct[:self['choose']] | ||
192 | 197 | ||
193 | # ------------------------------------------------------------------------ | 198 | # ------------------------------------------------------------------------ |
194 | # can return negative values for wrong answers | 199 | # can return negative values for wrong answers |
@@ -443,20 +448,20 @@ class QFactory(object): | @@ -443,20 +448,20 @@ class QFactory(object): | ||
443 | 'textarea': QuestionTextArea, | 448 | 'textarea': QuestionTextArea, |
444 | # -- informative panels -- | 449 | # -- informative panels -- |
445 | 'information': QuestionInformation, | 450 | 'information': QuestionInformation, |
451 | + 'success': QuestionInformation, | ||
446 | 'warning': QuestionInformation, | 452 | 'warning': QuestionInformation, |
447 | 'alert': QuestionInformation, | 453 | 'alert': QuestionInformation, |
448 | - 'success': QuestionInformation, | ||
449 | } | 454 | } |
450 | 455 | ||
451 | - def __init__(self, question_dict: QDict = QDict({})) -> None: | ||
452 | - self.question = question_dict | 456 | + def __init__(self, qdict: QDict = QDict({})) -> None: |
457 | + self.question = qdict | ||
453 | 458 | ||
454 | # ----------------------------------------------------------------------- | 459 | # ----------------------------------------------------------------------- |
455 | # Given a ref returns an instance of a descendent of Question(), | 460 | # Given a ref returns an instance of a descendent of Question(), |
456 | # i.e. a question object (radio, checkbox, ...). | 461 | # i.e. a question object (radio, checkbox, ...). |
457 | # ----------------------------------------------------------------------- | 462 | # ----------------------------------------------------------------------- |
458 | def generate(self) -> Question: | 463 | def generate(self) -> Question: |
459 | - logger.debug(f'[generate] "{self.question["ref"]}"...') | 464 | + logger.debug(f'[QFactory.generate] "{self.question["ref"]}"...') |
460 | # Shallow copy so that script generated questions will not replace | 465 | # Shallow copy so that script generated questions will not replace |
461 | # the original generators | 466 | # the original generators |
462 | q = self.question.copy() | 467 | q = self.question.copy() |
@@ -487,7 +492,7 @@ class QFactory(object): | @@ -487,7 +492,7 @@ class QFactory(object): | ||
487 | 492 | ||
488 | # ----------------------------------------------------------------------- | 493 | # ----------------------------------------------------------------------- |
489 | async def generate_async(self) -> Question: | 494 | async def generate_async(self) -> Question: |
490 | - logger.debug(f'[generate_async] "{self.question["ref"]}"...') | 495 | + logger.debug(f'[QFactory.generate_async] "{self.question["ref"]}"...') |
491 | # Shallow copy so that script generated questions will not replace | 496 | # Shallow copy so that script generated questions will not replace |
492 | # the original generators | 497 | # the original generators |
493 | q = self.question.copy() | 498 | q = self.question.copy() |
aprendizations/tools.py
@@ -145,7 +145,7 @@ def load_yaml(filename: str, default: Any = None) -> Any: | @@ -145,7 +145,7 @@ def load_yaml(filename: str, default: Any = None) -> Any: | ||
145 | logger.error(f'Cannot open "{filename}": not found') | 145 | logger.error(f'Cannot open "{filename}": not found') |
146 | except PermissionError: | 146 | except PermissionError: |
147 | logger.error(f'Cannot open "{filename}": no permission') | 147 | logger.error(f'Cannot open "{filename}": no permission') |
148 | - except IOError: | 148 | + except OSError: |
149 | logger.error(f'Cannot open file "{filename}"') | 149 | logger.error(f'Cannot open file "{filename}"') |
150 | else: | 150 | else: |
151 | with f: | 151 | with f: |