From 31b2eb9f019cbc319be7a3bd6ddcd6961f15d1a9 Mon Sep 17 00:00:00 2001 From: Miguel BarĂ£o Date: Fri, 14 Jan 2022 23:06:46 +0000 Subject: [PATCH] add --correct option --- perguntations/app.py | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------ perguntations/main.py | 2 +- 2 files changed, 58 insertions(+), 61 deletions(-) diff --git a/perguntations/app.py b/perguntations/app.py index 4129091..69c7ecf 100644 --- a/perguntations/app.py +++ b/perguntations/app.py @@ -8,6 +8,7 @@ Description: Main application logic. import asyncio import csv import io +import json import logging import os from typing import Optional @@ -23,6 +24,8 @@ import yaml from .models import Student, Test, Question from .tools import load_yaml from .testfactory import TestFactory, TestFactoryException +from .test import Test as TestInstance +from .questions import question_from # setup logger for this module logger = logging.getLogger(__name__) @@ -59,6 +62,8 @@ class App(): self._make_test_factory(config['testfile']) self._db_setup() # setup engine and load all students + asyncio.get_event_loop().run_until_complete(self._assign_tests()) + # command line options: --allow-all, --allow-list filename if config['allow_all']: self.allow_all_students() @@ -67,8 +72,8 @@ class App(): else: logger.info('Students login not yet allowed') - # if config['correct']: - # self._correct_tests() + if config['correct']: + self._correct_tests() # ------------------------------------------------------------------------ def _db_setup(self) -> None: @@ -255,65 +260,57 @@ class App(): session.commit() logger.info('"%s" database updated.', uid) -# # ------------------------------------------------------------------------ -# def _correct_tests(self): -# with Session(self._engine, future=True) as session: -# # Find which tests have to be corrected -# dbtests = session.execute( -# select(Test). -# where(Test.ref == self.testfactory['ref']). -# where(Test.state == "SUBMITTED") -# ).all() -# # dbtests = session.query(Test)\ -# # .filter(Test.ref == self.testfactory['ref'])\ -# # .filter(Test.state == "SUBMITTED")\ -# # .all() - -# logger.info('Correcting %d tests...', len(dbtests)) -# for dbtest in dbtests: -# try: -# with open(dbtest.filename) as file: -# testdict = json.load(file) -# except FileNotFoundError: -# logger.error('File not found: %s', dbtest.filename) -# continue - -# # creates a class Test with the methods to correct it -# # the questions are still dictionaries, so we have to call -# # question_from() to produce Question() instances that can be -# # corrected. Finally the test can be corrected. -# test = perguntations.test.Test(testdict) -# test['questions'] = [question_from(q) for q in test['questions']] -# test.correct() -# logger.info('Student %s: grade = %f', test['student']['number'], test['grade']) - -# # save JSON file (overwriting the old one) -# uid = test['student']['number'] -# ref = test['ref'] -# finish_time = test['finish_time'] -# answers_dir = test['answers_dir'] -# fname = f'{uid}--{ref}--{finish_time}.json' -# fpath = os.path.join(answers_dir, fname) -# test.save_json(fpath) -# logger.info('%s saved JSON file.', uid) - -# # update database -# dbtest.grade = test['grade'] -# dbtest.state = test['state'] -# dbtest.questions = [ -# Question( -# number=n, -# ref=q['ref'], -# grade=q['grade'], -# comment=q.get('comment', ''), -# starttime=str(test['start_time']), -# finishtime=str(test['finish_time']), -# test_id=test['ref'] -# ) -# for n, q in enumerate(test['questions']) -# ] -# logger.info('%s database updated.', uid) + # ------------------------------------------------------------------------ + def _correct_tests(self) -> None: + with Session(self._engine, future=True) as session: + # Find which tests have to be corrected + query = select(Test) \ + .where(Test.ref == self._testfactory['ref']) \ + .where(Test.state == "SUBMITTED") + dbtests = session.execute(query).scalars().all() + if not dbtests: + logger.info('No tests to correct') + return + logger.info('Correcting %d tests...', len(dbtests)) + for dbtest in dbtests: + try: + with open(dbtest.filename) as file: + testdict = json.load(file) + except OSError: + logger.error('Failed: %s', dbtest.filename) + continue + + # creates a class Test with the methods to correct it + # the questions are still dictionaries, so we have to call + # question_from() to produce Question() instances that can be + # corrected. Finally the test can be corrected. + test = TestInstance(testdict) + test['questions'] = [question_from(q) for q in test['questions']] + test.correct() + logger.info(' %s: %f', test['student'], test['grade']) + + # save JSON file (overwriting the old one) + uid = test['student'] + test.save_json(dbtest.filename) + logger.debug('%s saved JSON file.', uid) + + # update database + dbtest.grade = test['grade'] + dbtest.state = test['state'] + dbtest.questions = [ + Question( + number=n, + ref=q['ref'], + grade=q['grade'], + comment=q.get('comment', ''), + starttime=str(test['start_time']), + finishtime=str(test['finish_time']), + test_id=test['ref'] + ) for n, q in enumerate(test['questions']) + ] + session.commit() + logger.info('Database updated') # ------------------------------------------------------------------------ # def giveup_test(self, uid): diff --git a/perguntations/main.py b/perguntations/main.py index 770963e..2ac5135 100644 --- a/perguntations/main.py +++ b/perguntations/main.py @@ -76,7 +76,7 @@ def get_logger_config(debug=False) -> dict: dateformat = '' else: level = 'INFO' - fmt = '%(asctime)s |%(levelname)-8s| %(message)s' + fmt = '%(asctime)s| %(levelname)-8s| %(message)s' dateformat = '%Y-%m-%d %H:%M:%S' modules = ['main', 'serve', 'app', 'models', 'questions', 'test', 'testfactory', 'tools'] -- libgit2 0.21.2