Commit b6f3badfe6abdd4ccbc68f525e0ee547e05a3570

Authored by Miguel Barão
1 parent 7e984525
Exists in master and in 1 other branch dev

- fix some mypy errors.

- added some type annotations
- fix recomment_topic_sequence argument not being used
- fix load_yaml error line number info
BUGS.md
... ... @@ -40,6 +40,7 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in
40 40  
41 41 # FIXED
42 42  
  43 +- forgetting factor is hardcoded in student.py
43 44 - add aprendizatons --version
44 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 46 - nos topicos learn.yaml, qd falha acrescenta no fim. nao faz sentido.
... ...
aprendizations/serve.py
... ... @@ -299,14 +299,14 @@ class QuestionHandler(BaseHandler):
299 299 # --- answers are in a list. fix depending on question type
300 300 qtype = self.learn.get_student_question_type(user)
301 301 if qtype in ('success', 'information', 'info'):
302   - answer = None
  302 + ans = None
303 303 elif qtype == 'radio' and not answer:
304   - answer = None
  304 + ans = None
305 305 elif qtype != 'checkbox': # radio, text, textarea, ...
306   - answer = answer[0]
  306 + ans = answer[0]
307 307  
308 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 311 # --- built response to return
312 312 response = {'method': action, 'params': {}}
... ...
aprendizations/student.py
... ... @@ -3,6 +3,7 @@
3 3 import random
4 4 from datetime import datetime
5 5 import logging
  6 +from typing import List
6 7  
7 8 # third party libraries
8 9 import networkx as nx
... ... @@ -52,7 +53,7 @@ class StudentState(object):
52 53 pred = self.deps.predecessors(topic)
53 54 min_level = self.deps.node[topic]['min_level']
54 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 58 self.state[topic] = {
58 59 'level': 0.0, # unlocked
... ... @@ -92,11 +93,6 @@ class StudentState(object):
92 93 questions = t['questions'][:k]
93 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 96 self.questions = [await self.factory[ref].generate_async()
101 97 for ref in questions]
102 98  
... ... @@ -180,14 +176,21 @@ class StudentState(object):
180 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 180 return self.current_question is None
185 181  
186 182 # ------------------------------------------------------------------------
187 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 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 194 unlocked = [t for t in tt if t in self.state]
192 195 locked = [t for t in tt if t not in unlocked]
193 196 return unlocked + locked
... ... @@ -197,11 +200,11 @@ class StudentState(object):
197 200 return self.current_question
198 201  
199 202 # ------------------------------------------------------------------------
200   - def get_current_topic(self):
  203 + def get_current_topic(self) -> str:
201 204 return self.current_topic
202 205  
203 206 # ------------------------------------------------------------------------
204   - def is_locked(self, topic):
  207 + def is_locked(self, topic: str) -> bool:
205 208 return topic not in self.state
206 209  
207 210 # ------------------------------------------------------------------------
... ... @@ -227,7 +230,7 @@ class StudentState(object):
227 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 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 154 except yaml.YAMLError as e:
155 155 if hasattr(e, 'problem_mark'):
156 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 158 f'column {mark.column+1}')
159 159 else:
160 160 logger.error(f'File "{filename}"')
... ...
demo/demo.yaml
... ... @@ -3,7 +3,6 @@
3 3 title: Example
4 4 database: students.db
5 5  
6   -
7 6 # values applied to each topic, if undefined there
8 7 file: questions.yaml
9 8 shuffle_questions: true
... ...