Commit 2ed48b705dc5fdb067b6d46d94f078999c3e4f26
1 parent
02782cd5
Exists in
master
and in
1 other branch
- 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
Showing
5 changed files
with
53 additions
and
12 deletions
Show diff stats
app.py
@@ -144,7 +144,9 @@ class App(object): | @@ -144,7 +144,9 @@ class App(object): | ||
144 | starttime=str(t['start_time']), | 144 | starttime=str(t['start_time']), |
145 | finishtime=str(t['finish_time']), | 145 | finishtime=str(t['finish_time']), |
146 | filename=fpath, | 146 | filename=fpath, |
147 | - student_id=t['student']['number'])) | 147 | + student_id=t['student']['number'], |
148 | + state=t['state'], | ||
149 | + comment='')) | ||
148 | s.add_all([Question( | 150 | s.add_all([Question( |
149 | ref=q['ref'], | 151 | ref=q['ref'], |
150 | grade=q['grade'], | 152 | grade=q['grade'], |
@@ -159,13 +161,29 @@ class App(object): | @@ -159,13 +161,29 @@ class App(object): | ||
159 | 161 | ||
160 | # ----------------------------------------------------------------------- | 162 | # ----------------------------------------------------------------------- |
161 | def giveup_test(self, uid): | 163 | def giveup_test(self, uid): |
162 | - logger.info('Student {0}: gave up.'.format(uid)) | ||
163 | t = self.online[uid]['test'] | 164 | t = self.online[uid]['test'] |
164 | grade = t.giveup() | 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 | return t | 187 | return t |
170 | 188 | ||
171 | # ----------------------------------------------------------------------- | 189 | # ----------------------------------------------------------------------- |
models.py
@@ -29,8 +29,10 @@ class Test(Base): | @@ -29,8 +29,10 @@ class Test(Base): | ||
29 | __tablename__ = 'tests' | 29 | __tablename__ = 'tests' |
30 | id = Column(Integer, primary_key=True) # auto_increment | 30 | id = Column(Integer, primary_key=True) # auto_increment |
31 | ref = Column(String) | 31 | ref = Column(String) |
32 | - title = Column(String) | 32 | + title = Column(String) # FIXME depends on ref and should come from another table... |
33 | grade = Column(Float) | 33 | grade = Column(Float) |
34 | + state = Column(String) # ONGOING, FINISHED, QUIT, NULL | ||
35 | + comment = Column(String) | ||
34 | starttime = Column(String) | 36 | starttime = Column(String) |
35 | finishtime = Column(String) | 37 | finishtime = Column(String) |
36 | filename = Column(String) | 38 | filename = Column(String) |
templates/grade.html
@@ -50,8 +50,16 @@ | @@ -50,8 +50,16 @@ | ||
50 | <div class="container"> | 50 | <div class="container"> |
51 | <div class="jumbotron drop-shadow"> | 51 | <div class="jumbotron drop-shadow"> |
52 | <h1>Resultado</h1> | 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 | </div> | 63 | </div> |
56 | 64 | ||
57 | <div class="panel panel-default drop-shadow"> | 65 | <div class="panel panel-default drop-shadow"> |
templates/review.html
@@ -62,7 +62,13 @@ | @@ -62,7 +62,13 @@ | ||
62 | % else: | 62 | % else: |
63 | <span class="label label-success">${t['grade']}</span> valores | 63 | <span class="label label-success">${t['grade']}</span> valores |
64 | % endif | 64 | % endif |
65 | + % if t['state'] == 'QUIT': | ||
66 | + (DESISTÊNCIA) | ||
67 | + % endif | ||
65 | </dd> | 68 | </dd> |
69 | + % if t['comment'] != '': | ||
70 | + <dt>Comentário:</dt><dd>${t['comment']}</dd> | ||
71 | + % endif | ||
66 | </dl> | 72 | </dl> |
67 | </big> | 73 | </big> |
68 | <small> | 74 | <small> |
@@ -116,7 +122,6 @@ | @@ -116,7 +122,6 @@ | ||
116 | ${md_to_html_review(q['text'], q)} | 122 | ${md_to_html_review(q['text'], q)} |
117 | </p> | 123 | </p> |
118 | </div> | 124 | </div> |
119 | - | ||
120 | % else: | 125 | % else: |
121 | <div class="panel panel-primary drop-shadow"> | 126 | <div class="panel panel-primary drop-shadow"> |
122 | <div class="panel-heading clearfix"> | 127 | <div class="panel-heading clearfix"> |
@@ -224,6 +229,8 @@ | @@ -224,6 +229,8 @@ | ||
224 | % endif | 229 | % endif |
225 | 230 | ||
226 | </div> <!-- panel-body --> | 231 | </div> <!-- panel-body --> |
232 | + | ||
233 | + % if t['state'] == 'FINISHED': | ||
227 | <div class="panel-footer"> | 234 | <div class="panel-footer"> |
228 | % if q['grade'] > 0.99: | 235 | % if q['grade'] > 0.99: |
229 | <p class="text-success"> | 236 | <p class="text-success"> |
@@ -245,8 +252,10 @@ | @@ -245,8 +252,10 @@ | ||
245 | </p> | 252 | </p> |
246 | % endif | 253 | % endif |
247 | </div> | 254 | </div> |
255 | + % endif | ||
256 | + | ||
248 | </div> <!-- panel --> | 257 | </div> <!-- panel --> |
249 | - % endif | 258 | + % endif # question type |
250 | </div> <!-- ui-corner-all custom-corners --> | 259 | </div> <!-- ui-corner-all custom-corners --> |
251 | % endfor | 260 | % endfor |
252 | </div> <!-- container --> | 261 | </div> <!-- container --> |
test.py
@@ -202,6 +202,8 @@ class Test(dict): | @@ -202,6 +202,8 @@ class Test(dict): | ||
202 | super().__init__(d) | 202 | super().__init__(d) |
203 | self['start_time'] = datetime.now() | 203 | self['start_time'] = datetime.now() |
204 | self['finish_time'] = None | 204 | self['finish_time'] = None |
205 | + self['state'] = 'ONGOING' | ||
206 | + self['comment'] = '' | ||
205 | logger.info('Student {}: starting test.'.format(self['student']['number'])) | 207 | logger.info('Student {}: starting test.'.format(self['student']['number'])) |
206 | 208 | ||
207 | # ----------------------------------------------------------------------- | 209 | # ----------------------------------------------------------------------- |
@@ -224,6 +226,7 @@ class Test(dict): | @@ -224,6 +226,7 @@ class Test(dict): | ||
224 | # Corrects all the answers and computes the final grade | 226 | # Corrects all the answers and computes the final grade |
225 | def correct(self): | 227 | def correct(self): |
226 | self['finish_time'] = datetime.now() | 228 | self['finish_time'] = datetime.now() |
229 | + self['state'] = 'FINISHED' | ||
227 | 230 | ||
228 | grade = 0.0 | 231 | grade = 0.0 |
229 | total_points = 0.0 | 232 | total_points = 0.0 |
@@ -237,7 +240,8 @@ class Test(dict): | @@ -237,7 +240,8 @@ class Test(dict): | ||
237 | 240 | ||
238 | # ----------------------------------------------------------------------- | 241 | # ----------------------------------------------------------------------- |
239 | def giveup(self): | 242 | def giveup(self): |
240 | - self['comments'] = 'DESISTIU' | 243 | + self['finish_time'] = datetime.now() |
244 | + self['state'] = 'QUIT' | ||
241 | self['grade'] = 0.0 | 245 | self['grade'] = 0.0 |
242 | logger.info('Student {}: gave up.'.format(self['student']['number'])) | 246 | logger.info('Student {}: gave up.'.format(self['student']['number'])) |
243 | return self['grade'] | 247 | return self['grade'] |