Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
2 changed files with 141 additions and 106 deletions
Showing only changes of commit 5828d4aaaf - Show all commits

View File

@ -353,90 +353,90 @@ class JuryPE(object):
):
trajectoires_tagguees.append(trajectoire_tagguee)
# Ajout des notes
notes = pd.DataFrame(index=etudids, columns=[ [descr], [""], ["note"] ])
# Combien de notes vont être injectées ?
nbre_notes_injectees = 0
for traj in trajectoires_tagguees:
moy_traj = traj.moyennes_tags[tag]
notes_traj = moy_traj.get_df_notes(arrondi=True)
etudids_communs = notes_traj.index.intersection(etudids)
inscrits_traj = moy_traj.inscrits_ids
etudids_communs = set(etudids) & set(inscrits_traj)
nbre_notes_injectees += len(etudids_communs)
notes.loc[etudids_communs, (descr, "", "note")] = notes_traj.loc[etudids_communs, "notes"]
# Si l'aggrégat est significatif (aka il y a des notes)
if nbre_notes_injectees > 0:
df_synthese = df_synthese.join(notes)
# Ajout des classements & statistiques
donnees = pd.DataFrame(
index=etudids,
columns=[ [descr]*4, [NOM_STAT_GROUPE]*4, ["class.", "min", "moy", "max"] ],
)
# donnees[(descr, NOM_STAT_GROUPE, "class.")] = donnees[
# (descr, NOM_STAT_GROUPE, "class.")
# ].astype(str)
# donnees[(descr, NOM_STAT_GROUPE, "class.")] = np.nan
for traj in trajectoires_tagguees:
moy_traj = traj.moyennes_tags[tag]
# Les classements
rangs = moy_traj.get_df_rangs_pertinents()
# Les etudids communs pour la trajectoire
etudids_communs = rangs.index.intersection(etudids)
donnees.loc[
etudids_communs, (descr, NOM_STAT_GROUPE, "class.")
] = rangs.loc[etudids_communs, "rangs"]
# Le min
donnees.loc[
etudids_communs, (descr, NOM_STAT_GROUPE, "min")
] = moy_traj.get_min_for_df()
# Le max
donnees.loc[
etudids_communs, (descr, NOM_STAT_GROUPE, "max")
] = moy_traj.get_max_for_df()
# La moyenne
donnees.loc[
etudids_communs, (descr, NOM_STAT_GROUPE, "moy")
] = moy_traj.get_moy_for_df()
df_synthese = df_synthese.join(donnees)
# Ajoute les données d'interclassement
interclass = self.interclassements_taggues[aggregat]
moy_traj = interclass.moyennes_tags[tag]
# Ajout des données classements & statistiques
nom_stat_promo = f"{NOM_STAT_PROMO} {self.diplome}"
donnees = pd.DataFrame(
index=etudids,
columns=[ [descr]*4, [nom_stat_promo]*4, ["class.", "min", "moy", "max"] ],
columns=[
[descr] * (1 + 4 * 2),
[""] + [NOM_STAT_GROUPE] * 4 + [nom_stat_promo] * 4,
["note"] + ["class.", "min", "moy", "max"] * 2,
],
)
# Les classements
rangs = moy_traj.get_df_rangs_pertinents()
for traj in trajectoires_tagguees:
# Les données des trajectoires_tagguees
moy_traj = traj.moyennes_tags[tag]
etudids_communs = rangs.index.intersection(etudids)
# Les étudiants communs entre tableur de synthèse et trajectoires
inscrits_traj = moy_traj.inscrits_ids
etudids_communs = list(set(etudids) & set(inscrits_traj))
donnees.loc[
etudids_communs, (descr, nom_stat_promo, "class.")
] = rangs.loc[etudids_communs, "rangs"]
# Les notes
champ = (descr, "", "note")
notes_traj = moy_traj.get_notes()
donnees.loc[etudids_communs, champ] = notes_traj.loc[
etudids_communs]
# Le min
donnees.loc[
etudids_communs, (descr, nom_stat_promo, "min")
] = moy_traj.get_min_for_df()
# Le max
donnees.loc[
etudids_communs, (descr, nom_stat_promo, "max")
] = moy_traj.get_max_for_df()
# La moyenne
donnees.loc[
etudids_communs, (descr, nom_stat_promo, "moy")
] = moy_traj.get_moy_for_df()
# Les rangs
champ = (descr, NOM_STAT_GROUPE, "class.")
rangs = moy_traj.get_rangs_inscrits()
donnees.loc[etudids_communs, champ] = rangs.loc[
etudids_communs
]
# Les mins
champ = (descr, NOM_STAT_GROUPE, "min")
mins = moy_traj.get_min()
donnees.loc[etudids_communs, champ] = mins.loc[etudids_communs]
# Les max
champ = (descr, NOM_STAT_GROUPE, "max")
maxs = moy_traj.get_max()
donnees.loc[etudids_communs, champ] = maxs.loc[etudids_communs]
# Les moys
champ = (descr, NOM_STAT_GROUPE, "moy")
moys = moy_traj.get_max()
donnees.loc[etudids_communs, champ] = moys.loc[etudids_communs]
# Ajoute les données d'interclassement
interclass = self.interclassements_taggues[aggregat]
moy_interclass = interclass.moyennes_tags[tag]
# Les étudiants communs entre tableur de synthèse et l'interclassement
inscrits_interclass = moy_interclass.inscrits_ids
etudids_communs = list(set(etudids) & set(inscrits_interclass))
# Les classements d'interclassement
champ = (descr, nom_stat_promo, "class.")
rangs = moy_interclass.get_rangs_inscrits()
donnees.loc[etudids_communs, champ] = rangs.loc[etudids_communs]
# Les mins
champ = (descr, nom_stat_promo, "min")
mins = moy_interclass.get_min()
donnees.loc[etudids_communs, champ] = mins.loc[etudids_communs]
# Les max
champ = (descr, nom_stat_promo, "max")
maxs = moy_interclass.get_max()
donnees.loc[etudids_communs, champ] = maxs.loc[etudids_communs]
# Les moys
champ = (descr, nom_stat_promo, "moy")
moys = moy_interclass.get_max()
donnees.loc[etudids_communs, champ] = moys.loc[etudids_communs]
df_synthese = df_synthese.join(donnees)
# Fin de l'aggrégat

