From d363c6a8c17d71fa62c25429506005a67e667dec Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand Date: Thu, 23 Mar 2017 20:23:05 +0300 Subject: [PATCH] Move eval_tools to eval annd Start Student pov --- notes_tools/tools/eval.py | 144 ++++++++++++++++++++++++++++++++ notes_tools/tools/eval_tools.py | 108 ------------------------ 2 files changed, 144 insertions(+), 108 deletions(-) create mode 100644 notes_tools/tools/eval.py delete mode 100644 notes_tools/tools/eval_tools.py diff --git a/notes_tools/tools/eval.py b/notes_tools/tools/eval.py new file mode 100644 index 0000000..e9cc3e8 --- /dev/null +++ b/notes_tools/tools/eval.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import pandas as pd +import numpy as np + +class Student(object): + + """ + Informations on a student which can be use inside template. + + Those informations should not be modify or use for compute analysis otherwise they won't be spread over other POV. + """ + + def __init__(self, quest_df, exo_df, eval_df): + """ + Description of a student from quest, exo and eval + + """ + + name = {*quest_df["Eleve"].unique(), + *exo_df["Eleve"].unique(), + *eval_df["Eleve"].unique(), + } + + if len(name) != 1: + raise ValueError("Can't initiate Student: dfs contains different student names") + + self.name = name.pop() + + evalname = {*quest_df["Nom"].unique(), + *exo_df["Nom"].unique(), + *eval_df["Nom"].unique(), + } + + if len(evalname) != 1: + raise ValueError("Can't initiate Student: dfs contains different evaluation names") + + self.quest_df = quest_df + self.exo_df = exo_df + self.eval = eval_df.to_dict('records')[0] + + @property + def latex_exo_tabulars(self): + """ Return list of latex tabulars. One by exercise of the evaluation """ + try: + self._latex_exo_tabulars + except AttributeError: + self._latex_exo_tabulars = self.build_latex_exo_tabulars() + return self._latex_exo_tabulars + + def build_latex_exo_tabulars(self): + tabulars = [] + for t in self.exo_df["Exercice"]: + tabulars.append(self.build_latex_exo_tabular(t)) + + return tabulars + + def build_latex_exo_tabular(self, exo_name): + exo = self.exo_df[self.exo_df["Exercice"] == exo_name] + quest = self.quest_df[self.quest_df["Exercice"] == exo_name] + + tabular = [r"\begin{tabular}{|p{2cm}|c|}"] + tabular.append(r"\hline") + + if type(exo_name) == int: + tabular.append(f"Exercice {exo_name} & {exo['Mark_barem'].all()} \\\\") + else: + tabular.append(f"{exo_name} & {exo['Mark_barem'].all()} \\\\") + tabular.append(r"\hline") + + if len(quest) > 1: + for _, q in quest.iterrows(): + line = "" + if not pd.isnull(q["Question"]): + line += str(q['Question']) + if not pd.isnull(q["Commentaire"]): + line += str(q['Commentaire']) + + line += " & " + if q["Niveau"] == 1: + line += q['Latex_rep'] + else: + line += str(q['Mark']) + tabular.append(line) + tabular.append(r"\hline") + + tabular.append(r"\end{tabular}") + return '\n'.join(tabular) + + +class Classe(object): + + """ + Informations on a class which can be use inside template. + + Those informations should not be modify or use for compute analysis otherwise they won't be spread over other POV. + """ + pass + +# TODO: à factoriser Il y a la même dans term.py |jeu. mars 23 19:36:28 EAT 2017 +def select(quest_df, exo_df, eval_df, index, value): + """ Return quest, exo and eval rows which correspond index == value + + :param quest_df: TODO + :param exo_df: TODO + :param eval_df: TODO + + """ + qu = quest_df[quest_df[index] == value] + exo = exo_df[exo_df[index] == value] + ev = eval_df[eval_df[index] == value] + return qu, exo, ev + +def select_contains(quest_df, exo_df, eval_df, index, name_part): + """ Return quest, exo and eval rows which contains name_part + + :param quest_df: TODO + :param exo_df: TODO + :param eval_df: TODO + + """ + qu = quest_df[quest_df[index].str.contains(name_part)] + exo = exo_df[exo_df[index].str.contains(name_part)] + ev = eval_df[eval_df[index].str.contains(name_part)] + return qu, exo, ev + +def students_pov(quest_df, exo_df, eval_df): + es = [] + for e in eval_df["Eleve"].unique(): + d = select(quest_df, exo_df, eval_df, "Eleve", e) + eleve = Student(*d) + es.append(eleve) + return es + +def class_pov(quest_df, exo_df, eval_df): + return Classe(quest_df, exo_df, eval_df) + + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/notes_tools/tools/eval_tools.py b/notes_tools/tools/eval_tools.py deleted file mode 100644 index 88cb971..0000000 --- a/notes_tools/tools/eval_tools.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -import pandas as pd -import numpy as np - - -def select(quest_df, exo_df, eval_df, evalname): - """ Return quest, exo and eval rows which correspond to evalname - - :param quest_df: TODO - :param exo_df: TODO - :param eval_df: TODO - - """ - qu = quest_df[quest_df["Nom"] == evalname] - exo = exo_df[exo_df["Nom"] == evalname] - ev = eval_df[eval_df["Nom"] == evalname] - return qu, exo, ev - -def select_contains(quest_df, exo_df, eval_df, name_part): - """ Return quest, exo and eval rows which contains name_part - - :param quest_df: TODO - :param exo_df: TODO - :param eval_df: TODO - - """ - qu = quest_df[quest_df["Nom"].str.contains(name_part)] - exo = exo_df[exo_df["Nom"].str.contains(name_part)] - ev = eval_df[eval_df["Nom"].str.contains(name_part)] - return qu, exo, ev - -def get_present_absent(eval_df): - """ Return list of student who where present (Mark > 0) and - the list of those who weren't - - """ - presents = eval_df[eval_df["Mark"] > 0]["Eleve"] - absents = eval_df[eval_df["Mark"] == 0]["Eleve"] - return {"presents": presents, "absents": absents} - -def keep_only_presents(quest_df, exo_df, eval_df, presents): - """ Return quest, exo and eval rows of presents students """ - qu = quest_df[quest_df["Eleve"].isin(presents)] - exo = exo_df[exo_df["Eleve"].isin(presents)] - ev = eval_df[eval_df["Eleve"].isin(presents)] - return qu, exo, ev - -def students_pov(quest_df, exo_df, eval_df): - """ - - >>> from .df_marks_manip import digest_flat_df - >>> d = {"Eleve":["E1"]*6 + ["E2"]*6, - ... "Nom": ["N1"]*4+["N2"]*2 + ["N1"]*4+["N2"]*2, - ... "Exercice":["Ex1"]*2+["Ex2"]*2+["Ex1"]+["Ex2"] + ["Ex1"]*2+["Ex2"]*2+["Ex1"]+["Ex2"], - ... "Question":["Q1"]+["Q2"]+["Q1"]+["Q2"]+["Q1"]+["Q1"] + ["Q1"]+["Q2"]+["Q1"]+["Q2"]+["Q1"]+["Q1"], - ... "Date":["16/09/2016"]*4+["01/10/2016"]*2 + ["16/09/2016"]*4+["01/10/2016"]*2, - ... "Trimestre": ["1"]*12, - ... "Bareme":[1]*2+[2]*2+[2]*2 + [1]*2+[2]*2+[2]*2, - ... "Niveau":[0]*4+[1]*2 + [0]*4+[1]*2, - ... "Note":[1, 0.33, 2, 1.5, 1, 3, 0.666, 1, 1.5, 1, 2, 3], - ... } - >>> df = pd.DataFrame(d) - >>> quest_df, exo_df, eval_df = digest_flat_df(df) - >>> std_pov = students_pov(quest_df, exo_df, eval_df) - >>> std = std_pov[0] - >>> std["Nom"] - 'E1' - >>> "{} / {}".format(std["Total"]["Mark"], std["Total"]["Bareme"]) - '5.0 / 6.0' - >>> for exo in std["Exercices"]: - ... print("{}: {} / {}".format(exo["Nom"], exo["Total"]["Mark"], exo["Total"]["Bareme"])) - Ex1: 1.5 / 2.0 - Ex2: 3.5 / 4.0 - >>> exo = std["Exercices"][0] - >>> for _,q in exo["Questions"].iterrows(): - ... print("{} : {}".format(q["Question"], q["Latex_rep"])) - Q1 : 1.0 - Q2 : 0.33 - Q1 : \RepU - - """ - es = [] - for e in eval_df["Eleve"].unique(): - eleve = {"Nom":e} - e_quest = quest_df[quest_df["Eleve"] == e] - eleve["quest"] = e_quest - e_exo = exo_df[exo_df["Eleve"] == e] - #e_df = ds_df[ds_df["Eleve"] == e][["Exercice", "Question", "Bareme", "Commentaire", "Niveau", "Mark", "Latex_rep"]] - eleve["Total"] = eval_df[eval_df["Eleve"]==e].iloc[0] - - exos = [] - for exo in e_exo["Exercice"].unique(): - ex = {"Nom":exo} - ex["Total"] = e_exo[e_exo["Exercice"]==exo].iloc[0] - ex["Questions"] = e_quest[e_quest["Exercice"] == exo] - exos.append(ex) - eleve["Exercices"] = exos - - es.append(eleve) - return es - - -# ----------------------------- -# Reglages pour 'vim' -# vim:set autoindent expandtab tabstop=4 shiftwidth=4: -# cursor: 16 del