From 159e7a9f2ea10238407e4a87eea9f4f8d6a1b3b0 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Sun, 10 Jan 2021 06:53:16 +0100 Subject: [PATCH] Feat: move exam to Exam class --- recopytex/scripts/exam.py | 112 +++++++++++++++++++++++++++++++++ recopytex/scripts/prompts.py | 14 ++--- recopytex/scripts/recopytex.py | 67 +++++++------------- 3 files changed, 140 insertions(+), 53 deletions(-) create mode 100644 recopytex/scripts/exam.py diff --git a/recopytex/scripts/exam.py b/recopytex/scripts/exam.py new file mode 100644 index 0000000..c11fd61 --- /dev/null +++ b/recopytex/scripts/exam.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from datetime import datetime +from pathlib import Path +from .getconfig import config + + +class Exam: + def __init__(self, name, tribename, date, term, **kwrds): + self._name = name + self._tribename = tribename + try: + self._date = datetime.strptime(date, "%y%m%d") + except: + self._date = date + + self._term = term + + self._exercises = {} + + @property + def name(self): + return self._name + + @property + def tribename(self): + return self._tribename + + @property + def date(self): + return self._date + + @property + def term(self): + return self._term + + def add_exercise(self, name, questions): + """ Add key with questions in ._exercises """ + try: + self._exercises[name] + except KeyError: + self._exercises[name] = questions + else: + raise KeyError("The exercise already exsists. Use modify_exercise") + + def modify_exercise(self, name, questions, append=False): + """Modify questions of an exercise + + If append==True, add questions to the exercise questions + + """ + try: + self._exercises[name] + except KeyError: + raise KeyError("The exercise already exsists. Use modify_exercise") + else: + if append: + self._exercises[name] += questions + else: + self._exercises[name] = questions + + @property + def exercices(self): + return self._exercises + + @property + def tribe_path(self): + return Path(config["source"]) / self.tribename + + @property + def tribe_student_path(self): + return ( + Path(config["source"]) + / [t["students"] for t in config["tribes"] if t["name"] == self.tribename][ + 0 + ] + ) + + @property + def long_name(self): + """ Get exam name with date inside """ + return f"{self.date.strftime('%y%m%d')}_{self.name}" + + def path(self, extention=""): + return self.tribe_path / (self.long_name + extention) + + def to_dict(self): + return { + "name": self.name, + "tribename": self.tribename, + "date": self.date, + "term": self.term, + "exercices": self.exercices, + } + + def to_row(self): + rows = [] + for ex, questions in self.exercices.items(): + for q in questions: + rows.append( + { + "term": self.term, + "assessment": self.name, + "date": self.date.strftime("%d/%m/%Y"), + "exercise": ex, + "question": q["id"], + **q, + } + ) + return rows + diff --git a/recopytex/scripts/prompts.py b/recopytex/scripts/prompts.py index 180bd98..19de4fd 100644 --- a/recopytex/scripts/prompts.py +++ b/recopytex/scripts/prompts.py @@ -134,17 +134,17 @@ def prompt_exam(**kwrd): @prompt_until_validate() def prompt_exercise(number=1, **kwrd): + exercise = {} try: kwrd["name"] except KeyError: print(HTML("Nouvel exercice")) + exercise["name"] = prompt( + "Nom de l'exercice: ", default=kwrd.get("name", f"Exercice {number}") + ) else: print(HTML(f"Modification de l'exercice: {kwrd['name']}")) - - exercise = {} - exercise["name"] = prompt( - "Nom de l'exercice: ", default=kwrd.get("name", f"Exercice {number}") - ) + exercise["name"] = kwrd["name"] exercise["questions"] = [] @@ -187,9 +187,7 @@ def prompt_question(last_question_id="1a", **kwrd): print(HTML("Nouvel élément de notation")) else: print( - HTML( - f"Modification de l'élément {kwrd['id']} ({kwrd['comment']})" - ) + HTML(f"Modification de l'élément {kwrd['id']} ({kwrd['comment']})") ) question = {} diff --git a/recopytex/scripts/recopytex.py b/recopytex/scripts/recopytex.py index acb1198..a70a290 100644 --- a/recopytex/scripts/recopytex.py +++ b/recopytex/scripts/recopytex.py @@ -12,6 +12,7 @@ import yaml from .getconfig import config, CONFIGPATH from .prompts import prompt_exam, prompt_exercise, prompt_validate from ..config import NO_ST_COLUMNS +from .exam import Exam @click.group() @@ -35,70 +36,46 @@ def setup(): print(f"The file {tribe['students']} does not exists") -def exam_dict2row(exam): - """ Transform an exam in dictionnary for into list of rows to evaluate""" - rows = [] - for ex in exam["exercices"]: - for q in ex["questions"]: - rows.append( - { - "term": exam["term"], - "assessment": exam["name"], - "date": exam["date"].strftime("%d/%m/%Y"), - "exercise": ex["name"], - "question": q["id"], - **q, - } - ) - return rows - -def get_exam_name(exam): - """ Get exam name from exam data """ - return f"{exam['date'].strftime('%y%m%d')}_{exam['name']}" - -def get_tribe_path(exam): - """ Get tribe path from exam data """ - return Path(config["source"]) / exam["tribe"]["name"] - -def get_exam_path(exam, extention=""): - return get_tribe_path(exam)/ (get_exam_name(exam) + extention) - - @cli.command() def new_exam(): """ Create new exam csv file """ - exam = prompt_exam() + exam = Exam(**prompt_exam()) - if get_exam_path(exam, ".yml").exists(): - with open(get_exam_path(exam, ".yml"), "r") as f: - exam["exercices"] = yaml.load(f, Loader=yaml.SafeLoader)["exercices"] - else: - exam["exercices"] = [] + print(f"Sauvegarde temporaire dans {exam.path('.yml')}") - for i, ex in enumerate(exam["exercices"]): - exam["exercices"][i] = prompt_exercise(**ex) + if exam.path(".yml").exists(): + print(f"Fichier sauvegarde trouvé à {exam.path('.yml')} -- importation") + with open(exam.path(".yml"), "r") as f: + for name, questions in yaml.load(f, Loader=yaml.SafeLoader)[ + "exercices" + ].items(): + exam.add_exercise(name, questions) + + # print(yaml.dump(exam.to_dict())) + + for name, questions in exam.exercices.items(): + exam.modify_exercise(**prompt_exercise(name=name, questions=questions)) new_exercise = prompt_validate("Ajouter un exercice? ") while new_exercise: - exam["exercices"].append(prompt_exercise(len(exam["exercices"])+1)) + exam.add_exercise(**prompt_exercise(len(exam.exercices) + 1)) new_exercise = prompt_validate("Ajouter un exercice? ") + print(yaml.dump(exam.to_dict())) - rows = exam_dict2row(exam) + rows = exam.to_row() base_df = pd.DataFrame.from_dict(rows)[NO_ST_COLUMNS.keys()] base_df.rename(columns=NO_ST_COLUMNS, inplace=True) - students = pd.read_csv(exam["tribe"]["students"])["Nom"] + students = pd.read_csv(exam.tribe_student_path)["Nom"] for student in students: base_df[student] = "" - path = Path(config["source"]) / exam["tribe"]["name"] - path.mkdir(exist_ok=True) + exam.tribe_path.mkdir(exist_ok=True) - dest = path / get_exam_name(exam) + ".csv" - base_df.to_csv(dest, index=False) - print(f"Le fichier note a été enregistré à {dest}") + base_df.to_csv(exam.path(".csv"), index=False) + print(f"Le fichier note a été enregistré à {exam.path('.csv')}") @cli.command()