From 2265a158598c1603fc503e0f79e312c41b0193bc Mon Sep 17 00:00:00 2001 From: Miguel Barão Date: Fri, 15 Nov 2019 23:59:05 +0000 Subject: [PATCH] new transform option in text questions --- .gitignore | 11 ++++++----- BUGS.md | 21 +++++++++++++++++++++ aprendizations/learnapp.py | 4 ++-- aprendizations/questions.py | 29 +++++++++++++++++++++++++++-- aprendizations/serve.py | 2 +- aprendizations/student.py | 4 ++-- 6 files changed, 59 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 46f1ed9..62b521e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ # Specify filepatterns you want git to ignore. -/aprendizations.egg-info/ -/aprendizations/__pycache__/ -/demo/students.db -/node_modules/ -/.mypy_cache/ +aprendizations.egg-info/ +aprendizations/__pycache__/ +aprendizations/.mypy_cache/ +demo/students.db +node_modules/ +.mypy_cache/ .DS_Store demo/.DS_Store demo/solar_system/.DS_Store diff --git a/BUGS.md b/BUGS.md index 3a21391..b22d01f 100644 --- a/BUGS.md +++ b/BUGS.md @@ -1,6 +1,27 @@ # 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. - 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. - 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) diff --git a/aprendizations/learnapp.py b/aprendizations/learnapp.py index 03490ee..a72fcd4 100644 --- a/aprendizations/learnapp.py +++ b/aprendizations/learnapp.py @@ -352,7 +352,7 @@ class LearnApp(object): topics: Dict[str, Dict] = config.get('topics', {}) g.add_nodes_from(topics.keys()) for tref, attr in topics.items(): - logger.debug(f' + {tref}...') + logger.debug(f' + {tref}') for d in attr.get('deps', []): if d not in g.nodes(): logger.error(f'Topic "{tref}" depends on "{d}" but it ' @@ -370,7 +370,6 @@ class LearnApp(object): t['path'] = path.join(g.graph['prefix'], tref) # prefix/topic - # ======================================================================== # methods that do not change state (pure functions) # ======================================================================== @@ -379,6 +378,7 @@ class LearnApp(object): # Buils dictionary of question factories # ------------------------------------------------------------------------ def make_factory(self) -> Dict[str, QFactory]: + logger.info('Building questions factory:') factory: Dict[str, QFactory] = {} g = self.deps diff --git a/aprendizations/questions.py b/aprendizations/questions.py index cb15512..82bc440 100644 --- a/aprendizations/questions.py +++ b/aprendizations/questions.py @@ -234,7 +234,8 @@ class QuestionText(Question): self.set_defaults(QDict({ 'text': '', - 'correct': [], + 'correct': [], # no correct answers, always wrong + 'transform': [], # transformations applied to the answer, in order })) # make sure its always a list of possible correct answers @@ -244,12 +245,36 @@ class QuestionText(Question): # make sure all elements of the list are strings self['correct'] = [str(a) for a in self['correct']] + # make sure that the answers are invariant with respect to the filters + if any(c != self.transform(c) for c in self['correct']): + logger.warning(f'in "{self["ref"]}", correct answers are not ' + 'invariant wrt transformations') + + # ------------------------------------------------------------------------ + # apply optional filters to the answer + def transform(self, ans): + for f in self['transform']: + if f == 'remove_space': # removes all spaces + ans = ans.replace(' ', '') + elif f == 'trim': # removes spaces around + ans = ans.strip() + elif f == 'normalize_space': # replaces multiple spaces by one + ans = re.sub(r'\s+', ' ', ans.strip()) + elif f == 'lower': # convert to lowercase + ans = ans.lower() + elif f == 'upper': # convert to uppercase + ans = ans.upper() + else: + logger.warning(f'in "{self["ref"]}", unknown transform "{f}"') + return ans + # ------------------------------------------------------------------------ def correct(self) -> None: super().correct() if self['answer'] is not None: - self['grade'] = 1.0 if self['answer'] in self['correct'] else 0.0 + answer = self.transform(self['answer']) # apply transformations + self['grade'] = 1.0 if answer in self['correct'] else 0.0 # ============================================================================ diff --git a/aprendizations/serve.py b/aprendizations/serve.py index 0784e9d..5ba1bc8 100644 --- a/aprendizations/serve.py +++ b/aprendizations/serve.py @@ -434,7 +434,7 @@ def run_webserver(app, except Exception: logger.critical('Failed to start web application.') raise - sys.exit(1) + # sys.exit(1) else: logger.info('Web application started (tornado.web.Application)') diff --git a/aprendizations/student.py b/aprendizations/student.py index 10fad38..6319bb2 100644 --- a/aprendizations/student.py +++ b/aprendizations/student.py @@ -3,7 +3,7 @@ from datetime import datetime import logging import random -from typing import Dict, List, Optional, Tuple +from typing import List, Optional, Tuple # third party libraries import networkx as nx @@ -176,7 +176,7 @@ class StudentState(object): dt = now - s['date'] try: forgetting_factor = self.deps.nodes[tref]['forgetting_factor'] - s['level'] *= forgetting_factor ** dt.days # forgetting factor + s['level'] *= forgetting_factor ** dt.days # forgetting factor except KeyError: logger.warning(f'Topic {tref} is not on the graph!') -- libgit2 0.21.2