Commit bab5f36055ea9544520899e366629f54cdbe3f41
1 parent
bfedb0e2
Exists in
master
and in
1 other branch
- jobe_server on the test.yaml applies as default JOBE server for all questions,…
… but can be overriden. - comments are parsed by markdown when reviewing tests.
Showing
6 changed files
with
31 additions
and
15 deletions
Show diff stats
BUGS.md
1 | 1 | |
2 | 2 | # BUGS |
3 | 3 | |
4 | +- 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. | |
5 | +- QuestionCode falta reportar nos comments os vários erros que podem ocorrer (timeout, etc) | |
4 | 6 | - permitir remover alunos que estão online para poderem comecar de novo. |
5 | -- grade gives internal server error | |
7 | +- grade gives internal server error?? | |
6 | 8 | - reload do teste recomeça a contagem no inicio do tempo. |
7 | 9 | - 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. |
8 | 10 | - 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). | ... | ... |
demo/demo.yaml
... | ... | @@ -14,6 +14,9 @@ database: students.db |
14 | 14 | # Directory where the submitted and corrected test are stored for later review. |
15 | 15 | answers_dir: ans |
16 | 16 | |
17 | +# Server used to compile & execute code | |
18 | +jobe_server: 192.168.1.85 | |
19 | + | |
17 | 20 | # --- optional settings: ----------------------------------------------------- |
18 | 21 | |
19 | 22 | # Title of this test, e.g. course name, year or test number |
... | ... | @@ -37,6 +40,7 @@ show_points: true |
37 | 40 | # (default: no scaling, just use question points) |
38 | 41 | scale: [0, 5] |
39 | 42 | |
43 | + | |
40 | 44 | # ---------------------------------------------------------------------------- |
41 | 45 | # Base path applied to the questions files and all the scripts |
42 | 46 | # including question generators and correctors. | ... | ... |
demo/questions/questions-tutorial.yaml
... | ... | @@ -26,6 +26,7 @@ |
26 | 26 | show_points: true # mostra cotação das perguntas (default: true) |
27 | 27 | scale: [0, 20] # limites inferior e superior da escala (default: [0,20]) |
28 | 28 | scale_points: true # normaliza cotações para a escala definida |
29 | + jobe_server: moodle-jobe.uevora.pt # server used to compile & execute code | |
29 | 30 | debug: false # mostra informação de debug no browser |
30 | 31 | |
31 | 32 | # -------------------------------------------------------------------------- |
... | ... | @@ -626,7 +627,6 @@ |
626 | 627 | Escreva um programa em C que recebe uma string no standard input e |
627 | 628 | mostra a mensagem `hello ` seguida da string. |
628 | 629 | Por exemplo, se o input for `Maria`, o output deverá ser `hello Maria`. |
629 | - server: 127.0.0.1 # replace by appropriate address | |
630 | 630 | language: c |
631 | 631 | correct: |
632 | 632 | - stdin: 'Maria' |
... | ... | @@ -641,6 +641,10 @@ |
641 | 641 | Se um caso incluir `stdin`, este será enviado para o programa e o `stdout` |
642 | 642 | obtido será comparado com o declarado. A pergunta é considerada correcta se |
643 | 643 | todos os outputs coincidirem. |
644 | + | |
645 | + Por defeito é o usado o servidor JOBE declarado no teste. Para usar outro | |
646 | + diferente nesta pergunta usa-se a opção `server: 127.0.0.1` com o endereço | |
647 | + apropriado. | |
644 | 648 | answer: | |
645 | 649 | #include <stdio.h> |
646 | 650 | int main() { |
... | ... | @@ -648,7 +652,7 @@ |
648 | 652 | scanf("%s", name); |
649 | 653 | printf("hello %s", name); |
650 | 654 | } |
651 | - server: 192.168.1.141 | |
655 | + # server: 192.168.1.85 | |
652 | 656 | language: c |
653 | 657 | correct: |
654 | 658 | - stdin: 'Maria' | ... | ... |
perguntations/questions.py
... | ... | @@ -591,11 +591,8 @@ class QuestionTextArea(Question): |
591 | 591 | |
592 | 592 | # ============================================================================ |
593 | 593 | class QuestionCode(Question): |
594 | - '''An instance of QuestionCode will always have the keys: | |
595 | - type (str) | |
596 | - text (str) | |
597 | - correct (str with script to run) | |
598 | - answer (None or an actual answer) | |
594 | + ''' | |
595 | + Submits answer to a JOBE server to compile and run against the test cases. | |
599 | 596 | ''' |
600 | 597 | |
601 | 598 | _outcomes = { |
... | ... | @@ -669,13 +666,15 @@ class QuestionCode(Question): |
669 | 666 | return |
670 | 667 | logger.debug(self._outcomes[outcome]) |
671 | 668 | |
669 | + | |
670 | + | |
672 | 671 | if result['cmpinfo']: # compiler errors and warnings |
673 | 672 | self['comments'] = f'Erros de compilação:\n{result["cmpinfo"]}' |
674 | 673 | self['grade'] = 0.0 |
675 | 674 | return |
676 | 675 | |
677 | - if result['stdout'] != expected['stdout']: | |
678 | - self['comments'] = 'O output gerado é diferente do esperado.' | |
676 | + if result['stdout'] != expected.get('stdout', ''): | |
677 | + self['comments'] = 'O output gerado é diferente do esperado.' # FIXME mostrar porque? | |
679 | 678 | self['grade'] = 0.0 |
680 | 679 | return |
681 | 680 | ... | ... |
perguntations/templates/review-question.html
... | ... | @@ -39,14 +39,14 @@ |
39 | 39 | {{ round(q['grade'] * q['points'], 2) }} |
40 | 40 | pontos |
41 | 41 | </p> |
42 | - <p class="text-success">{{ q['comments'] }}</p> | |
42 | + <p class="text-success">{{ md(q['comments']) }}</p> | |
43 | 43 | {% elif q['grade'] > 0.49 %} |
44 | 44 | <p class="text-warning"> |
45 | 45 | <i class="fas fa-exclamation-triangle fa-3x" aria-hidden="true"></i> |
46 | 46 | {{ round(q['grade'] * q['points'], 2) }} |
47 | 47 | pontos |
48 | 48 | </p> |
49 | - <p class="text-warning">{{ q['comments'] }}</p> | |
49 | + <p class="text-warning">{{ md(q['comments']) }}</p> | |
50 | 50 | {% if q['solution'] %} |
51 | 51 | <hr> |
52 | 52 | {{ md('**Solução:** \n\n' + q['solution']) }} |
... | ... | @@ -57,7 +57,7 @@ |
57 | 57 | {{ round(q['grade'] * q['points'], 2) }} |
58 | 58 | pontos |
59 | 59 | </p> |
60 | - <p class="text-danger"><pre>{{ q['comments'] }}</pre></p> | |
60 | + <p class="text-danger">{{ md(q['comments']) }}</p> | |
61 | 61 | {% if q['solution'] %} |
62 | 62 | <hr> |
63 | 63 | {{ md('**Solução:** \n\n' + q['solution']) }} |
... | ... | @@ -101,7 +101,7 @@ |
101 | 101 | <p class="text-secondary"> |
102 | 102 | <i class="fas fa-ban fa-3x" aria-hidden="true"></i> |
103 | 103 | {{ round(q['grade'] * q['points'], 2) }} pontos<br> |
104 | - {{ q['comments'] }} | |
104 | + {{ md(q['comments']) }} | |
105 | 105 | {% if q['solution'] %} |
106 | 106 | <hr> |
107 | 107 | {{ md('**Solução:** \n\n' + q['solution']) }} | ... | ... |
perguntations/testfactory.py
... | ... | @@ -98,16 +98,23 @@ class TestFactory(dict): |
98 | 98 | |
99 | 99 | # make factory only for the questions used in the test |
100 | 100 | if question['ref'] in qrefs: |
101 | - question.setdefault('type', 'information') | |
101 | + # question.setdefault('type', 'information') | |
102 | 102 | question.update({ |
103 | 103 | 'filename': filename, |
104 | 104 | 'path': dirname, |
105 | 105 | 'index': i # position in the file, 0 based |
106 | 106 | }) |
107 | + if question['type'] == 'code' and 'server' not in question: | |
108 | + try: | |
109 | + question['server'] = self['jobe_server'] | |
110 | + except KeyError as exc: | |
111 | + msg = f'Missing JOBE server in "{question["ref"]}"' | |
112 | + raise TestFactoryException(msg) | |
107 | 113 | |
108 | 114 | self.question_factory[question['ref']] = QFactory(question) |
109 | 115 | |
110 | 116 | # check if all the questions can be correctly generated |
117 | + # TODO and corrected | |
111 | 118 | try: |
112 | 119 | self.question_factory[question['ref']].generate() |
113 | 120 | except Exception as exc: | ... | ... |