Commit adb8522e262fd313534d8b3c6577b71d95efe9a1
1 parent
ed0097b4
Exists in
master
and in
1 other branch
add some type annotations
Showing
3 changed files
with
21 additions
and
22 deletions
Show diff stats
BUGS.md
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' |