Commit 913dbfb228dbe9631224a56a7539c01502862c5b

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

fix args in textarea questions.

fix some flake8 errors in test.py.
add debug log on individual question correction.
perguntations/questions.py
@@ -335,9 +335,10 @@ class QuestionTextArea(Question): @@ -335,9 +335,10 @@ class QuestionTextArea(Question):
335 335
336 self.set_defaults({ 336 self.set_defaults({
337 'text': '', 337 'text': '',
338 - 'lines': 8,  
339 - 'timeout': 5, # seconds  
340 - 'correct': '' # trying to execute this will fail => grade 0.0 338 + 'lines': 8, # FIXME not being used???
  339 + 'timeout': 5, # seconds
  340 + 'correct': '', # trying to execute this will fail => grade 0.0
  341 + 'args': []
341 }) 342 })
342 343
343 self['correct'] = path.join(self['path'], self['correct']) 344 self['correct'] = path.join(self['path'], self['correct'])
perguntations/test.py
@@ -84,7 +84,7 @@ class TestFactory(dict): @@ -84,7 +84,7 @@ class TestFactory(dict):
84 logger.critical(f'Found {nerrs} errors generating questions.') 84 logger.critical(f'Found {nerrs} errors generating questions.')
85 raise TestFactoryException() 85 raise TestFactoryException()
86 else: 86 else:
87 - logger.info(f'No errors found. Test factory ready for "{self["ref"]}".') 87 + logger.info(f'No errors found. Factory ready for "{self["ref"]}".')
88 88
89 # ----------------------------------------------------------------------- 89 # -----------------------------------------------------------------------
90 # Checks for valid keys and sets default values. 90 # Checks for valid keys and sets default values.
@@ -126,14 +126,17 @@ class TestFactory(dict): @@ -126,14 +126,17 @@ class TestFactory(dict):
126 f'Using {path.abspath(path.curdir)}') 126 f'Using {path.abspath(path.curdir)}')
127 self['questions_dir'] = path.curdir 127 self['questions_dir'] = path.curdir
128 elif not path.isdir(path.expanduser(self['questions_dir'])): 128 elif not path.isdir(path.expanduser(self['questions_dir'])):
129 - logger.critical(f'Can\'t find questions directory "{self["questions_dir"]}"') 129 + logger.critical(f'Can\'t find questions directory '
  130 + f'"{self["questions_dir"]}"')
130 raise TestFactoryException() 131 raise TestFactoryException()
131 132
132 # --- files 133 # --- files
133 if 'files' not in self: 134 if 'files' not in self:
134 - logger.warning('Missing "files" key. Loading all YAML files from "questions_dir"... DANGEROUS!!!') 135 + logger.warning('Missing "files" key. Loading all YAML files from '
  136 + '"questions_dir"... DANGEROUS!!!')
135 try: 137 try:
136 - self['files'] = fnmatch.filter(listdir(self['questions_dir']), '*.yaml') 138 + self['files'] = fnmatch.filter(listdir(self['questions_dir']),
  139 + '*.yaml')
137 except OSError: 140 except OSError:
138 logger.critical('Couldn\'t get list of YAML question files.') 141 logger.critical('Couldn\'t get list of YAML question files.')
139 raise TestFactoryException() 142 raise TestFactoryException()
@@ -165,13 +168,13 @@ class TestFactory(dict): @@ -165,13 +168,13 @@ class TestFactory(dict):
165 168
166 n = 1 169 n = 1
167 loop = asyncio.get_running_loop() 170 loop = asyncio.get_running_loop()
168 - 171 + qgenerator = self.question_factory.generate
169 for qq in self['questions']: 172 for qq in self['questions']:
170 # generate Question() selected randomly from list of references 173 # generate Question() selected randomly from list of references
171 qref = random.choice(qq['ref']) 174 qref = random.choice(qq['ref'])
172 175
173 try: 176 try:
174 - q = await loop.run_in_executor(None, self.question_factory.generate, qref) 177 + q = await loop.run_in_executor(None, qgenerator, qref)
175 except Exception: 178 except Exception:
176 logger.error(f'Can\'t generate question "{qref}". Skipping.') 179 logger.error(f'Can\'t generate question "{qref}". Skipping.')
177 continue 180 continue
@@ -209,8 +212,9 @@ class TestFactory(dict): @@ -209,8 +212,9 @@ class TestFactory(dict):
209 }) 212 })
210 213
211 # ----------------------------------------------------------------------- 214 # -----------------------------------------------------------------------
212 - # def __repr__(self):  
213 - # return '{\n' + '\n'.join(' {0:14s}: {1}'.format(k, v) for k,v in self.items()) + '\n}' 215 + def __repr__(self):
  216 + testsettings = '\n'.join(f' {k:14s}: {v}' for k, v in self.items())
  217 + return '{\n' + testsettings + '\n}'
214 218
215 219
216 # =========================================================================== 220 # ===========================================================================
@@ -241,8 +245,8 @@ class Test(dict): @@ -241,8 +245,8 @@ class Test(dict):
241 # Given a dictionary ans={index: 'some answer'} updates the 245 # Given a dictionary ans={index: 'some answer'} updates the
242 # answers of the test. Only affects questions referred. 246 # answers of the test. Only affects questions referred.
243 def update_answers(self, ans): 247 def update_answers(self, ans):
244 - for i in ans:  
245 - self['questions'][i]['answer'] = ans[i] 248 + for ref, answer in ans.items():
  249 + self['questions'][ref]['answer'] = answer
246 logger.info(f'Student {self["student"]["number"]}: ' 250 logger.info(f'Student {self["student"]["number"]}: '
247 f'{len(ans)} answers updated.') 251 f'{len(ans)} answers updated.')
248 252
@@ -253,8 +257,11 @@ class Test(dict): @@ -253,8 +257,11 @@ class Test(dict):
253 self['state'] = 'FINISHED' 257 self['state'] = 'FINISHED'
254 grade = 0.0 258 grade = 0.0
255 for q in self['questions']: 259 for q in self['questions']:
256 - grade += await q.correct_async() * q['points']  
257 - self['grade'] = max(0, round(grade, 1)) # avoid negative grade 260 + g = await q.correct_async()
  261 + grade += g * q['points']
  262 + logger.debug(f'Correcting "{q["ref"]}": {g*100.0} %')
  263 +
  264 + self['grade'] = max(0, round(grade, 1)) # avoid negative grades
258 logger.info(f'Student {self["student"]["number"]}: ' 265 logger.info(f'Student {self["student"]["number"]}: '
259 f'{self["grade"]} points.') 266 f'{self["grade"]} points.')
260 return self['grade'] 267 return self['grade']