Commit 1d65b0b71481e46943b1baa64534f1d507ff8db0
Exists in
master
and in
1 other branch
Merge branch 'dev'
Showing
4 changed files
with
30 additions
and
44 deletions
Show diff stats
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 | ... | ... |