reorga files
This commit is contained in:
13
notes_tools/tools/__init__.py
Normal file
13
notes_tools/tools/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/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
|
||||
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
||||
341
notes_tools/tools/df_marks_manip.py
Normal file
341
notes_tools/tools/df_marks_manip.py
Normal file
@@ -0,0 +1,341 @@
|
||||
#!/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
|
||||
|
||||
:param x: dictionnary with "Niveau" and "Note" keys
|
||||
|
||||
>>> 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
|
||||
|
||||
:param x: dictionnary with "Niveau", "Note" and "Bareme" keys
|
||||
|
||||
>>> 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
|
||||
|
||||
:param df: DataFrame with "Note", "Niveau" and "Bareme" columns.
|
||||
|
||||
>>> 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
|
||||
|
||||
:param df: DataFrame with "Note" and "Niveau" columns.
|
||||
|
||||
>>> 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("??")
|
||||
|
||||
def compute_normalized(df):
|
||||
""" Compute the normalized mark (Mark / Bareme)
|
||||
|
||||
:param df: DataFrame with "Mark" and "Bareme" columns
|
||||
|
||||
>>> 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_normalized(df)
|
||||
0 1.000000
|
||||
1 0.330000
|
||||
2 1.000000
|
||||
3 0.750000
|
||||
4 0.333333
|
||||
5 1.000000
|
||||
6 0.666000
|
||||
7 1.000000
|
||||
8 0.750000
|
||||
9 0.500000
|
||||
10 0.666667
|
||||
11 1.000000
|
||||
dtype: float64
|
||||
"""
|
||||
return df["Mark"] / df["Bareme"]
|
||||
|
||||
# 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.0 1.5 Total 0
|
||||
1 E1 N1 Ex2 16/09/2016 1 4.0 3.5 Total 0
|
||||
2 E1 N2 Ex1 01/10/2016 1 2.0 1.0 Total 0
|
||||
3 E1 N2 Ex2 01/10/2016 1 2.0 2.0 Total 0
|
||||
4 E2 N1 Ex1 16/09/2016 1 2.0 2.0 Total 0
|
||||
5 E2 N1 Ex2 16/09/2016 1 4.0 2.5 Total 0
|
||||
6 E2 N2 Ex1 01/10/2016 1 2.0 1.5 Total 0
|
||||
7 E2 N2 Ex2 01/10/2016 1 2.0 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.0 5.0 Total 0
|
||||
1 E1 N2 01/10/2016 1 4.0 3.0 Total 0
|
||||
2 E2 N1 16/09/2016 1 6.0 4.5 Total 0
|
||||
3 E2 N2 01/10/2016 1 4.0 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)
|
||||
df["Normalized"] = compute_normalized(df)
|
||||
|
||||
exo_df = compute_exo_marks(df)
|
||||
exo_df["Normalized"] = compute_normalized(exo_df)
|
||||
eval_df = compute_eval_marks(exo_df)
|
||||
eval_df["Normalized"] = compute_normalized(eval_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
|
||||
133
notes_tools/tools/extract.py
Normal file
133
notes_tools/tools/extract.py
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/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"]
|
||||
|
||||
def list_classes(path = notes_path):
|
||||
"""
|
||||
List classes available in notes_path
|
||||
|
||||
>>> list_classes()
|
||||
[]
|
||||
>>> p = Path("./samples/")
|
||||
>>> list_classes(p)
|
||||
['503', '312', '308']
|
||||
>>> list_classes("./samples/")
|
||||
['503', '312', '308']
|
||||
"""
|
||||
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
|
||||
"""
|
||||
p = Path(path)
|
||||
if classe in list_classes(p):
|
||||
return pd.ExcelFile(p/classe+".xlsx")
|
||||
else:
|
||||
raise ValueError("This class is not disponible in {p}. You have to choose in {c}".format(p = p, c = list_classes(p)))
|
||||
|
||||
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 parse_sheets(ws,
|
||||
marks_sheetnames = ["Notes", "Connaissances", "Calcul mental"]):
|
||||
""" Parse sheets from marks_sheetnames
|
||||
|
||||
:param ws: the worksheet
|
||||
:param marks_sheetnames: names of sheets for extracting
|
||||
|
||||
"""
|
||||
sheets = []
|
||||
for sheetname in marks_sheetnames:
|
||||
try:
|
||||
sheets.append(ws.parse(sheetname))
|
||||
except xlrd.biffh.XLRDError:
|
||||
pass
|
||||
return sheets
|
||||
|
||||
def extract_flat_marks(ws,
|
||||
marks_sheetnames=["Notes", "Connaissances", "Calcul mental"]):
|
||||
""" Extract, flat and contact marks from the worksheet
|
||||
|
||||
:param ws: the worksheet
|
||||
:param marks_sheetnames: name of worksheets
|
||||
:returns: TODO
|
||||
|
||||
"""
|
||||
sheets = parse_sheets(ws, marks_sheetnames)
|
||||
|
||||
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
|
||||
62
notes_tools/tools/test/test_df_marks_manip.py
Normal file
62
notes_tools/tools/test/test_df_marks_manip.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
from notes_tools.tools import df_marks_manip
|
||||
import pandas
|
||||
|
||||
|
||||
def test_round_half_point():
|
||||
assert df_marks_manip.round_half_point(2) == 2
|
||||
assert df_marks_manip.round_half_point(2.1) == 2.5
|
||||
assert df_marks_manip.round_half_point(2.4) == 2.5
|
||||
assert df_marks_manip.round_half_point(2.6) == 3
|
||||
assert df_marks_manip.round_half_point(2.9) == 3
|
||||
assert df_marks_manip.round_half_point(pandas.np.nan)
|
||||
|
||||
def test_note_to_rep():
|
||||
d = {"Niveau": 1, "Note": 0}
|
||||
assert df_marks_manip.note_to_rep(d) == "\\RepZ"
|
||||
|
||||
d = {"Niveau": 1, "Note": 1}
|
||||
assert df_marks_manip.note_to_rep(d) == "\\RepU"
|
||||
|
||||
d = {"Niveau": 1, "Note": 2}
|
||||
assert df_marks_manip.note_to_rep(d) == "\\RepD"
|
||||
|
||||
d = {"Niveau": 1, "Note": 3}
|
||||
assert df_marks_manip.note_to_rep(d) == "\\RepT"
|
||||
|
||||
d = {"Niveau": 1, "Note": None}
|
||||
assert df_marks_manip.note_to_rep(d) == "\\NoRep"
|
||||
|
||||
d = {"Niveau": 1, "Note": pandas.np.nan}
|
||||
assert df_marks_manip.note_to_rep(d) == "\\NoRep"
|
||||
|
||||
d = {"Niveau": 0, "Note": "plop"}
|
||||
assert df_marks_manip.note_to_rep(d) == "plop"
|
||||
|
||||
d = {"Niveau": 0, "Note": 1}
|
||||
assert df_marks_manip.note_to_rep(d) == 1
|
||||
|
||||
|
||||
def test_note_to_mark():
|
||||
d = {"Niveau": 1, "Note": 0, "Bareme": 6}
|
||||
assert df_marks_manip.note_to_mark(d) == 6/3*0
|
||||
|
||||
d = {"Niveau": 1, "Note": 1, "Bareme": 6}
|
||||
assert df_marks_manip.note_to_mark(d) == 6/3*1
|
||||
|
||||
d = {"Niveau": 1, "Note": 2, "Bareme": 6}
|
||||
assert df_marks_manip.note_to_mark(d) == 6/3*2
|
||||
|
||||
d = {"Niveau": 1, "Note": 3, "Bareme": 6}
|
||||
assert df_marks_manip.note_to_mark(d) == 6/3*3
|
||||
|
||||
d = {"Niveau": 0, "Note": 3, "Bareme": 6}
|
||||
assert df_marks_manip.note_to_mark(d) == 3
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
||||
59
notes_tools/tools/test/test_extract.py
Normal file
59
notes_tools/tools/test/test_extract.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
from notes_tools.tools import extract
|
||||
import pandas
|
||||
import pytest
|
||||
|
||||
|
||||
sample_path = "./samples/"
|
||||
|
||||
def test_list_classes():
|
||||
clss = extract.list_classes(sample_path)
|
||||
assert clss == ["503", "312", "308"]
|
||||
|
||||
def test_get_class_ws_raise():
|
||||
with pytest.raises(Exception) as e_info:
|
||||
extract.get_class_ws("312")
|
||||
|
||||
def test_parse_sheets():
|
||||
ws = extract.get_class_ws("312", sample_path)
|
||||
sheets = extract.parse_sheets(ws)
|
||||
assert len(sheets) == 2
|
||||
assert type(sheets[0]) == pandas.core.frame.DataFrame
|
||||
|
||||
def test_extract_students():
|
||||
ws = extract.get_class_ws("312", sample_path)
|
||||
sheets = extract.parse_sheets(ws)
|
||||
students = extract.extract_students(sheets[0])
|
||||
_students = pandas.Index(['Eleve 1', 'Eleve 10', 'Eleve 2', 'Eleve 3', 'Eleve 4', 'Eleve 5', 'Eleve 6', 'Eleve 7', 'Eleve 8', 'Eleve 9'], dtype='object')
|
||||
assert list(students) == list(_students)
|
||||
|
||||
def test_check_students():
|
||||
ws = extract.get_class_ws("312", sample_path)
|
||||
sheets = extract.parse_sheets(ws)
|
||||
students = extract.check_students(sheets)
|
||||
_students = pandas.Index(['Eleve 1', 'Eleve 10', 'Eleve 2', 'Eleve 3', 'Eleve 4', 'Eleve 5', 'Eleve 6', 'Eleve 7', 'Eleve 8', 'Eleve 9'], dtype='object')
|
||||
assert list(students) == list(_students)
|
||||
|
||||
|
||||
ws = extract.get_class_ws("308", sample_path)
|
||||
sheets = extract.parse_sheets(ws)
|
||||
with pytest.raises(Exception) as e_info:
|
||||
students = extract.check_students(sheets)
|
||||
|
||||
def test_flat_df_students():
|
||||
ws = extract.get_class_ws("312", sample_path)
|
||||
sheets = extract.parse_sheets(ws)
|
||||
students = extract.check_students(sheets)
|
||||
|
||||
# Sheets[1] is the sheet Connaissances
|
||||
flat_df = extract.flat_df_students(sheets[1], students)
|
||||
assert len(flat_df) == 80
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
||||
Reference in New Issue
Block a user