Commit f6fdbdbd5f3714cdcf00a8f374855e5cabf3a985

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

- fix some imports

- codemirror converts tabs to 4 spaces. tab indents, shift-tab dedents
1 1
2 # BUGS 2 # BUGS
3 3
4 -- correct devia poder ser corrido mais que uma vez (por exemplo para alterar cotacoes, corrigir perguntas) 4 +- show_points nao esta a funcionar (mostra sempre)
  5 +- esta a corrigir código JOBE mesmo que nao tenha respondido???
  6 +- correct devia poder ser corrido mais que uma vez (por exemplo para alterar
  7 + cotacoes, corrigir perguntas)
5 - nao esta a mostrar imagens?? internal server error? 8 - nao esta a mostrar imagens?? internal server error?
6 -- guardar testes em JSON assim que sao atribuidos aos alunos (ou guardados inicialmente com um certo nome, e atribuidos posteriormente ao aluno).  
7 -- cookies existe um perguntations_user e um user. De onde vem o user?  
8 -- QuestionCode falta reportar nos comments os vários erros que podem ocorrer (timeout, etc)  
9 -- algumas vezes a base de dados guarda o mesmo teste em duplicado. ver se dois submits dao origem a duas correcções.  
10 -talvez a base de dados devesse ter como chave do teste um id que fosse único desse teste particular (não um auto counter, nem ref do teste)  
11 -- em caso de timeout na submissão (e.g. JOBE ou script nao responde) a correcção não termina e o teste não é guardado. 9 +- guardar testes em JSON assim que sao atribuidos aos alunos (ou guardados
  10 + inicialmente com um certo nome, e atribuidos posteriormente ao aluno).
  11 +- cookies existe um `perguntations_user` e um user. De onde vem o user?
  12 +- QuestionCode falta reportar nos comments os vários erros que podem ocorrer
  13 + (timeout, etc)
  14 +- algumas vezes a base de dados guarda o mesmo teste em duplicado. ver se dois
  15 + submits dao origem a duas correcções. talvez a base de dados devesse ter
  16 + como chave do teste um id que fosse único desse teste particular (não um auto
  17 + counter, nem ref do teste)
  18 +- em caso de timeout na submissão (e.g. JOBE ou script nao responde) a
  19 + correcção não termina e o teste não é guardado.
12 - grade gives internal server error?? 20 - grade gives internal server error??
13 - reload do teste recomeça a contagem no inicio do tempo. 21 - reload do teste recomeça a contagem no inicio do tempo.
14 -- 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.  
15 -- 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).  
16 -- 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>.  
17 -- 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. 22 +- em admin, quando `scale_max` não é 20, as cores das barras continuam a
  23 + reflectir a escala 0,20. a tabela teste na DB não tem a escala desse teste.
  24 +- em grade.html as barras estao normalizadas para os limites `scale_min` e max
  25 + do teste actual e nao dos testes realizados no passado (tabela test devia
  26 + guardar a escala).
  27 +- codigo `hello world` nao esta a preservar o whitespace. O renderer de
  28 + markdown gera a tag `<code>` que não preserva whitespace. Necessario
  29 + adicionar `<pre>.`
  30 +- mensagems de erro do assembler aparecem na mesma linha na correcao e nao
  31 + fazerm rendering do `$t`, ver se servidor faz parse do markdown dessas
  32 + mensagens.
18 - a revisao do teste não mostra as imagens. 33 - a revisao do teste não mostra as imagens.
19 -- Test.reset_answers() unused. 34 +- `Test.reset_answers()` unused.
20 - teste nao esta a mostrar imagens de vez em quando.??? 35 - teste nao esta a mostrar imagens de vez em quando.???
21 - show-ref nao esta a funcionar na correccao (pelo menos) 36 - show-ref nao esta a funcionar na correccao (pelo menos)
22 37
23 # TODO 38 # TODO
24 39
25 -- JOBE correct async  
26 -- esta a corrigir código JOBE mesmo que nao tenha respondido??? 40 +- permitir que textarea nao tenha correct definido, da sempre 0 e é para
  41 + corrigir manualmente.
  42 +- permitir corrigir mais que uma vez, actualizando a base de dados.
  43 +- yaml schemas para validar os ficheiros yaml (ver cerberus e jsonschema)
