Commit 2ed48b705dc5fdb067b6d46d94f078999c3e4f26

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

- added two new fields to the test table in the database: state, comment

- the test state indicates if the test was corrected normally, the student quit, or the test is null because of cheating.
- tests are always stored in the database, even if the student quits.
- added support to review quit tests
app.py
... ... @@ -144,7 +144,9 @@ class App(object):
144 144 starttime=str(t['start_time']),
145 145 finishtime=str(t['finish_time']),
146 146 filename=fpath,
147   - student_id=t['student']['number']))
  147 + student_id=t['student']['number'],
  148 + state=t['state'],
  149 + comment=''))
148 150 s.add_all([Question(
149 151 ref=q['ref'],
150 152 grade=q['grade'],
... ... @@ -159,13 +161,29 @@ class App(object):
159 161  
160 162 # -----------------------------------------------------------------------
161 163 def giveup_test(self, uid):
162   - logger.info('Student {0}: gave up.'.format(uid))
163 164 t = self.online[uid]['test']
164 165 grade = t.giveup()
165   - if t['save_answers']:
166   - fname = ' -- '.join((t['student']['number'], t['ref'], str(t['finish_time']))) + '.json'
167   - fpath = path.abspath(path.join(t['answers_dir'], fname))
168   - t.save_json(fpath)
  166 +
  167 + # save JSON with the test
  168 + fname = ' -- '.join((t['student']['number'], t['ref'], str(t['finish_time']))) + '.json'
  169 + fpath = path.abspath(path.join(t['answers_dir'], fname))
  170 + t.save_json(fpath)
  171 +
  172 + # insert test into database
  173 + with self.db_session() as s:
  174 + s.add(Test(
  175 + ref=t['ref'],
  176 + title=t['title'],
  177 + grade=t['grade'],
  178 + starttime=str(t['start_time']),
  179 + finishtime=str(t['finish_time']),
  180 + filename=fpath,
  181 + student_id=t['student']['number'],
  182 + state=t['state'],
  183 + comment=''))
  184 + s.commit()
  185 +
  186 + logger.info('Student {0}: gave up.'.format(uid))
169 187 return t
170 188  
171 189 # -----------------------------------------------------------------------
... ...
models.py
... ... @@ -29,8 +29,10 @@ class Test(Base):
29 29 __tablename__ = 'tests'
30 30 id = Column(Integer, primary_key=True) # auto_increment
31 31 ref = Column(String)
32   - title = Column(String)
  32 + title = Column(String) # FIXME depends on ref and should come from another table...
33 33 grade = Column(Float)
  34 + state = Column(String) # ONGOING, FINISHED, QUIT, NULL
  35 + comment = Column(String)
34 36 starttime = Column(String)
35 37 finishtime = Column(String)
36 38 filename = Column(String)
... ...
templates/grade.html
... ... @@ -50,8 +50,16 @@
50 50 <div class="container">
51 51 <div class="jumbotron drop-shadow">
52 52 <h1>Resultado</h1>
53   - <p>Teve <strong>${t['grade']}</strong> valores na escala de 0 a 20.</p>
54   - <p>A prova está terminada, pode fechar o browser e desligar o computador.</p>
  53 +
  54 + % if t['state'] == 'FINISHED':
  55 + <p>Teve <strong>${t['grade']}</strong> valores na escala de 0 a 20.</p>
  56 +
  57 + % elif t['state'] == 'QUIT':
  58 + <p>Foi registada a sua desistência da prova.</p>
  59 +
  60 + % endif
  61 +
  62 + <p>Pode fechar o browser e desligar o computador.</p>
55 63 </div>
56 64  
57 65 <div class="panel panel-default drop-shadow">
... ...
templates/review.html
... ... @@ -62,7 +62,13 @@
62 62 % else:
63 63 <span class="label label-success">${t['grade']}</span> valores
64 64 % endif
  65 + % if t['state'] == 'QUIT':
  66 + (DESISTÊNCIA)
  67 + % endif
65 68 </dd>
  69 + % if t['comment'] != '':
  70 + <dt>Comentário:</dt><dd>${t['comment']}</dd>
  71 + % endif
66 72 </dl>
67 73 </big>
68 74 <small>
... ... @@ -116,7 +122,6 @@
116 122 ${md_to_html_review(q['text'], q)}
117 123 </p>
118 124 </div>
119   -
120 125 % else:
121 126 <div class="panel panel-primary drop-shadow">
122 127 <div class="panel-heading clearfix">
... ... @@ -224,6 +229,8 @@
224 229 % endif
225 230  
226 231 </div> <!-- panel-body -->
  232 +
  233 + % if t['state'] == 'FINISHED':
227 234 <div class="panel-footer">
228 235 % if q['grade'] > 0.99:
229 236 <p class="text-success">
... ... @@ -245,8 +252,10 @@
245 252 </p>
246 253 % endif
247 254 </div>
  255 + % endif
  256 +
248 257 </div> <!-- panel -->
249   - % endif
  258 + % endif # question type
250 259 </div> <!-- ui-corner-all custom-corners -->
251 260 % endfor
252 261 </div> <!-- container -->
... ...
test.py
... ... @@ -202,6 +202,8 @@ class Test(dict):
202 202 super().__init__(d)
203 203 self['start_time'] = datetime.now()
204 204 self['finish_time'] = None
  205 + self['state'] = 'ONGOING'
  206 + self['comment'] = ''
205 207 logger.info('Student {}: starting test.'.format(self['student']['number']))
206 208  
207 209 # -----------------------------------------------------------------------
... ... @@ -224,6 +226,7 @@ class Test(dict):
224 226 # Corrects all the answers and computes the final grade
225 227 def correct(self):
226 228 self['finish_time'] = datetime.now()
  229 + self['state'] = 'FINISHED'
227 230  
228 231 grade = 0.0
229 232 total_points = 0.0
... ... @@ -237,7 +240,8 @@ class Test(dict):
237 240  
238 241 # -----------------------------------------------------------------------
239 242 def giveup(self):
240   - self['comments'] = 'DESISTIU'
  243 + self['finish_time'] = datetime.now()
  244 + self['state'] = 'QUIT'
241 245 self['grade'] = 0.0
242 246 logger.info('Student {}: gave up.'.format(self['student']['number']))
243 247 return self['grade']
... ...