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 | # BUGS | 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 | - tabelas nas perguntas radio/checkbox não ocupam todo o espaço como em question. | 6 | - tabelas nas perguntas radio/checkbox não ocupam todo o espaço como em question. |
| 6 | - nas perguntas de código, quando erra nao se devia acrescentar mesma pergunta no fim. | 7 | - nas perguntas de código, quando erra nao se devia acrescentar mesma pergunta no fim. |
| 7 | 8 | ||
| @@ -28,6 +29,7 @@ | @@ -28,6 +29,7 @@ | ||
| 28 | 29 | ||
| 29 | # FIXED | 30 | # FIXED |
| 30 | 31 | ||
| 32 | +- max tries não avança para seguinte ao fim das tentativas. | ||
| 31 | - ver se ref guardada na BD é só a da pergunta ou inclui o path. -> so ref | 33 | - ver se ref guardada na BD é só a da pergunta ou inclui o path. -> so ref |
| 32 | - nao esta a guardar as respostas erradas. | 34 | - nao esta a guardar as respostas erradas. |
| 33 | - reload do topic não gera novas perguntas (alunos abusavam do reload) | 35 | - reload do topic não gera novas perguntas (alunos abusavam do reload) |
questions.py
| 1 | 1 | ||
| 2 | -# base | 2 | +# python standard library |
| 3 | import random | 3 | import random |
| 4 | import re | 4 | import re |
| 5 | from os import path | 5 | from os import path |
| 6 | import logging | 6 | import logging |
| 7 | +import asyncio | ||
| 7 | 8 | ||
| 8 | -# packages | 9 | +# user installed libraries |
| 9 | import yaml | 10 | import yaml |
| 10 | 11 | ||
| 11 | # this project | 12 | # this project |
| @@ -41,7 +42,7 @@ class Question(dict): | @@ -41,7 +42,7 @@ class Question(dict): | ||
| 41 | 'files': {}, | 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 | # def updateAnswer(answer=None): | 46 | # def updateAnswer(answer=None): |
| 46 | # self['answer'] = answer | 47 | # self['answer'] = answer |
| 47 | 48 | ||
| @@ -49,6 +50,11 @@ class Question(dict): | @@ -49,6 +50,11 @@ class Question(dict): | ||
| 49 | self['grade'] = 0.0 | 50 | self['grade'] = 0.0 |
| 50 | return 0.0 | 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 | def set_defaults(self, d): | 58 | def set_defaults(self, d): |
| 53 | 'Add k:v pairs from default dict d for nonexistent keys' | 59 | 'Add k:v pairs from default dict d for nonexistent keys' |
| 54 | for k,v in d.items(): | 60 | for k,v in d.items(): |
| @@ -148,7 +154,7 @@ class QuestionCheckbox(Question): | @@ -148,7 +154,7 @@ class QuestionCheckbox(Question): | ||
| 148 | # set defaults if missing | 154 | # set defaults if missing |
| 149 | self.set_defaults({ | 155 | self.set_defaults({ |
| 150 | 'text': '', | 156 | 'text': '', |
| 151 | - 'correct': [1.0] * n, # useful for questionaries | 157 | + 'correct': [0.0] * n, # useful for questionaries |
| 152 | 'shuffle': True, | 158 | 'shuffle': True, |
| 153 | 'discount': True, | 159 | 'discount': True, |
| 154 | 'choose': n, # number of options | 160 | 'choose': n, # number of options |
| @@ -184,7 +190,7 @@ class QuestionCheckbox(Question): | @@ -184,7 +190,7 @@ class QuestionCheckbox(Question): | ||
| 184 | if self['answer'] is not None: | 190 | if self['answer'] is not None: |
| 185 | sum_abs = sum(abs(p) for p in self['correct']) | 191 | sum_abs = sum(abs(p) for p in self['correct']) |
| 186 | if sum_abs < 1e-6: # case correct [0,...,0] avoid div-by-zero | 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 | else: | 195 | else: |
| 190 | x = 0.0 | 196 | x = 0.0 |
| @@ -293,15 +299,9 @@ class QuestionNumericInterval(Question): | @@ -293,15 +299,9 @@ class QuestionNumericInterval(Question): | ||
| 293 | super().correct() | 299 | super().correct() |
| 294 | if self['answer'] is not None: | 300 | if self['answer'] is not None: |
| 295 | lower, upper = self['correct'] | 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 | except ValueError: | 305 | except ValueError: |
| 306 | self['comments'] = 'A resposta não é numérica.' | 306 | self['comments'] = 'A resposta não é numérica.' |
| 307 | self['grade'] = 0.0 | 307 | self['grade'] = 0.0 |