View File

@ -73,8 +73,14 @@ class MoyenneTag:
"""
self.tag = tag
"""Le tag associé à la moyenne"""
self.synthese = self.comp_moy_et_stat(notes)
"""La synthèse des notes/classements/statistiques"""
self.etudids = list(notes.index) # calcul à venir
"""Les id des étudiants"""
self.inscrits_ids = notes[notes.notnull()].index.to_list()
"""Les id des étudiants dont la moyenne est non nulle"""
self.df: pd.DataFrame = self.comp_moy_et_stat(notes)
"""Le dataframe retraçant les moyennes/classements/statistiques"""
self.synthese = self.to_dict()
"""La synthèse (dictionnaire) des notes/classements/statistiques"""
def __eq__(self, other):
"""Egalité de deux MoyenneTag lorsque leur tag sont identiques"""
@ -94,54 +100,85 @@ class MoyenneTag:
Un dictionnaire stockant les notes, les classements, le min,
le max, la moyenne, le nb de notes (donc d'inscrits)
"""
# Supprime d'éventuels chaines de caractères dans les notes
df = pd.DataFrame(
np.nan,
index=self.etudids,
columns=[
"note",
"classement",
"rang",
"min",
"max",
"moy",
"nb_etuds",
"nb_inscrits",
],
)
# Supprime d'éventuelles chaines de caractères dans les notes
notes = pd.to_numeric(notes, errors="coerce")
df["note"] = notes
# Les indices des ... et les notes non nulles/pertinentes
indices = notes.notnull()
notes_non_nulles = notes[indices]
# Les nb d'étudiants & nb d'inscrits
df["nb_etuds"] = len(self.etudids)
df.loc[self.inscrits_ids, "nb_inscrits"] = len(self.inscrits_ids)
# Les classements sur les notes non nulles
(_, class_gen_ue_non_nul) = comp_ranks_series(notes_non_nulles)
# Le classement des inscrits
notes_non_nulles = notes[self.inscrits_ids]
(class_str, class_int) = comp_ranks_series(notes_non_nulles)
df.loc[self.inscrits_ids, "classement"] = class_int
# Les classements (toutes notes confondues, avec NaN si pas de notes)
class_gen_ue = pd.Series(np.nan, index=notes.index) # , dtype="Int64")
class_gen_ue[indices] = class_gen_ue_non_nul[indices]
# Le rang (classement/nb_inscrit)
df["rang"] = df["rang"].astype(str)
df.loc[self.inscrits_ids, "rang"] = (
df.loc[self.inscrits_ids, "classement"].astype(int).astype(str)
+ "/"
+ df.loc[self.inscrits_ids, "nb_inscrits"].astype(int).astype(str)
)
# Les stat (des inscrits)
df.loc[self.inscrits_ids, "min"] = notes.min()
df.loc[self.inscrits_ids, "max"] = notes.max()
df.loc[self.inscrits_ids, "moy"] = notes.mean()
return df
def to_dict(self) -> dict:
"""Renvoie un dictionnaire de synthèse des moyennes/classements/statistiques"""
synthese = {
"notes": notes,
"classements": class_gen_ue,
"min": notes.min(),
"max": notes.max(),
"moy": notes.mean(),
"nb_inscrits": sum(indices),
"notes": self.df["note"],
"classements": self.df["classement"],
"min": self.df["min"].mean(),
"max": self.df["max"].mean(),
"moy": self.df["moy"].mean(),
"nb_inscrits": self.df["nb_inscrits"].mean(),
}
return synthese
def get_df_notes(self, arrondi=False):
def get_notes(self):
"""Série des notes, arrondies à 2 chiffres après la virgule"""
if arrondi:
serie = self.synthese["notes"].round(2)
else:
serie = self.synthese["notes"]
df = serie.to_frame("notes")
return df
return self.df["note"].round(2)
def get_df_rangs_pertinents(self) -> pd.Series:
def get_rangs_inscrits(self) -> pd.Series:
"""Série des rangs classement/nbre_inscrit"""
classement = self.synthese["classements"]
indices = classement[classement.notnull()].index.to_list()
classement_non_nul = classement.loc[indices].to_frame("classements")
classement_non_nul.insert(1, "rangs", np.nan)
return self.df["rang"]
nb_inscrit = self.synthese["nb_inscrits"]
def get_min(self) -> pd.Series:
"""Série des min"""
return self.df["min"].round(2)
def get_max(self) -> pd.Series:
"""Série des max"""
return self.df["max"].round(2)
def get_moy(self) -> pd.Series:
"""Série des moy"""
return self.df["moy"].round(2)
classement_non_nul["rangs"] = classement_non_nul["classements"].astype(int).astype(str) + "/" + str(nb_inscrit)
return classement_non_nul["rangs"].to_frame("rangs")
def get_note_for_df(self, etudid: int):
"""Note d'un étudiant donné par son etudid"""
return round(self.synthese["notes"].loc[etudid], 2)
return round(self.df["note"].loc[etudid], 2)
def get_min_for_df(self) -> float:
"""Min renseigné pour affichage dans un df"""
@ -158,11 +195,9 @@ class MoyenneTag:
def get_class_for_df(self, etudid: int) -> str:
"""Classement ramené au nombre d'inscrits,
pour un étudiant donné par son etudid"""
classement = self.synthese["classements"].loc[etudid]
nb_inscrit = self.synthese["nb_inscrits"]
classement = self.df["rang"].loc[etudid]
if not pd.isna(classement):
classement = int(classement)
return f"{classement}/{nb_inscrit}"
return classement
else:
return pe_affichage.SANS_NOTE