Commit 2c577830bc6ae0dd496d5779cc25c75f4fb0ac0f

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

- allow chapters to not have any questions.yaml file

- fix some mypy errors
- other small improvements
1 1
2 # BUGS 2 # BUGS
3 3
4 -- dependencias que não são goals de um curso, só devem aparecer se ainda não tiverem sido feitas.  
5 - goals se forem do tipo chapter deve importar todas as dependencias do chapter (e não mostrar chapters?). 4 - goals se forem do tipo chapter deve importar todas as dependencias do chapter (e não mostrar chapters?).
6 - nao esta a seguir o max_tries definido no ficheiro de dependencias. 5 - nao esta a seguir o max_tries definido no ficheiro de dependencias.
7 - devia mostrar timeout para o aluno saber a razao. 6 - devia mostrar timeout para o aluno saber a razao.
@@ -9,7 +8,6 @@ @@ -9,7 +8,6 @@
9 - templates question-*.html tem input hidden question_ref que não é usado. remover? 8 - templates question-*.html tem input hidden question_ref que não é usado. remover?
10 - shift-enter não está a funcionar 9 - shift-enter não está a funcionar
11 - default prefix should be obtained from each course (yaml conf)? 10 - default prefix should be obtained from each course (yaml conf)?
12 -- initdb da integrity error se no mesmo comando existirem alunos repetidos (p.ex em ficheiros csv diferentes ou entre csv e opcao -a)  
13 11
14 # TODO 12 # TODO
15 13
@@ -34,6 +32,8 @@ @@ -34,6 +32,8 @@
34 32
35 # FIXED 33 # FIXED
36 34
  35 +- initdb da integrity error se no mesmo comando existirem alunos repetidos (p.ex em ficheiros csv diferentes ou entre csv e opcao -a)
  36 +- dependencias que não são goals de um curso, só devem aparecer se ainda não tiverem sido feitas.
37 - ir para inicio da pagina quando le nova pergunta. 37 - ir para inicio da pagina quando le nova pergunta.
38 - CRITICAL nao esta a guardar o progresso na base de dados. 38 - CRITICAL nao esta a guardar o progresso na base de dados.
39 - mesma ref no mesmo ficheiro não é detectado. 39 - mesma ref no mesmo ficheiro não é detectado.
aprendizations/__init__.py
@@ -30,7 +30,7 @@ are progressively uncovered as the students progress. @@ -30,7 +30,7 @@ are progressively uncovered as the students progress.
30 ''' 30 '''
31 31
32 APP_NAME = 'aprendizations' 32 APP_NAME = 'aprendizations'
33 -APP_VERSION = '2020.01.dev1' 33 +APP_VERSION = '2020.01.dev2'
34 APP_DESCRIPTION = __doc__ 34 APP_DESCRIPTION = __doc__
35 35
36 __author__ = 'Miguel Barão' 36 __author__ = 'Miguel Barão'
aprendizations/learnapp.py
@@ -245,7 +245,7 @@ class LearnApp(object): @@ -245,7 +245,7 @@ class LearnApp(object):
245 async def check_answer(self, uid: str, answer) -> Question: 245 async def check_answer(self, uid: str, answer) -> Question:
246 student = self.online[uid]['state'] 246 student = self.online[uid]['state']
247 await student.check_answer(answer) 247 await student.check_answer(answer)
248 - q = student.get_current_question() 248 + q: Question = student.get_current_question()
249 249
250 logger.info(f'User "{uid}" got {q["grade"]:.2} in "{q["ref"]}"') 250 logger.info(f'User "{uid}" got {q["grade"]:.2} in "{q["ref"]}"')
251 251
@@ -430,7 +430,7 @@ class LearnApp(object): @@ -430,7 +430,7 @@ class LearnApp(object):
430 # makes factory for a single topic 430 # makes factory for a single topic
431 # ------------------------------------------------------------------------ 431 # ------------------------------------------------------------------------
432 def factory_for(self, tref: str) -> Dict[str, QFactory]: 432 def factory_for(self, tref: str) -> Dict[str, QFactory]:
433 - factory = {} 433 + factory: Dict[str, QFactory] = {}
434 g = self.deps 434 g = self.deps
435 t = g.nodes[tref] # get node 435 t = g.nodes[tref] # get node
436 436
@@ -447,9 +447,12 @@ class LearnApp(object): @@ -447,9 +447,12 @@ class LearnApp(object):
447 try: 447 try:
448 questions: List[QDict] = load_yaml(fullpath) 448 questions: List[QDict] = load_yaml(fullpath)
449 except Exception: 449 except Exception:
450 - msg = f'Failed to load "{fullpath}"'  
451 - logger.error(msg)  
452 - raise LearnException(msg) 450 + if t['type'] == 'chapter':
  451 + return factory # chapters may have no "questions"
  452 + else:
  453 + msg = f'Failed to load "{fullpath}"'
  454 + logger.error(msg)
  455 + raise LearnException(msg)
453 456
454 if not isinstance(questions, list): 457 if not isinstance(questions, list):
455 msg = f'File "{fullpath}" must be a list of questions' 458 msg = f'File "{fullpath}" must be a list of questions'
@@ -500,40 +503,37 @@ class LearnApp(object): @@ -500,40 +503,37 @@ class LearnApp(object):
500 503
501 # ------------------------------------------------------------------------ 504 # ------------------------------------------------------------------------
502 def get_student_progress(self, uid: str) -> float: 505 def get_student_progress(self, uid: str) -> float:
503 - return self.online[uid]['state'].get_topic_progress() 506 + return float(self.online[uid]['state'].get_topic_progress())
504 507
505 # ------------------------------------------------------------------------ 508 # ------------------------------------------------------------------------
506 def get_current_question(self, uid: str) -> Optional[Question]: 509 def get_current_question(self, uid: str) -> Optional[Question]:
507 - return self.online[uid]['state'].get_current_question() 510 + q: Optional[Question] = self.online[uid]['state'].get_current_question()
  511 + return q
