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 | 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'] | ... | ... |