Commit 0b947002049e45c0a5db93291b8ee5920930a650

Authored by Miguel Barão
1 parent be82c164
Exists in master and in 1 other branch dev

- fix bug in password reset.

- new information question in the demo suggesting use of yamllint.
- version bump to 2020.05.dev3
BUGS.md
1 1  
2 2 # BUGS
3 3  
4   -- review does not show question refs when commandline --show-ref is used but not the test.yaml option.
5   -- em admin, quando scale_max não é 20, as cores das barras continuam a reflectir a escala 0,20. a tabela teste na DB não tem a escala desse teste.
6 4 - CRITICAL se answer for `i<n` a revisão de provas mostra apenas i (interpreta `<` como tag?)
7   -- na pagina grade.html as barras estao normalizadas para os limites scale_min e max do teste actual e nao do realizado.
  5 +
  6 +- em admin, quando scale_max não é 20, as cores das barras continuam a reflectir a escala 0,20. a tabela teste na DB não tem a escala desse teste.
  7 +- em grade.html as barras estao normalizadas para os limites scale_min e max do teste actual e nao dos testes realizados no passado (tabela test devia guardar a escala).
8 8 - codigo `hello world` nao esta a preservar o whitespace. O renderer de markdown gera a tag <code> que não preserva whitespace. Necessario adicionar <pre>.
9   -- teste nao esta a mostrar imagens de vez em quando.
10 9 - mensagems de erro do assembler aparecem na mesma linha na correcao e nao fazerm rendering do `$t`, ver se servidor faz parse do markdown dessas mensagens.
11 10 - impedir os eventos copy/paste. alunos usam isso para trazer codigo ja feito nos computadores. Obrigar a fazer reset? fazer um copy automaticamente?
12 11 - a revisao do teste não mostra as imagens.
13 12 - Test.reset_answers() unused.
14   -- incluir test_id na tabela questions (futuro semestre, pode quebrar compatibilidade).
15   -- na pagina admin, mostrar com cor vermelha as horas de entrada dos alunos que ja tenham excedido o tempo
  13 +- teste nao esta a mostrar imagens de vez em quando.???
16 14  
17 15 # TODO
18 16  
  17 +- na pagina admin, mostrar com cor vermelha as horas de entrada dos alunos que ja tenham excedido o tempo
19 18 - retornar None quando nao ha alteracoes relativamente à última vez.
20 19 ou usar push (websockets?)
21 20 - mudar ref do test para test_id (ref já é usado nas perguntas)
... ...
demo/demo.yaml
1 1 ---
2 2 # ============================================================================
3 3 # Unique identifier of the test.
  4 +# Valid names can only include letters, digits, dash and underscore,
  5 +# e.g. asc1-test3
4 6 # Database queries can be done in the terminal with
5   -# sqlite3 students.db "select * from tests where ref='tutorial'"
  7 +# sqlite3 students.db "select * from tests where ref='asc1-test3'"
6 8 ref: tutorial
7 9  
8 10 # Database file that includes student credentials, tests and questions grades.
... ... @@ -20,9 +22,9 @@ title: Teste de demonstração (tutorial)
20 22  
21 23 # Duration in minutes.
22 24 # (0 or undefined means infinite time)
23   -duration: 2
  25 +duration: 0
24 26  
25   -# Automatic test submission after the timeout 'duration'?
  27 +# Automatic test submission after the given 'duration' timeout
26 28 # (default: false)
27 29 autosubmit: true
28 30  
... ... @@ -40,9 +42,6 @@ scale: [0, 5]
40 42 # scale_min: 0
41 43 # scale_points: true
42 44  
43   -show_ref: true
44   -debug: false
45   -
46 45 # ----------------------------------------------------------------------------
47 46 # Base path applied to the questions files and all the scripts
48 47 # including question generators and correctors.
... ... @@ -75,7 +74,7 @@ questions:
75 74 - tut-warning
76 75 - [tut-alert1, tut-alert2]
77 76 - tut-generator
78   -
  77 + - tut-yamllint
