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