Commit 1d65b0b71481e46943b1baa64534f1d507ff8db0

Authored by Miguel Barão
2 parents e55079ef 6c5a961a
Exists in master and in 1 other branch dev

Merge branch 'dev'

BUGS.md
1   -# BUGS
  1 +# Bugs and Wishlist
  2 +
  3 +## BUGS
2 4  
3 5 - nao esta a respeitar o numero de tentativas `max_tries`.
4 6 - se na especificacao de um curso, a referencia do topico nao existir como
5 7 directorio, rebenta.
6 8 - internal server error ao fazer logout no macos python3.8
7   -- GET can get filtered by browser cache
8 9 - topicos chapter devem ser automaticamente completos assim que as dependencias
9 10 são satisfeitas. Nao devia ser necessario (ou possivel?) clicar neles.
10 11 - topicos do tipo learn deviam por defeito nao ser randomizados e assumir
... ... @@ -23,11 +24,11 @@
23 24 - shift-enter não está a funcionar
24 25 - default prefix should be obtained from each course (yaml conf)?
25 26  
26   -# TODO
  27 +## TODO
27 28  
28   -- shuffle das perguntas dentro de um topico
29 29 - alterar tabelas para incluir email de recuperacao de password (e outros
30 30 avisos)
  31 +- shuffle das perguntas dentro de um topico
31 32 - registar `last_seen` e remover os antigos de cada vez que houver um login.
32 33 - indicar qtos topicos faltam (>=50%) para terminar o curso.
33 34 - ao fim de 3 tentativas com password errada, envia email com nova password.
... ... @@ -50,8 +51,9 @@
50 51 mais falhadas, tempo médio por pergunta.
51 52 - normalizar com perguntations.
52 53  
53   -# FIXED
  54 +## FIXED
54 55  
  56 +- rankings rebenta se nunhum aluno tiver feito nenhum topico.
55 57 - templates question-*.html tem input hidden question_ref que não é usado.
56 58 remover?
57 59 - goals se forem do tipo chapter deve importar todas as dependencias do chapter.
... ...
aprendizations/learnapp.py
... ... @@ -288,7 +288,9 @@ class LearnApp():
288 288 logger.info('User "%s" finished "%s" (level=%.2f)',
289 289 uid, topic_id, level)
290 290  
291   - query = select(StudentTopic).where(StudentTopic.student_id == uid).where(StudentTopic.topic_id == topic_id)
  291 + query = select(StudentTopic) \
  292 + .where(StudentTopic.student_id == uid) \
  293 + .where(StudentTopic.topic_id == topic_id)
292 294 with Session(self._engine, future=True) as session:
293 295 student_topic = session.execute(query).scalar_one_or_none()
294 296  
... ... @@ -599,9 +601,9 @@ class LearnApp():
599 601 return self.courses[course_id]
600 602  
601 603 # ------------------------------------------------------------------------
602   - def get_rankings(self, uid: str, course_id: str) -> Iterable[Tuple[str, str, float, float]]:
  604 + def get_rankings(self, uid: str, cid: str) -> List[Tuple[str, str, float]]:
603 605 '''
604   - Returns rankings for a certain course_id.
  606 + Returns rankings for a certain cid (course_id).
605 607 User where uid have <=2 chars are considered ghosts are hidden from
606 608 the rankings. This is so that there can be users for development or
607 609 testing purposes, which are not real users.
... ... @@ -609,16 +611,13 @@ class LearnApp():
609 611 This should be modified to have a "visible" flag
610 612 '''
611 613  
612   - logger.info('User "%s" rankings for "%s"', uid, course_id)
  614 + logger.info('User "%s" rankings for "%s"', uid, cid)
  615 + query_students = select(Student.id, Student.name)
  616 + query_student_topics = select(StudentTopic.student_id,
  617 + StudentTopic.topic_id,
  618 + StudentTopic.level,
  619 + StudentTopic.date)
