Commit 73e9fbcb5a2faa859698806e75d20657fb20f8a3

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

- minimum grade is 0

- questions can add comments to be shown in the review (e.g. correct answer)
- cosmetic changes: space around tables, scaling hands up/down, review of unanswered questions is shaded.
1 1
2 # BUGS 2 # BUGS
3 3
  4 +- total do teste aparece negativo.
  5 +- espaco no final das tabelas.
4 - qual a diferenca entre md_to_html e md_to_html_review, parece desnecessario haver dois. 6 - qual a diferenca entre md_to_html e md_to_html_review, parece desnecessario haver dois.
5 - servir imagens das perguntas 7 - servir imagens das perguntas
6 - como alterar configuracao para mostrar logs de debug? 8 - como alterar configuracao para mostrar logs de debug?
@@ -70,6 +70,7 @@ class Question(dict): @@ -70,6 +70,7 @@ class Question(dict):
70 self.set_defaults({ 70 self.set_defaults({
71 'title': '', 71 'title': '',
72 'answer': None, 72 'answer': None,
  73 + 'comments': '',
73 'files': {}, 74 'files': {},
74 }) 75 })
75 76
@@ -78,7 +79,6 @@ class Question(dict): @@ -78,7 +79,6 @@ class Question(dict):
78 79
79 def correct(self): 80 def correct(self):
80 self['grade'] = 0.0 81 self['grade'] = 0.0
81 - self['comments'] = ''  
82 return 0.0 82 return 0.0
83 83
84 def set_defaults(self, d): 84 def set_defaults(self, d):
@@ -87,7 +87,7 @@ class Question(dict): @@ -87,7 +87,7 @@ class Question(dict):
87 self.setdefault(k, v) 87 self.setdefault(k, v)
88 88
89 89
90 -# =========================================================================== 90 +# ==========================================================================
91 class QuestionRadio(Question): 91 class QuestionRadio(Question):
92 '''An instance of QuestionRadio will always have the keys: 92 '''An instance of QuestionRadio will always have the keys:
93 type (str) 93 type (str)
static/css/test.css
@@ -15,7 +15,7 @@ body { @@ -15,7 +15,7 @@ body {
15 } 15 }
16 16
17 .card { 17 .card {
18 - margin-top: 70px; 18 + margin-top: 5em;
19 } 19 }
20 20
21 21
@@ -26,7 +26,8 @@ textarea { @@ -26,7 +26,8 @@ textarea {
26 /* make markdown tables beautiful */ 26 /* make markdown tables beautiful */
27 table { 27 table {
28 border-collapse: collapse; 28 border-collapse: collapse;
29 - margin-left: 50px; 29 + margin: 1em;
  30 + margin-left: 5em;
30 } 31 }
31 thead, tbody, td, th { 32 thead, tbody, td, th {
32 padding: 5px; 33 padding: 5px;
templates/grade.html
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 <link rel="stylesheet" href="/static/font-awesome/css/font-awesome.min.css"> 13 <link rel="stylesheet" href="/static/font-awesome/css/font-awesome.min.css">
14 <link rel="stylesheet" href="/static/css/test.css"> 14 <link rel="stylesheet" href="/static/css/test.css">
15 </head> 15 </head>
16 - <!-- ===================================================================== --> 16 + <!-- ================================================================= -->
17 <body> 17 <body>
18 18
19 <nav class="navbar navbar-expand-sm fixed-top navbar-dark bg-dark"> 19 <nav class="navbar navbar-expand-sm fixed-top navbar-dark bg-dark">
@@ -33,14 +33,17 @@ @@ -33,14 +33,17 @@
33 </span> 33 </span>
34 </div> 34 </div>
35 </nav> 35 </nav>
36 -<!-- ===================================================================== --> 36 +<!-- ================================================================== -->
37 <div class="container"> 37 <div class="container">
38 <div class="jumbotron"> 38 <div class="jumbotron">
39 <h1>Resultado</h1> 39 <h1>Resultado</h1>
40 40
41 {% if t['state'] == 'FINISHED' %} 41 {% if t['state'] == 'FINISHED' %}
42 <p><strong>{{t['grade']}}</strong> valores na escala de 0 a 20.</p> 42 <p><strong>{{t['grade']}}</strong> valores na escala de 0 a 20.</p>
  43 + {% if t['grade'] >= 15 %}
  44 + <i class="fa fa-thumbs-o-up fa-5x text-success" aria-hidden="true"></i>
43 45
  46 + {% end %}
44 {% elif t['state'] == 'QUIT' %} 47 {% elif t['state'] == 'QUIT' %}
45 <p>Foi registada a sua desistência da prova.</p> 48 <p>Foi registada a sua desistência da prova.</p>
46 49
templates/review-question.html
1 {% autoescape %} 1 {% autoescape %}
2 2
  3 +
3 {% block question %} 4 {% block question %}
4 -<div class="card border-dark mb-3">  
5 -  
6 - <h5 class="card-header text-white bg-dark">  
7 - {{ q['number'] }}. {{ q['title'] }}  
8 - <div class="pull-right">  
9 - <small>Classificar&nbsp;</small>  
10 - {% if q['answer'] is not None %}  
11 - <i class="fa fa-check-square-o" aria-hidden="true"></i>  
12 - {% else %}  
13 - <i class="fa fa-square-o" aria-hidden="true"></i>  
14 - {% end %}  
15 - </div>  
16 - </h5>  
17 -  
18 - <div class="card-body">  
19 - <p id="text">  
20 - {{ md(q['text'], q) }}  
21 - </p>  
22 -  
23 - {% block answer %}{% end %}  
24 -  
25 - {% if t['show_points'] %}  
26 - <p class="text-right">  
27 - <small>  
28 - (Cotação: {{ round(q['points'], 2) }})  
29 - </small>  
30 - </p>  
31 - {% end %}  
32 - </div> <!-- card-body -->  
33 -  
34 - {% if t['state'] == 'FINISHED' %}  
35 - <div class="card-footer">  
36 - {% if q['grade'] > 0.99 %}  
37 - <p class="text-success">  
38 - <i class="fa fa-thumbs-o-up" aria-hidden="true"></i>  
39 - {{ round(q['grade'] * q['points'], 2) }}  
40 - pontos<br>  
41 - {{ q['comments'] }} 5 + {% if q['answer'] is not None %}
  6 +
  7 + <div class="card border-dark mb-3">
  8 + <h5 class="card-header text-white bg-dark">
  9 + {{ q['number'] }}. {{ q['title'] }}
  10 + <div class="pull-right">
  11 + <small>Classificar&nbsp;</small>
  12 + <i class="fa fa-check-square-o" aria-hidden="true"></i>
  13 + </div>
  14 + </h5> <!-- card-header -->
  15 +
  16 + <div class="card-body">
  17 + <p id="text">
  18 + {{ md(q['text'], q) }}
42 </p> 19 </p>
43 - {% elif q['grade'] > 0.49 %}  
44 - <p class="text-warning">  
45 - <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>  
46 - {{ round(q['grade'] * q['points'], 2) }}  
47 - pontos<br>  
48 - {{ q['comments'] }} 20 +
  21 + {% block answer %}{% end %}
  22 +
  23 + <p class="text-right">
  24 + <small>
  25 + (Cotação: {{ round(q['points'], 2) }})
  26 + </small>
49 </p> 27 </p>
50 - {% else %}  
51 - <p class="text-danger">  
52 - <i class="fa fa-thumbs-o-down" aria-hidden="true"></i>  
53 - {{ round(q['grade'] * q['points'], 2) }}  
54 - pontos<br>  
55 - {{ q['comments'] }} 28 + </div> <!-- card-body -->
  29 +
  30 + <div class="card-footer">
  31 + {% if q['grade'] > 0.99 %}
  32 + <p class="text-success">
  33 + <i class="fa fa-thumbs-o-up fa-3x" aria-hidden="true"></i>
  34 + {{ round(q['grade'] * q['points'], 2) }}
  35 + pontos<br>
  36 + {{ q['comments'] }}
  37 + </p>
  38 + {% elif q['grade'] > 0.49 %}
  39 + <p class="text-warning">
  40 + <i class="fa fa-exclamation-triangle fa-3x" aria-hidden="true"></i>
  41 + {{ round(q['grade'] * q['points'], 2) }}
  42 + pontos<br>
  43 + {{ q['comments'] }}
  44 + </p>
  45 + {% else %}
  46 + <p class="text-danger">
  47 + <i class="fa fa-thumbs-o-down fa-3x" aria-hidden="true"></i>
  48 + {{ round(q['grade'] * q['points'], 2) }}
  49 + pontos<br>
  50 + {{ q['comments'] }}
  51 + </p>
  52 + {% end %}
  53 + </div> <!-- card-footer -->
  54 + </div> <!-- card -->
  55 +
  56 + {% else %}
  57 +
  58 + <div class="card border-secondary mb-3">
  59 + <h5 class="card-header text-white bg-secondary">
  60 + {{ q['number'] }}. {{ q['title'] }}
  61 + <div class="pull-right">
  62 + <small>Classificar&nbsp;</small>
  63 + <i class="fa fa-square-o" aria-hidden="true"></i>
  64 + </div>
  65 + </h5> <!-- card-header -->
  66 +
  67 + <div class="card-body text-secondary">
  68 + <p id="text">
  69 + {{ md(q['text'], q) }}
56 </p> 70 </p>
57 - {% end %}  
58 - </div> <!-- card-footer -->  
59 - {% end %}  
60 71
  72 + {% block answer %}{% end %}
61 73
62 -</div>  
63 -{% end %}  
64 \ No newline at end of file 74 \ No newline at end of file
  75 + <p class="text-right">
  76 + <small>
  77 + (Cotação: {{ round(q['points'], 2) }})
  78 + </small>
  79 + </p>
  80 + </div> <!-- card-body -->
  81 +
  82 + <div class="card-footer">
  83 + <p class="text-secondary">
  84 + <i class="fa fa-ban fa-3x" aria-hidden="true"></i>
  85 + {{ round(q['grade'] * q['points'], 2) }} pontos<br>
  86 + {{ q['comments'] }}
  87 + </p>
  88 + </div> <!-- card-footer -->
  89 + </div> <!-- card -->
  90 + {% end %} <!-- if answer not None -->
  91 +{% end %} <!-- block -->
65 \ No newline at end of file 92 \ No newline at end of file
@@ -234,7 +234,7 @@ class Test(dict): @@ -234,7 +234,7 @@ class Test(dict):
234 self['state'] = 'FINISHED' 234 self['state'] = 'FINISHED'
235 235
236 grade = sum(q.correct()*q['points'] for q in self['questions']) 236 grade = sum(q.correct()*q['points'] for q in self['questions'])
237 - self['grade'] = round(grade, 1) 237 + self['grade'] = max(0, round(grade, 1)) # truncate FIXME scale?
238 238
239 logger.info(f'Student {self["student"]["number"]}: correction gave {self["grade"]} points.') 239 logger.info(f'Student {self["student"]["number"]}: correction gave {self["grade"]} points.')
240 return self['grade'] 240 return self['grade']