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
@@ -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