diff --git a/aprendizations/learnapp.py b/aprendizations/learnapp.py index f5ac70e..6171ab6 100644 --- a/aprendizations/learnapp.py +++ b/aprendizations/learnapp.py @@ -36,6 +36,16 @@ class DatabaseUnusableError(LearnException): # ============================================================================ # LearnApp - application logic +# +# self.deps - networkx topic dependencies +# self.courses - dict {course_id: {'title': ..., +# 'description': ..., +# 'goals': ...,}, ...} +# self.factory = dict {qref: QFactory()} +# self.online - dict {student_id: {'number': ..., +# 'name': ..., +# 'state': StudentState(), +# 'counter': ...}, ...} # ============================================================================ class LearnApp(object): # ------------------------------------------------------------------------ @@ -95,8 +105,9 @@ class LearnApp(object): d.setdefault('title', '') # course title undefined for goal in d['goals']: if goal not in self.deps.nodes(): - raise LearnException(f'Goal "{goal}" from course "{c}" ' - ' does not exist') + msg = f'Goal "{goal}" from course "{c}" does not exist' + logger.error(msg) + raise LearnException(msg) # --- factory is a dict with question generators for all topics self.factory: Dict[str, QFactory] = self.make_factory() @@ -291,15 +302,15 @@ class LearnApp(object): # ------------------------------------------------------------------------ # Start course # ------------------------------------------------------------------------ - def start_course(self, uid: str, course: str) -> None: + def start_course(self, uid: str, course_id: str) -> None: student = self.online[uid]['state'] try: - student.start_course(course) - except Exception as e: - logger.warning(f'"{uid}" could not start course "{course}": {e}') + student.start_course(course_id) + except Exception: + logger.warning(f'"{uid}" could not start course "{course_id}"') raise else: - logger.info(f'User "{uid}" started course "{course}"') + logger.info(f'User "{uid}" started course "{course_id}"') # ------------------------------------------------------------------------ # Start new topic @@ -516,6 +527,11 @@ class LearnApp(object): return self.online[uid]['state'].get_current_course_id() # ------------------------------------------------------------------------ + # def get_student_course(self, uid: str) -> Optional[str]: + # course_id = self.online[uid]['state'].get_current_course_id() + # return course_id, self.courses[course_id] + + # ------------------------------------------------------------------------ def get_topic_name(self, ref: str) -> str: return self.deps.nodes[ref]['name'] @@ -529,6 +545,9 @@ class LearnApp(object): def get_courses(self, uid: str) -> Dict: return self.courses + def get_course(self, course_id: str) -> Dict: + return self.courses[course_id] + # ------------------------------------------------------------------------ def get_rankings(self, uid: str, course_id: str) -> Iterable[Tuple[str, str, float, float]]: diff --git a/aprendizations/serve.py b/aprendizations/serve.py index 5acc6a7..7fcec7f 100644 --- a/aprendizations/serve.py +++ b/aprendizations/serve.py @@ -205,13 +205,11 @@ class CoursesHandler(BaseHandler): # ---------------------------------------------------------------------------- class CourseHandler(BaseHandler): @tornado.web.authenticated - def get(self, course): + def get(self, course_id): uid = self.current_user - if course == '': - course = self.learn.get_student_course_id(uid) try: - self.learn.start_course(uid, course) + self.learn.start_course(uid, course_id) except KeyError: self.redirect('/courses') @@ -220,8 +218,8 @@ class CourseHandler(BaseHandler): uid=uid, name=self.learn.get_student_name(uid), state=self.learn.get_student_state(uid), - course_title=self.learn.get_student_course_title(uid), - course_id=self.learn.get_student_course_id(uid), + course_id=course_id, + course=self.learn.get_course(course_id) ) diff --git a/aprendizations/student.py b/aprendizations/student.py index b181fa5..87298eb 100644 --- a/aprendizations/student.py +++ b/aprendizations/student.py @@ -236,9 +236,17 @@ class StudentState(object): G = self.deps ts = set(goals) for t in goals: - ts.update(nx.ancestors(G, t)) - # FIXME filter by level done, only level < 50% are included - tl = list(nx.topological_sort(G.subgraph(ts))) + ts.update(nx.ancestors(G, t)) # include dependencies not in goals + + todo = [] + for t in ts: + level = self.state[t]['level'] if t in self.state else 0.0 + min_level = G.nodes[t]['min_level'] + if t in goals or level < min_level: + todo.append(t) + + # FIXME topological sort is a poor way to sort topics + tl = list(nx.topological_sort(G.subgraph(todo))) # sort with unlocked first unlocked = [t for t in tl if t in self.state] diff --git a/aprendizations/templates/maintopics-table.html b/aprendizations/templates/maintopics-table.html index f764a79..fad46b5 100644 --- a/aprendizations/templates/maintopics-table.html +++ b/aprendizations/templates/maintopics-table.html @@ -60,7 +60,7 @@
-