Commit 5f1ed5cb60f51e188d8bd32dd1a1209a0b1b3b0c

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

new demo test to work as tutorial.

1 1
2 # BUGS 2 # BUGS
3 3
  4 +
  5 +- choose: n em perguntas checkbox
4 - se aluno tem teste activo e é allowed uma segunda vez, deve manter o mesmo teste. adicionar opcao para eliminar um teste em curso. 6 - se aluno tem teste activo e é allowed uma segunda vez, deve manter o mesmo teste. adicionar opcao para eliminar um teste em curso.
5 - melhorar o botao de autorizar (desliga-se), usar antes um botao? 7 - melhorar o botao de autorizar (desliga-se), usar antes um botao?
6 e.g. retornar None quando nao ha alteracoes relativamente à última vez. 8 e.g. retornar None quando nao ha alteracoes relativamente à última vez.
demo/questions/questions-tutorial.yaml
1 --  
2 - ref: tut-information  
3 - type: information  
4 - title: information (ou info)  
5 - text: |  
6 - Texto informativo. Não conta para avaliação. 1 +- type: information
  2 + ref: tut-test
  3 + title: Configuração do teste
  4 + text: |
  5 + O teste é configurado num ficheiro `yaml` (ver especificação [aqui](https://yaml.org)).
  6 + Esta configuração indica a identificação do teste, base de dados dos alunos, ficheiros de perguntas a importar e uma selecção de perguntas e respectivas cotações.
7 7
8 - A distribuição gaussiana $\mathcal{N}(x\mid\mu,\sigma^2)$ é definida por 8 + Exemplo:
9 9
10 - $$  
11 - p(x) = \frac{1}{\sqrt{2\pi\sigma^2}}e^{-\tfrac{1}{2}\tfrac{(x-\mu)^2}{\sigma^2}}.  
12 - $$ 10 + ```yaml
  11 + #-----------------------------------------------------------------------------
  12 + ref: tutorial
  13 + title: Teste de Avaliação
  14 + database: demo/students.db
  15 + answers_dir: demo/ans
13 16
  17 + # (opcional) minutos
  18 + duration: 90
  19 +
  20 + # (opcional, default: False) mostra cotação das perguntas aos alunos, escala 0-20.
  21 + show_points: True
  22 +
  23 + # (opcional, default: False)
  24 + debug: False
  25 +
  26 + #-----------------------------------------------------------------------------
  27 + # Directório base onde estão as perguntas
  28 + questions_dir: ~/topics/P1
  29 +
  30 + # Ficheiros de perguntas a importar
  31 + files:
  32 + - topico_A/parte_1/questions.yaml
  33 + - topico_A/parte_2/questions.yaml
  34 + - topico_B/parte_3/questions.yaml
  35 +
  36 + #-----------------------------------------------------------------------------
  37 + # Perguntas do teste e respectivas cotações
  38 + questions:
  39 + - ref: pergunta1
  40 + grade: 3.5
  41 +
  42 + - ref: pergunta2
  43 + grade: 2
  44 +
  45 + - ref: tabela-auxiliar
  46 +
  47 + # escolhe uma das seguintes aleatoriamente
  48 + - ref: [ pergunta3a, pergunta3b ]
  49 + grade: 0.5
  50 +
  51 + # a cotação é 1.0 por defeito, caso não esteja definida
  52 + - ref: pergunta4
  53 + - pergunta5
  54 + #-----------------------------------------------------------------------------
  55 + ```
  56 +
  57 + O mesmo teste pode ser realizado várias vezes em vários turnos, não é necessário alterar nada.
  58 +
  59 +
  60 +- type: information
  61 + ref: tut-questions
  62 + title: Especificação das perguntas
  63 + text: |
  64 + As perguntas estão definidas num ou mais ficheiros `yaml` como uma lista de dicionários, onde cada pergunta é um dicionário.
  65 +
  66 + Por exemplo, um ficheiro com o conteúdo abaixo contém duas perguntas, uma de escolha múltipla e outra apenas informativa:
  67 +
  68 + ```yaml
  69 + #-----------------------------------------------------------------------------
  70 + - type: radio
  71 + ref: chave-unica-1
  72 + text: Quanto é $1+1$?
  73 + options:
  74 + - 1
  75 + - 2
  76 + - 3
  77 +
  78 + #-----------------------------------------------------------------------------
  79 + - type: info
  80 + ref: chave-unica-2
  81 + text: |
  82 + Quando o texto da pergunta tem várias linhas, dá jeito usar o símbolo pipe, para indicar que tudo o que estiver indentado relativamente à linha `text: |` faz parte do corpo do texto.
  83 +
  84 + É o caso desta pergunta.
  85 +
  86 + #-----------------------------------------------------------------------------
  87 + ```
  88 +
  89 + As chaves são usadas para construir o teste e não se podem repetir em ficheiros diferentes. A seguir vamos ver exemplos de cada tipo de pergunta.
  90 +
  91 +
  92 +# ----------------------------------------------------------------------------
  93 +- type: radio
  94 + ref: tut-radio
  95 + title: Escolha simples, uma opção correcta.
  96 + text: |
  97 + As perguntas de escolha simples, permitem fazer uma pergunta e apresentar várias opções de resposta em que apenas uma delas está certa.
  98 + A utilização mais simples é a seguinte:
  99 +
  100 + ```yaml
  101 + - type: radio
  102 + ref: pergunta-1
  103 + title: Escolha simples, uma opção correcta.
  104 + text: |
  105 + Bla bla bla.
  106 + options:
  107 + - Opção 0
  108 + - Opção 1
  109 + - Opção 2
  110 + - Opção 3
  111 + - Opção 4
  112 + ```
  113 +
  114 + Sem outras configurações, assume-se que a primeira opção ("Opção 0" neste caso) é a resposta correcta, e todas as 5 opções são apresentadas por ordem aleatória.
  115 +
  116 + Para evitar que os alunos memorizem os textos das opções, podem definir-se várias opções correctas com escrita ligeiramente diferente, sendo apresentada apenas uma delas.
  117 + Por exemplo, se as 2 primeiras opções estiverem correctas e as restantes erradas, e quisermos apresentar 3 opções no total com uma delas correcta adiciona-se:
  118 +
  119 + ```yaml
  120 + correct: [1, 1, 0, 0, 0]
  121 + choose: 3
  122 + ```
  123 +
  124 + Assim será escolhida uma opção certa e mais 2 opções erradas.
  125 +
  126 + Por defeito, as opções são sempre baralhadas. Adicionando `shuffle: False` evita que o sejam.
  127 +
  128 + Por defeito, as respostas erradas descontam 1/(n-1) do valor da pergunta, onde n é o número de opções apresentadas. Para não descontar usa-se `discount: False`.
  129 +
  130 + options:
  131 + - Opção 0
  132 + - Opção 1
  133 + - Opção 2
  134 + - Opção 3
  135 + - Opção 4
  136 + correct: [1, 1, 0, 0, 0]
  137 + choose: 3
  138 + shuffle: True
  139 +# ----------------------------------------------------------------------------
  140 +- type: checkbox
  141 + ref: tut-checkbox
  142 + title: Escolha múltipla, várias opções correctas
  143 + text: |
  144 + As perguntas de escolha múltipla permitem apresentar um conjunto de opções podendo ser seleccionadas várias em simultaneo.
  145 + Funcionam como múltiplas perguntas independentes com a cotação indicada em `correct`. As opções não seleccionadas têm a cotação simétrica à indicada.
  146 + Deste modo, um aluno só deve responder se tiver confiança em pelo menos metade das respostas, caso contrário arrisca-se a ter cotação negativa na pergunta.
  147 +
  148 + ```yaml
  149 + - type: checkbox
  150 + ref: tut-checkbox
  151 + title: Escolha múltipla, várias opções correctas
  152 + text: |
  153 + Bla bla bla.
  154 + options:
  155 + - Opção 0
  156 + - Opção 1
  157 + - Opção 2
  158 + - Opção 3
  159 + - Opção 4
  160 + correct: [1, -1, -1, 1, -1]
  161 + ```
  162 +
  163 + Neste exemplo, seleccionando as opções 0 e 3 obtém-se cotação +1 em cada uma, enquanto que seleccionando as opções 1, 2 e 4 obtém-se cotação -1.
  164 + As opções não seleccionadas pelo aluno dão a cotação simétrica à indicada. Por exemplo se não seleccionar a opção 0, tem cotação -1, e não seleccionando a opção 1 obtém-se +1.
  165 +
  166 + Cada opção pode opcionalmente ser escrita como uma afirmação e o seu contrário, de maneira a dar mais aleatoriedade à apresentação deste tipo de perguntas. Por exemplo:
  167 +
  168 + ```yaml
  169 + options:
  170 + - ["O céu é azul", "O céu não é azul"]
  171 + - ["Um triangulo tem 3 lados", "Um triangulo tem 2 lados"]
  172 + - O nosso planeta tem um satélite natural
  173 + correct: [1, 1, 1]
  174 + ```
  175 +
  176 + Assume-se que a primeira alternativa de cada opção tem a cotação +1, enquanto a segunda alternativa tem a cotação simétrica -1 (desconta se for seleccionada).
  177 +
  178 + Estão disponíveis as configurações `shuffle` e `discount`. Se `discount: False` então as respostas erradas têm cotação 0 em vez do simétrico.
  179 +
  180 + options:
  181 + - Opção 0 (sim)
  182 + - Opção 1 (não)
  183 + - Opção 2 (não)
  184 + - Opção 3 (sim)
  185 + correct: [1, -1, -1, 1]
  186 + shuffle: True
  187 +# ----------------------------------------------------------------------------
  188 +- type: text
  189 + ref: tut-text
  190 + title: Resposta de texto em linha
  191 + text: |
  192 + Este tipo de perguntas permite uma resposta numa linha de texto. A resposta está correcta se coincidir com alguma das respostas admissíveis.
  193 +
  194 + ```yaml
  195 + - type: text
  196 + ref: tut-text
  197 + title: Resposta de texto em linha
  198 + text: |
  199 + Bla bla bla
  200 + correct: ['azul', 'Azul', 'AZUL']
  201 + ```
  202 +
  203 + Neste exemplo a resposta correcta é `azul`, `Azul` ou `AZUL`.
  204 + correct: ['azul', 'Azul', 'AZUL']
14 # --------------------------------------------------------------------------- 205 # ---------------------------------------------------------------------------
15 --  
16 - ref: tut-success  
17 - type: success  
18 - title: success  
19 - text: |  
20 - Texto positivo (sucesso). Não conta para avaliação.  
21 -  
22 - ```C  
23 - int main() {  
24 - printf("Hello world!");  
25 - return 0; // comentario  
26 - }  
27 - ```  
28 -  
29 - Inline `code`. 206 +- type: text-regex
  207 + ref: tut-text-regex
  208 + title: Resposta de texto em linha
  209 + text: |
  210 + Este tipo de pergunta é semelhante à linha de texto da pergunta anterior. A única diferença é que esta é validada por uma expressão regular.
  211 +
  212 + ```yaml
  213 + - type: text-regex
  214 + ref: tut-text-regex
  215 + title: Resposta de texto em linha
  216 + text: |
  217 + Bla bla bla
  218 + correct: !regex '(VERDE|[Vv]erde)'
  219 + ```
  220 +
  221 + Neste exemplo a expressão regular é `(VERDE|[Vv]erde)`.
  222 + correct: !regex '(VERDE|[Vv]erde)'
  223 +# ---------------------------------------------------------------------------
  224 +- type: numeric-interval
  225 + ref: tut-numeric-interval
  226 + title: Resposta numérica em linha de texto
  227 + text: |
  228 + Este tipo de perguntas esperam uma resposta numérica (vírgula flutuante).
  229 + O resultado é considerado correcto se estiver dentro do intervalo (fechado) indicado.
  230 +
  231 + ```yaml
  232 + - type: numeric-interval
  233 + ref: tut-numeric-interval
  234 + title: Resposta numérica em linha de texto
  235 + text: |
  236 + Bla bla bla
  237 + correct: [3.14, 3.15]
  238 + ```
  239 +
  240 + Neste exemplo o intervalo de respostas correctas é [3.14, 3.15].
  241 + correct: [3.14, 3.15]
  242 +# ---------------------------------------------------------------------------
  243 +- type: textarea
  244 + ref: tut-textarea
  245 + title: Resposta em múltiplas linhas de texto
  246 + text: |
  247 + Este tipo de perguntas permitem respostas em múltiplas linhas de texto, que podem ser úteis por exemplo para validar código.
  248 + A resposta é enviada para ser avaliada por um programa externo (programa executável).
  249 + O programa externo, recebe a resposta via stdin e devolve a classificação via stdout. Exemplo:
  250 +
  251 + ```yaml
  252 + - type: textarea
  253 + ref: tut-textarea
  254 + title: Resposta em múltiplas linhas de texto
  255 + text: |
  256 + Bla bla bla
  257 + correct: correct/correct-question.py
  258 + lines: 3
  259 + timeout: 5
  260 + ```
  261 +
  262 + Neste exemplo, o programa de avaliação é um script python que verifica se a resposta contém as três palavras red, green e blue, e calcula uma nota de 0.0 a 1.0.
  263 + O programa externo pode ser escrito em qualquer linguagem e a interacção com o servidor faz-se via stdin/stdout.
  264 + Se o programa externo demorar mais do que o `timout` indicado, é automaticamente cancelado e é atribuída a classificação de 0.0 valores.
  265 + `lines: 3` é a dimensão inicial da caixa de texto (pode depois ser redimensionada pelo aluno).
  266 +
  267 + O programa externo deve atribuir uma classificação entre 0.0 e 1.0. Pode simplesmente fazer print da classificação como um número, ou opcionalmente escrever em formato yaml eventualmente com um comentário. Exemplo:
  268 +
  269 + ```yaml
  270 + grade: 0.5
  271 + comments: A resposta correcta é "red green blue".
  272 + ```
  273 +
  274 + O comentário é mostrado na revisão de prova.
  275 + correct: correct/correct-question.py
  276 + lines: 3
  277 + timeout: 5
  278 +
  279 +# ---------------------------------------------------------------------------
  280 +- type: information
  281 + ref: tut-information
  282 + title: Texto informativo
  283 + text: |
  284 + As perguntas deste tipo não contam para avaliação. O objectivo é fornecer instruções para os alunos, por exemplo tabelas para consulta, fórmulas, etc.
  285 + Nesta como em todos os tipos de perguntas pode escrever-se fórmulas em LaTeX. Exemplo:
  286 +
  287 + ```yaml
  288 + - type: information
  289 + ref: tut-information
  290 + title: Texto informativo
  291 + text: |
  292 + A distribuição gaussiana $\mathcal{N}(x\mid\mu,\sigma^2)$ é definida por
  293 +
  294 + $$
  295 + p(x) = \frac{1}{\sqrt{2\pi\sigma^2}}e^{-\tfrac{1}{2}\tfrac{(x-\mu)^2}{\sigma^2}}.
  296 + $$
  297 + ```
  298 +
  299 + Produz:
  300 +
  301 + A distribuição gaussiana $\mathcal{N}(x\mid\mu,\sigma^2)$ é definida por
  302 +
  303 + $$
  304 + p(x) = \frac{1}{\sqrt{2\pi\sigma^2}}e^{-\tfrac{1}{2}\tfrac{(x-\mu)^2}{\sigma^2}}.
  305 + $$
  306 +
  307 +
  308 +
  309 +# ---------------------------------------------------------------------------
  310 +- type: success
  311 + ref: tut-success
  312 + title: Texto informativo (sucesso)
  313 + text: |
  314 + Também não conta para avaliação.
  315 +
  316 + Além das fórmulas LaTeX, também se pode escrever troços de código:
  317 +
  318 + ```C
  319 + int main() {
  320 + printf("Hello world!");
  321 + return 0; // comentario
  322 + }
  323 + ```
  324 +
  325 + Faz-se assim:
  326 +
  327 + - type: success
  328 + ref: tut-success
  329 + title: Texto informativo (sucesso)
  330 + text: |
  331 + Também não conta para avaliação.
  332 +
  333 + Já vimos como se introduzem fórmulas LaTeX, também se pode escrever troços de código:
  334 +
  335 + ```C
  336 + int main() {
  337 + printf("Hello world!");
  338 + return 0; // comentario
  339 + }
  340 + ```
  341 +
30 342
31 # --------------------------------------------------------------------------- 343 # ---------------------------------------------------------------------------
32 --  
33 - ref: tut-warning  
34 - type: warning  
35 - title: warning (ou warn)  
36 - text: |  
37 - Texto de aviso. Não conta para avaliação. 344 +- type: warning
  345 + ref: tut-warning
  346 + title: Texto informativo (aviso)
  347 + text: |
  348 + Não conta para avaliação.
  349 +
  350 + Neste exemplo mostramos como se pode construir uma tabela como a seguinte:
  351 +
  352 + Left | Center | Right
  353 + -----------------|:-------------:|----------:
  354 + $\sin(x^2)$ | *hello* | $1600.00
  355 + $\frac{1}{2\pi}$ | **world** | $12.50
  356 + $\sqrt{\pi}$ | `code` | $1.99
  357 +
  358 + As tabelas podem conter Markdown e LaTeX. Faz-se assim:
  359 +
  360 + ```yaml
  361 + - type: warning
  362 + ref: tut-warning
  363 + title: Texto informativo (aviso)
  364 + text: |
  365 + Bla bla bla
38 366
39 Left | Center | Right 367 Left | Center | Right
40 -----------------|:-------------:|----------: 368 -----------------|:-------------:|----------:
41 $\sin(x^2)$ | *hello* | $1600.00 369 $\sin(x^2)$ | *hello* | $1600.00
42 $\frac{1}{2\pi}$ | **world** | $12.50 370 $\frac{1}{2\pi}$ | **world** | $12.50
43 $\sqrt{\pi}$ | `code` | $1.99 371 $\sqrt{\pi}$ | `code` | $1.99
  372 + ```
  373 +
  374 + A linha de separação entre o cabeçalho e o corpo da tabela indica o alinhamento da coluna com os sinais de dois-pontos.
44 375
45 # ---------------------------------------------------------------------------- 376 # ----------------------------------------------------------------------------
46 --  
47 - ref: tut-alert  
48 - type: alert  
49 - title: alert  
50 - text: |  
51 - Texto negativo (alerta). Não conta para avaliação. 377 +- type: alert
  378 + ref: tut-alert
  379 + title: Texto informativo (perigo)
  380 + text: |
  381 + Texto importante (perigo!). Não conta para avaliação.
52 382
53 - ![imagem](image.jpg "Título da imagem") 383 + ![imagem](image.jpg "Título da imagem")
  384 +
  385 + As imagens ainda não estão a funcionar.
54 386
55 -# ----------------------------------------------------------------------------  
56 --  
57 - ref: tut-radio  
58 - type: radio  
59 - title: radio  
60 - text: Escolha simples, apenas uma opção está correcta.  
61 - options:  
62 - - Opção 0 (correcta)  
63 - - Opção 1  
64 - - Opção 2  
65 - - Opção 3  
66 - # opcionais e valores por defeito  
67 - shuffle: True  
68 - correct: 0  
69 -# ----------------------------------------------------------------------------  
70 --  
71 - ref: tut-checkbox  
72 - type: checkbox  
73 - title: checkbox  
74 - text: Escolha múltipla, várias opções podem estar correctas.  
75 - options:  
76 - - Opção 0 (sim)  
77 - - Opção 1 (não)  
78 - - Opção 2 (não)  
79 - - Opção 3 (sim)  
80 - correct: [1,-1,-1,1]  
81 - # opcionais e valores por defeito  
82 - shuffle: True  
83 -# ----------------------------------------------------------------------------  
84 --  
85 - ref: tut-text  
86 - type: text  
87 - title: text  
88 - text: |  
89 - Resposta numa linha de texto. A resposta está correcta se coincidir com alguma das respostas admissíveis.  
90 - Neste exemplo a resposta correcta é `azul`, `Azul` ou `AZUL`.  
91 - correct: ['azul', 'Azul', 'AZUL']  
92 -# ---------------------------------------------------------------------------  
93 --  
94 - ref: tut-text-regex  
95 - type: text-regex  
96 - title: text-regex  
97 - text: |  
98 - Resposta numa linha de texto. A resposta é validada com uma expressão regular.  
99 - Neste exemplo a expressão regular é `(VERDE|[Vv]erde)`.  
100 - correct: !regex '(VERDE|[Vv]erde)'  
101 -# ---------------------------------------------------------------------------  
102 --  
103 - ref: tut-numeric-interval  
104 - type: numeric-interval  
105 - title: numeric-interval  
106 - text: |  
107 - Resposta numérica numa linha de texto. A resposta é convertida para um float e tem de pertencer a um intervalo de valores.  
108 - Neste exemplo o intervalo é [3.14, 3.15].  
109 - correct: [3.14, 3.15]  
110 -# ---------------------------------------------------------------------------  
111 --  
112 - ref: tut-textarea  
113 - type: textarea  
114 - title: textarea  
115 - text: |  
116 - Resposta num bloco de texto que pode ser usado para introduzir código.  
117 - A resposta é avaliada por um programa externo.  
118 - O programa externo, recebe a resposta no stdin e devolve a classificação no stdout.  
119 - Neste exemplo, o programa de avaliação verifica se a resposta contém as três palavras red, green e blue.  
120 - correct: correct/correct-question.py  
121 - # opcionais e defaults  
122 - lines: 3  
123 - timeout: 5  
demo/test-tutorial.yaml
@@ -43,14 +43,18 @@ files: @@ -43,14 +43,18 @@ files:
43 # The order is preserved. 43 # The order is preserved.
44 # There are several ways to define each question (explained below). 44 # There are several ways to define each question (explained below).
45 questions: 45 questions:
46 - - tut-information  
47 - - tut-success  
48 - - tut-warning  
49 - - tut-alert  
50 - 46 + - tut-test
  47 + - tut-questions
  48 +
51 - tut-radio 49 - tut-radio
52 - tut-checkbox 50 - tut-checkbox
53 - tut-text 51 - tut-text
54 - tut-text-regex 52 - tut-text-regex
55 - tut-numeric-interval 53 - tut-numeric-interval
56 - tut-textarea 54 - tut-textarea
  55 +
  56 + - tut-information
  57 + - tut-success
  58 + - tut-warning
  59 + - tut-alert
  60 +