repytex/repytex/tools/term.py

197 lines
6.1 KiB
Python

#!/usr/bin/env python
# encoding: utf-8
import pandas as pd
import numpy as np
from repytex.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 """
return pie_pivot_table(self.quest_df,
index = "Level",
columns = "Competence",
values = "Eleve",
aggfunc = len,
fill_value = 0,
)
@property
def pies_on_domaine(self):
""" Pies chart on domaines """
return pie_pivot_table(self.quest_df,
index = "Level",
columns = "Domaine",
values = "Eleve",
aggfunc = len,
fill_value = 0,
)
@property
def radar_on_competence(self):
""" Radar plot on competence """
return radar_on(self.quest_df,
"Competence")
@property
def radar_on_domaine(self):
""" Radar plot on domaine """
return radar_on(self.quest_df,
"Domaine")
@property
def heatmap_on_domain(self):
""" Heatmap over evals on domains """
comp = pd.pivot_table(self.quest_df,
index = "Domaine",
columns = ["Date","Nom"],
values = ["Normalized"],
aggfunc = np.mean,
)
comp.columns = [i[1].strftime("%Y-%m-%d") + "\n" + i[2] for i in comp.columns]
return sns.heatmap(comp)
@property
def heatmap_on_competence(self):
""" Heatmap over evals on competences """
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]
return sns.heatmap(comp)
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