Commit 0f88b4f185d910e4efc368988e8a28f2c5aa9a50
1 parent
2c577830
Exists in
master
and in
1 other branch
fix error where topics declared in chapters but not in goals were not shown.
fix error where finishing a course would try to start empty course. goals that are chapters will recursively import dependencies.
Showing
4 changed files
with
21 additions
and
10 deletions
Show diff stats
BUGS.md
| 1 | 1 | |
| 2 | 2 | # BUGS |
| 3 | 3 | |
| 4 | -- goals se forem do tipo chapter deve importar todas as dependencias do chapter (e não mostrar chapters?). | |
| 5 | 4 | - nao esta a seguir o max_tries definido no ficheiro de dependencias. |
| 6 | 5 | - devia mostrar timeout para o aluno saber a razao. |
| 7 | 6 | - permitir configuracao para escolher entre static files locais ou remotos |
| 8 | -- templates question-*.html tem input hidden question_ref que não é usado. remover? | |
| 9 | 7 | - shift-enter não está a funcionar |
| 10 | 8 | - default prefix should be obtained from each course (yaml conf)? |
| 11 | 9 | |
| ... | ... | @@ -32,6 +30,8 @@ |
| 32 | 30 | |
| 33 | 31 | # FIXED |
| 34 | 32 | |
| 33 | +- templates question-*.html tem input hidden question_ref que não é usado. remover? | |
| 34 | +- goals se forem do tipo chapter deve importar todas as dependencias do chapter. | |
| 35 | 35 | - initdb da integrity error se no mesmo comando existirem alunos repetidos (p.ex em ficheiros csv diferentes ou entre csv e opcao -a) |
| 36 | 36 | - dependencias que não são goals de um curso, só devem aparecer se ainda não tiverem sido feitas. |
| 37 | 37 | - ir para inicio da pagina quando le nova pergunta. | ... | ... |
aprendizations/learnapp.py
| ... | ... | @@ -108,6 +108,9 @@ class LearnApp(object): |
| 108 | 108 | msg = f'Goal "{goal}" from course "{c}" does not exist' |
| 109 | 109 | logger.error(msg) |
| 110 | 110 | raise LearnException(msg) |
| 111 | + elif self.deps.nodes[goal]['type'] == 'chapter': | |
| 112 | + d['goals'] += [g for g in self.deps.predecessors(goal) | |
| 113 | + if g not in d['goals']] | |
| 111 | 114 | |
| 112 | 115 | # --- factory is a dict with question generators for all topics |
| 113 | 116 | self.factory: Dict[str, QFactory] = self.make_factory() |
| ... | ... | @@ -318,7 +321,7 @@ class LearnApp(object): |
| 318 | 321 | async def start_topic(self, uid: str, topic: str) -> None: |
| 319 | 322 | student = self.online[uid]['state'] |
| 320 | 323 | if uid == '0': |
| 321 | - logger.warning(f'Reloading "{topic}"') | |
| 324 | + logger.warning(f'Reloading "{topic}"') # FIXME should be an option | |
| 322 | 325 | self.factory.update(self.factory_for(topic)) |
| 323 | 326 | |
| 324 | 327 | try: |
| ... | ... | @@ -406,6 +409,7 @@ class LearnApp(object): |
| 406 | 409 | |
| 407 | 410 | t['path'] = path.join(g.graph['prefix'], tref) # prefix/topic |
| 408 | 411 | |
| 412 | + | |
| 409 | 413 | # ======================================================================== |
| 410 | 414 | # methods that do not change state (pure functions) |
| 411 | 415 | # ======================================================================== | ... | ... |
aprendizations/serve.py
| ... | ... | @@ -201,12 +201,14 @@ class CoursesHandler(BaseHandler): |
| 201 | 201 | |
| 202 | 202 | # ---------------------------------------------------------------------------- |
| 203 | 203 | # /course/... |
| 204 | -# Start a given course | |
| 204 | +# Start a given course and show list of topics | |
| 205 | 205 | # ---------------------------------------------------------------------------- |
| 206 | 206 | class CourseHandler(BaseHandler): |
| 207 | 207 | @tornado.web.authenticated |
| 208 | 208 | def get(self, course_id): |
| 209 | 209 | uid = self.current_user |
| 210 | + if course_id == '': | |
| 211 | + course_id = self.learn.get_current_course_id(uid) | |
| 210 | 212 | |
| 211 | 213 | try: |
| 212 | 214 | self.learn.start_course(uid, course_id) | ... | ... |
aprendizations/student.py
| ... | ... | @@ -59,12 +59,15 @@ class StudentState(object): |
| 59 | 59 | self.current_course: Optional[str] = None |
| 60 | 60 | self.topic_sequence: List[str] = [] |
| 61 | 61 | self.current_topic: Optional[str] = None |
| 62 | - # self.previous_topic: Optional[str] = None | |
| 63 | 62 | else: |
| 64 | - logger.debug(f'starting course {course}') | |
| 63 | + try: | |
| 64 | + topics = self.courses[course]['goals'] | |
| 65 | + except KeyError: | |
| 66 | + logger.debug(f'course "{course}" does not exist') | |
| 67 | + raise | |
| 68 | + logger.debug(f'starting course "{course}"') | |
| 65 | 69 | self.current_course = course |
| 66 | - topics = self.courses[course]['goals'] | |
| 67 | - self.topic_sequence = self.recommend_topic_sequence(topics) | |
| 70 | + self.topic_sequence = self.recommend_sequence(topics) | |
| 68 | 71 | |
| 69 | 72 | # ------------------------------------------------------------------------ |
| 70 | 73 | # Start a new topic. |
| ... | ... | @@ -178,7 +181,7 @@ class StudentState(object): |
| 178 | 181 | # The current topic is unchanged. |
| 179 | 182 | # ------------------------------------------------------------------------ |
| 180 | 183 | def finish_topic(self) -> None: |
| 181 | - logger.debug(f'finished "{self.current_topic}"') | |
| 184 | + logger.debug(f'finished {self.current_topic} in {self.current_course}') | |
| 182 | 185 | |
| 183 | 186 | self.state[self.current_topic] = { |
| 184 | 187 | 'date': datetime.now(), |
| ... | ... | @@ -232,7 +235,7 @@ class StudentState(object): |
| 232 | 235 | # ------------------------------------------------------------------------ |
| 233 | 236 | # compute recommended sequence of topics ['a', 'b', ...] |
| 234 | 237 | # ------------------------------------------------------------------------ |
| 235 | - def recommend_topic_sequence(self, goals: List[str] = []) -> List[str]: | |
| 238 | + def recommend_sequence(self, goals: List[str] = []) -> List[str]: | |
| 236 | 239 | G = self.deps |
| 237 | 240 | ts = set(goals) |
| 238 | 241 | for t in goals: |
| ... | ... | @@ -245,6 +248,8 @@ class StudentState(object): |
| 245 | 248 | if t in goals or level < min_level: |
| 246 | 249 | todo.append(t) |
| 247 | 250 | |
| 251 | + logger.debug(f' {len(ts)} total topics, {len(todo)} listed ') | |
| 252 | + | |
| 248 | 253 | # FIXME topological sort is a poor way to sort topics |
| 249 | 254 | tl = list(nx.topological_sort(G.subgraph(todo))) |
| 250 | 255 | ... | ... |