#!/usr/bin/env python # encoding: utf-8 import pandas as pd import numpy as np from notes_tools.tools.marks_plottings import (pie_pivot_table, parallel_on, radar_on, ) import seaborn as sns __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 """ 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() 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"]] self._marks_tabular.columns = ["Devoir", "Note"] return self._marks_tabular.to_latex() @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 @property def heatmap_on_domain(self): """ Heatmap over evals on domains """ try: self._heatmap_on_domain except AttributeError: comp = pd.pivot_table(self.quest_df, index = "Competence", columns = ["Date","Nom"], values = ["Normalized"], aggfunc = np.mean, ) comp.columns = [i[1].strftime("%Y-%m-%d") + "\n" + i[2] for i in comp.columns] self._heatmap_on_domain = sns.heatmap(comp) return self._heatmap_on_domain 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[["Competence", "Bareme", "Exercice", "Question", "Commentaire"]].drop_duplicates(), 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[["Domaine", "Bareme", "Exercice", "Question", "Commentaire"]].drop_duplicates(), 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[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(): 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