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: | ... | ... |