Commit f3635fa022e624a62b9941073656563a3ecec6e3
1 parent
a0ab1672
Exists in
master
and in
1 other branch
minor reorganization
update BUGS
Showing
8 changed files
with
694 additions
and
869 deletions
Show diff stats
BUGS.md
| 1 | +# Perguntations | ||
| 1 | 2 | ||
| 2 | -# BUGS | 3 | +## BUGS |
| 3 | 4 | ||
| 4 | -- correct devia poder ser corrido mais que uma vez (por exemplo para alterar cotacoes, corrigir perguntas) | ||
| 5 | -- guardar testes em JSON assim que sao atribuidos aos alunos (ou guardados inicialmente com um certo nome, e atribuidos posteriormente ao aluno). | ||
| 6 | -- cookies existe um perguntations_user e um user. De onde vem o user? | ||
| 7 | -- QuestionCode falta reportar nos comments os vários erros que podem ocorrer (timeout, etc) | ||
| 8 | -- algumas vezes a base de dados guarda o mesmo teste em duplicado. ver se dois submits dao origem a duas correcções. | ||
| 9 | -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) | ||
| 10 | -- 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. | ||
| 11 | -- grade gives internal server error?? | 5 | +- talvez a base de dados devesse ter como chave do teste um id que fosse único |
| 6 | + desse teste particular (não um auto counter, nem ref do teste) | ||
| 7 | +- em caso de timeout na submissão (e.g. JOBE ou script nao responde) a correcção | ||
| 8 | + não termina e o teste não é guardado. | ||
| 12 | - reload do teste recomeça a contagem no inicio do tempo. | 9 | - reload do teste recomeça a contagem no inicio do tempo. |
| 13 | -- 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. | ||
| 14 | -- 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). | ||
| 15 | -- 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>. | ||
| 16 | -- 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. | ||
| 17 | -- a revisao do teste não mostra as imagens. | ||
| 18 | -- Test.reset_answers() unused. | ||
| 19 | -- teste nao esta a mostrar imagens de vez em quando.??? | ||
| 20 | -- show-ref nao esta a funcionar na correccao (pelo menos) | 10 | +- em admin, quando scale_max não é 20, as cores das barras continuam a reflectir |
| 11 | + a escala 0,20. a tabela teste na DB não tem a escala desse teste. | ||
| 12 | +- mensagems de erro do assembler aparecem na mesma linha na correcao e nao | ||
| 13 | + fazerm rendering do `$t`, ver se servidor faz parse do markdown dessas | ||
| 14 | + mensagens. | ||
| 15 | +- a revisao do teste não mostra as imagens que nao estejam ja em cache. | ||
| 21 | 16 | ||
| 22 | -# TODO | 17 | +## TODO |
| 23 | 18 | ||
| 24 | -- JOBE correct async | ||
| 25 | -- esta a corrigir código JOBE mesmo que nao tenha respondido??? | ||
| 26 | -- permitir remover alunos que estão online para poderem comecar de novo. | ||
| 27 | -- 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) | ||
| 28 | -- stress tests. use https://locust.io | ||
| 29 | -- wait for admin to start test. (students can be allowed earlier) | ||
| 30 | -- impedir os eventos copy/paste. alunos usam isso para trazer codigo ja feito nos computadores. Obrigar a fazer reset? fazer um copy automaticamente? | ||
| 31 | -- na pagina admin, mostrar com cor vermelha as horas de entrada dos alunos que ja tenham excedido o tempo | ||
| 32 | -- retornar None quando nao ha alteracoes relativamente à última vez. | ||
| 33 | -ou usar push (websockets?) | 19 | +- QuestionTextArea falta reportar nos comments os vários erros que podem ocorrer |
| 20 | + (timeout, etc) | ||
| 21 | +- pergunta com varias partes. | ||
| 22 | +- /review incluir identificacao do aluno no jumbotron (para poder gerar pdf). | ||
| 23 | +- corrir mais que uma vez (por ex. para alterar cotacoes, corrigir perguntas) | ||
| 24 | +- guardar testes em JSON assim que sao atribuidos aos alunos. | ||
| 25 | +- impedir os eventos copy/paste. alunos usam isso para trazer codigo ja feito | ||
| 26 | + nos computadores. Obrigar a fazer reset? fazer um copy automaticamente? | ||
| 27 | +- na pagina admin, mostrar com cor vermelha as horas de entrada dos alunos que | ||
| 28 | + ja tenham excedido o tempo | ||
| 29 | +- /admin long pooling. | ||
| 34 | - mudar ref do test para test_id (ref já é usado nas perguntas) | 30 | - mudar ref do test para test_id (ref já é usado nas perguntas) |
| 35 | - servidor ntpd no x220 para configurar a data/hora dos portateis dell | 31 | - servidor ntpd no x220 para configurar a data/hora dos portateis dell |
| 36 | -- sala de espera: autorização dada, mas teste não disponível até que seja dada ordem para começar. | ||
| 37 | -- alunos com necessidades especiais nao podem ter autosubmit. ter um autosubmit_exceptions: ['123', '456'] | ||
| 38 | -- submissao fazer um post ajax? | ||
| 39 | -- adicionar opcao para eliminar um teste em curso. | 32 | +- sala de espera: autorização dada, mas teste não disponível até que seja dada |
| 33 | + ordem para começar. | ||
| 34 | +- alunos com necessidades especiais nao podem ter autosubmit. ter um | ||
| 35 | + autosubmit_exceptions: ['123', '456'] | ||
| 40 | - enviar resposta de cada pergunta individualmente. | 36 | - enviar resposta de cada pergunta individualmente. |
| 41 | -- experimentar gerador de svg que inclua no markdown da pergunta e ver se funciona. | ||
| 42 | -- quando ha varias perguntas para escolher, escolher sucessivamente em vez de aleatoriamente. | ||
| 43 | -- como refrescar a tabela de admin sem fazer reload da pagina? | ||
| 44 | -- 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. | ||
| 45 | -- 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. | 37 | +- experimentar gerador de svg que inclua no markdown da pergunta. |
| 38 | +- botao "testar resposta" que valida syntax mas nao classifica. | ||
| 39 | + perguntas devem ter opcao validate: script.py. | ||
| 40 | + Aluno pressiona botao e codigo é enviado para servidor para validação, | ||
| 41 | +- test: botao submeter valida se esta online com um post willing_to_submit, | ||
| 42 | + se estiver online, mostra mensagem de confirmacao, caso contrario avisa que | ||
| 43 | + nao esta online. | ||
| 46 | - test: Cada pergunta respondida é logo submetida. | 44 | - test: Cada pergunta respondida é logo submetida. |
| 47 | -- test: calculadora javascript. | ||
| 48 | - admin: histograma das notas. | 45 | - admin: histograma das notas. |
| 49 | - admin: mostrar as horas a que o teste terminou para os testes terminados. | 46 | - admin: mostrar as horas a que o teste terminou para os testes terminados. |
| 50 | - admin: histograma das notas. | 47 | - admin: histograma das notas. |
| 51 | - admin: mostrar teste gerado para aluno (tipo review). | 48 | - admin: mostrar teste gerado para aluno (tipo review). |
| 52 | -- fazer renderer para formulas com mathjax serverside (mathjax-node) ou usar katex. | ||
| 53 | -- fazer renderer para imagens, com links /file?ref=xpto;name=zzz.jpg | ||
| 54 | -- fazer renderer para linguagem assembly mips? | ||
| 55 | -- cancelar teste no menu admin. Dado o numero de aluno remove teste e faz logout do aluno. | 49 | +- admin: Cancelar teste e fazer logout do aluno (e.g. fraude) |
| 56 | - mathjax-node: | 50 | - mathjax-node: |
| 57 | sudo pkg install node npm | 51 | sudo pkg install node npm |
| 58 | npm install mathjax-node mathjax-node-cli # pacotes em ~/node_modules | 52 | npm install mathjax-node mathjax-node-cli # pacotes em ~/node_modules |
| 59 | node_modules/mathjax-node-cli/bin/tex2svg '\sqrt{x}' | 53 | node_modules/mathjax-node-cli/bin/tex2svg '\sqrt{x}' |
| 60 | - usar isto para gerar svg que passa a fazer parte do texto da pergunta (markdown suporta tags svg?) | 54 | + usar isto para gerar svg que passa a fazer parte do texto da pergunta |
| 55 | + (markdown suporta tags svg?) | ||
| 61 | fazer funçao tex() que recebe formula e converte para svg. exemplo: | 56 | fazer funçao tex() que recebe formula e converte para svg. exemplo: |
| 62 | fr'''A formula é {tex("\sqrt{x]}")}''' | 57 | fr'''A formula é {tex("\sqrt{x]}")}''' |
| 63 | -- Gerar pdf's com todos os testes no final (pdfkit). | ||
| 64 | -- manter registo dos unfocus durante o teste e de qual a pergunta visivel nesse momento | 58 | +- Gerar pdf's com todos os testes no final (pdfkit, firefox marionette). |
| 59 | +- registos unfocus durante o teste e qual a pergunta visivel nesse momento | ||
| 65 | - permitir varios testes, aluno escolhe qual o teste que quer fazer. | 60 | - permitir varios testes, aluno escolhe qual o teste que quer fazer. |
| 66 | - se ocorrer um erro na correcçao avisar aluno para contactar o professor. | 61 | - se ocorrer um erro na correcçao avisar aluno para contactar o professor. |
| 67 | -- abrir o teste numa janela maximizada e que nao permite que o aluno a redimensione/mova? | ||
| 68 | -- 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) | ||
| 69 | -- 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? | ||
| 70 | -- criar perguntas de outros tipos, e.g. associação, ordenação, varios textinput | ||
| 71 | -- perguntas para professor corrigir mais tarde. permitir que review possa alterar as notas | ||
| 72 | -- fazer uma calculadora javascript e por no menu. surge como modal | ||
| 73 | - | ||
| 74 | -# FIXED | ||
| 75 | - | ||
| 76 | -- testar as perguntas todas no início do teste como o aprendizations. | ||
| 77 | -- adicionar identificacao do aluno no jumbotron inicial do teste, para que ao imprimir para pdf a identificacao do aluno venha escrita no documento. | ||
| 78 | -- internal server error quando em --review, download csv detalhado. | ||
| 79 | -- perguntas repetidas (mesma ref) dao asneira, porque a referencia é usada como chave em varios sitios e as chaves nao podem ser dupplicadas. | ||
| 80 | - 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. | ||
| 81 | -- mostrar unfocus e window area em /admin | ||
| 82 | -- CRITICAL se answer for `i<n` a revisão de provas mostra apenas i (interpreta `<` como tag?) | ||
| 83 | -- botao de autorizar desliga-se, fazer debounce. | ||
| 84 | -- link na pagina com a nota para voltar ao principio. | ||
| 85 | -- default logger config mostrar horas com segundos | ||
| 86 | -- test: mostrar duração do teste com progressbar no navbar. | ||
| 87 | -- lidar com eventos unfocus. | ||
| 88 | -- servidor nao esta a lidar com eventos resize. | ||
| 89 | -- sock.bind(sockaddr) OSError: [Errno 48] Address already in use | ||
| 90 | -- dizer quanto desconta em cada pergunta de escolha multipla | ||
| 91 | -- se houver erros a abrir ficheiros .yaml de perguntas, depois dos testes diz "No errors found". | ||
| 92 | -- se faltarem files na especificação do teste, o check não detecta e factory não gera para essas perguntas. | ||
| 93 | -- nao esta a usar points das perguntas | ||
| 94 | -- quando se clica no texto de uma opcao, salta para outro lado na pagina. | ||
| 95 | -- 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. | ||
| 96 | -- fazer package para instalar perguntations com pip. | ||
| 97 | -- pymips: nao pode executar syscalls do spim. | ||
| 98 | -- exception sqlalchemy relacionada com threads. | ||
| 99 | -- acrescentar logger.conf que sirva de base. | ||
| 100 | -- 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 | ||
| 101 | -- textarea foi modificado em aprendizations para receber cmd line args. corrigir aqui tb. | ||
| 102 | -- usar npm para instalar javascript | ||
| 103 | -- se aluno entrar com l12345 rebenta. numa funcao get_... ver imagem no ipad | ||
| 104 | -- no test3 está contar 1.0 valores numa pergunta do tipo info? acontece para type: info, e não para type: information | ||
| 105 | -- default correct in checkbox must be 1.0, so that the pairs (right,wrong) still work with `correct` left undefined. | ||
| 106 | -- textarea com codemirror | ||
| 107 | -- decorador para user 0, evita o "if uid==0" em muitas funcoes. | ||
| 108 | -- numeric interval deve converter respostas que usam virgulas para pontos decimais | ||
| 109 | -- self.testapp.get_json_filename_of_test(test_id) retorna None quando test_id nao existe. | ||
| 110 | -- o eventloop está a bloquear. correção do teste é blocking. usar threadpoolexecutor? | ||
| 111 | -- substituir get_event_loop por get_runnint_loop (ver https://docs.python.org/3/library/asyncio-eventloop.html) | ||
| 112 | -- review nao esta a funcionar | ||
| 113 | -- servir imagens das perguntas não funciona. Necessario passar a ref da pergunta no link para poder ajustar o path no FileHandler. | ||
| 114 | -- a primeira coluna da tabela admin deveria estar sempre ordenada. | ||
| 115 | -- abortar depois de testar todas as perguntas, caso haja algum erro. | ||
| 116 | -- imagens jpg/png nas perguntas. | ||
| 117 | -- initdb está a inicializar com passwords iguais aos numeros. deveria ser vazio para alunos definirem. | ||
| 118 | -- upgrade popper e fazer link. | ||
| 119 | -- mover scripts js para head, com defer. ver todos os templates. | ||
| 120 | -- update fontawesome to 5. | ||
| 121 | -- mostrar comments e solution na revisao de prova. | ||
| 122 | -- upgrade para tornado 5.0. | ||
| 123 | -- ctrl-c should ask for confirmation before exiting. | ||
| 124 | -- md_to_html() nao usa o segundo argumento q. pode retirar-se dos templates? | ||
| 125 | -- config/logger.yaml ainda é do cherrypy... | ||
| 126 | -- uniformizar question.py com a de aprendizations... | ||
| 127 | -- qual a diferenca entre md_to_html e md_to_html_review, parece desnecessario haver dois. | ||
| 128 | -- converter markdown para mistune. | ||
| 129 | -- como alterar configuracao para mostrar logs de debug? | ||
| 130 | -- espaco no final das tabelas. | ||
| 131 | -- total do teste aparece negativo. | ||
| 132 | -- reset password nao funciona no admin | ||
| 133 | -- reload a intervalos não funciona. | ||
| 134 | -- allow/deny nao funciona no /admin. | ||
| 135 | -- Review de um teste que foi apagado rebenta. | ||
| 136 | -- numeracao das perguntas do teste esta a contar com paineis informativos... | ||
| 137 | -- markdown no teste nao funciona | ||
| 138 | -- review de um teste nao funciona (hardcoded...) | ||
| 139 | -- testar SSL | ||
| 140 | -- text-numeric não está a gerar a pergunta. faltam templates? | ||
| 141 | -- testar perguntas warning/warn | ||
| 142 | -- qd user 0 faz logout rebenta. | ||
| 143 | -- 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. | ||
| 144 | -- configuração do teste não joga bem com o do aprendizations. Em particular os scripts não ficam com o mesmo path!!! | ||
| 145 | -- configurar pf em freebsd, port forward 80 -> 8080. documentacao | ||
| 146 | -- barras com notas em grade estão desalinhadas. | ||
| 147 | -- erros nos generators devem ser ERROR e não WARNING. | ||
| 148 | -- se directorio "logs" não existir no directorio actual aborta com mensagem de erro. | ||
| 149 | -- 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']} | ||
| 150 | -- usar http://fontawesome.io/examples/ em vez dos do bootstrap3 | ||
| 151 | -- se pergunta tiver 'type:' errado, rebenta. | ||
| 152 | -- se submeter um teste so com information, da divisao por zero. | ||
| 153 | -- se save_answers nao existir, da warning que nao serao gravados, mas sao sempre gravados! pagina de administracao diz --not being saved-- | ||
| 154 | -- first login é INFO e não WARNING | ||
| 155 | -- /review não mostra imagens porque precisa que teste esteja a decorrer... | ||
| 156 | -- visualizar um teste ja realizado na página de administração | ||
| 157 | -- Depois da correcção, mostra testes realizados que não foram realizados pelo próprio | ||
| 158 | -- 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) | ||
| 159 | -- server nao esta a receber eventos focus/blur dos utilizadores diferentes de '0', estranho... | ||
| 160 | -- permitir adicionar imagens nas perguntas. | ||
| 161 | -- detect_unfocus.js so funciona se estiver inline no html. porquê??? | ||
| 162 | -- inserir novo aluno /admin não fecha. | ||
| 163 | -- se aluno desistir, ainda fica marcado como online | ||
| 164 | -- give dá None em vez de 0.0 | ||
| 165 | -- debug mode: log levels not working | ||
| 166 | -- Se aluno fizer logout, o teste não é gravado e ficamos sem registo do teste que o aluno viu. | ||
| 167 | -- 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. | ||
| 168 | -- sqlalchemy queixa-se de threads. | ||
| 169 | -- SQLAlchemy em vez da classe database. | ||
| 170 | -- replace sys.exit calls | ||
| 171 | -- if does not find questions, aborts silently | ||
| 172 | -- argumentos da linha de comando a funcionar. | ||
| 173 | -- configuracao dos logs cherrypy para se darem bem com os outros | ||
| 174 | -- browser e ip usados gravado no test. | ||
| 175 | -- botões allow all/deny all. | ||
| 176 | -- mostrar botão de reset apenas no final da pagina, com edit para escrever o número. | ||
| 177 | -- 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. | ||
| 178 | -- pagina de login nao esta a apresentar bem. parece que precisa de autorizacao para aceder a /static... | ||
| 179 | -- Não mostrar Professor nos activos em /admin | ||
| 180 | -- /admin mostrar actualizações automaticamente? | ||
| 181 | -- se no teste uma das "ref" nao existir nos ficheiros de perguntas, rebenta. | ||
| 182 | -- 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. | ||
| 183 | -- pagina de management dos alunos. | ||
| 184 | - mostrar online ordenados por hora de login, offline por número. | ||
| 185 | - permitir reset da pw e allow/disallow | ||
| 186 | -- script de correcção pode enviar dicionario yaml com grade e comentarios. ex: | ||
| 187 | - grade: 0.5 | ||
| 188 | - comments: Falhou na função xpto. | ||
| 189 | - os comentários são guardados no teste (ficheiro) ou enviados para o browser no modo practice. | ||
| 190 | -- testar regex na definicao das perguntas. como se faz rawstring em yaml? | ||
| 191 | - 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 | ||
| 192 | - correct: !regex '^(yes|no)' | 62 | +- abrir o teste numa janela maximizada e que nao permite que o aluno a |
| 63 | + redimensione/mova? modo kiosk? | ||
| 64 | +- detectar scroll e enviar posição para servidor (analise de scroll para detectar copianço?) | ||
| 65 | +- criar perguntas de outros tipos, e.g. associação, ordenação. | ||
| 66 | +- stress tests. use https://locust.io |
demo/demo.yaml
| @@ -47,7 +47,7 @@ scale: [0, 20] | @@ -47,7 +47,7 @@ scale: [0, 20] | ||
| 47 | # ---------------------------------------------------------------------------- | 47 | # ---------------------------------------------------------------------------- |
| 48 | # Files to import. Each file contains a list of questions in yaml format. | 48 | # Files to import. Each file contains a list of questions in yaml format. |
| 49 | files: | 49 | files: |
| 50 | - - questions/questions-tutorial.yaml | 50 | + - questions/tutorial.yaml |
| 51 | 51 | ||
| 52 | # This is the list of questions that will make up the test. | 52 | # This is the list of questions that will make up the test. |
| 53 | # The order is preserved. | 53 | # The order is preserved. |
| @@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
| 1 | +#!/usr/bin/env python3 | ||
| 2 | + | ||
| 3 | +''' | ||
| 4 | +Demonstação de um script de correcção | ||
| 5 | +''' | ||
| 6 | + | ||
| 7 | +import re | ||
| 8 | +import sys | ||
| 9 | + | ||
| 10 | +s = sys.stdin.read() | ||
| 11 | + | ||
| 12 | +ans = set(re.findall(r'[\w]+', s.lower())) # get words in lowercase | ||
| 13 | +rgb = set(['red', 'green', 'blue']) # the correct answer | ||
| 14 | + | ||
| 15 | +# a nota é o número de cores certas menos o número de erradas | ||
| 16 | +grade = max(0, | ||
| 17 | + len(rgb.intersection(ans)) - len(ans.difference(rgb))) / 3 | ||
| 18 | + | ||
| 19 | +if ans == rgb: | ||
| 20 | + print('---\n' | ||
| 21 | + 'grade: 1.0\n' | ||
| 22 | + 'comments: Muito bem!') | ||
| 23 | + | ||
| 24 | +else: | ||
| 25 | + print('---\n' | ||
| 26 | + f'grade: {grade}\n' | ||
| 27 | + 'comments: A resposta correcta é "red green blue".') |
| @@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
| 1 | +#!/usr/bin/env python3 | ||
| 2 | + | ||
| 3 | +import sys | ||
| 4 | +import time | ||
| 5 | + | ||
| 6 | +s = sys.stdin.read() | ||
| 7 | + | ||
| 8 | +# sleep a lot of time to generate timeout during correction | ||
| 9 | +time.sleep(100) | ||
| 10 | + | ||
| 11 | +# probably this result will not be seen because the script will be interrupted | ||
| 12 | +print(0.5) |
demo/questions/correct/correct-question.py
| @@ -1,27 +0,0 @@ | @@ -1,27 +0,0 @@ | ||
| 1 | -#!/usr/bin/env python3 | ||
| 2 | - | ||
| 3 | -''' | ||
| 4 | -Demonstação de um script de correcção | ||
| 5 | -''' | ||
| 6 | - | ||
| 7 | -import re | ||
| 8 | -import sys | ||
| 9 | - | ||
| 10 | -s = sys.stdin.read() | ||
| 11 | - | ||
| 12 | -ans = set(re.findall(r'[\w]+', s.lower())) # get words in lowercase | ||
| 13 | -rgb = set(['red', 'green', 'blue']) # the correct answer | ||
| 14 | - | ||
| 15 | -# a nota é o número de cores certas menos o número de erradas | ||
| 16 | -grade = max(0, | ||
| 17 | - len(rgb.intersection(ans)) - len(ans.difference(rgb))) / 3 | ||
| 18 | - | ||
| 19 | -if ans == rgb: | ||
| 20 | - print('---\n' | ||
| 21 | - 'grade: 1.0\n' | ||
| 22 | - 'comments: Muito bem!') | ||
| 23 | - | ||
| 24 | -else: | ||
| 25 | - print('---\n' | ||
| 26 | - f'grade: {grade}\n' | ||
| 27 | - 'comments: A resposta correcta é "red green blue".') |
demo/questions/correct/correct-timeout.py
| @@ -1,12 +0,0 @@ | @@ -1,12 +0,0 @@ | ||
| 1 | -#!/usr/bin/env python3 | ||
| 2 | - | ||
| 3 | -import sys | ||
| 4 | -import time | ||
| 5 | - | ||
| 6 | -s = sys.stdin.read() | ||
| 7 | - | ||
| 8 | -# sleep a lot of time to generate timeout during correction | ||
| 9 | -time.sleep(100) | ||
| 10 | - | ||
| 11 | -# probably this result will not be seen because the script will be interrupted | ||
| 12 | -print(0.5) |
demo/questions/questions-tutorial.yaml
| @@ -1,658 +0,0 @@ | @@ -1,658 +0,0 @@ | ||
| 1 | ---- | ||
| 2 | -# ---------------------------------------------------------------------------- | ||
| 3 | -- type: information | ||
| 4 | - ref: tut-test | ||
| 5 | - title: Configuração do teste | ||
| 6 | - text: | | ||
| 7 | - O teste é configurado num ficheiro `yaml` | ||
| 8 | - (ver especificação [aqui](https://yaml.org)). | ||
| 9 | - A configuração contém a identificação do teste, base de dados dos alunos, | ||
| 10 | - ficheiros de perguntas a importar e uma selecção de perguntas e respectivas | ||
| 11 | - cotações. | ||
| 12 | - | ||
| 13 | - Exemplo: | ||
| 14 | - | ||
| 15 | - ```yaml | ||
| 16 | - --- | ||
| 17 | - # -------------------------------------------------------------------------- | ||
| 18 | - ref: tutorial # referência, pode ser reusada em vários turnos | ||
| 19 | - title: Demonstração # título da prova | ||
| 20 | - database: students.db # base de dados previamente criada com initdb | ||
| 21 | - answers_dir: ans # directório onde ficam os testes dos alunos | ||
| 22 | - | ||
| 23 | - # opcionais | ||
| 24 | - duration: 60 # duração da prova em minutos (default: inf) | ||
| 25 | - autosubmit: true # submissão automática (default: false) | ||
| 26 | - show_points: true # mostra cotação das perguntas (default: true) | ||
| 27 | - scale: [0, 20] # normaliza cotações para o intervalo indicado. | ||
| 28 | - # não normaliza por defeito (default: None) | ||
| 29 | - | ||
| 30 | - # -------------------------------------------------------------------------- | ||
| 31 | - # Ficheiros de perguntas a importar (relativamente a `questions_dir`) | ||
| 32 | - files: | ||
| 33 | - - tabelas.yaml | ||
| 34 | - - topic1/questions.yaml | ||
| 35 | - - topic2/part1/questions.yaml | ||
| 36 | - - topic2/part2/questions.yaml | ||
| 37 | - | ||
| 38 | - # -------------------------------------------------------------------------- | ||
| 39 | - # Especificação das perguntas do teste e respectivas cotações. | ||
| 40 | - # O teste é uma lista de perguntas, onde cada pergunta é especificada num | ||
| 41 | - # dicionário com a referência da pergunta e a respectiva cotação. | ||
| 42 | - questions: | ||
| 43 | - - ref: pergunta1 | ||
| 44 | - points: 3.5 | ||
| 45 | - | ||
| 46 | - - ref: pergunta2 | ||
| 47 | - points: 2.0 | ||
| 48 | - | ||
| 49 | - # por defeinto, a cotação da pergunta é 1.0 valor | ||
| 50 | - - ref: pergunta3 | ||
| 51 | - | ||
| 52 | - # escolhe aleatoriamente uma das variantes da pergunta | ||
| 53 | - - ref: [pergunta3a, pergunta3b] | ||
| 54 | - points: 0.5 | ||
| 55 | - | ||
| 56 | - # -------------------------------------------------------------------------- | ||
| 57 | - ``` | ||
| 58 | - | ||
| 59 | - A ordem das perguntas é mantida quando apresentada no teste. | ||
| 60 | - | ||
| 61 | - O mesmo teste pode ser realizado várias vezes em turnos diferentes, não é | ||
| 62 | - necessário alterar nada. | ||
| 63 | - | ||
| 64 | -# ---------------------------------------------------------------------------- | ||
| 65 | -- type: information | ||
| 66 | - ref: tut-questions | ||
| 67 | - title: Especificação das perguntas | ||
| 68 | - text: | | ||
| 69 | - As perguntas estão definidas num ou mais ficheiros `yaml` como uma lista de | ||
| 70 | - perguntas, onde cada pergunta é um dicionário. | ||
| 71 | - | ||
| 72 | - Por exemplo, um ficheiro com o conteúdo abaixo contém duas perguntas, uma | ||
| 73 | - de escolha múltipla e outra apenas informativa: | ||
| 74 | - | ||
| 75 | - ```yaml | ||
| 76 | - --- | ||
| 77 | - #--------------------------------------------------------------------------- | ||
| 78 | - - type: radio | ||
| 79 | - ref: chave-unica-1 | ||
| 80 | - text: Quanto é $1+1$? | ||
| 81 | - options: | ||
| 82 | - - 1 | ||
| 83 | - - 2 | ||
| 84 | - - 3 | ||
| 85 | - | ||
| 86 | - #--------------------------------------------------------------------------- | ||
| 87 | - - type: information | ||
| 88 | - ref: chave-unica-2 | ||
| 89 | - text: | | ||
| 90 | - Quando o texto da pergunta tem várias linhas, dá jeito usar o símbolo | ||
| 91 | - `|` de pipe, para indicar que tudo o que estiver indentado faz parte do | ||
| 92 | - texto. É o caso desta pergunta. | ||
| 93 | - | ||
| 94 | - O texto das perguntas é escrito em `markdown` e suporta fórmulas em | ||
| 95 | - LaTeX. | ||
| 96 | - | ||
| 97 | - #--------------------------------------------------------------------------- | ||
| 98 | - ``` | ||
| 99 | - | ||
| 100 | - As chaves são usadas para construir o teste e não se podem repetir, mesmo | ||
| 101 | - em ficheiros diferentes. | ||
| 102 | - De seguida mostram-se exemplos dos vários tipos de perguntas. | ||
| 103 | - | ||
| 104 | -# ---------------------------------------------------------------------------- | ||
| 105 | -- type: radio | ||
| 106 | - ref: tut-radio | ||
| 107 | - title: Escolha simples, uma opção correcta. | ||
| 108 | - text: | | ||
| 109 | - As perguntas de escolha simples, permitem fazer uma pergunta e apresentar | ||
| 110 | - várias opções de resposta em que apenas uma delas está certa. | ||
| 111 | - A utilização mais simples é a seguinte: | ||
| 112 | - | ||
| 113 | - ```yaml | ||
| 114 | - - type: radio | ||
| 115 | - ref: pergunta-1 | ||
| 116 | - title: Escolha simples, uma opção correcta. | ||
| 117 | - text: | | ||
| 118 | - Bla bla bla. | ||
| 119 | - options: | ||
| 120 | - - Opção 0 | ||
| 121 | - - Opção 1 | ||
| 122 | - - Opção 2 | ||
| 123 | - - Opção 3 | ||
| 124 | - - Opção 4 | ||
| 125 | - ``` | ||
| 126 | - | ||
| 127 | - Sem outras configurações, assume-se que a primeira opção é a resposta | ||
| 128 | - correcta ("Opção 0" neste caso) e as 5 opções são apresentadas por ordem | ||
| 129 | - aleatória. | ||
| 130 | - | ||
| 131 | - Para evitar que os alunos memorizem os textos das opções, podem definir-se | ||
| 132 | - várias opções correctas com escrita ligeiramente diferente, sendo escolhida | ||
| 133 | - apenas uma delas para apresentação. | ||
| 134 | - Por exemplo, se as 2 primeiras opções estiverem correctas e as restantes | ||
| 135 | - erradas, e quisermos apresentar ao aluno 3 opções no total, acrescenta-se: | ||
| 136 | - | ||
| 137 | - ```yaml | ||
| 138 | - correct: [1, 1, 0, 0, 0] | ||
| 139 | - choose: 3 | ||
| 140 | - ``` | ||
| 141 | - | ||
| 142 | - Neste caso, será escolhida uma opção certa e duas erradas. | ||
| 143 | - Os valores em `correct` representam o grau de correcção no intervalo [0, 1] | ||
| 144 | - onde 1 representa 100% certo e 0 representa 0%. Podem ser usados valores | ||
| 145 | - entre 0 e 1, sendo atribuída a respectiva cotação, mas só o valor 1 | ||
| 146 | - representa uma opção certa. | ||
| 147 | - | ||
| 148 | - Por defeito, as opções são apresentadas por ordem aleatória, mas é possível | ||
| 149 | - usar a ordem predefinida. Por exemplo, para manter a ordem e indicar que a | ||
| 150 | - resposta correcta é a do meio define-se: | ||
| 151 | - | ||
| 152 | - ```yaml | ||
| 153 | - correct: [0, 0, 1, 0, 0] | ||
| 154 | - shuffle: false | ||
| 155 | - ``` | ||
| 156 | - | ||
| 157 | - As respostas erradas descontam, tendo uma cotação de $-1/(n-1)$ do valor da | ||
| 158 | - pergunta, onde $n$ é o número de opções apresentadas ao aluno (a ideia é o | ||
| 159 | - valor esperado ser zero quando as respostas são aleatórias e uniformemente | ||
| 160 | - distribuídas). Para não descontar acrescenta-se: | ||
| 161 | - | ||
| 162 | - ```yaml | ||
| 163 | - discount: false | ||
| 164 | - ``` | ||
| 165 | - options: | ||
| 166 | - - Opção 0 (certa) | ||
| 167 | - - Opção 1 (certa) | ||
| 168 | - - Opção 2 | ||
| 169 | - - Opção 3 | ||
| 170 | - - Opção 4 | ||
| 171 | - correct: [1, 1, 0, 0, 0] | ||
| 172 | - choose: 3 | ||
| 173 | - solution: | | ||
| 174 | - A solução correcta é a **Opção 0** ou a **Opção 1**. | ||
| 175 | - | ||
| 176 | -# ---------------------------------------------------------------------------- | ||
| 177 | -- type: checkbox | ||
| 178 | - ref: tut-checkbox | ||
| 179 | - title: Escolha múltipla, várias opções correctas | ||
| 180 | - text: | | ||
| 181 | - As perguntas de escolha múltipla permitem apresentar um conjunto de opções | ||
| 182 | - podendo ser seleccionadas várias em simultâneo. | ||
| 183 | - Funcionam como múltiplas perguntas independentes de resposta sim/não. | ||
| 184 | - | ||
| 185 | - As respostas que devem ou não ser seleccionadas são indicadas com `1` e `0` | ||
| 186 | - ou com booleanos `true` e `false`. | ||
| 187 | - Cada resposta errada desconta um valor que é o simétrico da resposta certa. | ||
| 188 | - Se acertar uma opção ganha `+1`, se errar obtém `-1`. | ||
| 189 | - | ||
| 190 | - ```yaml | ||
| 191 | - - type: checkbox | ||
| 192 | - ref: tut-checkbox | ||
| 193 | - title: Escolha múltipla, várias opções correctas | ||
| 194 | - text: | | ||
| 195 | - Bla bla bla. | ||
| 196 | - options: | ||
| 197 | - - Opção 0 (certa) | ||
| 198 | - - Opção 1 | ||
| 199 | - - Opção 2 | ||
| 200 | - - Opção 3 (certa) | ||
| 201 | - - Opção 4 | ||
| 202 | - correct: [1, 0, 0, 1, 0] | ||
| 203 | - ``` | ||
| 204 | - | ||
| 205 | - Neste exemplo, seleccionando as opções 0 e 3 obtém-se cotação `+1` em cada | ||
| 206 | - uma, enquanto que seleccionando erradamente as opções 1, 2 e 4 obtém-se | ||
| 207 | - cotação `-1`. | ||
| 208 | - Do mesmo modo, não seleccionando as opções certas 0 e 3 obtém-se a cotação | ||
| 209 | - `-1` em cada uma, e não seleccionando (correctamente) as 1, 2 e 4 obtém-se | ||
| 210 | - `+1` em cada. | ||
| 211 | - | ||
| 212 | - *(Neste tipo de perguntas não há forma de responder a apenas algumas delas, | ||
| 213 | - são sempre todas corrigidas. Se um aluno só sabe a resposta a algumas das | ||
| 214 | - opções, deve ter cuidado porque as restantes também serão classificadas e | ||
| 215 | - arrisca-se a ter cotação negativa)* | ||
| 216 | - | ||
| 217 | - Cada opção pode opcionalmente ser escrita como uma afirmação e o seu | ||
| 218 | - contrário, de maneira a aumentar a variabilidade dos textos. | ||
| 219 | - Por exemplo: | ||
| 220 | - | ||
| 221 | - ```yaml | ||
| 222 | - options: | ||
| 223 | - - ['O céu é azul', 'O céu não é azul'] | ||
| 224 | - - ['Um triangulo tem 3 lados', 'Um triangulo tem 2 lados'] | ||
| 225 | - - O nosso planeta tem um satélite natural | ||
| 226 | - correct: [1, 1, 1] | ||
| 227 | - ``` | ||
| 228 | - | ||
| 229 | - Assume-se que a primeira alternativa de cada opção tem a cotação indicada | ||
| 230 | - em `correct`, enquanto a segunda alternativa tem a cotação contrária. | ||
| 231 | - | ||
| 232 | - Tal como nas perguntas do tipo `radio`, podem ser usadas as configurações | ||
| 233 | - `shuffle` e `discount` com valor `false` para as desactivar. | ||
| 234 | - Se `discount` é `false` então as respostas erradas têm cotação 0 em vez do | ||
| 235 | - simétrico. | ||
| 236 | - options: | ||
| 237 | - - ['Opção 0 (sim)', 'Opção 0 (não)'] | ||
| 238 | - - ['Opção 1 (não)', 'Opção 1 (sim)'] | ||
| 239 | - - Opção 2 (não) | ||
| 240 | - - Opção 3 (sim) | ||
| 241 | - correct: [1, 0, 0, 1] | ||
| 242 | - shuffle: false | ||
| 243 | - | ||
| 244 | -# ---------------------------------------------------------------------------- | ||
| 245 | -- type: text | ||
| 246 | - ref: tut-text | ||
| 247 | - title: Resposta de texto em linha | ||
| 248 | - text: | | ||
| 249 | - Este tipo de perguntas permite uma resposta numa linha de texto. A resposta | ||
| 250 | - está correcta se coincidir exactamente com alguma das respostas admissíveis. | ||
| 251 | - | ||
| 252 | - ```yaml | ||
| 253 | - - type: text | ||
| 254 | - ref: tut-text | ||
| 255 | - title: Resposta de texto em linha | ||
| 256 | - text: | | ||
| 257 | - De que cor é o céu? | ||
| 258 | - | ||
| 259 | - Escreva a resposta em português. | ||
| 260 | - correct: ['azul', 'Azul', 'AZUL'] | ||
| 261 | - ``` | ||
| 262 | - | ||
| 263 | - Neste caso, as respostas aceites são `azul`, `Azul` ou `AZUL`. | ||
| 264 | - | ||
| 265 | - Em alguns casos pode ser conveniente transformar a resposta antes de a | ||
| 266 | - comparar, por exemplo para remover espaços ou converter para minúsculas. | ||
| 267 | - A opção `transform` permite dar uma sequência de transformações a aplicar à | ||
| 268 | - resposta do aluno, por exemplo: | ||
| 269 | - | ||
| 270 | - ```yaml | ||
| 271 | - transform: ['trim', 'lower'] | ||
| 272 | - correct: ['azul'] | ||
| 273 | - ``` | ||
| 274 | - | ||
| 275 | - Estão disponíveis as seguintes transformações: | ||
| 276 | - | ||
| 277 | - * `trim` remove os espaços do início e fim da resposta, os espaços do meio | ||
| 278 | - mantêm-se inalterados. | ||
| 279 | - * `remove_space` remove todos os espaços (início, meio e fim). | ||
| 280 | - * `normalize_space` remove espaços do início e fim (trim), e substitui | ||
| 281 | - múltiplos espaços por um único espaço (no meio). | ||
| 282 | - * `lower` e `upper` convertem respectivamente para minúsculas e maiúsculas. | ||
| 283 | - transform: ['trim', 'lower'] | ||
| 284 | - correct: ['azul'] | ||
| 285 | - solution: | | ||
| 286 | - O céu é `azul`, pelo menos durante o dia e se estiver bom tempo... | ||
| 287 | - | ||
| 288 | -# --------------------------------------------------------------------------- | ||
| 289 | -- type: text-regex | ||
| 290 | - ref: tut-text-regex | ||
| 291 | - title: Resposta de texto em linha, expressão regular | ||
| 292 | - text: | | ||
| 293 | - Este tipo de pergunta é semelhante à linha de texto da pergunta anterior. | ||
| 294 | - A única diferença é que esta é validada por uma expressão regular. | ||
| 295 | - | ||
| 296 | - ```yaml | ||
| 297 | - - type: text-regex | ||
| 298 | - ref: tut-text-regex | ||
| 299 | - title: Resposta de texto em linha | ||
| 300 | - text: | | ||
| 301 | - Bla bla bla | ||
| 302 | - correct: '(VERDE|[Vv]erde)' | ||
| 303 | - ``` | ||
| 304 | - | ||
| 305 | - Neste exemplo a expressão regular é `(VERDE|[Vv]erde)`. | ||
| 306 | - | ||
| 307 | - Também se pode dar uma lista de expressões regulares. Nesse caso a resposta | ||
| 308 | - é considerada correcta se fizer match com alguma delas. | ||
| 309 | - No exemplo acima, poder-se-ia ter usado uma lista | ||
| 310 | - | ||
| 311 | - ```yaml | ||
| 312 | - correct: | ||
| 313 | - - 'VERDE' | ||
| 314 | - - '[Vv]erde' | ||
| 315 | - ``` | ||
| 316 | - | ||
| 317 | - --- | ||
| 318 | - | ||
| 319 | - **Atenção:** A expressão regular deve seguir as convenções da suportadas em | ||
| 320 | - python (ver | ||
| 321 | - [Regular expression operations](https://docs.python.org/3/library/re.html)). | ||
| 322 | - Em particular, a expressão regular acima também aceita a resposta | ||
| 323 | - `verde, azul`. | ||
| 324 | - Deve marcar-se o início e final `^(VERDE|[Vv]erde)$` para evitar estas | ||
| 325 | - situações. | ||
| 326 | - | ||
| 327 | - correct: '(VERDE|[Vv]erde)' | ||
| 328 | - solution: | | ||
| 329 | - Deveria ter escrito `VERDE` ou `Verde` ou `verde`. | ||
| 330 | - | ||
| 331 | -# --------------------------------------------------------------------------- | ||
| 332 | -- type: numeric-interval | ||
| 333 | - ref: tut-numeric-interval | ||
| 334 | - title: Resposta numérica em linha de texto | ||
| 335 | - text: | | ||
| 336 | - Este tipo de perguntas esperam uma resposta numérica (vírgula flutuante). | ||
| 337 | - O resultado é considerado correcto se estiver dentro do intervalo fechado | ||
| 338 | - indicado. | ||
| 339 | - | ||
| 340 | - ```yaml | ||
| 341 | - - type: numeric-interval | ||
| 342 | - ref: tut-numeric-interval | ||
| 343 | - title: Resposta numérica em linha de texto | ||
| 344 | - text: | | ||
| 345 | - Escreva o número $\pi$ com pelo menos duas casa decimais. | ||
| 346 | - correct: [3.14, 3.15] | ||
| 347 | - ``` | ||
| 348 | - | ||
| 349 | - Neste exemplo o intervalo de respostas correctas é o intervalo fechado | ||
| 350 | - [3.14, 3.15]. | ||
| 351 | - | ||
| 352 | - Se em vez de dar um intervalo, apenas for indicado um valor numérico $n$, | ||
| 353 | - este é automaticamente convertido para para um intervalo $[n,n]$. | ||
| 354 | - | ||
| 355 | - **Atenção:** as respostas têm de usar o ponto como separador decimal. | ||
| 356 | - Em geral são aceites números inteiros, como `123`, | ||
| 357 | - ou em vírgula flutuante, como em `0.23`, `1e-3`. | ||
| 358 | - correct: [3.14, 3.15] | ||
| 359 | - solution: | | ||
| 360 | - Sabemos que $\pi\approx 3.14159265359$. | ||
| 361 | - Portanto, um exemplo de uma resposta correcta é `3.1416`. | ||
| 362 | - | ||
| 363 | -# --------------------------------------------------------------------------- | ||
| 364 | -- type: textarea | ||
| 365 | - ref: tut-textarea | ||
| 366 | - title: Resposta em múltiplas linhas de texto | ||
| 367 | - text: | | ||
| 368 | - Este tipo de perguntas permitem respostas em múltiplas linhas de texto e | ||
| 369 | - são as mais flexíveis. | ||
| 370 | - | ||
| 371 | - A resposta é enviada para um programa externo para ser avaliada. | ||
| 372 | - O programa externo é um programa que tem de ser executável pelo pelo | ||
| 373 | - sistema operativo (pode ser um binário ou script desde que o respectivo | ||
| 374 | - interpretador instalado). | ||
| 375 | - Este programa externo recebe a resposta submetida pelo aluno via `stdin` e | ||
| 376 | - devolve a classificação via `stdout`. | ||
| 377 | - Exemplo: | ||
| 378 | - | ||
| 379 | - ```yaml | ||
| 380 | - - type: textarea | ||
| 381 | - ref: tut-textarea | ||
| 382 | - title: Resposta em múltiplas linhas de texto | ||
| 383 | - text: | | ||
| 384 | - Bla bla bla | ||
| 385 | - correct: correct/correct-question.py # programa a executar | ||
| 386 | - timeout: 5 | ||
| 387 | - ``` | ||
| 388 | - | ||
| 389 | - Neste exemplo, o programa de avaliação é um script python que verifica se a | ||
| 390 | - resposta contém as três palavras red, green e blue, e calcula uma nota no | ||
| 391 | - intervalo 0.0 a 1.0. | ||
| 392 | - O programa externo é executado num processo separado e a interacção faz-se | ||
| 393 | - via stdin/stdout. | ||
| 394 | - | ||
| 395 | - Se o programa externo exceder o `timeout` indicado (em segundos), | ||
| 396 | - este é automaticamente terminado e é atribuída a classificação de 0.0 | ||
| 397 | - valores na pergunta. | ||
| 398 | - | ||
| 399 | - Após terminar a correcção, o programa externo deve enviar a classificação | ||
| 400 | - para o stdout. | ||
| 401 | - Pode simplesmente fazer `print` da classificação como um número em vírgula | ||
| 402 | - flutuante, por exemplo | ||
| 403 | - | ||
| 404 | - ```yaml | ||
| 405 | - 0.75 | ||
| 406 | - ``` | ||
| 407 | - | ||
| 408 | - ou opcionalmente escrever em formato json ou yaml, eventualmente com um | ||
| 409 | - comentário que será arquivado com o teste. | ||
| 410 | - Exemplo: | ||
| 411 | - | ||
| 412 | - ```yaml | ||
| 413 | - grade: 0.5 | ||
| 414 | - comments: | | ||
| 415 | - Esqueceu-se de algumas cores. | ||
| 416 | - A resposta correcta era `red green blue`. | ||
| 417 | - ``` | ||
| 418 | - | ||
| 419 | - O comentário é mostrado na revisão de prova. | ||
| 420 | - answer: | | ||
| 421 | - Aqui o aluno escreve a resposta. | ||
| 422 | - Esta caixa aumenta de tamanho automaticamente e | ||
| 423 | - pode estar previamente preenchida como neste caso (use `answer: texto`). | ||
| 424 | - correct: correct/correct-question.py | ||
| 425 | - timeout: 5 | ||
| 426 | - tests_right: | ||
| 427 | - - 'red green blue' | ||
| 428 | - # tests_wrong: | ||
| 429 | - # - 'blue gray yellow' | ||
| 430 | - | ||
| 431 | -# --------------------------------------------------------------------------- | ||
| 432 | -- type: information | ||
| 433 | - ref: tut-information | ||
| 434 | - title: Texto informativo | ||
| 435 | - text: | | ||
| 436 | - As perguntas deste tipo não contam para avaliação. O objectivo é fornecer | ||
| 437 | - instruções para os alunos, por exemplo tabelas para consulta, fórmulas, etc. | ||
| 438 | - Nesta, tal como em todos os tipos de perguntas podem escrever-se fórmulas | ||
| 439 | - em LaTeX. Exemplo: | ||
| 440 | - | ||
| 441 | - A distribuição gaussiana $\mathcal{N}(x\mid\mu,\sigma^2)$ é | ||
| 442 | - definida pela função densidade de probabilidade | ||
| 443 | - | ||
| 444 | - $$ | ||
| 445 | - p(x) = \frac{1}{\sqrt{2\pi\sigma^2}} | ||
| 446 | - \exp\Big({-\frac{(x-\mu)^2}{2\sigma^2}}\Big). | ||
| 447 | - $$ | ||
| 448 | - | ||
| 449 | - --- | ||
| 450 | - | ||
| 451 | - ```yaml | ||
| 452 | - - type: information | ||
| 453 | - ref: tut-information | ||
| 454 | - title: Texto informativo | ||
| 455 | - text: | | ||
| 456 | - A distribuição gaussiana $\mathcal{N}(x\mid\mu,\sigma^2)$ é | ||
| 457 | - definida pela função densidade de probabilidade | ||
| 458 | - | ||
| 459 | - $$ | ||
| 460 | - p(x) = \frac{1}{\sqrt{2\pi\sigma^2}} | ||
| 461 | - \exp\Big({-\frac{(x-\mu)^2}{2\sigma^2}}\Big). | ||
| 462 | - $$ | ||
| 463 | - ``` | ||
| 464 | - | ||
| 465 | -# --------------------------------------------------------------------------- | ||
| 466 | -- type: success | ||
| 467 | - ref: tut-success | ||
| 468 | - title: Texto informativo (sucesso) | ||
| 469 | - text: | | ||
| 470 | - Não conta para avaliação. É apenas o aspecto gráfico que muda. | ||
| 471 | - | ||
| 472 | - Um pedaço de código em linha, por exemplo `x = sqrt(z)` é marcado com uma | ||
| 473 | - fonte e cor diferente. | ||
| 474 | - Também se podem escrever troços de código coloridos conforme a linguagem: | ||
| 475 | - | ||
| 476 | - ```C | ||
| 477 | - int main() { | ||
| 478 | - printf("Hello world!"); | ||
| 479 | - return 0; // comentario | ||
| 480 | - } | ||
| 481 | - ``` | ||
| 482 | - | ||
| 483 | - --- | ||
| 484 | - | ||
| 485 | - ```yaml | ||
| 486 | - - type: success | ||
| 487 | - ref: tut-success | ||
| 488 | - title: Texto informativo (sucesso) | ||
| 489 | - text: | | ||
| 490 | - Não conta para avaliação. É apenas o aspecto gráfico que muda. | ||
| 491 | - | ||
| 492 | - Um pedaço de código em linha, por exemplo `x = sqrt(z)` é marcado com | ||
| 493 | - uma fonte e cor diferente. | ||
| 494 | - Também se podem escrever troços de código coloridos conforme a | ||
| 495 | - linguagem: | ||
| 496 | - | ||
| 497 | - ```C | ||
| 498 | - int main() { | ||
| 499 | - printf("Hello world!"); | ||
| 500 | - return 0; // comentario | ||
| 501 | - } | ||
| 502 | - ``` | ||
| 503 | - | ||
| 504 | - ``` | ||
| 505 | - | ||
| 506 | -# --------------------------------------------------------------------------- | ||
| 507 | -- type: warning | ||
| 508 | - ref: tut-warning | ||
| 509 | - title: Texto informativo (aviso) | ||
| 510 | - text: | | ||
| 511 | - Não conta para avaliação. | ||
| 512 | - | ||
| 513 | - Neste exemplo mostramos como se pode construir uma tabela como a seguinte: | ||
| 514 | - | ||
| 515 | - Left | Center | Right | ||
| 516 | - -----------------|:----------------:|----------: | ||
| 517 | - *hello* | $\sin(x^2)$ | $1600.00 | ||
| 518 | - **world** | $\frac{1}{2\pi}$ | $12.50 | ||
| 519 | - `code` | $\sqrt{\pi}$ | $1.99 | ||
| 520 | - | ||
| 521 | - As tabelas podem conter Markdown e LaTeX e permitem alinhamento das colunas, | ||
| 522 | - mas o markdown é muito simples e não permite mais funcionalidades. | ||
| 523 | - | ||
| 524 | - --- | ||
| 525 | - | ||
| 526 | - ```yaml | ||
| 527 | - - type: warning | ||
| 528 | - ref: tut-warning | ||
| 529 | - title: Texto informativo (aviso) | ||
| 530 | - text: | | ||
| 531 | - Bla bla bla | ||
| 532 | - | ||
| 533 | - Left | Center | Right | ||
| 534 | - -----------------|:----------------:|----------: | ||
| 535 | - *hello* | $\sin(x^2)$ | $1600.00 | ||
| 536 | - **world** | $\frac{1}{2\pi}$ | $12.50 | ||
| 537 | - `code` | $\sqrt{\pi}$ | $1.99 | ||
| 538 | - ``` | ||
| 539 | - | ||
| 540 | -# ---------------------------------------------------------------------------- | ||
| 541 | -- type: alert | ||
| 542 | - ref: tut-alert1 | ||
| 543 | - title: Texto informativo (perigo) - versão 1 | ||
| 544 | - text: | | ||
| 545 | - Não conta para avaliação. Texto importante. | ||
| 546 | - | ||
| 547 | -  | ||
| 548 | - | ||
| 549 | - As imagens podem ser adicionadas usando a notação standard em markdown. Há | ||
| 550 | - duas possibilidads: | ||
| 551 | - | ||
| 552 | - - Imagens inline: não têm título definido e podem ser incluídas no meio de | ||
| 553 | - uma linha de texto usando``. | ||
| 554 | - - Imagens centradas com título: ``. | ||
| 555 | - O título é colocado por baixo da imagem. Pode ser uma string vazia. | ||
| 556 | - | ||
| 557 | -- type: alert | ||
| 558 | - ref: tut-alert2 | ||
| 559 | - title: Texto informativo (perigo) - versão 2 | ||
| 560 | - text: | | ||
| 561 | - Não conta para avaliação. Texto importante. | ||
| 562 | - | ||
| 563 | -  | ||
| 564 | - | ||
| 565 | - As imagens podem ser adicionadas usando a notação standard em markdown. Há | ||
| 566 | - duas possibilidads: | ||
| 567 | - | ||
| 568 | - - Imagens inline: não têm título definido e podem ser incluídas no meio de | ||
| 569 | - uma linha de texto usando ``. | ||
| 570 | - - Imagens centradas com título: ``. | ||
| 571 | - O título é colocado por baixo da imagem. Pode ser uma string vazia. | ||
| 572 | - | ||
| 573 | -# ---------------------------------------------------------------------------- | ||
| 574 | -- type: information | ||
| 575 | - text: | | ||
| 576 | - This question is not included in the test and will not show up. | ||
| 577 | - It also lacks a "ref" and is automatically named | ||
| 578 | - `questions/questions-tutorial.yaml:0013`. | ||
| 579 | - A warning is shown on the console about this. | ||
| 580 | - The number at the end is the index position of this question. | ||
| 581 | - Indices start at 0. | ||
| 582 | - | ||
| 583 | -# ---------------------------------------------------------------------------- | ||
| 584 | -- type: generator | ||
| 585 | - ref: tut-generator | ||
| 586 | - script: generate-question.py | ||
| 587 | - args: [1, 100] | ||
| 588 | - | ||
| 589 | -# ---------------------------------------------------------------------------- | ||
| 590 | -- type: information | ||
| 591 | - ref: tut-yamllint | ||
| 592 | - title: Sugestões para validar yaml | ||
| 593 | - text: | | ||
| 594 | - Como os testes e perguntas são ficheiros `yaml`, é conveniente validar se | ||
| 595 | - estão correctamente definitos. Um *linter* recomendado é o `yamllint`. Pode | ||
| 596 | - ser instalado com `pip install yamllint` e usado do seguinte modo: | ||
| 597 | - | ||
| 598 | - ```sh | ||
| 599 | - yamllint test.yaml | ||
| 600 | - yamllint questions.yaml | ||
| 601 | - ``` | ||
| 602 | - | ||
| 603 | - No caso de programas geradores de perguntas e programas de correcção de | ||
| 604 | - respostas pode usar-se um *pipe*: | ||
| 605 | - | ||
| 606 | - ```sh | ||
| 607 | - generate-question | yamllint - | ||
| 608 | - correct-answer | yamllint - | ||
| 609 | - ``` | ||
| 610 | - | ||
| 611 | -# ---------------------------------------------------------------------------- | ||
| 612 | -# - type: code | ||
| 613 | -# ref: tut-code | ||
| 614 | -# title: Submissão de código (JOBE) | ||
| 615 | -# text: | | ||
| 616 | -# É possível enviar código para ser compilado e executado por um servidor | ||
| 617 | -# JOBE instalado separadamente, ver [JOBE](https://github.com/trampgeek/jobe). | ||
| 618 | - | ||
| 619 | -# ```yaml | ||
| 620 | -# - type: code | ||
| 621 | -# ref: tut-code | ||
| 622 | -# title: Submissão de código (JOBE) | ||
| 623 | -# text: | | ||
| 624 | -# Escreva um programa em C que recebe uma string no standard input e | ||
| 625 | -# mostra a mensagem `hello ` seguida da string. | ||
| 626 | -# Por exemplo, se o input for `Maria`, o output deverá ser `hello Maria`. | ||
| 627 | -# language: c | ||
| 628 | -# correct: | ||
| 629 | -# - stdin: 'Maria' | ||
| 630 | -# stdout: 'hello Maria' | ||
| 631 | -# - stdin: 'xyz' | ||
| 632 | -# stdout: 'hello xyz' | ||
| 633 | -# ``` | ||
| 634 | - | ||
| 635 | -# Existem várias linguagens suportadas pelo servidor JOBE (C, C++, Java, | ||
| 636 | -# Python2, Python3, Octave, Pascal, PHP). | ||
| 637 | -# O campo `correct` deverá ser uma lista de casos a testar. | ||
| 638 | -# Se um caso incluir `stdin`, este será enviado para o programa e o `stdout` | ||
| 639 | -# obtido será comparado com o declarado. A pergunta é considerada correcta se | ||
| 640 | -# todos os outputs coincidirem. | ||
| 641 | - | ||
| 642 | -# Por defeito é o usado o servidor JOBE declarado no teste. Para usar outro | ||
| 643 | -# diferente nesta pergunta usa-se a opção `server: 127.0.0.1` com o endereço | ||
| 644 | -# apropriado. | ||
| 645 | -# answer: | | ||
| 646 | -# #include <stdio.h> | ||
| 647 | -# int main() { | ||
| 648 | -# char name[20]; | ||
| 649 | -# scanf("%s", name); | ||
| 650 | -# printf("hello %s", name); | ||
| 651 | -# } | ||
| 652 | -# # server: 192.168.1.85 | ||
| 653 | -# language: c | ||
| 654 | -# correct: | ||
| 655 | -# - stdin: 'Maria' | ||
| 656 | -# stdout: 'hello Maria' | ||
| 657 | -# - stdin: 'xyz' | ||
| 658 | -# stdout: 'hello xyz' |
| @@ -0,0 +1,609 @@ | @@ -0,0 +1,609 @@ | ||
| 1 | +--- | ||
| 2 | +# ---------------------------------------------------------------------------- | ||
| 3 | +- type: information | ||
| 4 | + ref: tut-test | ||
| 5 | + title: Configuração do teste | ||
| 6 | + text: | | ||
| 7 | + O teste é configurado num ficheiro `yaml` | ||
| 8 | + (ver especificação [aqui](https://yaml.org)). | ||
| 9 | + A configuração contém a identificação do teste, base de dados dos alunos, | ||
| 10 | + ficheiros de perguntas a importar e uma selecção de perguntas e respectivas | ||
| 11 | + cotações. | ||
| 12 | + | ||
| 13 | + Exemplo: | ||
| 14 | + | ||
| 15 | + ```yaml | ||
| 16 | + --- | ||
| 17 | + # -------------------------------------------------------------------------- | ||
| 18 | + ref: tutorial # referência, pode ser reusada em vários turnos | ||
| 19 | + title: Demonstração # título da prova | ||
| 20 | + database: students.db # base de dados previamente criada com initdb | ||
| 21 | + answers_dir: ans # directório onde ficam os testes dos alunos | ||
| 22 | + | ||
| 23 | + # opcionais | ||
| 24 | + duration: 60 # duração da prova em minutos (default: inf) | ||
| 25 | + autosubmit: true # submissão automática (default: false) | ||
| 26 | + show_points: true # mostra cotação das perguntas (default: true) | ||
| 27 | + scale: [0, 20] # normaliza cotações para o intervalo indicado. | ||
| 28 | + # não normaliza por defeito (default: None) | ||
| 29 | + | ||
| 30 | + # -------------------------------------------------------------------------- | ||
| 31 | + # Ficheiros de perguntas a importar (relativamente a `questions_dir`) | ||
| 32 | + files: | ||
| 33 | + - tabelas.yaml | ||
| 34 | + - topic1/questions.yaml | ||
| 35 | + - topic2/part1/questions.yaml | ||
| 36 | + - topic2/part2/questions.yaml | ||
| 37 | + | ||
| 38 | + # -------------------------------------------------------------------------- | ||
| 39 | + # Especificação das perguntas do teste e respectivas cotações. | ||
| 40 | + # O teste é uma lista de perguntas, onde cada pergunta é especificada num | ||
| 41 | + # dicionário com a referência da pergunta e a respectiva cotação. | ||
| 42 | + questions: | ||
| 43 | + - ref: pergunta1 | ||
| 44 | + points: 3.5 | ||
| 45 | + | ||
| 46 | + - ref: pergunta2 | ||
| 47 | + points: 2.0 | ||
| 48 | + | ||
| 49 | + # por defeinto, a cotação da pergunta é 1.0 valor | ||
| 50 | + - ref: pergunta3 | ||
| 51 | + | ||
| 52 | + # escolhe aleatoriamente uma das variantes da pergunta | ||
| 53 | + - ref: [pergunta3a, pergunta3b] | ||
| 54 | + points: 0.5 | ||
| 55 | + | ||
| 56 | + # -------------------------------------------------------------------------- | ||
| 57 | + ``` | ||
| 58 | + | ||
| 59 | + A ordem das perguntas é mantida quando apresentada no teste. | ||
| 60 | + | ||
| 61 | + O mesmo teste pode ser realizado várias vezes em turnos diferentes, não é | ||
| 62 | + necessário alterar nada. | ||
| 63 | + | ||
| 64 | +# ---------------------------------------------------------------------------- | ||
| 65 | +- type: information | ||
| 66 | + ref: tut-questions | ||
| 67 | + title: Especificação das perguntas | ||
| 68 | + text: | | ||
| 69 | + As perguntas estão definidas num ou mais ficheiros `yaml` como uma lista de | ||
| 70 | + perguntas, onde cada pergunta é um dicionário. | ||
| 71 | + | ||
| 72 | + Por exemplo, um ficheiro com o conteúdo abaixo contém duas perguntas, uma | ||
| 73 | + de escolha múltipla e outra apenas informativa: | ||
| 74 | + | ||
| 75 | + ```yaml | ||
| 76 | + --- | ||
| 77 | + #--------------------------------------------------------------------------- | ||
| 78 | + - type: radio | ||
| 79 | + ref: chave-unica-1 | ||
| 80 | + text: Quanto é $1+1$? | ||
| 81 | + options: | ||
| 82 | + - 1 | ||
| 83 | + - 2 | ||
| 84 | + - 3 | ||
| 85 | + | ||
| 86 | + #--------------------------------------------------------------------------- | ||
| 87 | + - type: information | ||
| 88 | + ref: chave-unica-2 | ||
| 89 | + text: | | ||
| 90 | + Quando o texto da pergunta tem várias linhas, dá jeito usar o símbolo | ||
| 91 | + `|` de pipe, para indicar que tudo o que estiver indentado faz parte do | ||
| 92 | + texto. É o caso desta pergunta. | ||
| 93 | + | ||
| 94 | + O texto das perguntas é escrito em `markdown` e suporta fórmulas em | ||
| 95 | + LaTeX. | ||
| 96 | + | ||
| 97 | + #--------------------------------------------------------------------------- | ||
| 98 | + ``` | ||
| 99 | + | ||
| 100 | + As chaves são usadas para construir o teste e não se podem repetir, mesmo | ||
| 101 | + em ficheiros diferentes. | ||
| 102 | + De seguida mostram-se exemplos dos vários tipos de perguntas. | ||
| 103 | + | ||
| 104 | +# ---------------------------------------------------------------------------- | ||
| 105 | +- type: radio | ||
| 106 | + ref: tut-radio | ||
| 107 | + title: Escolha simples, uma opção correcta. | ||
| 108 | + text: | | ||
| 109 | + As perguntas de escolha simples, permitem fazer uma pergunta e apresentar | ||
| 110 | + várias opções de resposta em que apenas uma delas está certa. | ||
| 111 | + A utilização mais simples é a seguinte: | ||
| 112 | + | ||
| 113 | + ```yaml | ||
| 114 | + - type: radio | ||
| 115 | + ref: pergunta-1 | ||
| 116 | + title: Escolha simples, uma opção correcta. | ||
| 117 | + text: | | ||
| 118 | + Bla bla bla. | ||
| 119 | + options: | ||
| 120 | + - Opção 0 | ||
| 121 | + - Opção 1 | ||
| 122 | + - Opção 2 | ||
| 123 | + - Opção 3 | ||
| 124 | + - Opção 4 | ||
| 125 | + ``` | ||
| 126 | + | ||
| 127 | + Sem outras configurações, assume-se que a primeira opção é a resposta | ||
| 128 | + correcta ("Opção 0" neste caso) e as 5 opções são apresentadas por ordem | ||
| 129 | + aleatória. | ||
| 130 | + | ||
| 131 | + Para evitar que os alunos memorizem os textos das opções, podem definir-se | ||
| 132 | + várias opções correctas com escrita ligeiramente diferente, sendo escolhida | ||
| 133 | + apenas uma delas para apresentação. | ||
| 134 | + Por exemplo, se as 2 primeiras opções estiverem correctas e as restantes | ||
| 135 | + erradas, e quisermos apresentar ao aluno 3 opções no total, acrescenta-se: | ||
| 136 | + | ||
| 137 | + ```yaml | ||
| 138 | + correct: [1, 1, 0, 0, 0] | ||
| 139 | + choose: 3 | ||
| 140 | + ``` | ||
| 141 | + | ||
| 142 | + Neste caso, será escolhida uma opção certa e duas erradas. | ||
| 143 | + Os valores em `correct` representam o grau de correcção no intervalo [0, 1] | ||
| 144 | + onde 1 representa 100% certo e 0 representa 0%. Podem ser usados valores | ||
| 145 | + entre 0 e 1, sendo atribuída a respectiva cotação, mas só o valor 1 | ||
| 146 | + representa uma opção certa. | ||
| 147 | + | ||
| 148 | + Por defeito, as opções são apresentadas por ordem aleatória, mas é possível | ||
| 149 | + usar a ordem predefinida. Por exemplo, para manter a ordem e indicar que a | ||
| 150 | + resposta correcta é a do meio define-se: | ||
| 151 | + | ||
| 152 | + ```yaml | ||
| 153 | + correct: [0, 0, 1, 0, 0] | ||
| 154 | + shuffle: false | ||
| 155 | + ``` | ||
| 156 | + | ||
| 157 | + As respostas erradas descontam, tendo uma cotação de $-1/(n-1)$ do valor da | ||
| 158 | + pergunta, onde $n$ é o número de opções apresentadas ao aluno (a ideia é o | ||
| 159 | + valor esperado ser zero quando as respostas são aleatórias e uniformemente | ||
| 160 | + distribuídas). Para não descontar acrescenta-se: | ||
| 161 | + | ||
| 162 | + ```yaml | ||
| 163 | + discount: false | ||
| 164 | + ``` | ||
| 165 | + options: | ||
| 166 | + - Opção 0 (certa) | ||
| 167 | + - Opção 1 (certa) | ||
| 168 | + - Opção 2 | ||
| 169 | + - Opção 3 | ||
| 170 | + - Opção 4 | ||
| 171 | + correct: [1, 1, 0, 0, 0] | ||
| 172 | + choose: 3 | ||
| 173 | + solution: | | ||
| 174 | + A solução correcta é a **Opção 0** ou a **Opção 1**. | ||
| 175 | + | ||
| 176 | +# ---------------------------------------------------------------------------- | ||
| 177 | +- type: checkbox | ||
| 178 | + ref: tut-checkbox | ||
| 179 | + title: Escolha múltipla, várias opções correctas | ||
| 180 | + text: | | ||
| 181 | + As perguntas de escolha múltipla permitem apresentar um conjunto de opções | ||
| 182 | + podendo ser seleccionadas várias em simultâneo. | ||
| 183 | + Funcionam como múltiplas perguntas independentes de resposta sim/não. | ||
| 184 | + | ||
| 185 | + As respostas que devem ou não ser seleccionadas são indicadas com `1` e `0` | ||
| 186 | + ou com booleanos `true` e `false`. | ||
| 187 | + Cada resposta errada desconta um valor que é o simétrico da resposta certa. | ||
| 188 | + Se acertar uma opção ganha `+1`, se errar obtém `-1`. | ||
| 189 | + | ||
| 190 | + ```yaml | ||
| 191 | + - type: checkbox | ||
| 192 | + ref: tut-checkbox | ||
| 193 | + title: Escolha múltipla, várias opções correctas | ||
| 194 | + text: | | ||
| 195 | + Bla bla bla. | ||
| 196 | + options: | ||
| 197 | + - Opção 0 (certa) | ||
| 198 | + - Opção 1 | ||
| 199 | + - Opção 2 | ||
| 200 | + - Opção 3 (certa) | ||
| 201 | + - Opção 4 | ||
| 202 | + correct: [1, 0, 0, 1, 0] | ||
| 203 | + ``` | ||
| 204 | + | ||
| 205 | + Neste exemplo, seleccionando as opções 0 e 3 obtém-se cotação `+1` em cada | ||
| 206 | + uma, enquanto que seleccionando erradamente as opções 1, 2 e 4 obtém-se | ||
| 207 | + cotação `-1`. | ||
| 208 | + Do mesmo modo, não seleccionando as opções certas 0 e 3 obtém-se a cotação | ||
| 209 | + `-1` em cada uma, e não seleccionando (correctamente) as 1, 2 e 4 obtém-se | ||
| 210 | + `+1` em cada. | ||
| 211 | + | ||
| 212 | + *(Neste tipo de perguntas não há forma de responder a apenas algumas delas, | ||
| 213 | + são sempre todas corrigidas. Se um aluno só sabe a resposta a algumas das | ||
| 214 | + opções, deve ter cuidado porque as restantes também serão classificadas e | ||
| 215 | + arrisca-se a ter cotação negativa)* | ||
| 216 | + | ||
| 217 | + Cada opção pode opcionalmente ser escrita como uma afirmação e o seu | ||
| 218 | + contrário, de maneira a aumentar a variabilidade dos textos. | ||
| 219 | + Por exemplo: | ||
| 220 | + | ||
| 221 | + ```yaml | ||
| 222 | + options: | ||
| 223 | + - ['O céu é azul', 'O céu não é azul'] | ||
| 224 | + - ['Um triangulo tem 3 lados', 'Um triangulo tem 2 lados'] | ||
| 225 | + - O nosso planeta tem um satélite natural | ||
| 226 | + correct: [1, 1, 1] | ||
| 227 | + ``` | ||
| 228 | + | ||
| 229 | + Assume-se que a primeira alternativa de cada opção tem a cotação indicada | ||
| 230 | + em `correct`, enquanto a segunda alternativa tem a cotação contrária. | ||
| 231 | + | ||
| 232 | + Tal como nas perguntas do tipo `radio`, podem ser usadas as configurações | ||
| 233 | + `shuffle` e `discount` com valor `false` para as desactivar. | ||
| 234 | + Se `discount` é `false` então as respostas erradas têm cotação 0 em vez do | ||
| 235 | + simétrico. | ||
| 236 | + options: | ||
| 237 | + - ['Opção 0 (sim)', 'Opção 0 (não)'] | ||
| 238 | + - ['Opção 1 (não)', 'Opção 1 (sim)'] | ||
| 239 | + - Opção 2 (não) | ||
| 240 | + - Opção 3 (sim) | ||
| 241 | + correct: [1, 0, 0, 1] | ||
| 242 | + shuffle: false | ||
| 243 | + | ||
| 244 | +# ---------------------------------------------------------------------------- | ||
| 245 | +- type: text | ||
| 246 | + ref: tut-text | ||
| 247 | + title: Resposta de texto em linha | ||
| 248 | + text: | | ||
| 249 | + Este tipo de perguntas permite uma resposta numa linha de texto. A resposta | ||
| 250 | + está correcta se coincidir exactamente com alguma das respostas admissíveis. | ||
| 251 | + | ||
| 252 | + ```yaml | ||
| 253 | + - type: text | ||
| 254 | + ref: tut-text | ||
| 255 | + title: Resposta de texto em linha | ||
| 256 | + text: | | ||
| 257 | + De que cor é o céu? | ||
| 258 | + | ||
| 259 | + Escreva a resposta em português. | ||
| 260 | + correct: ['azul', 'Azul', 'AZUL'] | ||
| 261 | + ``` | ||
| 262 | + | ||
| 263 | + Neste caso, as respostas aceites são `azul`, `Azul` ou `AZUL`. | ||
| 264 | + | ||
| 265 | + Em alguns casos pode ser conveniente transformar a resposta antes de a | ||
| 266 | + comparar, por exemplo para remover espaços ou converter para minúsculas. | ||
| 267 | + A opção `transform` permite dar uma sequência de transformações a aplicar à | ||
| 268 | + resposta do aluno, por exemplo: | ||
| 269 | + | ||
| 270 | + ```yaml | ||
| 271 | + transform: ['trim', 'lower'] | ||
| 272 | + correct: ['azul'] | ||
| 273 | + ``` | ||
| 274 | + | ||
| 275 | + Estão disponíveis as seguintes transformações: | ||
| 276 | + | ||
| 277 | + * `trim` remove os espaços do início e fim da resposta, os espaços do meio | ||
| 278 | + mantêm-se inalterados. | ||
| 279 | + * `remove_space` remove todos os espaços (início, meio e fim). | ||
| 280 | + * `normalize_space` remove espaços do início e fim (trim), e substitui | ||
| 281 | + múltiplos espaços por um único espaço (no meio). | ||
| 282 | + * `lower` e `upper` convertem respectivamente para minúsculas e maiúsculas. | ||
| 283 | + transform: ['trim', 'lower'] | ||
| 284 | + correct: ['azul'] | ||
| 285 | + solution: | | ||
| 286 | + O céu é `azul`, pelo menos durante o dia e se estiver bom tempo... | ||
| 287 | + | ||
| 288 | +# --------------------------------------------------------------------------- | ||
| 289 | +- type: text-regex | ||
| 290 | + ref: tut-text-regex | ||
| 291 | + title: Resposta de texto em linha, expressão regular | ||
| 292 | + text: | | ||
| 293 | + Este tipo de pergunta é semelhante à linha de texto da pergunta anterior. | ||
| 294 | + A única diferença é que esta é validada por uma expressão regular. | ||
| 295 | + | ||
| 296 | + ```yaml | ||
| 297 | + - type: text-regex | ||
| 298 | + ref: tut-text-regex | ||
| 299 | + title: Resposta de texto em linha | ||
| 300 | + text: | | ||
| 301 | + Bla bla bla | ||
| 302 | + correct: '(VERDE|[Vv]erde)' | ||
| 303 | + ``` | ||
| 304 | + | ||
| 305 | + Neste exemplo a expressão regular é `(VERDE|[Vv]erde)`. | ||
| 306 | + | ||
| 307 | + Também se pode dar uma lista de expressões regulares. Nesse caso a resposta | ||
| 308 | + é considerada correcta se fizer match com alguma delas. | ||
| 309 | + No exemplo acima, poder-se-ia ter usado uma lista | ||
| 310 | + | ||
| 311 | + ```yaml | ||
| 312 | + correct: | ||
| 313 | + - 'VERDE' | ||
| 314 | + - '[Vv]erde' | ||
| 315 | + ``` | ||
| 316 | + | ||
| 317 | + --- | ||
| 318 | + | ||
| 319 | + **Atenção:** A expressão regular deve seguir as convenções da suportadas em | ||
| 320 | + python (ver | ||
| 321 | + [Regular expression operations](https://docs.python.org/3/library/re.html)). | ||
| 322 | + Em particular, a expressão regular acima também aceita a resposta | ||
| 323 | + `verde, azul`. | ||
| 324 | + Deve marcar-se o início e final `^(VERDE|[Vv]erde)$` para evitar estas | ||
| 325 | + situações. | ||
| 326 | + | ||
| 327 | + correct: '(VERDE|[Vv]erde)' | ||
| 328 | + solution: | | ||
| 329 | + Deveria ter escrito `VERDE` ou `Verde` ou `verde`. | ||
| 330 | + | ||
| 331 | +# --------------------------------------------------------------------------- | ||
| 332 | +- type: numeric-interval | ||
| 333 | + ref: tut-numeric-interval | ||
| 334 | + title: Resposta numérica em linha de texto | ||
| 335 | + text: | | ||
| 336 | + Este tipo de perguntas esperam uma resposta numérica (vírgula flutuante). | ||
| 337 | + O resultado é considerado correcto se estiver dentro do intervalo fechado | ||
| 338 | + indicado. | ||
| 339 | + | ||
| 340 | + ```yaml | ||
| 341 | + - type: numeric-interval | ||
| 342 | + ref: tut-numeric-interval | ||
| 343 | + title: Resposta numérica em linha de texto | ||
| 344 | + text: | | ||
| 345 | + Escreva o número $\pi$ com pelo menos duas casa decimais. | ||
| 346 | + correct: [3.14, 3.15] | ||
| 347 | + ``` | ||
| 348 | + | ||
| 349 | + Neste exemplo o intervalo de respostas correctas é o intervalo fechado | ||
| 350 | + [3.14, 3.15]. | ||
| 351 | + | ||
| 352 | + Se em vez de dar um intervalo, apenas for indicado um valor numérico $n$, | ||
| 353 | + este é automaticamente convertido para para um intervalo $[n,n]$. | ||
| 354 | + | ||
| 355 | + **Atenção:** as respostas têm de usar o ponto como separador decimal. | ||
| 356 | + Em geral são aceites números inteiros, como `123`, | ||
| 357 | + ou em vírgula flutuante, como em `0.23`, `1e-3`. | ||
| 358 | + correct: [3.14, 3.15] | ||
| 359 | + solution: | | ||
| 360 | + Sabemos que $\pi\approx 3.14159265359$. | ||
| 361 | + Portanto, um exemplo de uma resposta correcta é `3.1416`. | ||
| 362 | + | ||
| 363 | +# --------------------------------------------------------------------------- | ||
| 364 | +- type: textarea | ||
| 365 | + ref: tut-textarea | ||
| 366 | + title: Resposta em múltiplas linhas de texto | ||
| 367 | + text: | | ||
| 368 | + Este tipo de perguntas permitem respostas em múltiplas linhas de texto e | ||
| 369 | + são as mais flexíveis. | ||
| 370 | + | ||
| 371 | + A resposta é enviada para um programa externo para ser avaliada. | ||
| 372 | + O programa externo é um programa que tem de ser executável pelo pelo | ||
| 373 | + sistema operativo (pode ser um binário ou script desde que o respectivo | ||
| 374 | + interpretador instalado). | ||
| 375 | + Este programa externo recebe a resposta submetida pelo aluno via `stdin` e | ||
| 376 | + devolve a classificação via `stdout`. | ||
| 377 | + Exemplo: | ||
| 378 | + | ||
| 379 | + ```yaml | ||
| 380 | + - type: textarea | ||
| 381 | + ref: tut-textarea | ||
| 382 | + title: Resposta em múltiplas linhas de texto | ||
| 383 | + text: | | ||
| 384 | + Bla bla bla | ||
| 385 | + correct: correct-question.py # programa a executar | ||
| 386 | + timeout: 5 | ||
| 387 | + ``` | ||
| 388 | + | ||
| 389 | + Neste exemplo, o programa de avaliação é um script python que verifica se a | ||
| 390 | + resposta contém as três palavras red, green e blue, e calcula uma nota no | ||
| 391 | + intervalo 0.0 a 1.0. | ||
| 392 | + O programa externo é executado num processo separado e a interacção faz-se | ||
| 393 | + via stdin/stdout. | ||
| 394 | + | ||
| 395 | + Se o programa externo exceder o `timeout` indicado (em segundos), | ||
| 396 | + este é automaticamente terminado e é atribuída a classificação de 0.0 | ||
| 397 | + valores na pergunta. | ||
| 398 | + | ||
| 399 | + Após terminar a correcção, o programa externo deve enviar a classificação | ||
| 400 | + para o stdout. | ||
| 401 | + Pode simplesmente fazer `print` da classificação como um número em vírgula | ||
| 402 | + flutuante, por exemplo | ||
| 403 | + | ||
| 404 | + ```yaml | ||
| 405 | + 0.75 | ||
| 406 | + ``` | ||
| 407 | + | ||
| 408 | + ou opcionalmente escrever em formato json ou yaml, eventualmente com um | ||
| 409 | + comentário que será arquivado com o teste. | ||
| 410 | + Exemplo: | ||
| 411 | + | ||
| 412 | + ```yaml | ||
| 413 | + grade: 0.5 | ||
| 414 | + comments: | | ||
| 415 | + Esqueceu-se de algumas cores. | ||
| 416 | + A resposta correcta era `red green blue`. | ||
| 417 | + ``` | ||
| 418 | + | ||
| 419 | + O comentário é mostrado na revisão de prova. | ||
| 420 | + answer: | | ||
| 421 | + Aqui o aluno escreve a resposta. | ||
| 422 | + Esta caixa aumenta de tamanho automaticamente e | ||
| 423 | + pode estar previamente preenchida como neste caso (use `answer: texto`). | ||
| 424 | + correct: correct-question.py | ||
| 425 | + timeout: 5 | ||
| 426 | + tests_right: | ||
| 427 | + - 'red green blue' | ||
| 428 | + # tests_wrong: | ||
| 429 | + # - 'blue gray yellow' | ||
| 430 | + | ||
| 431 | +# --------------------------------------------------------------------------- | ||
| 432 | +- type: information | ||
| 433 | + ref: tut-information | ||
| 434 | + title: Texto informativo | ||
| 435 | + text: | | ||
| 436 | + As perguntas deste tipo não contam para avaliação. O objectivo é fornecer | ||
| 437 | + instruções para os alunos, por exemplo tabelas para consulta, fórmulas, etc. | ||
| 438 | + Nesta, tal como em todos os tipos de perguntas podem escrever-se fórmulas | ||
| 439 | + em LaTeX. Exemplo: | ||
| 440 | + | ||
| 441 | + A distribuição gaussiana $\mathcal{N}(x\mid\mu,\sigma^2)$ é | ||
| 442 | + definida pela função densidade de probabilidade | ||
| 443 | + | ||
| 444 | + $$ | ||
| 445 | + p(x) = \frac{1}{\sqrt{2\pi\sigma^2}} | ||
| 446 | + \exp\Big({-\frac{(x-\mu)^2}{2\sigma^2}}\Big). | ||
| 447 | + $$ | ||
| 448 | + | ||
| 449 | + --- | ||
| 450 | + | ||
| 451 | + ```yaml | ||
| 452 | + - type: information | ||
| 453 | + ref: tut-information | ||
| 454 | + title: Texto informativo | ||
| 455 | + text: | | ||
| 456 | + A distribuição gaussiana $\mathcal{N}(x\mid\mu,\sigma^2)$ é | ||
| 457 | + definida pela função densidade de probabilidade | ||
| 458 | + | ||
| 459 | + $$ | ||
| 460 | + p(x) = \frac{1}{\sqrt{2\pi\sigma^2}} | ||
| 461 | + \exp\Big({-\frac{(x-\mu)^2}{2\sigma^2}}\Big). | ||
| 462 | + $$ | ||
| 463 | + ``` | ||
| 464 | + | ||
| 465 | +# --------------------------------------------------------------------------- | ||
| 466 | +- type: success | ||
| 467 | + ref: tut-success | ||
| 468 | + title: Texto informativo (sucesso) | ||
| 469 | + text: | | ||
| 470 | + Não conta para avaliação. É apenas o aspecto gráfico que muda. | ||
| 471 | + | ||
| 472 | + Um pedaço de código em linha, por exemplo `x = sqrt(z)` é marcado com uma | ||
| 473 | + fonte e cor diferente. | ||
| 474 | + Também se podem escrever troços de código coloridos conforme a linguagem: | ||
| 475 | + | ||
| 476 | + ```C | ||
| 477 | + int main() { | ||
| 478 | + printf("Hello world!"); | ||
| 479 | + return 0; // comentario | ||
| 480 | + } | ||
| 481 | + ``` | ||
| 482 | + | ||
| 483 | + --- | ||
| 484 | + | ||
| 485 | + ```yaml | ||
| 486 | + - type: success | ||
| 487 | + ref: tut-success | ||
| 488 | + title: Texto informativo (sucesso) | ||
| 489 | + text: | | ||
| 490 | + Não conta para avaliação. É apenas o aspecto gráfico que muda. | ||
| 491 | + | ||
| 492 | + Um pedaço de código em linha, por exemplo `x = sqrt(z)` é marcado com | ||
| 493 | + uma fonte e cor diferente. | ||
| 494 | + Também se podem escrever troços de código coloridos conforme a | ||
| 495 | + linguagem: | ||
| 496 | + | ||
| 497 | + ```C | ||
| 498 | + int main() { | ||
| 499 | + printf("Hello world!"); | ||
| 500 | + return 0; // comentario | ||
| 501 | + } | ||
| 502 | + ``` | ||
| 503 | + | ||
| 504 | + ``` | ||
| 505 | + | ||
| 506 | +# --------------------------------------------------------------------------- | ||
| 507 | +- type: warning | ||
| 508 | + ref: tut-warning | ||
| 509 | + title: Texto informativo (aviso) | ||
| 510 | + text: | | ||
| 511 | + Não conta para avaliação. | ||
| 512 | + | ||
| 513 | + Neste exemplo mostramos como se pode construir uma tabela como a seguinte: | ||
| 514 | + | ||
| 515 | + Left | Center | Right | ||
| 516 | + -----------------|:----------------:|----------: | ||
| 517 | + *hello* | $\sin(x^2)$ | $1600.00 | ||
| 518 | + **world** | $\frac{1}{2\pi}$ | $12.50 | ||
| 519 | + `code` | $\sqrt{\pi}$ | $1.99 | ||
| 520 | + | ||
| 521 | + As tabelas podem conter Markdown e LaTeX e permitem alinhamento das colunas, | ||
| 522 | + mas o markdown é muito simples e não permite mais funcionalidades. | ||
| 523 | + | ||
| 524 | + --- | ||
| 525 | + | ||
| 526 | + ```yaml | ||
| 527 | + - type: warning | ||
| 528 | + ref: tut-warning | ||
| 529 | + title: Texto informativo (aviso) | ||
| 530 | + text: | | ||
| 531 | + Bla bla bla | ||
| 532 | + | ||
| 533 | + Left | Center | Right | ||
| 534 | + -----------------|:----------------:|----------: | ||
| 535 | + *hello* | $\sin(x^2)$ | $1600.00 | ||
| 536 | + **world** | $\frac{1}{2\pi}$ | $12.50 | ||
| 537 | + `code` | $\sqrt{\pi}$ | $1.99 | ||
| 538 | + ``` | ||
| 539 | + | ||
| 540 | +# ---------------------------------------------------------------------------- | ||
| 541 | +- type: alert | ||
| 542 | + ref: tut-alert1 | ||
| 543 | + title: Texto informativo (perigo) - versão 1 | ||
| 544 | + text: | | ||
| 545 | + Não conta para avaliação. Texto importante. | ||
| 546 | + | ||
| 547 | +  | ||
| 548 | + | ||
| 549 | + As imagens podem ser adicionadas usando a notação standard em markdown. Há | ||
| 550 | + duas possibilidads: | ||
| 551 | + | ||
| 552 | + - Imagens inline: não têm título definido e podem ser incluídas no meio de | ||
| 553 | + uma linha de texto usando``. | ||
| 554 | + - Imagens centradas com título: ``. | ||
| 555 | + O título é colocado por baixo da imagem. Pode ser uma string vazia. | ||
| 556 | + | ||
| 557 | +- type: alert | ||
| 558 | + ref: tut-alert2 | ||
| 559 | + title: Texto informativo (perigo) - versão 2 | ||
| 560 | + text: | | ||
| 561 | + Não conta para avaliação. Texto importante. | ||
| 562 | + | ||
| 563 | +  | ||
| 564 | + | ||
| 565 | + As imagens podem ser adicionadas usando a notação standard em markdown. Há | ||
| 566 | + duas possibilidads: | ||
| 567 | + | ||
| 568 | + - Imagens inline: não têm título definido e podem ser incluídas no meio de | ||
| 569 | + uma linha de texto usando ``. | ||
| 570 | + - Imagens centradas com título: ``. | ||
| 571 | + O título é colocado por baixo da imagem. Pode ser uma string vazia. | ||
| 572 | + | ||
| 573 | +# ---------------------------------------------------------------------------- | ||
| 574 | +- type: information | ||
| 575 | + text: | | ||
| 576 | + This question is not included in the test and will not show up. | ||
| 577 | + It also lacks a "ref" and is automatically named | ||
| 578 | + `questions/questions-tutorial.yaml:0013`. | ||
| 579 | + A warning is shown on the console about this. | ||
| 580 | + The number at the end is the index position of this question. | ||
| 581 | + Indices start at 0. | ||
| 582 | + | ||
| 583 | +# ---------------------------------------------------------------------------- | ||
| 584 | +- type: generator | ||
| 585 | + ref: tut-generator | ||
| 586 | + script: generate-question.py | ||
| 587 | + args: [1, 100] | ||
| 588 | + | ||
| 589 | +# ---------------------------------------------------------------------------- | ||
| 590 | +- type: information | ||
| 591 | + ref: tut-yamllint | ||
| 592 | + title: Sugestões para validar yaml | ||
| 593 | + text: | | ||
| 594 | + Como os testes e perguntas são ficheiros `yaml`, é conveniente validar se | ||
| 595 | + estão correctamente definitos. Um *linter* recomendado é o `yamllint`. Pode | ||
| 596 | + ser instalado com `pip install yamllint` e usado do seguinte modo: | ||
| 597 | + | ||
| 598 | + ```sh | ||
| 599 | + yamllint test.yaml | ||
| 600 | + yamllint questions.yaml | ||
| 601 | + ``` | ||
| 602 | + | ||
| 603 | + No caso de programas geradores de perguntas e programas de correcção de | ||
| 604 | + respostas pode usar-se um *pipe*: | ||
| 605 | + | ||
| 606 | + ```sh | ||
| 607 | + generate-question | yamllint - | ||
| 608 | + correct-answer | yamllint - | ||
| 609 | + ``` |