613 620 with Session(self._engine, future=True) as session:
614   - query_students = select(Student.id, Student.name)
615   - query_student_topics = select(StudentTopic.student_id,
616   - StudentTopic.topic_id,
617   - StudentTopic.level,
618   - StudentTopic.date)
619   - query_total = select(Answer.student_id, func.count(Answer.ref))
620   - query_right = select(Answer.student_id, func.count(Answer.ref)) \
621   - .where(Answer.grade == 1.0)
622 621  
623 622 # all students in the database FIXME only with answers of this course
624 623 students = session.execute(query_students).all()
... ... @@ -626,28 +625,17 @@ class LearnApp():
626 625 # topic levels FIXME only topics of this course
627 626 student_topics = session.execute(query_student_topics).all()
628 627  
629   - # answer performance
630   -
631   - # FIXME this does not work when nobody has done anything...
632   - # FIXME row to dict seems to be deprecated in 1.4+
633   - total = dict(session.execute(query_total).all())
634   - right = dict(session.execute(query_right).all())
635   -
636   - # compute percentage of right answers
637   - perf: Dict[str, float] = {u: right.get(u, 0.0) / total[u]
638   - for u in total}
639   -
640 628 # compute topic progress
641 629 now = datetime.now()
642   - goals = self.courses[course_id]['goals']
  630 + goals = self.courses[cid]['goals']
643 631 progress: DefaultDict[str, float] = defaultdict(int)
644 632  
645   - for student, topic, level, date in student_topics:
  633 + for student, topic, level, datestr in student_topics:
646 634 if topic in goals:
647   - date = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f")
  635 + date = datetime.strptime(datestr, "%Y-%m-%d %H:%M:%S.%f")
648 636 progress[student] += level**(now - date).days / len(goals)
649 637  
650   - return sorted(((u, name, progress[u], perf.get(u, 0.0))
  638 + return sorted(((u, name, progress[u])
651 639 for u, name in students
652 640 if u in progress and (len(u) > 2 or len(uid) <= 2)),
653 641 key=lambda x: x[2], reverse=True)
... ...
aprendizations/templates/rankings.html
... ... @@ -61,7 +61,6 @@
61 61 <tr>
62 62 <th scope="col" class="text-center">Posição</th>
63 63 <th scope="col">Aluno</th>
64   - <th scope="col"></th>
65 64 <th scope="col">Progresso</th>
66 65 </tr>
67 66 </thead>
... ... @@ -76,9 +75,6 @@
76 75 <td> <!-- student name -->
77 76 {{ ' '.join(r[1].split()[n] for n in (0,-1)) }}
78 77 </td>
79   - <td> <!-- nice -->
80   - {{ '<i class="far fa-thumbs-up text-success" title="Mais de 75% de respostas correctas"></i>' if r[3] > 0.75 else '' }}
81   - </td>
82 78 <td> <!-- progress -->
83 79 <div class="progress" style="height: 24px;">
84 80 <div class="progress-bar" role="progressbar" style="width: {{ 100*r[2] }}%;" aria-valuenow="{{round(100*r[2])}}%" aria-valuemin="0" aria-valuemax="100">{{round(100*r[2])}}%</div>
... ...
mypy.ini
... ... @@ -2,14 +2,14 @@
2 2 python_version = 3.9
3 3 plugins = sqlalchemy.ext.mypy.plugin
4 4  
5   -[mypy-pygments.*]
6   -ignore_missing_imports = True
  5 +; [mypy-pygments.*]
  6 +; ignore_missing_imports = True
7 7  
8   -[mypy-networkx.*]
9   -ignore_missing_imports = True
  8 +; [mypy-networkx.*]
  9 +; ignore_missing_imports = True
10 10  
11   -[mypy-bcrypt.*]
12   -ignore_missing_imports = True
  11 +; [mypy-bcrypt.*]
  12 +; ignore_missing_imports = True
13 13  
14   -[mypy-mistune.*]
15   -ignore_missing_imports = True
  14 +; [mypy-mistune.*]
  15 +; ignore_missing_imports = True
... ...