Commit c3e0209787c7fbbfa278721544d82e6bb422aa68
1 parent
6eac0104
Exists in
master
and in
1 other branch
- fixed default correct for checkbox questions.
- fixed debug messages alignment. - updated codemirror and fontawesome links to latest versions
Showing
8 changed files
with
17 additions
and
13 deletions
Show diff stats
BUGS.md
1 | 1 | |
2 | 2 | # BUGS |
3 | 3 | |
4 | +- se aluno entrar com l12345 rebenta. numa funcao get_... ver imagem no ipad | |
4 | 5 | - a revisao do teste não mostra as imagens. |
5 | 6 | - melhorar o botao de autorizar (desliga-se), usar antes um botao? |
6 | 7 | e.g. retornar None quando nao ha alteracoes relativamente à última vez. |
... | ... | @@ -19,7 +20,7 @@ ou usar push (websockets?) |
19 | 20 | - adicionar opcao para eliminar um teste em curso. |
20 | 21 | - gerar teste qd o prof autoriza? melhor nao, pode apagar o teste em curso. gerar previamente e manter uma pool de testes gerados? |
21 | 22 | - enviar resposta de cada pergunta individualmente. |
22 | -- experimentar gerador de svg que inclua no markdown da pergunta e ver se funciona. | |
23 | +- experimentar gerador de svg que inclua no markdown da pergunta e ver se funciona. | |
23 | 24 | - suportar cotacao to teste diferente de 20 (e.g. para juntar perguntas em papel). opcao "points: 18" que normaliza total para 18 em vez de 20. |
24 | 25 | - quando ha varias perguntas para escolher, escolher sucessivamente em vez de aleatoriamente. |
25 | 26 | - como refrescar a tabela de admin sem fazer reload da pagina? |
... | ... | @@ -61,6 +62,7 @@ ou usar push (websockets?) |
61 | 62 | |
62 | 63 | # FIXED |
63 | 64 | |
65 | +- default correct in checkbox must be 1.0, so that the pairs (right,wrong) still work with `correct` left undefined. | |
64 | 66 | - textarea com codemirror |
65 | 67 | - decorador para user 0, evita o "if uid==0" em muitas funcoes. |
66 | 68 | - numeric interval deve converter respostas que usam virgulas para pontos decimais | ... | ... |
app.py
... | ... | @@ -74,7 +74,6 @@ class App(object): |
74 | 74 | dbfile = path.expanduser(self.testfactory['database']) |
75 | 75 | engine = create_engine(f'sqlite:///{dbfile}', echo=False) |
76 | 76 | self.Session = sessionmaker(bind=engine) |
77 | - | |
78 | 77 | try: |
79 | 78 | with self.db_session() as s: |
80 | 79 | n = s.query(Student).filter(Student.id != '0').count() |
... | ... | @@ -117,7 +116,7 @@ class App(object): |
117 | 116 | else: # check password |
118 | 117 | pw_ok = await check_password(try_pw, password) # async bcrypt |
119 | 118 | |
120 | - if pw_ok: # success | |
119 | + if pw_ok: # success | |
121 | 120 | self.allowed.discard(uid) # remove from set of allowed students |
122 | 121 | if uid in self.online: |
123 | 122 | logger.warning(f'Student {uid}: already logged in.') | ... | ... |
config/logger-debug.yaml
questions.py
... | ... | @@ -154,7 +154,7 @@ class QuestionCheckbox(Question): |
154 | 154 | # set defaults if missing |
155 | 155 | self.set_defaults({ |
156 | 156 | 'text': '', |
157 | - 'correct': [0.0] * n, # useful for questionaries | |
157 | + 'correct': [1.0] * n, # Using 0.0 breaks the (right, wrong) options | |
158 | 158 | 'shuffle': True, |
159 | 159 | 'discount': True, |
160 | 160 | 'choose': n, # number of options |
... | ... | @@ -167,7 +167,7 @@ class QuestionCheckbox(Question): |
167 | 167 | # FIXME it's possible that all options are chosen wrong |
168 | 168 | options = [] |
169 | 169 | correct = [] |
170 | - for o,c in zip(self['options'], self['correct']): | |
170 | + for o, c in zip(self['options'], self['correct']): | |
171 | 171 | if isinstance(o, list): |
172 | 172 | r = random.randint(0,1) |
173 | 173 | o = o[r] |
... | ... | @@ -190,7 +190,7 @@ class QuestionCheckbox(Question): |
190 | 190 | if self['answer'] is not None: |
191 | 191 | sum_abs = sum(abs(p) for p in self['correct']) |
192 | 192 | if sum_abs < 1e-6: # case correct [0,...,0] avoid div-by-zero |
193 | - self['grade'] = 0.0 | |
193 | + self['grade'] = 1.0 | |
194 | 194 | |
195 | 195 | else: |
196 | 196 | x = 0.0 |
... | ... | @@ -332,7 +332,8 @@ class QuestionTextArea(Question): |
332 | 332 | 'correct': '' # trying to execute this will fail => grade 0.0 |
333 | 333 | }) |
334 | 334 | |
335 | - self['correct'] = path.abspath(path.normpath(path.join(self['path'], self['correct']))) # abspath will prepend cwd, which is plain wrong... | |
335 | + # self['correct'] = path.join(self['path'], self['correct']) | |
336 | + self['correct'] = path.abspath(path.normpath(path.join(self['path'], self['correct']))) | |
336 | 337 | |
337 | 338 | #------------------------------------------------------------------------ |
338 | 339 | # can return negative values for wrong answers | ... | ... |
serve.py
... | ... | @@ -10,14 +10,15 @@ import argparse |
10 | 10 | import mimetypes |
11 | 11 | import signal |
12 | 12 | import asyncio |
13 | -import json | |
14 | 13 | import functools |
14 | +import json | |
15 | 15 | |
16 | 16 | # user installed libraries |
17 | 17 | import tornado.ioloop |
18 | 18 | import tornado.web |
19 | 19 | import tornado.httpserver |
20 | 20 | from tornado import template, gen |
21 | +import yaml | |
21 | 22 | |
22 | 23 | # this project |
23 | 24 | from app import App, AppException |
... | ... | @@ -293,7 +294,7 @@ class TestHandler(BaseHandler): |
293 | 294 | # --- REVIEW ------------------------------------------------------------- |
294 | 295 | class ReviewHandler(BaseHandler): |
295 | 296 | SUPPORTED_METHODS = ['GET'] |
296 | - | |
297 | + | |
297 | 298 | _templates = { |
298 | 299 | 'radio': 'review-question-radio.html', |
299 | 300 | 'checkbox': 'review-question-checkbox.html', |
... | ... | @@ -327,6 +328,7 @@ class ReviewHandler(BaseHandler): |
327 | 328 | else: |
328 | 329 | with f: |
329 | 330 | t = json.load(f) |
331 | + # print(yaml.dump(t, default_flow_style=False)) | |
330 | 332 | self.render('review.html', t=t, md=md_to_html, templ=self._templates) |
331 | 333 | |
332 | 334 | ... | ... |
static/codemirror
static/fontawesome.min.js
test.py
... | ... | @@ -191,7 +191,7 @@ class TestFactory(dict): |
191 | 191 | 'debug': self['debug'], # required by template test.html |
192 | 192 | 'database': self['database'], |
193 | 193 | 'questions_dir': self['questions_dir'], |
194 | - 'files': self['files'], | |
194 | + # 'files': self['files'], | |
195 | 195 | }) |
196 | 196 | |
197 | 197 | # ----------------------------------------------------------------------- | ... | ... |