Commit 9a20acc83647839c33d1d80b3290cbe6d5a73d25
1 parent
2c260807
Exists in
master
and in
1 other branch
rankings:
- show rankings per course - don't show students with no activity in a course
Showing
4 changed files
with
15 additions
and
13 deletions
Show diff stats
BUGS.md
1 | 1 | ||
2 | # BUGS | 2 | # BUGS |
3 | 3 | ||
4 | -- obter rankings por curso GET course=course_id | ||
5 | -- indicar qtos topicos faltam (>=50%) para terminar o curso. | 4 | +- initdb da integrity error se no mesmo comando existirem alunos repetidos (p.ex em ficheiros csv diferentes ou entre csv e opcao -a) |
6 | - permite definir goal, mas nao verifica se esta no grafo. rebenta no start_topic. | 5 | - permite definir goal, mas nao verifica se esta no grafo. rebenta no start_topic. |
7 | - double click submits twice. | 6 | - double click submits twice. |
8 | - nao esta a seguir o max_tries definido no ficheiro de dependencias. | 7 | - nao esta a seguir o max_tries definido no ficheiro de dependencias. |
@@ -29,6 +28,7 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in | @@ -29,6 +28,7 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in | ||
29 | 28 | ||
30 | # TODO | 29 | # TODO |
31 | 30 | ||
31 | +- indicar qtos topicos faltam (>=50%) para terminar o curso. | ||
32 | - use run_script_async to run run_script using asyncio.run? | 32 | - use run_script_async to run run_script using asyncio.run? |
33 | - ao fim de 3 tentativas de login, envial email para aluno com link para definir nova password (com timeout de 5 minutos). | 33 | - ao fim de 3 tentativas de login, envial email para aluno com link para definir nova password (com timeout de 5 minutos). |
34 | - mostrar capitulos e subtopicos de forma hierarquica. clicar no capitulo expande as dependencias. | 34 | - mostrar capitulos e subtopicos de forma hierarquica. clicar no capitulo expande as dependencias. |
@@ -50,6 +50,7 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in | @@ -50,6 +50,7 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in | ||
50 | 50 | ||
51 | # FIXED | 51 | # FIXED |
52 | 52 | ||
53 | +- obter rankings por curso GET course=course_id | ||
53 | - no curso de linear algebra, as perguntas estao shuffled, mas nao deviam estar... nao esta a obedecer a keyword shuffle. | 54 | - no curso de linear algebra, as perguntas estao shuffled, mas nao deviam estar... nao esta a obedecer a keyword shuffle. |
54 | - menu nao mostra as opcoes correctamente | 55 | - menu nao mostra as opcoes correctamente |
55 | - finish topic vai para a lista de cursos. devia ficar no mesmo curso. | 56 | - finish topic vai para a lista de cursos. devia ficar no mesmo curso. |
aprendizations/__init__.py
@@ -30,7 +30,7 @@ are progressively uncovered as the students progress. | @@ -30,7 +30,7 @@ are progressively uncovered as the students progress. | ||
30 | ''' | 30 | ''' |
31 | 31 | ||
32 | APP_NAME = 'aprendizations' | 32 | APP_NAME = 'aprendizations' |
33 | -APP_VERSION = '2019.10.dev1' | 33 | +APP_VERSION = '2019.11.dev1' |
34 | APP_DESCRIPTION = __doc__ | 34 | APP_DESCRIPTION = __doc__ |
35 | 35 | ||
36 | __author__ = 'Miguel Barão' | 36 | __author__ = 'Miguel Barão' |
aprendizations/learnapp.py
1 | 1 | ||
2 | # python standard library | 2 | # python standard library |
3 | import asyncio | 3 | import asyncio |
4 | +from collections import defaultdict | ||
4 | from contextlib import contextmanager # `with` statement in db sessions | 5 | from contextlib import contextmanager # `with` statement in db sessions |
5 | from datetime import datetime | 6 | from datetime import datetime |
6 | import logging | 7 | import logging |
@@ -478,10 +479,9 @@ class LearnApp(object): | @@ -478,10 +479,9 @@ class LearnApp(object): | ||
478 | 479 | ||
479 | # topic progress | 480 | # topic progress |
480 | student_topics = s.query(StudentTopic.student_id, | 481 | student_topics = s.query(StudentTopic.student_id, |
481 | - StudentTopic.topic_id, # FIXME Filter topics of the course | 482 | + StudentTopic.topic_id, |
482 | StudentTopic.level, | 483 | StudentTopic.level, |
483 | StudentTopic.date).all() | 484 | StudentTopic.date).all() |
484 | - total_topics = s.query(Topic).count() | ||
485 | 485 | ||
486 | # answer performance | 486 | # answer performance |
487 | total = dict(s.query(Answer.student_id, sa.func.count(Answer.ref)). | 487 | total = dict(s.query(Answer.student_id, sa.func.count(Answer.ref)). |
@@ -497,15 +497,18 @@ class LearnApp(object): | @@ -497,15 +497,18 @@ class LearnApp(object): | ||
497 | for uid in total} | 497 | for uid in total} |
498 | 498 | ||
499 | # compute topic progress | 499 | # compute topic progress |
500 | - prog: Dict[str, float] = {s[0]: 0.0 for s in students} | ||
501 | now = datetime.now() | 500 | now = datetime.now() |
501 | + goals = self.courses[course_id]['goals'] | ||
502 | + prog = defaultdict(int) | ||
503 | + | ||
502 | for uid, topic, level, date in student_topics: | 504 | for uid, topic, level, date in student_topics: |
503 | - date = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f") | ||
504 | - prog[uid] += level**(now - date).days / total_topics | 505 | + if topic in goals: |
506 | + date = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f") | ||
507 | + prog[uid] += level**(now - date).days / len(goals) | ||
505 | 508 | ||
506 | rankings = [(uid, name, prog[uid], perf.get(uid, 0.0)) | 509 | rankings = [(uid, name, prog[uid], perf.get(uid, 0.0)) |
507 | - for uid, name in students if uid != '0'] | ||
508 | - | ||
509 | - return sorted(rankings, key=lambda x: x[2], reverse=True) | 510 | + for uid, name in students if uid != '0' and uid in prog] |
511 | + rankings.sort(key=lambda x: x[2], reverse=True) | ||
512 | + return rankings | ||
510 | 513 | ||
511 | # ------------------------------------------------------------------------ | 514 | # ------------------------------------------------------------------------ |
aprendizations/templates/rankings.html
@@ -71,8 +71,6 @@ | @@ -71,8 +71,6 @@ | ||
71 | {% for i,r in enumerate(rankings) %} | 71 | {% for i,r in enumerate(rankings) %} |
72 | {% if r[0] == uid %} | 72 | {% if r[0] == uid %} |
73 | <tr class="table-primary"> <!-- this is me --> | 73 | <tr class="table-primary"> <!-- this is me --> |
74 | - {% elif r[2] == 0 %} | ||
75 | - <tr class="table-secondary"> <!-- level = 0 --> | ||
76 | {% else %} | 74 | {% else %} |
77 | <tr> | 75 | <tr> |
78 | {% end %} | 76 | {% end %} |