79 78  
80 79 # test:
81 80 # - ref1
... ...
demo/questions/generators/generate-question.py
... ... @@ -18,11 +18,10 @@ print(f&quot;&quot;&quot;---
18 18 type: text
19 19 title: Geradores de perguntas
20 20 text: |
21   - Existe a possibilidade da pergunta ser gerada por um programa externo. Este
22   - programa deve escrever no `stdout` uma pergunta em formato `yaml` como nos
  21 + Existe a possibilidade da pergunta ser gerada por um programa externo. O
  22 + programa deve escrever no `stdout` uma pergunta em formato `yaml` tal como os
23 23 exemplos anteriores. Pode também receber argumentos para parametrizar a
24   - geração da pergunta. Aqui está um exemplo de uma pergunta gerada por um
25   - script python:
  24 + pergunta. Aqui está um exemplo de uma pergunta gerada por um script python:
26 25  
27 26 ```python
28 27 #!/usr/bin/env python3
... ... @@ -46,9 +45,7 @@ text: |
46 45 A solução é {{r}}.''')
47 46 ```
48 47  
49   - Este script deve ter permissões para poder ser executado no terminal. Dá
50   - jeito usar o comando `gen-somar.py 1 100 | yamllint -` para validar o `yaml`
51   - gerado.
  48 + Este script deve ter permissões para poder ser executado no terminal.
52 49  
53 50 Para indicar que uma pergunta é gerada externamente, esta é declarada com
54 51  
... ... @@ -56,12 +53,12 @@ text: |
56 53 - type: generator
57 54 ref: gen-somar
58 55 script: gen-somar.py
59   - # opcional
  56 + # argumentos opcionais
60 57 args: [1, 100]
61 58 ```
62 59  
63   - Os argumentos `args` são opcionais e são passados para o programa como
64   - argumentos da linha de comando.
  60 + Opcionalmente, o programa pode receber uma lista de argumentos declarados em
  61 + `args`.
65 62  
66 63 ---
67 64  
... ...
demo/questions/questions-tutorial.yaml
... ... @@ -581,3 +581,25 @@
581 581 ref: tut-generator
582 582 script: generators/generate-question.py
583 583 args: [1, 100]
  584 +
  585 +# ----------------------------------------------------------------------------
  586 +- type: information
  587 + ref: tut-yamllint
  588 + title: Sugestões para validar yaml
  589 + text: |
  590 + Como os testes e perguntas são ficheiros `yaml`, é conveniente validar se
  591 + estão correctamente definitos. Um *linter* recomendado é o `yamllint`. Pode
  592 + ser instalado com `pip install yamllint` e usado do seguinte modo:
  593 +
  594 + ```sh
  595 + yamllint test.yaml
  596 + yamllint questions.yaml
  597 + ```
  598 +
  599 + No caso de programas geradores de perguntas e programas de correcção de
  600 + respostas pode usar-se um *pipe*:
  601 +
  602 + ```sh
  603 + generate-question | yamllint -
  604 + correct-answer | yamllint -
  605 + ```
... ...
perguntations/__init__.py
... ... @@ -32,7 +32,7 @@ proof of submission and for review.
32 32 '''
33 33  
34 34 APP_NAME = 'perguntations'
35   -APP_VERSION = '2020.05.dev2'
  35 +APP_VERSION = '2020.05.dev3'
36 36 APP_DESCRIPTION = __doc__
37 37  
38 38 __author__ = 'Miguel Barão'
... ...
perguntations/app.py
... ... @@ -276,8 +276,9 @@ class App():
276 276 uid, area, win_x, win_y, scr_x, scr_y)
277 277  
278 278 # ------------------------------------------------------------------------
  279 + # --- GETTERS
  280 + # ------------------------------------------------------------------------
279 281  
280   - # --- helpers (getters)
281 282 # def get_student_name(self, uid):
282 283 # return self.online[uid]['student']['name']
283 284  
... ... @@ -388,7 +389,10 @@ class App():
388 389 # if q['ref'] == ref and key in q['files']:
389 390 # return path.abspath(path.join(q['path'], q['files'][key]))
390 391  
391   - # --- helpers (change state)
  392 + # ------------------------------------------------------------------------
  393 + # --- SETTERS
  394 + # ------------------------------------------------------------------------
  395 +
392 396 def allow_student(self, uid):
393 397 '''allow a single student to login'''
394 398 self.allowed.add(uid)
... ...
perguntations/models.py
... ... @@ -90,5 +90,5 @@ class Question(Base):
90 90 f' grade: "{self.grade}"\n'
91 91 f' starttime: "{self.starttime}"\n'
92 92 f' finishtime: "{self.finishtime}"\n'
93   - f' student_id: "{self.student_id}"\n'
  93 + f' student_id: "{self.student_id}"\n' # FIXME normal form
94 94 f' test_id: "{self.test_id}"\n')
... ...
perguntations/serve.py
... ... @@ -246,7 +246,7 @@ class AdminHandler(BaseHandler):
246 246 self.testapp.deny_student(value)
247 247  
248 248 elif cmd == 'reset_password':
249   - await self.testapp.update_student_password(uid=value, pw='')
  249 + await self.testapp.update_student_password(uid=value, password='')
250 250  
251 251 elif cmd == 'insert_student':
252 252 student = json.loads(value)
... ...
perguntations/templates/review-question-information.html
... ... @@ -18,7 +18,7 @@
18 18 </div>
19 19 {% if t['show_ref'] %}
20 20 <hr>
21   - File: <code>{{ q['path'] }}/{{ q['filename'] }}</code>,
22   - Ref: <code>{{ q['ref'] }}</code>
  21 + file: <code>{{ q['path'] }}/{{ q['filename'] }}</code><br>
  22 + ref: <code>{{ q['ref'] }}</code>
23 23 {% end %}
24 24 </div>
25 25 \ No newline at end of file
... ...
perguntations/templates/review-question.html
... ... @@ -66,8 +66,8 @@
66 66  
67 67 {% if t['show_ref'] %}
68 68 <hr>
69   - File: <code>{{ q['path'] }}/{{ q['filename'] }}</code>,
70   - Ref: <code>{{ q['ref'] }}</code>
  69 + file: <code>{{ q['path'] }}/{{ q['filename'] }}</code><br>
  70 + ref: <code>{{ q['ref'] }}</code>
71 71 {% end %}
72 72  
73 73 </div> <!-- card-footer -->
... ... @@ -110,8 +110,8 @@
110 110  
111 111 {% if t['show_ref'] %}
112 112 <hr>
113   - File: <code>{{ q['path'] }}/{{ q['filename'] }}</code>,
114   - Ref: <code>{{ q['ref'] }}</code>
  113 + file: <code>{{ q['path'] }}/{{ q['filename'] }}</code><br>
  114 + ref: <code>{{ q['ref'] }}</code>
115 115 {% end %}
116 116  
117 117 </div> <!-- card-footer -->
... ...