Commit 861d9ae5ba6dfc9fe2b16f0265701d06e00c65a5
1 parent
e3d61b82
Exists in
master
and in
1 other branch
Much faster rankings
Showing
4 changed files
with
35 additions
and
25 deletions
Show diff stats
aprendizations/knowledge.py
... | ... | @@ -70,7 +70,6 @@ class StudentKnowledge(object): |
70 | 70 | # questions: list of generated questions to do in the topic |
71 | 71 | # current_question: the current question to be presented |
72 | 72 | # ------------------------------------------------------------------------ |
73 | - # FIXME async mas nao tem awaits... do not allow restart same topic | |
74 | 73 | async def start_topic(self, topic): |
75 | 74 | logger.debug('StudentKnowledge.start_topic()') |
76 | 75 | if self.current_topic == topic: | ... | ... |
aprendizations/learnapp.py
... | ... | @@ -8,7 +8,7 @@ from datetime import datetime |
8 | 8 | |
9 | 9 | # user installed libraries |
10 | 10 | import bcrypt |
11 | -from sqlalchemy import create_engine | |
11 | +from sqlalchemy import create_engine, func | |
12 | 12 | from sqlalchemy.orm import sessionmaker |
13 | 13 | import networkx as nx |
14 | 14 | |
... | ... | @@ -381,32 +381,36 @@ class LearnApp(object): |
381 | 381 | |
382 | 382 | # ------------------------------------------------------------------------ |
383 | 383 | def get_rankings(self, uid): |
384 | - logger.info(f'User {uid} get rankings') | |
384 | + logger.info(f'User "{uid}" get rankings') | |
385 | 385 | with self.db_session() as s: |
386 | 386 | students = s.query(Student.id, Student.name).all() |
387 | + # topic progress | |
387 | 388 | student_topics = s.query(StudentTopic.student_id, |
388 | 389 | StudentTopic.topic_id, |
389 | 390 | StudentTopic.level, |
390 | 391 | StudentTopic.date).all() |
391 | 392 | total_topics = s.query(Topic).count() |
392 | 393 | |
393 | - rankings = {s[0]: 0.0 for s in students} | |
394 | + # answer performance | |
395 | + totalans = dict(s.query(Answer.student_id, func.count(Answer.ref)). | |
396 | + group_by(Answer.student_id). | |
397 | + all()) | |
398 | + rightans = dict(s.query(Answer.student_id, func.count(Answer.ref)). | |
399 | + filter(Answer.grade == 1.0). | |
400 | + group_by(Answer.student_id). | |
401 | + all()) | |
402 | + | |
403 | + # compute percentage of right answers | |
404 | + perf = {uid: rightans.get(uid, 0.0)/totalans[uid] for uid in totalans} | |
405 | + | |
406 | + # compute topic progress | |
407 | + prog = {s[0]: 0.0 for s in students} | |
394 | 408 | now = datetime.now() |
395 | 409 | for uid, topic, level, date in student_topics: |
396 | 410 | date = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f") |
397 | - rankings[uid] += level**(now - date).days / total_topics | |
411 | + prog[uid] += level**(now - date).days / total_topics | |
398 | 412 | |
399 | - rankings = [(uid, name, rankings[uid]) | |
413 | + rankings = [(uid, name, prog[uid], perf.get(uid, 0.0)) | |
400 | 414 | for uid, name in students if uid != '0'] |
401 | - return sorted(rankings, key=lambda x: x[2], reverse=True) | |
402 | 415 | |
403 | - def get_performance(self): | |
404 | - perf = {} | |
405 | - with self.db_session() as s: | |
406 | - students = s.query(Student.id).all() | |
407 | - for uid, in students: | |
408 | - ans = s.query(Answer).filter_by(student_id=uid) | |
409 | - total = ans.count() | |
410 | - right = ans.filter_by(grade=1.0).count() | |
411 | - perf[uid] = right / total if total > 0 else 0.0 | |
412 | - return perf | |
416 | + return sorted(rankings, key=lambda x: x[2], reverse=True) | ... | ... |
aprendizations/serve.py
... | ... | @@ -88,21 +88,24 @@ class BaseHandler(tornado.web.RequestHandler): |
88 | 88 | return uid |
89 | 89 | |
90 | 90 | |
91 | +# ---------------------------------------------------------------------------- | |
92 | +# /rankings | |
93 | +# ---------------------------------------------------------------------------- | |
91 | 94 | class RankingsHandler(BaseHandler): |
92 | 95 | @tornado.web.authenticated |
93 | 96 | def get(self): |
94 | 97 | uid = self.current_user |
95 | 98 | rankings = self.learn.get_rankings(uid) |
96 | - performance = self.learn.get_performance() | |
99 | + # performance = self.learn.get_performance() | |
97 | 100 | self.render('rankings.html', |
98 | 101 | uid=uid, |
99 | 102 | name=self.learn.get_student_name(uid), |
100 | - rankings=rankings, | |
101 | - performance=performance) | |
103 | + rankings=rankings) | |
104 | + # performance=performance) | |
102 | 105 | |
103 | 106 | |
104 | 107 | # ---------------------------------------------------------------------------- |
105 | -# /auth/login and /auth/logout | |
108 | +# /auth/login | |
106 | 109 | # ---------------------------------------------------------------------------- |
107 | 110 | class LoginHandler(BaseHandler): |
108 | 111 | def get(self): |
... | ... | @@ -124,6 +127,8 @@ class LoginHandler(BaseHandler): |
124 | 127 | |
125 | 128 | |
126 | 129 | # ---------------------------------------------------------------------------- |
130 | +# /auth/logout | |
131 | +# ---------------------------------------------------------------------------- | |
127 | 132 | class LogoutHandler(BaseHandler): |
128 | 133 | @tornado.web.authenticated |
129 | 134 | def get(self): |
... | ... | @@ -157,7 +162,7 @@ class ChangePasswordHandler(BaseHandler): |
157 | 162 | |
158 | 163 | |
159 | 164 | # ---------------------------------------------------------------------------- |
160 | -# Main page: / | |
165 | +# / (main page) | |
161 | 166 | # Shows a list of topics and proficiency (stars, locked). |
162 | 167 | # ---------------------------------------------------------------------------- |
163 | 168 | class RootHandler(BaseHandler): |
... | ... | @@ -173,7 +178,9 @@ class RootHandler(BaseHandler): |
173 | 178 | |
174 | 179 | |
175 | 180 | # ---------------------------------------------------------------------------- |
176 | -# Start a given topic: /topic/... | |
181 | +# /topic/... | |
182 | +# Start a given topic | |
183 | +# FIXME should not change state... | |
177 | 184 | # ---------------------------------------------------------------------------- |
178 | 185 | class TopicHandler(BaseHandler): |
179 | 186 | SUPPORTED_METHODS = ['GET'] | ... | ... |
aprendizations/templates/rankings.html
... | ... | @@ -87,8 +87,8 @@ |
87 | 87 | <td> <!-- student name --> |
88 | 88 | {{ ' '.join(r[1].split()[n] for n in (0,-1)) }} |
89 | 89 | |
90 | - {{ '<i class="fas fa-brain fa-2x text-success" title="Mais de 75% das respostas correctas"></i>' if performance[r[0]] > 0.75 else '' }} | |
91 | - {{ '<i class="fas fa-frown text-secondary" title="Menos de 50% das respostas correctas" ></i>' if 0.0 < performance[r[0]] < 0.5 else '' }} | |
90 | + {{ '<i class="fas fa-brain fa-2x text-success" title="Mais de 75% de respostas correctas"></i>' if r[3] > 0.75 else '' }} | |
91 | + {{ '<i class="fas fa-frown text-secondary" title="Menos de 50% de respostas correctas" ></i>' if 0.0 < r[3] < 0.5 else '' }} | |
92 | 92 | </td> |
93 | 93 | <td> <!-- progress --> |
94 | 94 | <div class="progress"> | ... | ... |