From 37e9cdd27f183640ded58fcb54c3ae3581df648a Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand Date: Fri, 10 Mar 2017 08:15:30 +0300 Subject: [PATCH] Change organisation in term report to use POV --- notes_tools/reports/term_pov.py | 176 ---------------------------- notes_tools/reports/term_reports.py | 13 +- notes_tools/tools/plottings.py | 4 +- notes_tools/tools/term_tools.py | 174 +++++++++++++++++++++++++-- 4 files changed, 171 insertions(+), 196 deletions(-) delete mode 100644 notes_tools/reports/term_pov.py diff --git a/notes_tools/reports/term_pov.py b/notes_tools/reports/term_pov.py deleted file mode 100644 index e98f7e1..0000000 --- a/notes_tools/reports/term_pov.py +++ /dev/null @@ -1,176 +0,0 @@ -#! /usr/bin/env python -# -*- coding: utf-8 -*- -# vim:fenc=utf-8 -# -# Copyright © 2017 lafrite -# -# Distributed under terms of the MIT license. - -""" -POV tools on term -""" - -from notes_tools.tools.marks_plottings import (pie_pivot_table, - parallel_on, - radar_on, - ) -import pandas as pd -import numpy as np - -__all__ = ["Student", "Classe"] - -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 - - """ - if len(quest_df["Eleve"].unique()) != 1: - raise ValueError("Can't initiate Student: quest_df contains different student names") - elif len(exo_df["Eleve"].unique()) != 1: - raise ValueError("Can't initiate Student: exo_df contains different student names") - elif len(eval_df["Eleve"].unique()) != 1: - raise ValueError("Can't initiate Student: eval_df contains different student names") - elif quest_df["Eleve"].iloc[0] != exo_df["Eleve"].iloc[0] or \ - quest_df["Eleve"].iloc[0] != eval_df["Eleve"].iloc[0]: - raise ValueError("Can't initiate Student: dfs contains different student names") - - self.name = quest_df["Eleve"].iloc[0] - - self.quest_df = quest_df - self.exo_df = exo_df - self.eval_df = eval_df - - @property - def marks_tabular(self): - """ Latex tabular with all of his marks of the term """ - try: - self._marks_tabular - except AttributeError: - self._marks_tabular = self.eval_df[["Nom", "Mark", "Bareme"]].to_latex() - return self._marks_tabular - - @property - def pies_on_competence(self): - """ Pies chart on competences """ - try: - self._pies_on_competence - except AttributeError: - self._pies_on_competence = pie_pivot_table(self.quest_df, - index = "Level", - columns = "Competence", - values = "Eleve", - aggfunc = len, - fill_value = 0, - ) - return self._pies_on_competence - - @property - def pies_on_domaine(self): - """ Pies chart on domaines """ - try: - self._pies_on_domaine - except AttributeError: - self._pies_on_domaine = pie_pivot_table(self.quest_df, - index = "Level", - columns = "Domaine", - values = "Eleve", - aggfunc = len, - fill_value = 0, - ) - return self._pies_on_domaine - - @property - def radar_on_competence(self): - """ Radar plot on competence """ - try: - self._radar_on_competence - except AttributeError: - self._radar_on_competence = radar_on(self.quest_df, - "Competence") - return self._radar_on_competence - - @property - def radar_on_domaine(self): - """ Radar plot on domaine """ - try: - self._radar_on_domaine - except AttributeError: - self._radar_on_domaine = radar_on(self.quest_df, - "Domaine") - return self._radar_on_domaine - - - def parallel_on_evals(self, classe_evals): - """ Parallel coordinate plot of the class with student line highlight """ - return parallel_on(classe_evals, "Nom", self.name) - -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. - """ - - def __init__(self, quest_df, exo_df, eval_df): - """ Init of a class from quest, exo and eval """ - self.quest_df = quest_df - self.exo_df = exo_df - self.eval_df = eval_df - - @property - def evals_tabular(self): - """ Summary of all evaluations for all students """ - try: - self._evals_tabular - except AttributeError: - self._evals_tabular = pd.pivot_table(self.eval_df, - index = "Eleve", - columns = "Nom", - values = "Mark_barem", - aggfunc = lambda x: " ".join(x)).to_latex() - return self._evals_tabular - - - @property - def parallel_on_evals(self): - """ Parallel coordinate plot of the class """ - return parallel_on(self.eval_df, "Nom") - - @property - def pies_eff_pts_on_competence(self): - """ Pie charts on competence with repartition of evaluated times and attributed points """ - return pie_pivot_table(self.quest_df, - index = "Competence", - #columns = "Level", - values = "Bareme", - aggfunc=[len,np.sum], - fill_value=0) - - @property - def pies_eff_pts_on_domaine(self): - """ Pie charts on domaine with repartition of evaluated times and attributed points """ - return pie_pivot_table(self.quest_df, - index = "Domaine", - #columns = "Level", - values = "Bareme", - aggfunc=[len,np.sum], - fill_value=0) - - - - - - -# ----------------------------- -# Reglages pour 'vim' -# vim:set autoindent expandtab tabstop=4 shiftwidth=4: -# cursor: 16 del diff --git a/notes_tools/reports/term_reports.py b/notes_tools/reports/term_reports.py index 8dcbd10..231e987 100755 --- a/notes_tools/reports/term_reports.py +++ b/notes_tools/reports/term_reports.py @@ -54,14 +54,17 @@ def term_report(classe, term, path = Path('./'), term_df = flat_df[flat_df['Trimestre'] == term] quest_df, exo_df, eval_df = digest_flat_df(term_df) - conn_df = exo_df[exo_df["Nom"].str.contains('Conn')] + #conn_df = exo_df[exo_df["Nom"].str.contains('Conn')] report_info = term_info(classe, eval_df) - students = term_tools.students_pov(quest_df, exo_df, eval_df) - datas = {"report_info": report_info, "students":students, - "quest_df":quest_df, "exo_df":exo_df, "eval_df":eval_df, - "conn_df": conn_df} + students_pov = term_tools.students_pov(quest_df, exo_df, eval_df) + class_pov = term_tools.class_pov(quest_df, exo_df, eval_df) + + datas = {"report_info": report_info, + "classe": class_pov, + "students":students_pov, + } target = build_target_name(classe, term, path) feed_template(target, datas, template) diff --git a/notes_tools/tools/plottings.py b/notes_tools/tools/plottings.py index a44fdbc..17bf107 100644 --- a/notes_tools/tools/plottings.py +++ b/notes_tools/tools/plottings.py @@ -80,8 +80,8 @@ def my_autopct(values): def pivot_table_to_pie(pv, pies_per_lines = 3): nbr_pies = len(pv.columns) - nbr_cols = min(pies_per_lines, nbr_pies) - nbr_rows = nbr_pies // nbr_cols + nbr_cols = pies_per_lines + nbr_rows = nbr_pies // nbr_cols + 1 f, axs = plt.subplots(nbr_rows, nbr_cols, figsize = (4*nbr_cols,4*nbr_rows)) for (c, ax) in zip(pv, axs.flatten()): datas = pv[c] diff --git a/notes_tools/tools/term_tools.py b/notes_tools/tools/term_tools.py index 5c75f81..1333a76 100644 --- a/notes_tools/tools/term_tools.py +++ b/notes_tools/tools/term_tools.py @@ -3,35 +3,183 @@ import pandas as pd import numpy as np +from notes_tools.tools.marks_plottings import (pie_pivot_table, + parallel_on, + radar_on, + ) + +__all__ = ["students_pov", "class_pov"] + +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 + + """ + if len(quest_df["Eleve"].unique()) != 1: + raise ValueError("Can't initiate Student: quest_df contains different student names") + elif len(exo_df["Eleve"].unique()) != 1: + raise ValueError("Can't initiate Student: exo_df contains different student names") + elif len(eval_df["Eleve"].unique()) != 1: + raise ValueError("Can't initiate Student: eval_df contains different student names") + elif quest_df["Eleve"].iloc[0] != exo_df["Eleve"].iloc[0] or \ + quest_df["Eleve"].iloc[0] != eval_df["Eleve"].iloc[0]: + raise ValueError("Can't initiate Student: dfs contains different student names") + + self.name = quest_df["Eleve"].iloc[0] + + self.quest_df = quest_df + self.exo_df = exo_df + self.eval_df = eval_df + + @property + def marks_tabular(self): + """ Latex tabular with all of his marks of the term """ + try: + self._marks_tabular + except AttributeError: + self._marks_tabular = self.eval_df[["Nom", "Mark_barem"]].to_latex() + return self._marks_tabular + + @property + def pies_on_competence(self): + """ Pies chart on competences """ + try: + self._pies_on_competence + except AttributeError: + self._pies_on_competence = pie_pivot_table(self.quest_df, + index = "Level", + columns = "Competence", + values = "Eleve", + aggfunc = len, + fill_value = 0, + ) + return self._pies_on_competence + + @property + def pies_on_domaine(self): + """ Pies chart on domaines """ + try: + self._pies_on_domaine + except AttributeError: + self._pies_on_domaine = pie_pivot_table(self.quest_df, + index = "Level", + columns = "Domaine", + values = "Eleve", + aggfunc = len, + fill_value = 0, + ) + return self._pies_on_domaine + + @property + def radar_on_competence(self): + """ Radar plot on competence """ + try: + self._radar_on_competence + except AttributeError: + self._radar_on_competence = radar_on(self.quest_df, + "Competence") + return self._radar_on_competence + + @property + def radar_on_domaine(self): + """ Radar plot on domaine """ + try: + self._radar_on_domaine + except AttributeError: + self._radar_on_domaine = radar_on(self.quest_df, + "Domaine") + return self._radar_on_domaine -def select(quest_df, exo_df, eval_df, term): - """ Return quest, exo and eval rows which correspond to evalname + def parallel_on_evals(self, classe_evals): + """ Parallel coordinate plot of the class with student line highlight """ + return parallel_on(classe_evals, "Nom", self.name) + +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. + """ + + def __init__(self, quest_df, exo_df, eval_df): + """ Init of a class from quest, exo and eval """ + self.quest_df = quest_df + self.exo_df = exo_df + self.eval_df = eval_df + + @property + def evals_tabular(self): + """ Summary of all evaluations for all students """ + try: + self._evals_tabular + except AttributeError: + self._evals_tabular = pd.pivot_table(self.eval_df, + index = "Eleve", + columns = "Nom", + values = "Mark_barem", + aggfunc = lambda x: " ".join(x)).to_latex() + return self._evals_tabular + + + @property + def parallel_on_evals(self): + """ Parallel coordinate plot of the class """ + return parallel_on(self.eval_df, "Nom") + + @property + def pies_eff_pts_on_competence(self): + """ Pie charts on competence with repartition of evaluated times and attributed points """ + return pie_pivot_table(self.quest_df, + index = "Competence", + #columns = "Level", + values = "Bareme", + aggfunc=[len,np.sum], + fill_value=0) + + @property + def pies_eff_pts_on_domaine(self): + """ Pie charts on domaine with repartition of evaluated times and attributed points """ + return pie_pivot_table(self.quest_df, + index = "Domaine", + #columns = "Level", + values = "Bareme", + aggfunc=[len,np.sum], + fill_value=0) + +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["Trimestre"] == term] - exo = exo_df[exo_df["Trimestre"] == term] - ev = eval_df[eval_df["Trimestre"] == term] + 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 students_pov(quest_df, exo_df, eval_df): 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] - eleve["exo"] = e_exo - e_eval = eval_df[eval_df["Eleve"] == e] - eleve["eval"] = e_eval + 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'