Commit b6f3badfe6abdd4ccbc68f525e0ee547e05a3570
1 parent
7e984525
Exists in
master
and in
1 other branch
- fix some mypy errors.
- added some type annotations - fix recomment_topic_sequence argument not being used - fix load_yaml error line number info
Showing
5 changed files
with
20 additions
and
17 deletions
Show diff stats
BUGS.md
@@ -40,6 +40,7 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in | @@ -40,6 +40,7 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in | ||
40 | 40 | ||
41 | # FIXED | 41 | # FIXED |
42 | 42 | ||
43 | +- forgetting factor is hardcoded in student.py | ||
43 | - add aprendizatons --version | 44 | - add aprendizatons --version |
44 | - se aluno abre dois tabs no browser, conseque navegar em simultaneo para perguntas diferentes. quando submete uma delas dá asneira. Tem de haver um campo hidden que tenha um céodigo único que indique qual a pergunta. do lado do servidor apnas há o codigo da pergunta corrente, se forem diferentes faz redirect para /. | 45 | - se aluno abre dois tabs no browser, conseque navegar em simultaneo para perguntas diferentes. quando submete uma delas dá asneira. Tem de haver um campo hidden que tenha um céodigo único que indique qual a pergunta. do lado do servidor apnas há o codigo da pergunta corrente, se forem diferentes faz redirect para /. |
45 | - nos topicos learn.yaml, qd falha acrescenta no fim. nao faz sentido. | 46 | - nos topicos learn.yaml, qd falha acrescenta no fim. nao faz sentido. |
aprendizations/serve.py
@@ -299,14 +299,14 @@ class QuestionHandler(BaseHandler): | @@ -299,14 +299,14 @@ class QuestionHandler(BaseHandler): | ||
299 | # --- answers are in a list. fix depending on question type | 299 | # --- answers are in a list. fix depending on question type |
300 | qtype = self.learn.get_student_question_type(user) | 300 | qtype = self.learn.get_student_question_type(user) |
301 | if qtype in ('success', 'information', 'info'): | 301 | if qtype in ('success', 'information', 'info'): |
302 | - answer = None | 302 | + ans = None |
303 | elif qtype == 'radio' and not answer: | 303 | elif qtype == 'radio' and not answer: |
304 | - answer = None | 304 | + ans = None |
305 | elif qtype != 'checkbox': # radio, text, textarea, ... | 305 | elif qtype != 'checkbox': # radio, text, textarea, ... |
306 | - answer = answer[0] | 306 | + ans = answer[0] |
307 | 307 | ||
308 | # --- check answer (nonblocking) and get corrected question and action | 308 | # --- check answer (nonblocking) and get corrected question and action |
309 | - q, action = await self.learn.check_answer(user, answer) | 309 | + q, action = await self.learn.check_answer(user, ans) |
310 | 310 | ||
311 | # --- built response to return | 311 | # --- built response to return |
312 | response = {'method': action, 'params': {}} | 312 | response = {'method': action, 'params': {}} |
aprendizations/student.py
@@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
3 | import random | 3 | import random |
4 | from datetime import datetime | 4 | from datetime import datetime |
5 | import logging | 5 | import logging |
6 | +from typing import List | ||
6 | 7 | ||
7 | # third party libraries | 8 | # third party libraries |
8 | import networkx as nx | 9 | import networkx as nx |
@@ -52,7 +53,7 @@ class StudentState(object): | @@ -52,7 +53,7 @@ class StudentState(object): | ||
52 | pred = self.deps.predecessors(topic) | 53 | pred = self.deps.predecessors(topic) |
53 | min_level = self.deps.node[topic]['min_level'] | 54 | min_level = self.deps.node[topic]['min_level'] |
54 | if all(d in self.state and self.state[d]['level'] > min_level | 55 | if all(d in self.state and self.state[d]['level'] > min_level |
55 | - for d in pred): # all deps are greater than min_level | 56 | + for d in pred): # all deps are greater than min_level |
56 | 57 | ||
57 | self.state[topic] = { | 58 | self.state[topic] = { |
58 | 'level': 0.0, # unlocked | 59 | 'level': 0.0, # unlocked |
@@ -92,11 +93,6 @@ class StudentState(object): | @@ -92,11 +93,6 @@ class StudentState(object): | ||
92 | questions = t['questions'][:k] | 93 | questions = t['questions'][:k] |
93 | logger.debug(f'[start_topic] questions: {", ".join(questions)}') | 94 | logger.debug(f'[start_topic] questions: {", ".join(questions)}') |
94 | 95 | ||
95 | - # synchronous | ||
96 | - # self.questions = [self.factory[ref].generate() | ||
97 | - # for ref in questions] | ||
98 | - | ||
99 | - # asynchronous: | ||
100 | self.questions = [await self.factory[ref].generate_async() | 96 | self.questions = [await self.factory[ref].generate_async() |
101 | for ref in questions] | 97 | for ref in questions] |
102 | 98 | ||
@@ -180,14 +176,21 @@ class StudentState(object): | @@ -180,14 +176,21 @@ class StudentState(object): | ||
180 | # pure functions of the state (no side effects) | 176 | # pure functions of the state (no side effects) |
181 | # ======================================================================== | 177 | # ======================================================================== |
182 | 178 | ||
183 | - def topic_has_finished(self): | 179 | + def topic_has_finished(self) -> bool: |
184 | return self.current_question is None | 180 | return self.current_question is None |
185 | 181 | ||
186 | # ------------------------------------------------------------------------ | 182 | # ------------------------------------------------------------------------ |
187 | # compute recommended sequence of topics ['a', 'b', ...] | 183 | # compute recommended sequence of topics ['a', 'b', ...] |
188 | # ------------------------------------------------------------------------ | 184 | # ------------------------------------------------------------------------ |
189 | - def recommend_topic_sequence(self, target=None): | 185 | + def recommend_topic_sequence(self, target: str = '') -> List[str]: |
190 | tt = list(nx.topological_sort(self.deps)) | 186 | tt = list(nx.topological_sort(self.deps)) |
187 | + try: | ||
188 | + idx = tt.index(target) | ||
189 | + except ValueError: | ||
190 | + pass | ||
191 | + else: | ||
192 | + del tt[idx:] | ||
193 | + | ||
191 | unlocked = [t for t in tt if t in self.state] | 194 | unlocked = [t for t in tt if t in self.state] |
192 | locked = [t for t in tt if t not in unlocked] | 195 | locked = [t for t in tt if t not in unlocked] |
193 | return unlocked + locked | 196 | return unlocked + locked |
@@ -197,11 +200,11 @@ class StudentState(object): | @@ -197,11 +200,11 @@ class StudentState(object): | ||
197 | return self.current_question | 200 | return self.current_question |
198 | 201 | ||
199 | # ------------------------------------------------------------------------ | 202 | # ------------------------------------------------------------------------ |
200 | - def get_current_topic(self): | 203 | + def get_current_topic(self) -> str: |
201 | return self.current_topic | 204 | return self.current_topic |
202 | 205 | ||
203 | # ------------------------------------------------------------------------ | 206 | # ------------------------------------------------------------------------ |
204 | - def is_locked(self, topic): | 207 | + def is_locked(self, topic: str) -> bool: |
205 | return topic not in self.state | 208 | return topic not in self.state |
206 | 209 | ||
207 | # ------------------------------------------------------------------------ | 210 | # ------------------------------------------------------------------------ |
@@ -227,7 +230,7 @@ class StudentState(object): | @@ -227,7 +230,7 @@ class StudentState(object): | ||
227 | return self.state[topic]['level'] | 230 | return self.state[topic]['level'] |
228 | 231 | ||
229 | # ------------------------------------------------------------------------ | 232 | # ------------------------------------------------------------------------ |
230 | - def get_topic_date(self, topic): | 233 | + def get_topic_date(self, topic: str): |
231 | return self.state[topic]['date'] | 234 | return self.state[topic]['date'] |
232 | 235 | ||
233 | # ------------------------------------------------------------------------ | 236 | # ------------------------------------------------------------------------ |
aprendizations/tools.py
@@ -154,7 +154,7 @@ def load_yaml(filename: str, default: Any = None) -> Any: | @@ -154,7 +154,7 @@ def load_yaml(filename: str, default: Any = None) -> Any: | ||
154 | except yaml.YAMLError as e: | 154 | except yaml.YAMLError as e: |
155 | if hasattr(e, 'problem_mark'): | 155 | if hasattr(e, 'problem_mark'): |
156 | mark = e.problem_mark | 156 | mark = e.problem_mark |
157 | - logger.error(f'File "{filename}" near line {mark.line}, ' | 157 | + logger.error(f'File "{filename}" near line {mark.line+1}, ' |
158 | f'column {mark.column+1}') | 158 | f'column {mark.column+1}') |
159 | else: | 159 | else: |
160 | logger.error(f'File "{filename}"') | 160 | logger.error(f'File "{filename}"') |
demo/demo.yaml
@@ -3,7 +3,6 @@ | @@ -3,7 +3,6 @@ | ||
3 | title: Example | 3 | title: Example |
4 | database: students.db | 4 | database: students.db |
5 | 5 | ||
6 | - | ||
7 | # values applied to each topic, if undefined there | 6 | # values applied to each topic, if undefined there |
8 | file: questions.yaml | 7 | file: questions.yaml |
9 | shuffle_questions: true | 8 | shuffle_questions: true |