27 - permitir remover alunos que estão online para poderem comecar de novo. 44 - permitir remover alunos que estão online para poderem comecar de novo.
28 -- guardar nota final grade truncado em zero e sem ser truncado (quando é necessário fazer correcções à mão às perguntas, é necessário o valor não truncado)  
29 -- stress tests. use https://locust.io 45 +- guardar nota final grade truncado em zero e sem ser truncado (quando é
  46 + necessário fazer correcções à mão às perguntas, é necessário o valor não
  47 + truncado)
  48 +- stress tests. use [locust](https://locust.io)
30 - wait for admin to start test. (students can be allowed earlier) 49 - wait for admin to start test. (students can be allowed earlier)
31 -- impedir os eventos copy/paste. alunos usam isso para trazer codigo ja feito nos computadores. Obrigar a fazer reset? fazer um copy automaticamente?  
32 -- na pagina admin, mostrar com cor vermelha as horas de entrada dos alunos que ja tenham excedido o tempo  
33 -- retornar None quando nao ha alteracoes relativamente à última vez.  
34 -ou usar push (websockets?)  
35 -- mudar ref do test para test_id (ref já é usado nas perguntas) 50 +- impedir os eventos copy/paste. alunos usam isso para trazer codigo ja feito
  51 + nos computadores. Obrigar a fazer reset? fazer um copy automaticamente?
  52 +- na pagina admin, mostrar com cor vermelha as horas de entrada dos alunos que
  53 + ja tenham excedido o tempo
  54 +- retornar None quando nao ha alteracoes relativamente à última vez. ou usar
  55 + push (websockets?)
  56 +- mudar ref do test para `test_id` (ref já é usado nas perguntas)
36 - servidor ntpd no x220 para configurar a data/hora dos portateis dell 57 - servidor ntpd no x220 para configurar a data/hora dos portateis dell
37 -- sala de espera: autorização dada, mas teste não disponível até que seja dada ordem para começar.  
38 -- alunos com necessidades especiais nao podem ter autosubmit. ter um autosubmit_exceptions: ['123', '456'] 58 +- sala de espera: autorização dada, mas teste não disponível até que seja dada
  59 + ordem para começar.
  60 +- alunos com necessidades especiais nao podem ter autosubmit. ter um
  61 + `autosubmit_exceptions`: ['123', '456']
39 - submissao fazer um post ajax? 62 - submissao fazer um post ajax?
40 - adicionar opcao para eliminar um teste em curso. 63 - adicionar opcao para eliminar um teste em curso.
41 - enviar resposta de cada pergunta individualmente. 64 - enviar resposta de cada pergunta individualmente.
42 -- experimentar gerador de svg que inclua no markdown da pergunta e ver se funciona.  
43 -- quando ha varias perguntas para escolher, escolher sucessivamente em vez de aleatoriamente. 65 +- experimentar gerador de svg que inclua no markdown da pergunta e ver se
  66 + funciona.
  67 +- quando ha varias perguntas para escolher, escolher sucessivamente em vez de
  68 + aleatoriamente.
44 - como refrescar a tabela de admin sem fazer reload da pagina? 69 - como refrescar a tabela de admin sem fazer reload da pagina?
45 -- botao "testar resposta" que valida codigo relativamente a syntax, mas nao classifica. perguntas devem ter opcao validate: script.py. Aluno pressiona botao e codigo é enviado para servidor para validação, feedback é mostrado na pagina de teste.  
46 -- test: botao submeter valida se esta online com um post willing_to_submit, se estiver online, mostra mensagem de confirmacao, caso contrario avisa que nao esta online. 70 +- botao "testar resposta" que valida codigo relativamente a syntax, mas nao
  71 + classifica. perguntas devem ter opcao validate: script.py. Aluno pressiona
  72 + botao e codigo é enviado para servidor para validação, feedback é mostrado na
  73 + pagina de teste.
  74 +- test: botao submeter valida se esta online com um post `willing_to_submit`,
  75 + se estiver online, mostra mensagem de confirmacao, caso contrario avisa que
  76 + nao esta online.
47 - test: Cada pergunta respondida é logo submetida. 77 - test: Cada pergunta respondida é logo submetida.
48 - test: calculadora javascript. 78 - test: calculadora javascript.
49 - admin: histograma das notas. 79 - admin: histograma das notas.
50 - admin: mostrar as horas a que o teste terminou para os testes terminados. 80 - admin: mostrar as horas a que o teste terminou para os testes terminados.
51 - admin: histograma das notas. 81 - admin: histograma das notas.
52 - admin: mostrar teste gerado para aluno (tipo review). 82 - admin: mostrar teste gerado para aluno (tipo review).
53 -- fazer renderer para formulas com mathjax serverside (mathjax-node) ou usar katex. 83 +- fazer renderer para formulas com mathjax serverside (mathjax-node) ou usar
  84 + katex.
54 - fazer renderer para imagens, com links /file?ref=xpto;name=zzz.jpg 85 - fazer renderer para imagens, com links /file?ref=xpto;name=zzz.jpg
55 - fazer renderer para linguagem assembly mips? 86 - fazer renderer para linguagem assembly mips?
56 -- cancelar teste no menu admin. Dado o numero de aluno remove teste e faz logout do aluno.  
57 -- mathjax-node:  
58 - sudo pkg install node npm  
59 - npm install mathjax-node mathjax-node-cli # pacotes em ~/node_modules  
60 - node_modules/mathjax-node-cli/bin/tex2svg '\sqrt{x}'  
61 - usar isto para gerar svg que passa a fazer parte do texto da pergunta (markdown suporta tags svg?)  
62 - fazer funçao tex() que recebe formula e converte para svg. exemplo:  
63 - fr'''A formula é {tex("\sqrt{x]}")}''' 87 +- cancelar teste no menu admin. Dado o numero de aluno remove teste e faz
  88 + logout do aluno.
64 - Gerar pdf's com todos os testes no final (pdfkit). 89 - Gerar pdf's com todos os testes no final (pdfkit).
65 -- manter registo dos unfocus durante o teste e de qual a pergunta visivel nesse momento 90 +- manter registo dos unfocus durante o teste e de qual a pergunta visivel nesse
  91 + momento
66 - permitir varios testes, aluno escolhe qual o teste que quer fazer. 92 - permitir varios testes, aluno escolhe qual o teste que quer fazer.
67 - se ocorrer um erro na correcçao avisar aluno para contactar o professor. 93 - se ocorrer um erro na correcçao avisar aluno para contactar o professor.
68 -- abrir o teste numa janela maximizada e que nao permite que o aluno a redimensione/mova?  
69 -- detectar scroll e enviar posição para servidor (analise de scroll para detectar copianço? ou simplesmente para analisar como os alunos percorrem o teste)  
70 -- aviso na pagina principal para quem usa browser incompativel ou settings esquisitos... Apos login pode ser enviado e submetido um exemplo de teste para verificar se browser consegue submeter? ha alunos com javascript bloqueado? 94 +- abrir o teste numa janela maximizada e que nao permite que o aluno a
  95 + redimensione/mova?
  96 +- detectar scroll e enviar posição para servidor (analise de scroll para
  97 + detectar copianço? ou simplesmente para analisar como os alunos percorrem o
  98 + teste)
  99 +- aviso na pagina principal para quem usa browser incompativel ou settings
  100 + esquisitos... Apos login pode ser enviado e submetido um exemplo de teste
  101 + para verificar se browser consegue submeter? ha alunos com javascript
  102 + bloqueado?
71 - criar perguntas de outros tipos, e.g. associação, ordenação, varios textinput 103 - criar perguntas de outros tipos, e.g. associação, ordenação, varios textinput
72 -- perguntas para professor corrigir mais tarde. permitir que review possa alterar as notas 104 +- perguntas para professor corrigir mais tarde. permitir que review possa
  105 + alterar as notas
73 - fazer uma calculadora javascript e por no menu. surge como modal 106 - fazer uma calculadora javascript e por no menu. surge como modal
74 107
75 # FIXED 108 # FIXED
76 109
  110 +- JOBE correct async
77 - testar as perguntas todas no início do teste como o aprendizations. 111 - testar as perguntas todas no início do teste como o aprendizations.
78 -- adicionar identificacao do aluno no jumbotron inicial do teste, para que ao imprimir para pdf a identificacao do aluno venha escrita no documento. 112 +- adicionar identificacao do aluno no jumbotron inicial do teste, para que ao
  113 + imprimir para pdf a identificacao do aluno venha escrita no documento.
79 - internal server error quando em --review, download csv detalhado. 114 - internal server error quando em --review, download csv detalhado.
80 -- perguntas repetidas (mesma ref) dao asneira, porque a referencia é usada como chave em varios sitios e as chaves nao podem ser dupplicadas.  
81 - da asneira pelo menos na funcao get_questions_csv. na base de dados tem de estar registado tb o numero da pergunta, caso contrario é impossível saber a qual corresponde. 115 +- perguntas repetidas (mesma ref) dao asneira, porque a referencia é usada como
  116 + chave em varios sitios e as chaves nao podem ser dupplicadas. da asneira
  117 + pelo menos na funcao `get_questions_csv`. na base de dados tem de estar
  118 + registado tb o numero da pergunta, caso contrario é impossível saber a qual
  119 + corresponde.
82 - mostrar unfocus e window area em /admin 120 - mostrar unfocus e window area em /admin
83 -- CRITICAL se answer for `i<n` a revisão de provas mostra apenas i (interpreta `<` como tag?) 121 +- CRITICAL se answer for `i<n` a revisão de provas mostra apenas i (interpreta
  122 + `<` como tag?)
84 - botao de autorizar desliga-se, fazer debounce. 123 - botao de autorizar desliga-se, fazer debounce.
85 - link na pagina com a nota para voltar ao principio. 124 - link na pagina com a nota para voltar ao principio.
86 - default logger config mostrar horas com segundos 125 - default logger config mostrar horas com segundos
@@ -89,33 +128,45 @@ ou usar push (websockets?) @@ -89,33 +128,45 @@ ou usar push (websockets?)
89 - servidor nao esta a lidar com eventos resize. 128 - servidor nao esta a lidar com eventos resize.
90 - sock.bind(sockaddr) OSError: [Errno 48] Address already in use 129 - sock.bind(sockaddr) OSError: [Errno 48] Address already in use
91 - dizer quanto desconta em cada pergunta de escolha multipla 130 - dizer quanto desconta em cada pergunta de escolha multipla
92 -- se houver erros a abrir ficheiros .yaml de perguntas, depois dos testes diz "No errors found".  
93 -- se faltarem files na especificação do teste, o check não detecta e factory não gera para essas perguntas. 131 +- se houver erros a abrir ficheiros .yaml de perguntas, depois dos testes diz
  132 + "No errors found".
  133 +- se faltarem files na especificação do teste, o check não detecta e factory
  134 + não gera para essas perguntas.
94 - nao esta a usar points das perguntas 135 - nao esta a usar points das perguntas
95 - quando se clica no texto de uma opcao, salta para outro lado na pagina. 136 - quando se clica no texto de uma opcao, salta para outro lado na pagina.
96 -- 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. 137 +- suportar cotacao to teste diferente de 20 (e.g. para juntar perguntas em
  138 + papel). opcao "points: 18" que normaliza total para 18 em vez de 20.
97 - fazer package para instalar perguntations com pip. 139 - fazer package para instalar perguntations com pip.
98 - pymips: nao pode executar syscalls do spim. 140 - pymips: nao pode executar syscalls do spim.
99 - exception sqlalchemy relacionada com threads. 141 - exception sqlalchemy relacionada com threads.
100 - acrescentar logger.conf que sirva de base. 142 - acrescentar logger.conf que sirva de base.
101 -- questions.py textarea has a abspath which does not make sense! why is it there? not working for perguntations, but seems to work for aprendizations  
102 -- textarea foi modificado em aprendizations para receber cmd line args. corrigir aqui tb. 143 +- questions.py textarea has a abspath which does not make sense! why is it
  144 + there? not working for perguntations, but seems to work for aprendizations
  145 +- textarea foi modificado em aprendizations para receber cmd line args.
  146 + corrigir aqui tb.
103 - usar npm para instalar javascript 147 - usar npm para instalar javascript
104 - se aluno entrar com l12345 rebenta. numa funcao get_... ver imagem no ipad 148 - se aluno entrar com l12345 rebenta. numa funcao get_... ver imagem no ipad
105 -- no test3 está contar 1.0 valores numa pergunta do tipo info? acontece para type: info, e não para type: information  
106 -- default correct in checkbox must be 1.0, so that the pairs (right,wrong) still work with `correct` left undefined. 149 +- no test3 está contar 1.0 valores numa pergunta do tipo info? acontece para
  150 + type: info, e não para type: information
  151 +- default correct in checkbox must be 1.0, so that the pairs (right,wrong)
  152 + still work with `correct` left undefined.
107 - textarea com codemirror 153 - textarea com codemirror
108 - decorador para user 0, evita o "if uid==0" em muitas funcoes. 154 - decorador para user 0, evita o "if uid==0" em muitas funcoes.
109 -- numeric interval deve converter respostas que usam virgulas para pontos decimais  
110 -- self.testapp.get_json_filename_of_test(test_id) retorna None quando test_id nao existe.  
111 -- o eventloop está a bloquear. correção do teste é blocking. usar threadpoolexecutor?  
112 -- substituir get_event_loop por get_runnint_loop (ver https://docs.python.org/3/library/asyncio-eventloop.html) 155 +- numeric interval deve converter respostas que usam virgulas para pontos
  156 + decimais
  157 +- `self.testapp.get_json_filename_of_test(test_id)` retorna None quando test_id
  158 + nao existe.
  159 +- o eventloop está a bloquear. correção do teste é blocking. usar
  160 + threadpoolexecutor?
  161 +- substituir get_event_loop por get_runnint_loop
113 - review nao esta a funcionar 162 - review nao esta a funcionar
114 -- servir imagens das perguntas não funciona. Necessario passar a ref da pergunta no link para poder ajustar o path no FileHandler. 163 +- servir imagens das perguntas não funciona. Necessario passar a ref da
  164 + pergunta no link para poder ajustar o path no FileHandler.
115 - a primeira coluna da tabela admin deveria estar sempre ordenada. 165 - a primeira coluna da tabela admin deveria estar sempre ordenada.
116 - abortar depois de testar todas as perguntas, caso haja algum erro. 166 - abortar depois de testar todas as perguntas, caso haja algum erro.
117 - imagens jpg/png nas perguntas. 167 - imagens jpg/png nas perguntas.
118 -- initdb está a inicializar com passwords iguais aos numeros. deveria ser vazio para alunos definirem. 168 +- initdb está a inicializar com passwords iguais aos numeros. deveria ser vazio
  169 + para alunos definirem.
119 - upgrade popper e fazer link. 170 - upgrade popper e fazer link.
120 - mover scripts js para head, com defer. ver todos os templates. 171 - mover scripts js para head, com defer. ver todos os templates.
121 - update fontawesome to 5. 172 - update fontawesome to 5.
@@ -125,7 +176,8 @@ ou usar push (websockets?) @@ -125,7 +176,8 @@ ou usar push (websockets?)
125 - md_to_html() nao usa o segundo argumento q. pode retirar-se dos templates? 176 - md_to_html() nao usa o segundo argumento q. pode retirar-se dos templates?
126 - config/logger.yaml ainda é do cherrypy... 177 - config/logger.yaml ainda é do cherrypy...
127 - uniformizar question.py com a de aprendizations... 178 - uniformizar question.py com a de aprendizations...
128 -- qual a diferenca entre md_to_html e md_to_html_review, parece desnecessario haver dois. 179 +- qual a diferenca entre md_to_html e md_to_html_review, parece desnecessario
  180 + haver dois.
129 - converter markdown para mistune. 181 - converter markdown para mistune.
130 - como alterar configuracao para mostrar logs de debug? 182 - como alterar configuracao para mostrar logs de debug?
131 - espaco no final das tabelas. 183 - espaco no final das tabelas.
@@ -141,31 +193,43 @@ ou usar push (websockets?) @@ -141,31 +193,43 @@ ou usar push (websockets?)
141 - text-numeric não está a gerar a pergunta. faltam templates? 193 - text-numeric não está a gerar a pergunta. faltam templates?
142 - testar perguntas warning/warn 194 - testar perguntas warning/warn
143 - qd user 0 faz logout rebenta. 195 - qd user 0 faz logout rebenta.
144 -- Quando grava JSON do teste deve usar 'path' tal como definido na configuração e não expandido. Isto porque em OSX /home é /Users e quando se muda de um sistema para outro não encontra os testes. Assim, usando ~ na configuração deveria funcionar sempre.  
145 -- configuração do teste não joga bem com o do aprendizations. Em particular os scripts não ficam com o mesmo path!!! 196 +- Quando grava JSON do teste deve usar 'path' tal como definido na configuração
  197 + e não expandido. Isto porque em OSX /home é /Users e quando se muda de um
  198 + sistema para outro não encontra os testes. Assim, usando ~ na configuração
  199 + deveria funcionar sempre.
  200 +- configuração do teste não joga bem com o do aprendizations. Em particular os
  201 + scripts não ficam com o mesmo path!!!
146 - configurar pf em freebsd, port forward 80 -> 8080. documentacao 202 - configurar pf em freebsd, port forward 80 -> 8080. documentacao
147 - barras com notas em grade estão desalinhadas. 203 - barras com notas em grade estão desalinhadas.
148 - erros nos generators devem ser ERROR e não WARNING. 204 - erros nos generators devem ser ERROR e não WARNING.
149 -- se directorio "logs" não existir no directorio actual aborta com mensagem de erro.  
150 -- se um teste tiver a mesma pergunta repetida (ref igual), rebenta na correcçao. As respostas são agregadas numa lista para cada ref. Ex: {'ref1': 'resposta1', 'ref2': ['resposta2a', 'resposta2b']}  
151 -- usar http://fontawesome.io/examples/ em vez dos do bootstrap3 205 +- se directorio "logs" não existir no directorio actual aborta com mensagem de
  206 + erro.
  207 +- se um teste tiver a mesma pergunta repetida (ref igual), rebenta na
  208 + correcçao. As respostas são agregadas numa lista para cada ref. Ex: {'ref1':
  209 + 'resposta1', 'ref2': ['resposta2a', 'resposta2b']}
  210 +- usar [](http://fontawesome.io/examples/) em vez dos do bootstrap3
152 - se pergunta tiver 'type:' errado, rebenta. 211 - se pergunta tiver 'type:' errado, rebenta.
153 - se submeter um teste so com information, da divisao por zero. 212 - se submeter um teste so com information, da divisao por zero.
154 -- se save_answers nao existir, da warning que nao serao gravados, mas sao sempre gravados! pagina de administracao diz --not being saved-- 213 +- se save_answers nao existir, da warning que nao serao gravados, mas sao
  214 + sempre gravados! pagina de administracao diz --not being saved--
155 - first login é INFO e não WARNING 215 - first login é INFO e não WARNING
156 - /review não mostra imagens porque precisa que teste esteja a decorrer... 216 - /review não mostra imagens porque precisa que teste esteja a decorrer...
157 - visualizar um teste ja realizado na página de administração 217 - visualizar um teste ja realizado na página de administração
158 -- Depois da correcção, mostra testes realizados que não foram realizados pelo próprio  
159 -- detectar se janela perde focus e alertar o prof (http://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active)  
160 -- server nao esta a receber eventos focus/blur dos utilizadores diferentes de '0', estranho... 218 +- Depois da correcção, mostra testes realizados que não foram realizados pelo
  219 + próprio
  220 +- detectar se janela perde focus e alertar o prof
  221 +- server nao esta a receber eventos focus/blur dos utilizadores diferentes de
  222 + '0', estranho...
161 - permitir adicionar imagens nas perguntas. 223 - permitir adicionar imagens nas perguntas.
162 - detect_unfocus.js so funciona se estiver inline no html. porquê??? 224 - detect_unfocus.js so funciona se estiver inline no html. porquê???
163 - inserir novo aluno /admin não fecha. 225 - inserir novo aluno /admin não fecha.
164 - se aluno desistir, ainda fica marcado como online 226 - se aluno desistir, ainda fica marcado como online
165 - give dá None em vez de 0.0 227 - give dá None em vez de 0.0
166 - debug mode: log levels not working 228 - debug mode: log levels not working
167 -- Se aluno fizer logout, o teste não é gravado e ficamos sem registo do teste que o aluno viu.  
168 -- criar sqlalchemy sessions dentro de app de modo a estarem associadas a requests. ver se é facil usar with db:(...) para criar e fechar sessão. 229 +- Se aluno fizer logout, o teste não é gravado e ficamos sem registo do teste
  230 + que o aluno viu.
  231 +- criar sqlalchemy sessions dentro de app de modo a estarem associadas a
  232 + requests. ver se é facil usar with db:(...) para criar e fechar sessão.
169 - sqlalchemy queixa-se de threads. 233 - sqlalchemy queixa-se de threads.
170 - SQLAlchemy em vez da classe database. 234 - SQLAlchemy em vez da classe database.
171 - replace sys.exit calls 235 - replace sys.exit calls
@@ -174,20 +238,21 @@ ou usar push (websockets?) @@ -174,20 +238,21 @@ ou usar push (websockets?)
174 - configuracao dos logs cherrypy para se darem bem com os outros 238 - configuracao dos logs cherrypy para se darem bem com os outros
175 - browser e ip usados gravado no test. 239 - browser e ip usados gravado no test.
176 - botões allow all/deny all. 240 - botões allow all/deny all.
177 -- mostrar botão de reset apenas no final da pagina, com edit para escrever o número.  
178 -- aluno faz login, mas fecha browser, ficando no estado (online,deny). Ao tentar login com outro browser está deny e o prof não consegue pô-lo em allow pois já não está na lista. => solucao é manter todos os alunos numa tabela.  
179 -- pagina de login nao esta a apresentar bem. parece que precisa de autorizacao para aceder a /static... 241 +- mostrar botão de reset apenas no final da pagina, com edit para escrever o
  242 + número.
  243 +- aluno faz login, mas fecha browser, ficando no estado (online,deny). Ao
  244 + tentar login com outro browser está deny e o prof não consegue pô-lo em allow
  245 + pois já não está na lista. => solucao é manter todos os alunos numa tabela.
  246 +- pagina de login nao esta a apresentar bem. parece que precisa de autorizacao
  247 + para aceder a /static...
180 - Não mostrar Professor nos activos em /admin 248 - Não mostrar Professor nos activos em /admin
181 - /admin mostrar actualizações automaticamente? 249 - /admin mostrar actualizações automaticamente?
182 - se no teste uma das "ref" nao existir nos ficheiros de perguntas, rebenta. 250 - se no teste uma das "ref" nao existir nos ficheiros de perguntas, rebenta.
183 -- alunos podem estar online, mas browser perder sessao => nao conseguem mais entrar porque a App pensa que estão online. Permitir login e dar o mesmo teste.  
184 -- pagina de management dos alunos.  
185 - mostrar online ordenados por hora de login, offline por número.  
186 - permitir reset da pw e allow/disallow 251 +- alunos podem estar online, mas browser perder sessao => nao conseguem mais
  252 + entrar porque a App pensa que estão online. Permitir login e dar o mesmo
  253 + teste.
  254 +- pagina de management dos alunos. mostrar online ordenados por hora de login,
  255 + offline por número. permitir reset da pw e allow/disallow
187 - script de correcção pode enviar dicionario yaml com grade e comentarios. ex: 256 - script de correcção pode enviar dicionario yaml com grade e comentarios. ex:
188 - grade: 0.5  
189 - comments: Falhou na função xpto.  
190 - os comentários são guardados no teste (ficheiro) ou enviados para o browser no modo practice.  
191 -- testar regex na definicao das perguntas. como se faz rawstring em yaml?  
192 - singlequote? problemas de backslash??? sim... necessário fazer \\ em varios casos, mas não é claro! e.g. \n é convertido em espaço mas \w é convertido em \\ e w. Solução (http://stackoverflow.com/questions/10771163/python-interpreting-a-regex-from-a-yaml-config-file) é fazer  
193 - correct: !regex '^(yes|no)' 257 + grade: 0.5 comments: Falhou na função xpto. os comentários são guardados no
  258 + teste (ficheiro) ou enviados para o browser no modo practice.
perguntations/__init__.py
@@ -32,7 +32,7 @@ proof of submission and for review. @@ -32,7 +32,7 @@ proof of submission and for review.
32 ''' 32 '''
33 33
34 APP_NAME = 'perguntations' 34 APP_NAME = 'perguntations'
35 -APP_VERSION = '2021.01.dev1' 35 +APP_VERSION = '2021.02.dev1'
36 APP_DESCRIPTION = __doc__ 36 APP_DESCRIPTION = __doc__
37 37
38 __author__ = 'Miguel Barão' 38 __author__ = 'Miguel Barão'
perguntations/app.py
@@ -86,7 +86,7 @@ class App(): @@ -86,7 +86,7 @@ class App():
86 session.close() 86 session.close()
87 87
88 # ------------------------------------------------------------------------ 88 # ------------------------------------------------------------------------
89 - def __init__(self, conf): 89 + def __init__(self, conf) -> None:
90 self.online = dict() # {uid: {'student':{...}, 'test': {...}}, ...} 90 self.online = dict() # {uid: {'student':{...}, 'test': {...}}, ...}
91 self.allowed = set() # '0' is hardcoded to allowed elsewhere 91 self.allowed = set() # '0' is hardcoded to allowed elsewhere
92 self.unfocus = set() # set of students that have no browser focus 92 self.unfocus = set() # set of students that have no browser focus
@@ -127,9 +127,10 @@ class App(): @@ -127,9 +127,10 @@ class App():
127 self._correct_tests() 127 self._correct_tests()
128 128
129 # ------------------------------------------------------------------------ 129 # ------------------------------------------------------------------------
130 - def _correct_tests(self): 130 + def _correct_tests(self) -> None:
131 with self._db_session() as sess: 131 with self._db_session() as sess:
132 - # Find which tests have to be corrected 132 + # Find which tests have to be corrected.
  133 + # already corrected tests are not included.
133 dbtests = sess.query(Test)\ 134 dbtests = sess.query(Test)\
134 .filter(Test.ref == self.testfactory['ref'])\ 135 .filter(Test.ref == self.testfactory['ref'])\
135 .filter(Test.state == "SUBMITTED")\ 136 .filter(Test.state == "SUBMITTED")\
perguntations/initdb.py
@@ -14,6 +14,8 @@ from concurrent.futures import ThreadPoolExecutor @@ -14,6 +14,8 @@ from concurrent.futures import ThreadPoolExecutor
14 # installed packages 14 # installed packages
15 import bcrypt 15 import bcrypt
16 import sqlalchemy as sa 16 import sqlalchemy as sa
  17 +import sqlalchemy.orm
  18 +from sqlalchemy.exc import IntegrityError
17 19
18 # this project 20 # this project
19 from perguntations.models import Base, Student 21 from perguntations.models import Base, Student
@@ -119,8 +121,7 @@ def insert_students_into_db(session, students): @@ -119,8 +121,7 @@ def insert_students_into_db(session, students):
119 session.add_all([Student(id=s['uid'], name=s['name'], password=s['pw']) 121 session.add_all([Student(id=s['uid'], name=s['name'], password=s['pw'])
120 for s in students]) 122 for s in students])
121 session.commit() 123 session.commit()
122 -  
123 - except sa.exc.IntegrityError: 124 + except IntegrityError:
124 print('!!! Integrity error. Users already in database. Aborted !!!\n') 125 print('!!! Integrity error. Users already in database. Aborted !!!\n')
125 session.rollback() 126 session.rollback()
126 127
@@ -160,7 +161,7 @@ def main(): @@ -160,7 +161,7 @@ def main():
160 print(f'Using database: {args.db}') 161 print(f'Using database: {args.db}')
161 engine = sa.create_engine(f'sqlite:///{args.db}', echo=False) 162 engine = sa.create_engine(f'sqlite:///{args.db}', echo=False)
162 Base.metadata.create_all(engine) # Criates schema if needed 163 Base.metadata.create_all(engine) # Criates schema if needed
163 - SessionMaker = sa.orm.sessionmaker(bind=engine) 164 + SessionMaker = sqlalchemy.orm.sessionmaker(bind=engine)
164 session = SessionMaker() 165 session = SessionMaker()
165 166
166 # --- make list of students to insert 167 # --- make list of students to insert
perguntations/main.py
@@ -8,6 +8,7 @@ Main file that starts the application and the web server @@ -8,6 +8,7 @@ Main file that starts the application and the web server
8 # python standard library 8 # python standard library
9 import argparse 9 import argparse
10 import logging 10 import logging
  11 +import logging.config
11 import os 12 import os
12 from os import environ, path 13 from os import environ, path
13 import ssl 14 import ssl
@@ -64,7 +65,7 @@ def parse_cmdline_arguments(): @@ -64,7 +65,7 @@ def parse_cmdline_arguments():
64 65
65 66
66 # ---------------------------------------------------------------------------- 67 # ----------------------------------------------------------------------------
67 -def get_logger_config(debug=False): 68 +def get_logger_config(debug=False) -> dict:
68 ''' 69 '''
69 Load logger configuration from ~/.config directory if exists, 70 Load logger configuration from ~/.config directory if exists,
70 otherwise set default paramenters. 71 otherwise set default paramenters.
@@ -113,7 +114,7 @@ def get_logger_config(debug=False): @@ -113,7 +114,7 @@ def get_logger_config(debug=False):
113 114
114 115
115 # ---------------------------------------------------------------------------- 116 # ----------------------------------------------------------------------------
116 -def main(): 117 +def main() -> None:
117 ''' 118 '''
118 Tornado web server 119 Tornado web server
119 ''' 120 '''
perguntations/templates/test.html
@@ -156,6 +156,13 @@ @@ -156,6 +156,13 @@
156 viewportMargin: Infinity, 156 viewportMargin: Infinity,
157 matchBrackets: true, 157 matchBrackets: true,
158 styleActiveLine: true, 158 styleActiveLine: true,
  159 + indentUnit: 4,
  160 + indentWithTabs: false,
  161 + smartIndent: true,
  162 + extraKeys: {
  163 + "Tab": (cm) => cm.execCommand("indentMore"),
  164 + "Shift-Tab": (cm) => cm.execCommand("indentLess"),
  165 + },
159 }); 166 });
160 }); 167 });
161 </script> 168 </script>
perguntations/test.py
@@ -17,6 +17,16 @@ logger = logging.getLogger(__name__) @@ -17,6 +17,16 @@ logger = logging.getLogger(__name__)
17 class Test(dict): 17 class Test(dict):
18 ''' 18 '''
19 Each instance Test() is a concrete test of a single student. 19 Each instance Test() is a concrete test of a single student.
  20 + A test can be in one of the states: ACTIVE, SUBMITTED, CORRECTED, QUIT
  21 + Methods:
  22 + t.start(student) - marks start of test (register time and state)
  23 + t.reset_answers() - remove all answers from the test
  24 + t.update_answer(ref, ans) - update answer of a given question
  25 + t.submit(answers_dict) - update answers, register time and state
  26 + t.correct_async()
  27 + t.correct() - corrects questions and compute grade, register state
  28 + t.giveup() - register the test as given up, answers are not corrected
  29 + t.save_json(filename) - save the current test to file in JSON format
20 ''' 30 '''
21 31
22 # ------------------------------------------------------------------------ 32 # ------------------------------------------------------------------------