Compare commits
3 Commits
6eb918e0f5
...
27d7c45980
Author | SHA1 | Date | |
---|---|---|---|
27d7c45980 | |||
159e7a9f2e | |||
72afb26e2a |
132
recopytex/scripts/exam.py
Normal file
132
recopytex/scripts/exam.py
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
from prompt_toolkit import HTML
|
||||||
|
import yaml
|
||||||
|
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
|
||||||
|
|
||||||
|
@property
|
||||||
|
def themes(self):
|
||||||
|
themes = set()
|
||||||
|
for questions in self._exercises.values():
|
||||||
|
themes.update([q["theme"] for q in questions])
|
||||||
|
return themes
|
||||||
|
|
||||||
|
def display_exercise(self, name):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def display(self, name):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def write(self):
|
||||||
|
print(f"Sauvegarde temporaire dans {self.path('.yml')}")
|
||||||
|
self.tribe_path.mkdir(exist_ok=True)
|
||||||
|
with open(self.path(".yml"), "w") as f:
|
||||||
|
f.write(yaml.dump(self.to_dict()))
|
@ -133,18 +133,18 @@ def prompt_exam(**kwrd):
|
|||||||
|
|
||||||
|
|
||||||
@prompt_until_validate()
|
@prompt_until_validate()
|
||||||
def prompt_exercise(number=1, **kwrd):
|
def prompt_exercise(number=1, completer={}, **kwrd):
|
||||||
|
exercise = {}
|
||||||
try:
|
try:
|
||||||
kwrd["name"]
|
kwrd["name"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print(HTML("<b>Nouvel exercice</b>"))
|
print(HTML("<b>Nouvel exercice</b>"))
|
||||||
else:
|
|
||||||
print(HTML(f"<b>Modification de l'exercice: {kwrd['name']}</b>"))
|
|
||||||
|
|
||||||
exercise = {}
|
|
||||||
exercise["name"] = prompt(
|
exercise["name"] = prompt(
|
||||||
"Nom de l'exercice: ", default=kwrd.get("name", f"Exercice {number}")
|
"Nom de l'exercice: ", default=kwrd.get("name", f"Exercice {number}")
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
print(HTML(f"<b>Modification de l'exercice: {kwrd['name']}</b>"))
|
||||||
|
exercise["name"] = kwrd["name"]
|
||||||
|
|
||||||
exercise["questions"] = []
|
exercise["questions"] = []
|
||||||
|
|
||||||
@ -157,7 +157,9 @@ def prompt_exercise(number=1, **kwrd):
|
|||||||
else:
|
else:
|
||||||
for ques in kwrd["questions"]:
|
for ques in kwrd["questions"]:
|
||||||
try:
|
try:
|
||||||
exercise["questions"].append(prompt_question(**ques))
|
exercise["questions"].append(
|
||||||
|
prompt_question(completer=completer, **ques)
|
||||||
|
)
|
||||||
except CancelError:
|
except CancelError:
|
||||||
print("Cette question a été supprimée")
|
print("Cette question a été supprimée")
|
||||||
last_question_id = exercise["questions"][-1]["id"]
|
last_question_id = exercise["questions"][-1]["id"]
|
||||||
@ -167,7 +169,9 @@ def prompt_exercise(number=1, **kwrd):
|
|||||||
)
|
)
|
||||||
while appending:
|
while appending:
|
||||||
try:
|
try:
|
||||||
exercise["questions"].append(prompt_question(last_question_id))
|
exercise["questions"].append(
|
||||||
|
prompt_question(last_question_id, completer=completer)
|
||||||
|
)
|
||||||
except CancelError:
|
except CancelError:
|
||||||
print("Cette question a été supprimée")
|
print("Cette question a été supprimée")
|
||||||
else:
|
else:
|
||||||
@ -180,16 +184,14 @@ def prompt_exercise(number=1, **kwrd):
|
|||||||
|
|
||||||
|
|
||||||
@prompt_until_validate(cancelable=True)
|
@prompt_until_validate(cancelable=True)
|
||||||
def prompt_question(last_question_id="1a", **kwrd):
|
def prompt_question(last_question_id="1a", completer={}, **kwrd):
|
||||||
try:
|
try:
|
||||||
kwrd["id"]
|
kwrd["id"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print(HTML("<b>Nouvel élément de notation</b>"))
|
print(HTML("<b>Nouvel élément de notation</b>"))
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
HTML(
|
HTML(f"<b>Modification de l'élément {kwrd['id']} ({kwrd['comment']})</b>")
|
||||||
f"<b>Modification de l'élément {kwrd['id']} ({kwrd['comment']})</b>"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
question = {}
|
question = {}
|
||||||
@ -208,7 +210,7 @@ def prompt_question(last_question_id="1a", **kwrd):
|
|||||||
question["theme"] = prompt(
|
question["theme"] = prompt(
|
||||||
"Domaine: ",
|
"Domaine: ",
|
||||||
default=kwrd.get("theme", ""),
|
default=kwrd.get("theme", ""),
|
||||||
# completer
|
completer=WordCompleter(completer.get("theme", [])),
|
||||||
)
|
)
|
||||||
|
|
||||||
question["comment"] = prompt(
|
question["comment"] = prompt(
|
||||||
|
@ -12,6 +12,7 @@ import yaml
|
|||||||
from .getconfig import config, CONFIGPATH
|
from .getconfig import config, CONFIGPATH
|
||||||
from .prompts import prompt_exam, prompt_exercise, prompt_validate
|
from .prompts import prompt_exam, prompt_exercise, prompt_validate
|
||||||
from ..config import NO_ST_COLUMNS
|
from ..config import NO_ST_COLUMNS
|
||||||
|
from .exam import Exam
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
@ -35,70 +36,53 @@ def setup():
|
|||||||
print(f"The file {tribe['students']} does not exists")
|
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()
|
@cli.command()
|
||||||
def new_exam():
|
def new_exam():
|
||||||
""" Create new exam csv file """
|
""" Create new exam csv file """
|
||||||
exam = prompt_exam()
|
exam = Exam(**prompt_exam())
|
||||||
|
|
||||||
if get_exam_path(exam, ".yml").exists():
|
if exam.path(".yml").exists():
|
||||||
with open(get_exam_path(exam, ".yml"), "r") as f:
|
print(f"Fichier sauvegarde trouvé à {exam.path('.yml')} -- importation")
|
||||||
exam["exercices"] = yaml.load(f, Loader=yaml.SafeLoader)["exercices"]
|
with open(exam.path(".yml"), "r") as f:
|
||||||
else:
|
for name, questions in yaml.load(f, Loader=yaml.SafeLoader)[
|
||||||
exam["exercices"] = []
|
"exercices"
|
||||||
|
].items():
|
||||||
|
exam.add_exercise(name, questions)
|
||||||
|
|
||||||
for i, ex in enumerate(exam["exercices"]):
|
print(exam.themes)
|
||||||
exam["exercices"][i] = prompt_exercise(**ex)
|
# print(yaml.dump(exam.to_dict()))
|
||||||
|
|
||||||
|
exam.write()
|
||||||
|
|
||||||
|
for name, questions in exam.exercices.items():
|
||||||
|
exam.modify_exercise(
|
||||||
|
**prompt_exercise(
|
||||||
|
name=name, completer={"theme": exam.themes}, questions=questions
|
||||||
|
)
|
||||||
|
)
|
||||||
|
exam.write()
|
||||||
|
|
||||||
new_exercise = prompt_validate("Ajouter un exercice? ")
|
new_exercise = prompt_validate("Ajouter un exercice? ")
|
||||||
while new_exercise:
|
while new_exercise:
|
||||||
exam["exercices"].append(prompt_exercise(len(exam["exercices"])+1))
|
exam.add_exercise(
|
||||||
|
**prompt_exercise(len(exam.exercices) + 1, completer={"theme": exam.themes})
|
||||||
|
)
|
||||||
|
exam.write()
|
||||||
new_exercise = prompt_validate("Ajouter un exercice? ")
|
new_exercise = prompt_validate("Ajouter un exercice? ")
|
||||||
|
|
||||||
|
rows = exam.to_row()
|
||||||
rows = exam_dict2row(exam)
|
|
||||||
|
|
||||||
base_df = pd.DataFrame.from_dict(rows)[NO_ST_COLUMNS.keys()]
|
base_df = pd.DataFrame.from_dict(rows)[NO_ST_COLUMNS.keys()]
|
||||||
base_df.rename(columns=NO_ST_COLUMNS, inplace=True)
|
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:
|
for student in students:
|
||||||
base_df[student] = ""
|
base_df[student] = ""
|
||||||
|
|
||||||
path = Path(config["source"]) / exam["tribe"]["name"]
|
exam.tribe_path.mkdir(exist_ok=True)
|
||||||
path.mkdir(exist_ok=True)
|
|
||||||
|
|
||||||
dest = path / get_exam_name(exam) + ".csv"
|
base_df.to_csv(exam.path(".csv"), index=False)
|
||||||
base_df.to_csv(dest, index=False)
|
print(f"Le fichier note a été enregistré à {exam.path('.csv')}")
|
||||||
print(f"Le fichier note a été enregistré à {dest}")
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
|
Loading…
Reference in New Issue
Block a user