From 4f21e22aa2809b58662a64bb70bd114952abbbd4 Mon Sep 17 00:00:00 2001 From: Miguel Barão Date: Sun, 2 Apr 2017 20:33:09 +0100 Subject: [PATCH] - changed debug logs to show student id - fixed enter in textarea, tabs still need fix --- BUGS.md | 8 +++++++- app.py | 2 +- knowledge.py | 22 ++++++++++++---------- questions.py | 2 +- templates/learn.html | 29 ++++++++++++++++++++++------- 5 files changed, 43 insertions(+), 20 deletions(-) diff --git a/BUGS.md b/BUGS.md index 92be560..05fb929 100644 --- a/BUGS.md +++ b/BUGS.md @@ -1,15 +1,20 @@ BUGS: +- pymips: activar/desactivar instruções +- tabs em textarea nao funcionam correctamente (insere 1 espaco em vez de 4) +- reportar comentarios após submeter. +- logs debug mostrar user +- logs mostrar fim de topico - textarea, text devem mostrar no html os valores iniciais de ans, se existir - detect questions in questions.yaml without ref -> error ou generate default. - error if demo.yaml has no topics -- pymips a funcionar - reload da página rebenta o estado. - guardar state cada vez que topico termina - indicar o topico actual no sidebar - session management. close after inactive time. - implementar xsrf. Ver [http://www.tornadoweb.org/en/stable/guide/security.html#cross-site-request-forgery-protection]() +- titulos das perguntas não suportam markdown TODO: @@ -21,6 +26,7 @@ TODO: FIXED: +- pymips a funcionar - logs mostram que está a gerar cada pergunta 2 vezes...?? - letsencrypt.org - alterar password. diff --git a/app.py b/app.py index a62cec6..5aad327 100644 --- a/app.py +++ b/app.py @@ -69,7 +69,7 @@ class LearnApp(object): self.online[uid] = { 'name': student.name, 'number': student.id, - 'state': Knowledge(self.depgraph, state), + 'state': Knowledge(self.depgraph, state=state, student=student.id) } logger.info(f'User "{uid}" logged in') return True diff --git a/knowledge.py b/knowledge.py index 76bde95..81d8e9c 100644 --- a/knowledge.py +++ b/knowledge.py @@ -16,7 +16,8 @@ logger = logging.getLogger(__name__) # ---------------------------------------------------------------------------- # contains the kowledge state of each student. class Knowledge(object): - def __init__(self, depgraph, state={}): + def __init__(self, depgraph, state={}, student=''): + self.student = student self.depgraph = depgraph self.topic_sequence = nx.topological_sort(self.depgraph) # FIXME @@ -28,12 +29,12 @@ class Knowledge(object): # ------------------------------------------------------------------------ def new_topic(self, topic=None): - logger.debug(f'-> Knowledge.new_topic({topic})') if topic is None: # select the first topic that has level < 0.9 for topic in self.topic_sequence: if topic not in self.state or self.state[topic]['level'] < 0.9: break + logger.debug(f'Student {self.student}: new_topic({topic})') # FIXME if all are > 0.9, will stay in the last one forever... self.current_topic = topic @@ -44,7 +45,8 @@ class Knowledge(object): # ------------------------------------------------------------------------ def generate_questions_for_topic(self, topic): - logger.debug(f'-> Knowledge.generate_questions_for_topic({topic})') + logger.debug(f'Student {self.student}: generate_questions_for_topic "{topic}"') + factory_list = self.depgraph.node[topic]['factory'] return [q.generate() for q in factory_list] @@ -58,7 +60,7 @@ class Knowledge(object): # ------------------------------------------------------------------------ def get_knowledge_state(self): - logger.debug('-> Knowledge.get_knowledge_state()') + # logger.debug('-> Knowledge.get_knowledge_state()') ts = [] for t in self.topic_sequence: if t in self.state: @@ -69,15 +71,13 @@ class Knowledge(object): # ------------------------------------------------------------------------ def get_topic_progress(self): - logger.debug('-> Knowledge.get_topic_progress()') + # logger.debug('-> Knowledge.get_topic_progress()') return len(self.finished_questions) / (len(self.finished_questions) + len(self.questions)) # ------------------------------------------------------------------------ # if answer to current question is correct generates a new question - # otherwise returns none + # otherwise returns None def new_question(self): - logger.debug('-> Knowledge.new_question()') - if self.current_question is None or \ self.current_question.get('grade', 0.0) > 0.9: @@ -85,7 +85,7 @@ class Knowledge(object): # keep going if there are no questions in the next topics while not self.questions: self.state[self.current_topic] = { - 'level': 1.0, + 'level': 1.0, # FIXME depends on how many are correct 'date': datetime.now() } self.new_topic() @@ -94,15 +94,17 @@ class Knowledge(object): self.current_question['start_time'] = datetime.now() self.finished_questions.append(self.current_question) + logger.debug(f'Student {self.student}: new_question({self.current_question["ref"]})') return self.current_question # --- checks answer ------------------------------------------------------ # returns current question with correction, time and comments updated def check_answer(self, answer): - logger.debug(f'-> Knowledge.check_answer({answer})') question = self.current_question if question is not None: question['finish_time'] = datetime.now() question.correct(answer) + logger.debug(f'Student {self.student}: check_answer({answer}) = {question["grade"]}') + return question diff --git a/questions.py b/questions.py index 025636b..0a2c73c 100644 --- a/questions.py +++ b/questions.py @@ -316,7 +316,7 @@ class QuestionTextArea(Question): #------------------------------------------------------------------------ def __init__(self, q): - logger.debug('QuestionTextArea.__init__()') + # logger.debug('QuestionTextArea.__init__()') super().__init__(q) self.set_defaults({ diff --git a/templates/learn.html b/templates/learn.html index defa8a6..65b7d0a 100644 --- a/templates/learn.html +++ b/templates/learn.html @@ -163,17 +163,32 @@ function updateQuestion(response){ MathJax.Hub.Queue(["Typeset",MathJax.Hub,"question_div"]); - $("textarea, input:text, input:radio, input:checkbox").keydown(function (e) { + + $("input:text, input:radio, input:checkbox").keydown(function (e) { if (e.keyCode == 13 && e.shiftKey) { e.preventDefault(); getQuestion(); } - // if (e.keyCode == 13) { - // e.preventDefault(); - // if (e.shiftKey) { - // getQuestion(); - // } - // } + }); + + $("textarea").keydown(function (e) { + if (e.keyCode == 13 && e.shiftKey) { // shift enter + e.preventDefault(); + getQuestion(); + } + else if (e.keyCode === 9) { // tab + // get caret position/selection + var start = this.selectionStart; + var end = this.selectionEnd; + var value = $(this).val(); + + // set textarea value to: text before caret + tab + text after caret + $(this).val(value.substring(0, start) + " " + value.substring(end)); + + // put caret at right position again (add one for the tab) + this.selectionStart = this.selectionEnd = start + 4; + e.preventDefault(); // prevent the focus lose + } }); // var audio = new Audio('/static/sounds/correct.mp3'); // audio.play(); -- libgit2 0.21.2