Commit 7f38a110684591236eb205c0678d8e6b0abfae05
1 parent
dbe2b67c
Exists in
master
and in
1 other branch
merged questions.py from perguntations
Showing
2 changed files
with
16 additions
and
14 deletions
Show diff stats
BUGS.md
| 1 | 1 | |
| 2 | 2 | # BUGS |
| 3 | 3 | |
| 4 | -- max tries não avança para seguinte ao fim das tentativas. | |
| 4 | +- quando a pergunta devolve comments, este é apresentado, mas fica persistente nas tentativas seguintes. devia ser limpo apos a segunda submissao. | |
| 5 | +- a opcao max_tries na especificacao das perguntas é cumbersome... usar antes tries? | |
| 5 | 6 | - tabelas nas perguntas radio/checkbox não ocupam todo o espaço como em question. |
| 6 | 7 | - nas perguntas de código, quando erra nao se devia acrescentar mesma pergunta no fim. |
| 7 | 8 | |
| ... | ... | @@ -28,6 +29,7 @@ |
| 28 | 29 | |
| 29 | 30 | # FIXED |
| 30 | 31 | |
| 32 | +- max tries não avança para seguinte ao fim das tentativas. | |
| 31 | 33 | - ver se ref guardada na BD é só a da pergunta ou inclui o path. -> so ref |
| 32 | 34 | - nao esta a guardar as respostas erradas. |
| 33 | 35 | - reload do topic não gera novas perguntas (alunos abusavam do reload) | ... | ... |
questions.py
| 1 | 1 | |
| 2 | -# base | |
| 2 | +# python standard library | |
| 3 | 3 | import random |
| 4 | 4 | import re |
| 5 | 5 | from os import path |
| 6 | 6 | import logging |
| 7 | +import asyncio | |
| 7 | 8 | |
| 8 | -# packages | |
| 9 | +# user installed libraries | |
| 9 | 10 | import yaml |
| 10 | 11 | |
| 11 | 12 | # this project |
| ... | ... | @@ -41,7 +42,7 @@ class Question(dict): |
| 41 | 42 | 'files': {}, |
| 42 | 43 | }) |
| 43 | 44 | |
| 44 | - # FIXME unused. does childs need do override this? | |
| 45 | + # FIXME unused. do childs need do override this? | |
| 45 | 46 | # def updateAnswer(answer=None): |
| 46 | 47 | # self['answer'] = answer |
| 47 | 48 | |
| ... | ... | @@ -49,6 +50,11 @@ class Question(dict): |
| 49 | 50 | self['grade'] = 0.0 |
| 50 | 51 | return 0.0 |
| 51 | 52 | |
| 53 | + async def correct_async(self): | |
| 54 | + loop = asyncio.get_running_loop() | |
| 55 | + grade = await loop.run_in_executor(None, self.correct) | |
| 56 | + return grade | |
| 57 | + | |
| 52 | 58 | def set_defaults(self, d): |
| 53 | 59 | 'Add k:v pairs from default dict d for nonexistent keys' |
| 54 | 60 | for k,v in d.items(): |
| ... | ... | @@ -148,7 +154,7 @@ class QuestionCheckbox(Question): |
| 148 | 154 | # set defaults if missing |
| 149 | 155 | self.set_defaults({ |
| 150 | 156 | 'text': '', |
| 151 | - 'correct': [1.0] * n, # useful for questionaries | |
| 157 | + 'correct': [0.0] * n, # useful for questionaries | |
| 152 | 158 | 'shuffle': True, |
| 153 | 159 | 'discount': True, |
| 154 | 160 | 'choose': n, # number of options |
| ... | ... | @@ -184,7 +190,7 @@ class QuestionCheckbox(Question): |
| 184 | 190 | if self['answer'] is not None: |
| 185 | 191 | sum_abs = sum(abs(p) for p in self['correct']) |
| 186 | 192 | if sum_abs < 1e-6: # case correct [0,...,0] avoid div-by-zero |
| 187 | - self['grade'] = 0.0 | |
| 193 | + self['grade'] = 1.0 | |
| 188 | 194 | |
| 189 | 195 | else: |
| 190 | 196 | x = 0.0 |
| ... | ... | @@ -293,15 +299,9 @@ class QuestionNumericInterval(Question): |
| 293 | 299 | super().correct() |
| 294 | 300 | if self['answer'] is not None: |
| 295 | 301 | lower, upper = self['correct'] |
| 296 | - try: | |
| 297 | - answer = float(self['answer']) | |
| 298 | - | |
| 299 | - # TODO: | |
| 300 | - # alternative using locale (1.2 vs 1,2) | |
| 301 | - # import locale | |
| 302 | - # locale.setlocale(locale.LC_ALL, 'pt_PT') | |
| 303 | - # answer = locale.atof(self['answer']) | |
| 304 | 302 | |
| 303 | + try: # replace , by . and convert to float | |
| 304 | + answer = float(self['answer'].replace(',', '.', 1)) | |
| 305 | 305 | except ValueError: |
| 306 | 306 | self['comments'] = 'A resposta não é numérica.' |
| 307 | 307 | self['grade'] = 0.0 | ... | ... |