import work
This commit is contained in:
parent
c74dbe666e
commit
e0748227c9
295
df_marks_manip.py
Normal file
295
df_marks_manip.py
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
from math import ceil
|
||||||
|
|
||||||
|
# Values manipulations
|
||||||
|
|
||||||
|
def round_half_point(val):
|
||||||
|
try:
|
||||||
|
return 0.5 * ceil(2.0 * val)
|
||||||
|
except ValueError:
|
||||||
|
return val
|
||||||
|
|
||||||
|
latex_caract = ["\\NoRep", "\\RepZ", "\\RepU", "\\RepD", "\\RepT"]
|
||||||
|
def note_to_rep(x):
|
||||||
|
r""" Transform a Note to the latex caracter
|
||||||
|
|
||||||
|
>>> 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)
|
||||||
|
>>> note_to_rep(df.loc[0])
|
||||||
|
1.0
|
||||||
|
>>> note_to_rep(df.loc[4])
|
||||||
|
'\\RepU'
|
||||||
|
"""
|
||||||
|
if x["Niveau"]:
|
||||||
|
if pd.isnull(x["Note"]):
|
||||||
|
return latex_caract[0]
|
||||||
|
elif x["Note"] in range(4):
|
||||||
|
return latex_caract[int(x["Note"])+1]
|
||||||
|
return x["Note"]
|
||||||
|
|
||||||
|
def note_to_mark(x):
|
||||||
|
""" Compute the mark when it is a "Nivea" note
|
||||||
|
|
||||||
|
>>> 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)
|
||||||
|
>>> note_to_mark(df.loc[0])
|
||||||
|
1.0
|
||||||
|
>>> note_to_mark(df.loc[10])
|
||||||
|
1.3333333333333333
|
||||||
|
"""
|
||||||
|
|
||||||
|
if x["Niveau"]:
|
||||||
|
return x["Note"] * x["Bareme"] / 3
|
||||||
|
return x["Note"]
|
||||||
|
|
||||||
|
# DataFrame columns manipulations
|
||||||
|
|
||||||
|
def compute_marks(df):
|
||||||
|
""" Add Mark column to 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)
|
||||||
|
>>> compute_marks(df)
|
||||||
|
0 1.000000
|
||||||
|
1 0.330000
|
||||||
|
2 2.000000
|
||||||
|
3 1.500000
|
||||||
|
4 0.666667
|
||||||
|
5 2.000000
|
||||||
|
6 0.666000
|
||||||
|
7 1.000000
|
||||||
|
8 1.500000
|
||||||
|
9 1.000000
|
||||||
|
10 1.333333
|
||||||
|
11 2.000000
|
||||||
|
dtype: float64
|
||||||
|
"""
|
||||||
|
return df[["Note", "Niveau", "Bareme"]].apply(note_to_mark, axis=1).fillna(0)
|
||||||
|
|
||||||
|
def compute_latex_rep(df):
|
||||||
|
""" Add Latex_rep column to 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)
|
||||||
|
>>> compute_latex_rep(df)
|
||||||
|
0 1
|
||||||
|
1 0.33
|
||||||
|
2 2
|
||||||
|
3 1.5
|
||||||
|
4 \RepU
|
||||||
|
5 \RepT
|
||||||
|
6 0.666
|
||||||
|
7 1
|
||||||
|
8 1.5
|
||||||
|
9 1
|
||||||
|
10 \RepD
|
||||||
|
11 \RepT
|
||||||
|
dtype: object
|
||||||
|
"""
|
||||||
|
return df[["Note", "Niveau"]].apply(note_to_rep, axis=1).fillna("??")
|
||||||
|
|
||||||
|
# Computing custom values
|
||||||
|
|
||||||
|
def compute_exo_marks(df):
|
||||||
|
""" Compute Exercice level marks
|
||||||
|
|
||||||
|
:param df: the original marks
|
||||||
|
:returns: DataFrame with computed marks
|
||||||
|
|
||||||
|
>>> 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)
|
||||||
|
>>> df["Mark"] = compute_marks(df)
|
||||||
|
>>> compute_exo_marks(df)
|
||||||
|
Eleve Nom Exercice Date Trimestre Bareme Mark Question Niveau
|
||||||
|
0 E1 N1 Ex1 16/09/2016 1 2 1.5 Total 0
|
||||||
|
1 E1 N1 Ex2 16/09/2016 1 4 3.5 Total 0
|
||||||
|
2 E1 N2 Ex1 01/10/2016 1 2 1.0 Total 0
|
||||||
|
3 E1 N2 Ex2 01/10/2016 1 2 2.0 Total 0
|
||||||
|
4 E2 N1 Ex1 16/09/2016 1 2 2.0 Total 0
|
||||||
|
5 E2 N1 Ex2 16/09/2016 1 4 2.5 Total 0
|
||||||
|
6 E2 N2 Ex1 01/10/2016 1 2 1.5 Total 0
|
||||||
|
7 E2 N2 Ex2 01/10/2016 1 2 2.0 Total 0
|
||||||
|
|
||||||
|
"""
|
||||||
|
exo_pt = pd.pivot_table(df,
|
||||||
|
index = [ "Eleve", "Nom", "Exercice", "Date", "Trimestre"],
|
||||||
|
values = ["Bareme", "Mark"],
|
||||||
|
aggfunc=np.sum,
|
||||||
|
).applymap(round_half_point)
|
||||||
|
|
||||||
|
exo = exo_pt.reset_index()
|
||||||
|
exo["Question"] = "Total"
|
||||||
|
exo["Niveau"] = 0
|
||||||
|
return exo
|
||||||
|
|
||||||
|
def compute_eval_marks(df):
|
||||||
|
""" Compute Nom level marks from the dataframe using only row with Total in Question
|
||||||
|
|
||||||
|
:param df: DataFrame with value Total in Question column
|
||||||
|
:returns: DataFrame with evaluation marks
|
||||||
|
|
||||||
|
>>> 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)
|
||||||
|
>>> df["Mark"] = compute_marks(df)
|
||||||
|
>>> df_exo = compute_exo_marks(df)
|
||||||
|
>>> compute_eval_marks(df_exo)
|
||||||
|
Eleve Nom Date Trimestre Bareme Mark Exercice Niveau
|
||||||
|
0 E1 N1 16/09/2016 1 6 5.0 Total 0
|
||||||
|
1 E1 N2 01/10/2016 1 4 3.0 Total 0
|
||||||
|
2 E2 N1 16/09/2016 1 6 4.5 Total 0
|
||||||
|
3 E2 N2 01/10/2016 1 4 3.5 Total 0
|
||||||
|
|
||||||
|
"""
|
||||||
|
exo = df[df["Question"] == "Total"]
|
||||||
|
eval_pt = pd.pivot_table(exo,
|
||||||
|
index = [ "Eleve", "Nom", "Date", "Trimestre"],
|
||||||
|
values = ["Bareme", "Mark"],
|
||||||
|
aggfunc=np.sum,
|
||||||
|
).applymap(round_half_point)
|
||||||
|
|
||||||
|
eval_m = eval_pt.reset_index()
|
||||||
|
eval_m["Exercice"] = "Total"
|
||||||
|
eval_m["Niveau"] = 0
|
||||||
|
return eval_m
|
||||||
|
|
||||||
|
def digest_flat_df(flat_df):
|
||||||
|
""" Compute necessary element to make a flat df usable for analysis.
|
||||||
|
|
||||||
|
>>> 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)
|
||||||
|
"""
|
||||||
|
df = flat_df.copy()
|
||||||
|
df["Mark"] = compute_marks(flat_df)
|
||||||
|
df["Latex_rep"] = compute_latex_rep(flat_df)
|
||||||
|
|
||||||
|
exo_df = compute_exo_marks(df)
|
||||||
|
eval_df = compute_eval_marks(exo_df)
|
||||||
|
|
||||||
|
return df, exo_df, eval_df
|
||||||
|
|
||||||
|
def students_pov(quest_df, exo_df, eval_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]
|
||||||
|
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
|
134
extract.py
Normal file
134
extract.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
import xlrd
|
||||||
|
from path import Path
|
||||||
|
|
||||||
|
|
||||||
|
notes_path = Path("./")
|
||||||
|
notStudent = ["Trimestre", "Nom", "Date", "Exercice", "Question", "Competence", "Domaine", "Commentaire", "Bareme", "Niveau"]
|
||||||
|
pure_marks = ["Malus", "Bonus", "Presentation"]
|
||||||
|
|
||||||
|
def list_classes(path = notes_path):
|
||||||
|
"""
|
||||||
|
List classes available in notes_path
|
||||||
|
|
||||||
|
>>> list_classes()
|
||||||
|
['509', '503', '308', '312']
|
||||||
|
>>> p = Path("./")
|
||||||
|
>>> list_classes(p)
|
||||||
|
['509', '503', '308', '312']
|
||||||
|
>>> list_classes("./")
|
||||||
|
['509', '503', '308', '312']
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return [n.namebase for n in path.files("*.xlsx")]
|
||||||
|
except AttributeError:
|
||||||
|
p = Path(path)
|
||||||
|
return [n.namebase for n in p.files("*.xlsx")]
|
||||||
|
|
||||||
|
def get_class_ws(classe, path = notes_path):
|
||||||
|
"""
|
||||||
|
From the name of a classe, returns pd.ExcelFile
|
||||||
|
"""
|
||||||
|
if classe in list_classes(path):
|
||||||
|
return pd.ExcelFile(notes_path/classe+".xlsx")
|
||||||
|
else:
|
||||||
|
raise ValueError("This class is not disponible in {p}. You have to choose in {c}".format(p = path, c = list_classes(path)))
|
||||||
|
|
||||||
|
def extract_students(df, notStudent = notStudent):
|
||||||
|
""" Extract the list of students from df """
|
||||||
|
students = df.columns.difference(notStudent)
|
||||||
|
return students
|
||||||
|
|
||||||
|
def check_students(dfs, notStudent = notStudent):
|
||||||
|
""" Build students list """
|
||||||
|
dfs_students = [extract_students(df) for df in dfs]
|
||||||
|
|
||||||
|
if not are_equal(dfs_students):
|
||||||
|
raise ValueError("Not same list of students between df1 = {} ans df2 = {}".format(df1, df2))
|
||||||
|
|
||||||
|
return dfs_students[0]
|
||||||
|
|
||||||
|
def are_equal(elems):
|
||||||
|
""" Test if item of elems are equal
|
||||||
|
|
||||||
|
>>> L = [[1, 2, 3], [1, 3, 2], [1, 3, 2]]
|
||||||
|
>>> are_equal(L)
|
||||||
|
True
|
||||||
|
>>> L = [[0, 2, 3], [1, 3, 2], [1, 3, 2]]
|
||||||
|
>>> are_equal(L)
|
||||||
|
False
|
||||||
|
|
||||||
|
"""
|
||||||
|
first = sorted(elems[0])
|
||||||
|
others = [sorted(e) for e in elems[1:]]
|
||||||
|
diff = [e == first for e in others]
|
||||||
|
|
||||||
|
if False in diff:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def flat_df_students(df, students):
|
||||||
|
""" Flat the ws for students """
|
||||||
|
flat_df = pd.DataFrame()
|
||||||
|
flat_data = []
|
||||||
|
dfT = df.T
|
||||||
|
for n in dfT:
|
||||||
|
pre_di = dfT[n][notStudent].to_dict()
|
||||||
|
for e in students:
|
||||||
|
data = pre_di.copy()
|
||||||
|
data["Eleve"] = e
|
||||||
|
data["Note"] = dfT[n].loc[e]
|
||||||
|
flat_data.append(data)
|
||||||
|
return pd.DataFrame.from_dict(flat_data)
|
||||||
|
|
||||||
|
def get_all_marks(ws, marks_sheetnames = ["Notes", "Connaissances", "Calcul mental"]):
|
||||||
|
""" Extract marks from marks_sheetnames
|
||||||
|
|
||||||
|
:param ws: TODO
|
||||||
|
:returns: TODO
|
||||||
|
|
||||||
|
"""
|
||||||
|
for sheetname in marks_sheetnames:
|
||||||
|
try:
|
||||||
|
marks = ws.parse(sheetname)
|
||||||
|
except xlrd.biffh.XLRDError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def extract_flat_marks(ws):
|
||||||
|
""" Extract, flat and contact marks from the worksheet
|
||||||
|
|
||||||
|
:param ws: TODO
|
||||||
|
:returns: TODO
|
||||||
|
|
||||||
|
"""
|
||||||
|
marks_sheetnames = ["Notes", "Connaissances", "Calcul mental"]
|
||||||
|
|
||||||
|
sheets = []
|
||||||
|
for sheetname in marks_sheetnames:
|
||||||
|
try:
|
||||||
|
sheets.append(ws.parse(sheetname))
|
||||||
|
except xlrd.biffh.XLRDError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
students = check_students(sheets)
|
||||||
|
|
||||||
|
flat_df = pd.DataFrame()
|
||||||
|
for sheet in sheets:
|
||||||
|
flat = flat_df_students(sheet, students)
|
||||||
|
flat_df = pd.concat([flat_df, flat])
|
||||||
|
|
||||||
|
return flat_df
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Reglages pour 'vim'
|
||||||
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
# cursor: 16 del
|
118
generate_bilan.py
Executable file
118
generate_bilan.py
Executable file
@ -0,0 +1,118 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
from extract import extract_flat_marks, get_class_ws
|
||||||
|
from df_marks_manip import digest_flat_df, students_pov
|
||||||
|
from opytex import texenv
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
import optparse
|
||||||
|
import xlrd
|
||||||
|
|
||||||
|
notStudent = ["Trimestre", "Nom", "Date", "Exercice", "Question", "Competence", "Domaine", "Commentaire", "Bareme", "Niveau"]
|
||||||
|
pure_marks = ["Malus", "Bonus", "Presentation"]
|
||||||
|
|
||||||
|
def extract_students(df, notStudent = notStudent):
|
||||||
|
""" Extract the list of students from df """
|
||||||
|
students = df.columns.difference(notStudent)
|
||||||
|
return students
|
||||||
|
|
||||||
|
def build_students(df1, df2, notStudent = notStudent):
|
||||||
|
""" Build students list """
|
||||||
|
students_from_notes = extract_students(df1, notStudent)
|
||||||
|
students_from_conn = extract_students(df2, notStudent)
|
||||||
|
if students_from_conn.equals(students_from_notes):
|
||||||
|
return students_from_conn
|
||||||
|
else:
|
||||||
|
raise ValueError("Not same list of students between df1 = {} ans df2 = {}".format(df1, df2))
|
||||||
|
|
||||||
|
def flat_df_students(df, students):
|
||||||
|
""" Flat the ws for students """
|
||||||
|
flat_df = pd.DataFrame()
|
||||||
|
flat_data = []
|
||||||
|
dfT = df.T
|
||||||
|
for n in dfT:
|
||||||
|
pre_di = dfT[n][notStudent].to_dict()
|
||||||
|
for e in students:
|
||||||
|
data = pre_di.copy()
|
||||||
|
data["Eleve"] = e
|
||||||
|
data["Note"] = dfT[n].loc[e]
|
||||||
|
flat_data.append(data)
|
||||||
|
return pd.DataFrame.from_dict(flat_data)
|
||||||
|
|
||||||
|
def select_ds(ds_name, flat_df):
|
||||||
|
"""TODO: Docstring for select_ds.
|
||||||
|
|
||||||
|
:param ds_name: TODO
|
||||||
|
:param flat_df: TODO
|
||||||
|
:returns: TODO
|
||||||
|
|
||||||
|
"""
|
||||||
|
ds = flat_df[flat_df["Nom"] == ds_name]
|
||||||
|
if len(ds) == 0:
|
||||||
|
raise ValueError("{} is not a registered evaluation".format(ds_name))
|
||||||
|
return ds
|
||||||
|
|
||||||
|
def build_ds_info(classe, ds_df):
|
||||||
|
"""TODO: Docstring for build_ds_info.
|
||||||
|
|
||||||
|
:param ds_df: TODO
|
||||||
|
:returns: TODO
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: vérifier que toutes ces informations soient identiques sur les lignes |dim. nov. 6 16:06:58 EAT 2016
|
||||||
|
"""
|
||||||
|
ds_info = {}
|
||||||
|
ds_info["Classe"] = classe
|
||||||
|
ds_info["Nom"] = ds_df["Nom"].unique()[0]
|
||||||
|
ds_info["Date"] = pd.to_datetime(ds_df["Date"].unique()[0]).strftime("%d-%m-%Y")
|
||||||
|
ds_info["Trimestre"] = ds_df["Trimestre"].unique()[0]
|
||||||
|
return ds_info
|
||||||
|
|
||||||
|
def build_target_name(classe, ds_name):
|
||||||
|
return "./" + classe + "/bilan_" + ds_name + ".tex"
|
||||||
|
|
||||||
|
def feed_bilan(target, datas, template = "./tpl_bilan.tex"):
|
||||||
|
""" get the template and feed it to create bilans
|
||||||
|
|
||||||
|
:param ???:
|
||||||
|
:param datas: dictonnary to feed the template
|
||||||
|
:param template: the template
|
||||||
|
"""
|
||||||
|
bilan = texenv.get_template(template)
|
||||||
|
with open(target, "w") as f:
|
||||||
|
f.write(bilan.render(**datas))
|
||||||
|
print("{} est construit! Ya plus qu'à compiler!".format(target))
|
||||||
|
|
||||||
|
def build_bilan(classe, ds_name):
|
||||||
|
ws = get_class_ws(classe)
|
||||||
|
|
||||||
|
flat_df = extract_flat_marks(ws)
|
||||||
|
quest_df, exo_df, eval_df = digest_flat_df(flat_df)
|
||||||
|
|
||||||
|
quest_df = select_ds(ds_name, quest_df)
|
||||||
|
exo_df = select_ds(ds_name, exo_df)
|
||||||
|
eval_df = select_ds(ds_name, eval_df)
|
||||||
|
|
||||||
|
ds_info = build_ds_info(classe, eval_df)
|
||||||
|
students_df = students_pov(quest_df, exo_df, eval_df)
|
||||||
|
|
||||||
|
datas = {"ds_info": ds_info, "students":students_df}
|
||||||
|
|
||||||
|
target = build_target_name(classe, ds_name)
|
||||||
|
feed_bilan(target, datas)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
parser.add_option("-c","--classe",action="store",type="string",dest="classe", help="The classe")
|
||||||
|
parser.add_option("-e","--evaluation",action="store",type="string",dest="ds_name", help="The evaluation name.")
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
build_bilan(options.classe, options.ds_name)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Reglages pour 'vim'
|
||||||
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
# cursor: 16 del
|
88
tpl_bilan.tex
Normal file
88
tpl_bilan.tex
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
\documentclass{/media/documents/Cours/Prof/Enseignements/2016-2017/tools/style/classBilan}
|
||||||
|
\usepackage{/media/documents/Cours/Prof/Enseignements/2016-2017/theme}
|
||||||
|
|
||||||
|
\usepackage{multicol}
|
||||||
|
|
||||||
|
% Title Page
|
||||||
|
\titre{\Var{ds_info["Nom"]}}
|
||||||
|
% \seconde \premiereS \PSTMG \TSTMG
|
||||||
|
\classe{\Var{ds_info["Classe"]}}
|
||||||
|
\date{\Var{ds_info["Date"]}}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\Block{for e in students}
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
\begin{minipage}{0.5\linewidth}
|
||||||
|
\large
|
||||||
|
\Var{e["Nom"]}
|
||||||
|
\end{minipage}
|
||||||
|
\begin{minipage}{0.3\linewidth}
|
||||||
|
\begin{flushright}
|
||||||
|
\Large \Var{e["Total"]["Mark"]} / \Var{e["Total"]["Bareme"]}
|
||||||
|
\end{flushright}
|
||||||
|
\end{minipage}
|
||||||
|
|
||||||
|
\vfill
|
||||||
|
|
||||||
|
\fbox{%
|
||||||
|
\begin{minipage}{0.9\linewidth}
|
||||||
|
\hfill
|
||||||
|
\vspace{3cm}
|
||||||
|
\end{minipage}
|
||||||
|
}
|
||||||
|
|
||||||
|
\vfill
|
||||||
|
|
||||||
|
\scriptsize
|
||||||
|
\begin{multicols}{3}
|
||||||
|
|
||||||
|
\Block{for exo in e["Exercices"]}
|
||||||
|
\begin{tabular}{|p{2cm}|c|}
|
||||||
|
|
||||||
|
\Block{if exo["Nom"] in ["Bonus", "Malus", "Presentation"]}
|
||||||
|
\Block{for _,q in exo["Questions"].iterrows()}
|
||||||
|
\Block{if q["Mark"]}
|
||||||
|
\hline
|
||||||
|
\rowcolor{highlightbg}
|
||||||
|
\Var{exo["Nom"]} (\Var{q["Question"]}) & \Var{q["Latex_rep"]} \\
|
||||||
|
\Block{endif}
|
||||||
|
\Block{endfor}
|
||||||
|
\Block{else}
|
||||||
|
|
||||||
|
\hline
|
||||||
|
\rowcolor{highlightbg}
|
||||||
|
Exerice \Var{exo["Nom"]} & \Var{exo["Total"]["Mark"]} / \Var{exo["Total"]["Bareme"]} \\
|
||||||
|
\Block{for _,q in exo["Questions"].iterrows()}
|
||||||
|
\hline
|
||||||
|
\Var{q["Question"]} \newline \Var{q["Commentaire"]} & \Var{q["Latex_rep"]} \\
|
||||||
|
\Block{endfor}
|
||||||
|
\Block{endif}
|
||||||
|
|
||||||
|
|
||||||
|
\hline
|
||||||
|
\end{tabular}
|
||||||
|
\Block{endfor}
|
||||||
|
\end{multicols}
|
||||||
|
\vfill
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
Pas de réponse \NoRep \hfill
|
||||||
|
Tout faux \RepZ \hfill
|
||||||
|
Beaucoup d'erreurs \RepU \hfill
|
||||||
|
Quelques erreurs \RepD \hfill
|
||||||
|
Juste \RepT \hfill
|
||||||
|
\end{center}
|
||||||
|
\normalsize
|
||||||
|
\pagebreak
|
||||||
|
\Block{endfor}
|
||||||
|
|
||||||
|
\end{document}
|
||||||
|
|
||||||
|
%%% Local Variables:
|
||||||
|
%%% mode: latex
|
||||||
|
%%% TeX-master: "master"
|
||||||
|
%%% End:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user