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,7 +70,6 @@ class StudentKnowledge(object): | ||
70 | # questions: list of generated questions to do in the topic | 70 | # questions: list of generated questions to do in the topic |
71 | # current_question: the current question to be presented | 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 | async def start_topic(self, topic): | 73 | async def start_topic(self, topic): |
75 | logger.debug('StudentKnowledge.start_topic()') | 74 | logger.debug('StudentKnowledge.start_topic()') |
76 | if self.current_topic == topic: | 75 | if self.current_topic == topic: |
aprendizations/learnapp.py
@@ -8,7 +8,7 @@ from datetime import datetime | @@ -8,7 +8,7 @@ from datetime import datetime | ||
8 | 8 | ||
9 | # user installed libraries | 9 | # user installed libraries |
10 | import bcrypt | 10 | import bcrypt |
11 | -from sqlalchemy import create_engine | 11 | +from sqlalchemy import create_engine, func |
12 | from sqlalchemy.orm import sessionmaker | 12 | from sqlalchemy.orm import sessionmaker |
13 | import networkx as nx | 13 | import networkx as nx |
14 | 14 | ||
@@ -381,32 +381,36 @@ class LearnApp(object): | @@ -381,32 +381,36 @@ class LearnApp(object): | ||
381 | 381 | ||
382 | # ------------------------------------------------------------------------ | 382 | # ------------------------------------------------------------------------ |
383 | def get_rankings(self, uid): | 383 | def get_rankings(self, uid): |
384 | - logger.info(f'User {uid} get rankings') | 384 | + logger.info(f'User "{uid}" get rankings') |
385 | with self.db_session() as s: | 385 | with self.db_session() as s: |
386 | students = s.query(Student.id, Student.name).all() | 386 | students = s.query(Student.id, Student.name).all() |
387 | + # topic progress | ||
387 | student_topics = s.query(StudentTopic.student_id, | 388 | student_topics = s.query(StudentTopic.student_id, |
388 | StudentTopic.topic_id, | 389 | StudentTopic.topic_id, |
389 | StudentTopic.level, | 390 | StudentTopic.level, |
390 | StudentTopic.date).all() | 391 | StudentTopic.date).all() |
391 | total_topics = s.query(Topic).count() | 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 | now = datetime.now() | 408 | now = datetime.now() |
395 | for uid, topic, level, date in student_topics: | 409 | for uid, topic, level, date in student_topics: |
396 | date = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f") | 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 | for uid, name in students if uid != '0'] | 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,21 +88,24 @@ class BaseHandler(tornado.web.RequestHandler): | ||
88 | return uid | 88 | return uid |
89 | 89 | ||
90 | 90 | ||
91 | +# ---------------------------------------------------------------------------- | ||
92 | +# /rankings | ||
93 | +# ---------------------------------------------------------------------------- | ||
91 | class RankingsHandler(BaseHandler): | 94 | class RankingsHandler(BaseHandler): |
92 | @tornado.web.authenticated | 95 | @tornado.web.authenticated |
93 | def get(self): | 96 | def get(self): |
94 | uid = self.current_user | 97 | uid = self.current_user |
95 | rankings = self.learn.get_rankings(uid) | 98 | rankings = self.learn.get_rankings(uid) |
96 | - performance = self.learn.get_performance() | 99 | + # performance = self.learn.get_performance() |
97 | self.render('rankings.html', | 100 | self.render('rankings.html', |
98 | uid=uid, | 101 | uid=uid, |
99 | name=self.learn.get_student_name(uid), | 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 | class LoginHandler(BaseHandler): | 110 | class LoginHandler(BaseHandler): |
108 | def get(self): | 111 | def get(self): |
@@ -124,6 +127,8 @@ class LoginHandler(BaseHandler): | @@ -124,6 +127,8 @@ class LoginHandler(BaseHandler): | ||
124 | 127 | ||
125 | 128 | ||
126 | # ---------------------------------------------------------------------------- | 129 | # ---------------------------------------------------------------------------- |
130 | +# /auth/logout | ||
131 | +# ---------------------------------------------------------------------------- | ||
127 | class LogoutHandler(BaseHandler): | 132 | class LogoutHandler(BaseHandler): |
128 | @tornado.web.authenticated | 133 | @tornado.web.authenticated |
129 | def get(self): | 134 | def get(self): |
@@ -157,7 +162,7 @@ class ChangePasswordHandler(BaseHandler): | @@ -157,7 +162,7 @@ class ChangePasswordHandler(BaseHandler): | ||
157 | 162 | ||
158 | 163 | ||
159 | # ---------------------------------------------------------------------------- | 164 | # ---------------------------------------------------------------------------- |
160 | -# Main page: / | 165 | +# / (main page) |
161 | # Shows a list of topics and proficiency (stars, locked). | 166 | # Shows a list of topics and proficiency (stars, locked). |
162 | # ---------------------------------------------------------------------------- | 167 | # ---------------------------------------------------------------------------- |
163 | class RootHandler(BaseHandler): | 168 | class RootHandler(BaseHandler): |
@@ -173,7 +178,9 @@ 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 | class TopicHandler(BaseHandler): | 185 | class TopicHandler(BaseHandler): |
179 | SUPPORTED_METHODS = ['GET'] | 186 | SUPPORTED_METHODS = ['GET'] |
aprendizations/templates/rankings.html
@@ -87,8 +87,8 @@ | @@ -87,8 +87,8 @@ | ||
87 | <td> <!-- student name --> | 87 | <td> <!-- student name --> |
88 | {{ ' '.join(r[1].split()[n] for n in (0,-1)) }} | 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 | </td> | 92 | </td> |
93 | <td> <!-- progress --> | 93 | <td> <!-- progress --> |
94 | <div class="progress"> | 94 | <div class="progress"> |