Commit adb8522e262fd313534d8b3c6577b71d95efe9a1

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

add some type annotations

1 1
2 # BUGS 2 # BUGS
3 3
4 -- no login, dar mensagem de erro se aluno nao existir??  
5 -- Verificar o processo de logout.  
6 - permitir remover alunos que estão online para poderem comecar de novo. 4 - permitir remover alunos que estão online para poderem comecar de novo.
7 - grade gives internal server error 5 - grade gives internal server error
8 - reload do teste recomeça a contagem no inicio do tempo. 6 - reload do teste recomeça a contagem no inicio do tempo.
perguntations/main.py
@@ -55,7 +55,7 @@ def parse_cmdline_arguments(): @@ -55,7 +55,7 @@ def parse_cmdline_arguments():
55 help='port for the HTTPS server (default: 8443)') 55 help='port for the HTTPS server (default: 8443)')
56 parser.add_argument('--version', 56 parser.add_argument('--version',
57 action='version', 57 action='version',
58 - version=APP_VERSION, 58 + version=f'{APP_VERSION} - python {sys.version}',
59 help='Show version information and exit') 59 help='Show version information and exit')
60 return parser.parse_args() 60 return parser.parse_args()
61 61
@@ -100,7 +100,7 @@ def get_logger_config(debug=False): @@ -100,7 +100,7 @@ def get_logger_config(debug=False):
100 }, 100 },
101 } 101 }
102 default_config['loggers'].update({ 102 default_config['loggers'].update({
103 - APP_NAME+'.'+module: { 103 + f'{APP_NAME}.{module}': {
104 'handlers': ['default'], 104 'handlers': ['default'],
105 'level': level, 105 'level': level,
106 'propagate': False, 106 'propagate': False,
perguntations/test.py
@@ -10,6 +10,7 @@ import random @@ -10,6 +10,7 @@ import random
10 from datetime import datetime 10 from datetime import datetime
11 import logging 11 import logging
12 import re 12 import re
  13 +from typing import Any, Dict
13 14
14 # this project 15 # this project
15 from perguntations.questions import QFactory, QuestionException 16 from perguntations.questions import QFactory, QuestionException
@@ -33,7 +34,7 @@ class TestFactory(dict): @@ -33,7 +34,7 @@ class TestFactory(dict):
33 ''' 34 '''
34 35
35 # ------------------------------------------------------------------------ 36 # ------------------------------------------------------------------------
36 - def __init__(self, conf): 37 + def __init__(self, conf: Dict[str, Any]) -> None:
37 ''' 38 '''
38 Loads configuration from yaml file, then overrides some configurations 39 Loads configuration from yaml file, then overrides some configurations
39 using the conf argument. 40 using the conf argument.
@@ -123,7 +124,7 @@ class TestFactory(dict): @@ -123,7 +124,7 @@ class TestFactory(dict):
123 raise TestFactoryException(f'Could not find questions {qmissing}.') 124 raise TestFactoryException(f'Could not find questions {qmissing}.')
124 125
125 # ------------------------------------------------------------------------ 126 # ------------------------------------------------------------------------
126 - def check_test_ref(self): 127 + def check_test_ref(self) -> None:
127 '''Test must have a `ref`''' 128 '''Test must have a `ref`'''
128 if 'ref' not in self: 129 if 'ref' not in self:
129 raise TestFactoryException('Missing "ref" in configuration!') 130 raise TestFactoryException('Missing "ref" in configuration!')
@@ -131,7 +132,7 @@ class TestFactory(dict): @@ -131,7 +132,7 @@ class TestFactory(dict):
131 raise TestFactoryException('Test "ref" can only contain the ' 132 raise TestFactoryException('Test "ref" can only contain the '
132 'characters a-zA-Z0-9_-') 133 'characters a-zA-Z0-9_-')
133 134
134 - def check_missing_database(self): 135 + def check_missing_database(self) -> None:
135 '''Test must have a database''' 136 '''Test must have a database'''
136 if 'database' not in self: 137 if 'database' not in self:
137 raise TestFactoryException('Missing "database" in configuration') 138 raise TestFactoryException('Missing "database" in configuration')
@@ -139,13 +140,13 @@ class TestFactory(dict): @@ -139,13 +140,13 @@ class TestFactory(dict):
139 msg = f'Database "{self["database"]}" not found!' 140 msg = f'Database "{self["database"]}" not found!'
140 raise TestFactoryException(msg) 141 raise TestFactoryException(msg)
141 142
142 - def check_missing_answers_directory(self): 143 + def check_missing_answers_directory(self) -> None:
143 '''Test must have a answers directory''' 144 '''Test must have a answers directory'''
144 if 'answers_dir' not in self: 145 if 'answers_dir' not in self:
145 msg = 'Missing "answers_dir" in configuration' 146 msg = 'Missing "answers_dir" in configuration'
146 raise TestFactoryException(msg) 147 raise TestFactoryException(msg)
147 148
148 - def check_answers_directory_writable(self): 149 + def check_answers_directory_writable(self) -> None:
149 '''Answers directory must be writable''' 150 '''Answers directory must be writable'''
150 testfile = path.join(path.expanduser(self['answers_dir']), 'REMOVE-ME') 151 testfile = path.join(path.expanduser(self['answers_dir']), 'REMOVE-ME')
151 try: 152 try:
@@ -155,7 +156,7 @@ class TestFactory(dict): @@ -155,7 +156,7 @@ class TestFactory(dict):
155 msg = f'Cannot write answers to directory "{self["answers_dir"]}"' 156 msg = f'Cannot write answers to directory "{self["answers_dir"]}"'
156 raise TestFactoryException(msg) from exc 157 raise TestFactoryException(msg) from exc
157 158
158 - def check_questions_directory(self): 159 + def check_questions_directory(self) -> None:
159 '''Check if questions directory is missing or not accessible.''' 160 '''Check if questions directory is missing or not accessible.'''
160 if 'questions_dir' not in self: 161 if 'questions_dir' not in self:
161 logger.warning('Missing "questions_dir". Using "%s"', 162 logger.warning('Missing "questions_dir". Using "%s"',
@@ -165,7 +166,7 @@ class TestFactory(dict): @@ -165,7 +166,7 @@ class TestFactory(dict):
165 raise TestFactoryException(f'Can\'t find questions directory ' 166 raise TestFactoryException(f'Can\'t find questions directory '
166 f'"{self["questions_dir"]}"') 167 f'"{self["questions_dir"]}"')
167 168
168 - def check_import_files(self): 169 + def check_import_files(self) -> None:
169 '''Check if there are files to import (with questions)''' 170 '''Check if there are files to import (with questions)'''
170 if 'files' not in self: 171 if 'files' not in self:
171 msg = ('Missing "files" in configuration with the list of ' 172 msg = ('Missing "files" in configuration with the list of '
@@ -175,7 +176,7 @@ class TestFactory(dict): @@ -175,7 +176,7 @@ class TestFactory(dict):
175 if isinstance(self['files'], str): 176 if isinstance(self['files'], str):
176 self['files'] = [self['files']] 177 self['files'] = [self['files']]
177 178
178 - def check_question_list(self): 179 + def check_question_list(self) -> None:
179 '''normalize question list''' 180 '''normalize question list'''
180 if 'questions' not in self: 181 if 'questions' not in self:
181 raise TestFactoryException('Missing "questions" in configuration') 182 raise TestFactoryException('Missing "questions" in configuration')
@@ -191,12 +192,12 @@ class TestFactory(dict): @@ -191,12 +192,12 @@ class TestFactory(dict):
191 192
192 self['questions'][i] = question 193 self['questions'][i] = question
193 194
194 - def check_missing_title(self): 195 + def check_missing_title(self) -> None:
195 '''Warns if title is missing''' 196 '''Warns if title is missing'''
196 if not self['title']: 197 if not self['title']:
197 logger.warning('Title is undefined!') 198 logger.warning('Title is undefined!')
198 199
199 - def check_grade_scaling(self): 200 + def check_grade_scaling(self) -> None:
200 '''Just informs the scale limits''' 201 '''Just informs the scale limits'''
201 if 'scale_points' in self: 202 if 'scale_points' in self:
202 msg = ('*** DEPRECATION WARNING: *** scale_points, scale_min, ' 203 msg = ('*** DEPRECATION WARNING: *** scale_points, scale_min, '
@@ -206,7 +207,7 @@ class TestFactory(dict): @@ -206,7 +207,7 @@ class TestFactory(dict):
206 207
207 208
208 # ------------------------------------------------------------------------ 209 # ------------------------------------------------------------------------
209 - def sanity_checks(self): 210 + def sanity_checks(self) -> None:
210 ''' 211 '''
211 Checks for valid keys and sets default values. 212 Checks for valid keys and sets default values.
212 Also checks if some files and directories exist 213 Also checks if some files and directories exist
@@ -304,7 +305,7 @@ class Test(dict): @@ -304,7 +305,7 @@ class Test(dict):
304 # super().__init__(d) 305 # super().__init__(d)
305 306
306 # ------------------------------------------------------------------------ 307 # ------------------------------------------------------------------------
307 - def register(self, student): 308 + def register(self, student: dict) -> None:
308 ''' 309 '''
309 Write student id in the test and register start time 310 Write student id in the test and register start time
310 ''' 311 '''
@@ -315,18 +316,18 @@ class Test(dict): @@ -315,18 +316,18 @@ class Test(dict):
315 self['comment'] = '' 316 self['comment'] = ''
316 317
317 # ------------------------------------------------------------------------ 318 # ------------------------------------------------------------------------
318 - def reset_answers(self): 319 + def reset_answers(self) -> None:
319 '''Removes all answers from the test (clean)''' 320 '''Removes all answers from the test (clean)'''
320 for question in self['questions']: 321 for question in self['questions']:
321 question['answer'] = None 322 question['answer'] = None
322 323
323 # ------------------------------------------------------------------------ 324 # ------------------------------------------------------------------------
324 - def update_answer(self, ref, ans): 325 + def update_answer(self, ref: str, ans) -> None:
325 '''updates one answer in the test''' 326 '''updates one answer in the test'''
326 self['questions'][ref].set_answer(ans) 327 self['questions'][ref].set_answer(ans)
327 328
328 # ------------------------------------------------------------------------ 329 # ------------------------------------------------------------------------
329 - def update_answers(self, answers_dict): 330 + def update_answers(self, answers_dict) -> None:
330 ''' 331 '''
331 Given a dictionary ans={'ref': 'some answer'} updates the answers of 332 Given a dictionary ans={'ref': 'some answer'} updates the answers of
332 multiple questions in the test. 333 multiple questions in the test.
@@ -337,7 +338,7 @@ class Test(dict): @@ -337,7 +338,7 @@ class Test(dict):
337 # self['questions'][ref]['answer'] = ans 338 # self['questions'][ref]['answer'] = ans
338 339
339 # ------------------------------------------------------------------------ 340 # ------------------------------------------------------------------------
340 - async def correct(self): 341 + async def correct(self) -> float:
341 '''Corrects all the answers of the test and computes the final grade''' 342 '''Corrects all the answers of the test and computes the final grade'''
342 self['finish_time'] = datetime.now() 343 self['finish_time'] = datetime.now()
343 self['state'] = 'FINISHED' 344 self['state'] = 'FINISHED'
@@ -354,7 +355,7 @@ class Test(dict): @@ -354,7 +355,7 @@ class Test(dict):
354 return self['grade'] 355 return self['grade']
355 356
356 # ------------------------------------------------------------------------ 357 # ------------------------------------------------------------------------
357 - def giveup(self): 358 + def giveup(self) -> float:
358 '''Test is marqued as QUIT and is not corrected''' 359 '''Test is marqued as QUIT and is not corrected'''
359 self['finish_time'] = datetime.now() 360 self['finish_time'] = datetime.now()
360 self['state'] = 'QUIT' 361 self['state'] = 'QUIT'
@@ -363,7 +364,7 @@ class Test(dict): @@ -363,7 +364,7 @@ class Test(dict):
363 return self['grade'] 364 return self['grade']
364 365
365 # ------------------------------------------------------------------------ 366 # ------------------------------------------------------------------------
366 - def __str__(self): 367 + def __str__(self) -> str:
367 return ('Test:\n' 368 return ('Test:\n'
368 f' student: {self.get("student", "--")}\n' 369 f' student: {self.get("student", "--")}\n'
369 f' start_time: {self.get("start_time", "--")}\n' 370 f' start_time: {self.get("start_time", "--")}\n'