diff --git a/BUGS.md b/BUGS.md index 7a8a4ce..34ee95a 100644 --- a/BUGS.md +++ b/BUGS.md @@ -1,31 +1,10 @@ # BUGS - -Traceback (most recent call last): - File "/home/mjsb/.local/lib/python3.7/site-packages/tornado/web.py", line 1697, in _execute - result = method(*self.path_args, **self.path_kwargs) - File "/home/mjsb/.local/lib/python3.7/site-packages/tornado/web.py", line 3174, in wrapper - return method(self, *args, **kwargs) - File "/usr/home/mjsb/Work/Projects/aprendizations/aprendizations/serve.py", line 213, in get - self.learn.start_course(uid, course) - File "/usr/home/mjsb/Work/Projects/aprendizations/aprendizations/learnapp.py", line 275, in start_course - student.start_course(course) - File "/usr/home/mjsb/Work/Projects/aprendizations/aprendizations/student.py", line 57, in start_course - self.topic_sequence = self.recommend_topic_sequence(topics) - File "/usr/home/mjsb/Work/Projects/aprendizations/aprendizations/student.py", line 216, in recommend_topic_sequence - ts.update(nx.ancestors(G, t)) - File "/home/mjsb/.local/lib/python3.7/site-packages/networkx/algorithms/dag.py", line 92, in ancestors - raise nx.NetworkXError("The node %s is not in the graph." % source) -networkx.exception.NetworkXError: The node programming/languages/pseudo-tcg/functions-produtorio is not in the graph. - -- detectar se em courses.yaml falta declarar ficheiro. Por exemplo se houver goals que não estao em lado nenhum. +- nao esta a seguir o max_tries definido no ficheiro de dependencias. - registar last_seen e remover os antigos de cada vez que houver um login. - initdb da integrity error se no mesmo comando existirem alunos repetidos (p.ex em ficheiros csv diferentes ou entre csv e opcao -a) -- permite definir goal, mas nao verifica se esta no grafo. rebenta no start_topic. - double click submits twice. -- nao esta a seguir o max_tries definido no ficheiro de dependencias. -- impedir que quando students.db não é encontrado, crie um ficheiro vazio. - classificacoes so devia mostrar os que ja fizeram alguma coisa - QFactory.generate() devia fazer run da gen_async, ou remover. - marking all options right in a radio question breaks! @@ -70,6 +49,8 @@ sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in # FIXED +- impedir que quando students.db não é encontrado, crie um ficheiro vazio. +- permite definir goal, mas nao verifica se esta no grafo. rebenta no start_topic. - se num topico, a ultima pergunta tem imagens, o servidor nao fornece as imagengs porque o current_topic passa a None antes de carregar no botao continuar. O caminho é prefix+None e dá erro. - caixas com os cursos não se ajustam bem com ecran estreito. - obter rankings por curso GET course=course_id diff --git a/aprendizations/learnapp.py b/aprendizations/learnapp.py index e8bbc00..7ae92ce 100644 --- a/aprendizations/learnapp.py +++ b/aprendizations/learnapp.py @@ -69,28 +69,37 @@ class LearnApp(object): config: Dict[str, Any] = load_yaml(courses) - # --- courses dict - self.courses = config['courses'] - logger.info(f'Courses: {", ".join(self.courses.keys())}') - # --- topic dependencies are shared between all courses self.deps = nx.DiGraph(prefix=prefix) - logger.info('Populating graph:') + logger.info('Populating topic graph:') t = config.get('topics', {}) # topics defined directly in courses file self.populate_graph(t) logger.info(f'{len(t):>6} topics in {courses}') for f in config.get('topics_from', []): c = load_yaml(f) # course configuration + + # FIXME set defaults?? logger.info(f'{len(c["topics"]):>6} topics imported from {f}') self.populate_graph(c) logger.info(f'Graph has {len(self.deps)} topics') + # --- courses dict + self.courses = config['courses'] + logger.info(f'Courses: {", ".join(self.courses.keys())}') + for c, d in self.courses.items(): + for goal in d['goals']: + if goal not in self.deps.nodes(): + # logger.error(f'Goal "{goal}" of "{c}"" not in the graph') + raise LearnException(f'Goal "{goal}" from course "{c}" ' + ' does not exist') + # --- factory is a dict with question generators for all topics self.factory: Dict[str, QFactory] = self.make_factory() # if graph has topics that are not in the database, add them - self.db_add_missing_topics(self.deps.nodes()) + self.add_missing_topics(self.deps.nodes()) + if check: self.sanity_check_questions() @@ -301,7 +310,7 @@ class LearnApp(object): # ------------------------------------------------------------------------ # Fill db table 'Topic' with topics from the graph if not already there. # ------------------------------------------------------------------------ - def db_add_missing_topics(self, topics: List[str]) -> None: + def add_missing_topics(self, topics: List[str]) -> None: with self.db_session() as s: new_topics = [Topic(id=t) for t in topics if (t,) not in s.query(Topic.id)] @@ -317,6 +326,10 @@ class LearnApp(object): def db_setup(self, db: str) -> None: logger.info(f'Checking database "{db}":') + if not path.exists(db): + raise LearnException('Database does not exist. ' + 'Use "initdb-aprendizations" to create') + engine = sa.create_engine(f'sqlite:///{db}', echo=False) self.Session = sa.orm.sessionmaker(bind=engine) try: diff --git a/aprendizations/main.py b/aprendizations/main.py index ee8a993..294168a 100644 --- a/aprendizations/main.py +++ b/aprendizations/main.py @@ -9,7 +9,7 @@ import sys from typing import Any, Dict # this project -from .learnapp import LearnApp, DatabaseUnusableError +from .learnapp import LearnApp, DatabaseUnusableError, LearnException from .serve import run_webserver from .tools import load_yaml from . import APP_NAME, APP_VERSION @@ -160,7 +160,7 @@ def main(): else: logging.info('SSL certificates loaded') - # --- start application + # --- start application -------------------------------------------------- try: learnapp = LearnApp(courses=arg.courses, prefix=arg.prefix, @@ -178,13 +178,16 @@ def main(): '--------------------------------------------------------------', sep='\n') sys.exit(1) + except LearnException as e: + logging.critical(e) + sys.exit(1) except Exception: logging.critical('Failed to start backend.') sys.exit(1) else: logging.info('LearnApp started') - # --- run webserver forever + # --- run webserver forever ---------------------------------------------- run_webserver(app=learnapp, ssl=ssl_ctx, port=arg.port, debug=arg.debug) diff --git a/demo/astronomy.yaml b/demo/astronomy.yaml index 2f2a4a2..e1bf297 100644 --- a/demo/astronomy.yaml +++ b/demo/astronomy.yaml @@ -3,11 +3,11 @@ # optional values applied to each topic, if undefined there # ---------------------------------------------------------------------------- -# defaults: +# defaults: FIXME not working # file: questions.yaml # shuffle_questions: true # choose: 6 -# max_tries: 2 +# max_tries: 200 # forgetting_factor: 0.97 # min_level: 0.01 # append_wrong: true -- libgit2 0.21.2