Commit 84a1054c11302b9054394629529b2363450a5d45

Authored by Miguel Barão
1 parent 64f0b75c
Exists in master and in 1 other branch dev

- Each student is represented by a class Knowledge and checks answers and generates new questions..

- The learn app deals with multiple users, login/logout and database.
Showing 3 changed files with 51 additions and 51 deletions   Show diff stats
app.py
1 1  
2   -import random
  2 +# python standard library
3 3 from contextlib import contextmanager # `with` statement in db sessions
4   -from datetime import datetime
5 4 import logging
6 5  
7 6 # user installed libraries
... ... @@ -14,8 +13,8 @@ except ImportError:
14 13 sys.exit(1)
15 14  
16 15 # this project
17   -import questions
18 16 from models import Student, Answer
  17 +from knowledge import Knowledge
19 18  
20 19 # setup logger for this module
21 20 logger = logging.getLogger(__name__)
... ... @@ -25,18 +24,15 @@ logger = logging.getLogger(__name__)
25 24 # ============================================================================
26 25 class LearnApp(object):
27 26 def __init__(self):
28   - self.factory = questions.QuestionFactory()
29   - self.factory.load_files(['questions.yaml'], 'demo') # FIXME
30 27 self.online = {}
31 28  
32 29 # connect to database and check registered students
33 30 db = 'students.db' # FIXME
34 31 engine = create_engine(f'sqlite:///{db}', echo=False)
35   - # self.Session = scoped_session(sessionmaker(bind=engine))
36 32 self.Session = sessionmaker(bind=engine)
37 33 try:
38 34 with self.db_session() as s:
39   - n = s.query(Student).count() # filter(Student.id != '0').
  35 + n = s.query(Student).count()
40 36 except Exception as e:
41 37 logger.critical('Database not usable.')
42 38 raise e
... ... @@ -61,68 +57,37 @@ class LearnApp(object):
61 57 self.online[uid] = {
62 58 'name': student.name,
63 59 'number': student.id,
64   - 'current': None,
  60 + 'knowledge': Knowledge(), # FIXME initial state?
65 61 }
66   - print(self.online)
  62 + # print(self.online)
67 63 return True
68 64  
69 65 # ------------------------------------------------------------------------
70 66 # logout
71 67 def logout(self, uid):
72   - del self.online[uid] # FIXME save current question?
73   -
74   - # ------------------------------------------------------------------------
75   - def get_current_question(self, uid):
76   - return self.online[uid].get('current', None)
  68 + del self.online[uid] # FIXME save current state
77 69  
78 70 # ------------------------------------------------------------------------
79 71 def get_student_name(self, uid):
80 72 return self.online[uid].get('name', '')
81 73  
82 74 # ------------------------------------------------------------------------
83   - # given the currect state, generates a new question for the student
84   - def new_question_for(self, uid):
85   - # FIXME
86   - questions = list(self.factory)
87   - nextquestion = self.factory.generate(random.choice(questions))
88   - print(nextquestion)
89   - self.online[uid]['current'] = nextquestion
90   - return nextquestion
91   -
92   - # ------------------------------------------------------------------------
93 75 # check answer and if correct returns new question, otherise returns None
94 76 def check_answer(self, uid, answer):
95   - question = self.get_current_question(uid)
96   - print(question)
97   - print(answer)
98   -
99   - if question is not None:
100   - question['finish_time'] = datetime.now()
101   - grade = question.correct(answer) # correct answer
  77 + knowledge = self.online[uid]['knowledge']
  78 + current_question = knowledge.check_answer(answer)
102 79  
  80 + if current_question is not None:
103 81 with self.db_session() as s:
104 82 s.add(Answer(
105   - ref=question['ref'],
106   - grade=question['grade'],
107   - starttime=str(question['start_time']),
108   - finishtime=str(question['finish_time']),
  83 + ref=current_question['ref'],
  84 + grade=current_question['grade'],
  85 + starttime=str(current_question['start_time']),
  86 + finishtime=str(current_question['finish_time']),
109 87 student_id=uid))
110 88 s.commit()
111 89  
112   - correct = grade > 0.99999
113   - if correct:
114   - print('CORRECT')
115   - question = self.new_question_for(uid)
116   - question['start_time'] = datetime.now()
117   - return question
118   - else:
119   - print('WRONG')
120   - return None
121   - else:
122   - print('FIRST QUESTION')
123   - question = self.new_question_for(uid)
124   - question['start_time'] = datetime.now()
125   - return question
  90 + return knowledge.new_question()
126 91  
127 92 # ------------------------------------------------------------------------
128 93 # helper to manage db sessions using the `with` statement, for example
... ...
knowledge.py 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +
  2 +# python standard library
  3 +import random
  4 +from datetime import datetime
  5 +
  6 +# this project
  7 +import questions
  8 +
  9 +
  10 +# contains the kowledge state of each student.
  11 +class Knowledge(object):
  12 + def __init__(self):
  13 + self.factory = questions.QuestionFactory()
  14 + self.factory.load_files(['questions.yaml'], 'demo') # FIXME
  15 + self.current_question = None
  16 +
  17 + def get_current_question(self):
  18 + return self.current_question
  19 +
  20 + # --- generates a new question given the current state
  21 + def new_question(self):
  22 + # FIXME
  23 + if self.current_question is None or self.current_question.get('grade', 0.0) > 0.9999:
  24 + questions = list(self.factory)
  25 + self.current_question = self.factory.generate(random.choice(questions))
  26 + self.current_question['start_time'] = datetime.now()
  27 +
  28 + return self.current_question
  29 +
  30 + # --- checks answer and updates knowledge state
  31 + # returns current question with correction, time and comments updated
  32 + def check_answer(self, answer):
  33 + question = self.current_question
  34 + if question is not None:
  35 + question['finish_time'] = datetime.now()
  36 + question.correct(answer)
  37 + return question
... ...
serve.py
... ... @@ -130,11 +130,9 @@ class QuestionHandler(BaseHandler):
130 130  
131 131 @tornado.web.authenticated
132 132 def post(self):
133   - print('================= POST ==============')
134 133 # ref = self.get_body_arguments('question_ref')
135 134 user = self.current_user
136 135 answer = self.get_body_arguments('answer')
137   -
138 136 next_question = self.learn.check_answer(user, answer)
139 137  
140 138 if next_question is not None:
... ...