508 512
509 # ------------------------------------------------------------------------ 513 # ------------------------------------------------------------------------
510 def get_current_question_id(self, uid: str) -> str: 514 def get_current_question_id(self, uid: str) -> str:
511 - return self.online[uid]['state'].get_current_question()['qid'] 515 + return str(self.online[uid]['state'].get_current_question()['qid'])
512 516
513 # ------------------------------------------------------------------------ 517 # ------------------------------------------------------------------------
514 def get_student_question_type(self, uid: str) -> str: 518 def get_student_question_type(self, uid: str) -> str:
515 - return self.online[uid]['state'].get_current_question()['type'] 519 + return str(self.online[uid]['state'].get_current_question()['type'])
516 520
517 # ------------------------------------------------------------------------ 521 # ------------------------------------------------------------------------
518 def get_student_topic(self, uid: str) -> str: 522 def get_student_topic(self, uid: str) -> str:
519 - return self.online[uid]['state'].get_current_topic() 523 + return str(self.online[uid]['state'].get_current_topic())
520 524
521 # ------------------------------------------------------------------------ 525 # ------------------------------------------------------------------------
522 def get_student_course_title(self, uid: str) -> str: 526 def get_student_course_title(self, uid: str) -> str:
523 - return self.online[uid]['state'].get_current_course_title()  
524 -  
525 - # ------------------------------------------------------------------------  
526 - def get_student_course_id(self, uid: str) -> Optional[str]:  
527 - return self.online[uid]['state'].get_current_course_id() 527 + return str(self.online[uid]['state'].get_current_course_title())
528 528
529 # ------------------------------------------------------------------------ 529 # ------------------------------------------------------------------------
530 - # def get_student_course(self, uid: str) -> Optional[str]:  
531 - # course_id = self.online[uid]['state'].get_current_course_id()  
532 - # return course_id, self.courses[course_id] 530 + def get_current_course_id(self, uid: str) -> Optional[str]:
  531 + cid: Optional[str] = self.online[uid]['state'].get_current_course_id()
  532 + return cid
533 533
534 # ------------------------------------------------------------------------ 534 # ------------------------------------------------------------------------
535 def get_topic_name(self, ref: str) -> str: 535 def get_topic_name(self, ref: str) -> str:
536 - return self.deps.nodes[ref]['name'] 536 + return str(self.deps.nodes[ref]['name'])
537 537
538 # ------------------------------------------------------------------------ 538 # ------------------------------------------------------------------------
539 def get_current_public_dir(self, uid: str) -> str: 539 def get_current_public_dir(self, uid: str) -> str:
@@ -542,10 +542,11 @@ class LearnApp(object): @@ -542,10 +542,11 @@ class LearnApp(object):
542 return path.join(prefix, topic, 'public') 542 return path.join(prefix, topic, 'public')
543 543
544 # ------------------------------------------------------------------------ 544 # ------------------------------------------------------------------------
545 - def get_courses(self, uid: str) -> Dict: 545 + def get_courses(self) -> Dict[str, Dict[str, Any]]:
546 return self.courses 546 return self.courses
547 547
548 - def get_course(self, course_id: str) -> Dict: 548 + # ------------------------------------------------------------------------
  549 + def get_course(self, course_id: str) -> Dict[str, Any]:
549 return self.courses[course_id] 550 return self.courses[course_id]
550 551
551 # ------------------------------------------------------------------------ 552 # ------------------------------------------------------------------------
aprendizations/serve.py
@@ -96,7 +96,7 @@ class RankingsHandler(BaseHandler): @@ -96,7 +96,7 @@ class RankingsHandler(BaseHandler):
96 @tornado.web.authenticated 96 @tornado.web.authenticated
97 def get(self): 97 def get(self):
98 uid = self.current_user 98 uid = self.current_user
99 - current_course = self.learn.get_student_course_id(uid) 99 + current_course = self.learn.get_current_course_id(uid)
100 course_id = self.get_query_argument('course', default=current_course) 100 course_id = self.get_query_argument('course', default=current_course)
101 rankings = self.learn.get_rankings(uid, course_id) 101 rankings = self.learn.get_rankings(uid, course_id)
102 self.render('rankings.html', 102 self.render('rankings.html',
@@ -195,7 +195,7 @@ class CoursesHandler(BaseHandler): @@ -195,7 +195,7 @@ class CoursesHandler(BaseHandler):
195 appname=APP_NAME, 195 appname=APP_NAME,
196 uid=uid, 196 uid=uid,
197 name=self.learn.get_student_name(uid), 197 name=self.learn.get_student_name(uid),
198 - courses=self.learn.get_courses(uid), 198 + courses=self.learn.get_courses(),
199 ) 199 )
200 200
201 201
@@ -242,7 +242,7 @@ class TopicHandler(BaseHandler): @@ -242,7 +242,7 @@ class TopicHandler(BaseHandler):
242 uid=uid, 242 uid=uid,
243 name=self.learn.get_student_name(uid), 243 name=self.learn.get_student_name(uid),
244 # course_title=self.learn.get_student_course_title(uid), 244 # course_title=self.learn.get_student_course_title(uid),
245 - course_id=self.learn.get_student_course_id(uid), 245 + course_id=self.learn.get_current_course_id(uid),
246 ) 246 )
247 247
248 248