Commit 9a20acc83647839c33d1d80b3290cbe6d5a73d25

Authored by Miguel Barão
1 parent 2c260807
Exists in master and in 1 other branch dev

rankings:

- show rankings per course
- don't show students with no activity in a course
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 %}