forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -50,6 +50,7 @@ from zipfile import ZipFile
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from app.pe import pe_semtag
|
||||
from app.pe.pe_affichage import NOM_STAT_PROMO, SANS_NOTE, NOM_STAT_GROUPE
|
||||
import app.pe.pe_affichage as pe_affichage
|
||||
from app.pe.pe_etudiant import * # TODO A éviter -> pe_etudiant.
|
||||
@ -96,7 +97,9 @@ class JuryPE(object):
|
||||
pe_affichage.pe_print("*** Aucun étudiant diplômé")
|
||||
else:
|
||||
self._gen_xls_diplomes(zipfile)
|
||||
self._gen_rcss()
|
||||
self._gen_xls_resultats_semestres_taggues(zipfile)
|
||||
self._gen_xls_semestres_taggues(zipfile)
|
||||
# self._gen_xls_rcss_tags(zipfile)
|
||||
# self._gen_xls_interclassements_rcss(zipfile)
|
||||
# self._gen_xls_synthese_jury_par_tag(zipfile)
|
||||
@ -142,12 +145,53 @@ class JuryPE(object):
|
||||
output, engine="openpyxl"
|
||||
) as writer:
|
||||
for res_sem_tag in self.res_sems_tags.values():
|
||||
onglet = res_sem_tag.get_repr()
|
||||
onglet = res_sem_tag.get_repr(verbose=False)
|
||||
df = res_sem_tag.df_moyennes_et_classements()
|
||||
# écriture dans l'onglet
|
||||
df.to_excel(writer, onglet, index=True, header=True)
|
||||
output.seek(0)
|
||||
|
||||
self.add_file_to_zip(
|
||||
zipfile,
|
||||
f"resultats_semestres_taggues_{self.diplome}.xlsx",
|
||||
output.read(),
|
||||
path="details",
|
||||
)
|
||||
|
||||
def _gen_rcss(self):
|
||||
"""Génère les RCS (attribut `rcss_jury`), combinaisons de semestres suivis par les étudiants au sens
|
||||
d'un nom de RCS (par ex: '3S').
|
||||
"""
|
||||
pe_affichage.pe_print(
|
||||
"*** Génère les RCS (différentes combinaisons de semestres) des étudiants"
|
||||
)
|
||||
self.rcss_jury = pe_rcs.RCSsJuryPE(self.diplome)
|
||||
self.rcss_jury.cree_rcss(self.etudiants)
|
||||
|
||||
def _gen_xls_semestres_taggues(self, zipfile: ZipFile):
|
||||
"""Génère les semestres taggués en s'appuyant sur les RCS de type Sx (pour
|
||||
identifier les redoublements impactant les semestres taggués).
|
||||
"""
|
||||
# Génère les moyennes des RCS de type Sx
|
||||
pe_affichage.pe_print("*** Calcule les moyennes de semestres = RCS de type Sx")
|
||||
|
||||
self.sems_tags = {}
|
||||
for rcs_id, rcs in self.rcss_jury.rcss.items():
|
||||
if rcs.nom.startswith("S"):
|
||||
self.sems_tags[rcs_id] = pe_semtag.SemTag(rcs, self.res_sems_tags)
|
||||
|
||||
# Intègre le bilan des semestres taggués au zip final
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||
output, engine="openpyxl"
|
||||
) as writer:
|
||||
for sem_tag in self.sems_tags.values():
|
||||
onglet = sem_tag.get_repr(verbose=False)
|
||||
df = sem_tag.df_moyennes_et_classements()
|
||||
# écriture dans l'onglet
|
||||
df.to_excel(writer, onglet, index=True, header=True)
|
||||
output.seek(0)
|
||||
|
||||
self.add_file_to_zip(
|
||||
zipfile,
|
||||
f"semestres_taggues_{self.diplome}.xlsx",
|
||||
@ -156,11 +200,7 @@ class JuryPE(object):
|
||||
)
|
||||
|
||||
def _gen_xls_rcss_tags(self, zipfile: ZipFile):
|
||||
"""Génère :
|
||||
|
||||
* les RCS (combinaisons de semestres suivis par les étudiants au sens
|
||||
d'un aggrégat (par ex: '3S'))
|
||||
* les RCS tagguées des RCS, en calculant les moyennes et les classements par tag
|
||||
"""Génère les RCS tagguées des RCS, en calculant les moyennes et les classements par tag
|
||||
pour chacune.
|
||||
|
||||
Stocke le résultat dans self.rccs_tag, un dictionnaire de
|
||||
@ -183,14 +223,9 @@ class JuryPE(object):
|
||||
|
||||
|
||||
"""
|
||||
pe_affichage.pe_print(
|
||||
"*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants"
|
||||
)
|
||||
self.rcss_jury = pe_rcs.RCSsJuryPE(self.diplome)
|
||||
self.rcss_jury.cree_rcss(self.etudiants)
|
||||
|
||||
# Génère les moyennes par tags des trajectoires
|
||||
pe_affichage.pe_print("*** Calcule les moyennes par tag des RCS possibles")
|
||||
# Génère les moyennes des RCS de type Sx
|
||||
pe_affichage.pe_print("*** Calcule les moyennes des RCS de type Sx")
|
||||
|
||||
self.rcss_tags = {}
|
||||
for rcs_id, rcs in self.rcss_jury.rcss.items():
|
||||
@ -597,9 +632,6 @@ def compute_resultats_semestres_tag(etudiants: EtudiantsJuryPE) -> dict:
|
||||
return semestres_tags
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def compute_interclassements(
|
||||
etudiants: EtudiantsJuryPE,
|
||||
trajectoires_jury_pe: pe_rcs.RCSsJuryPE,
|
||||
|
@ -1,9 +1,11 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from app import comp
|
||||
from app.comp.moy_sem import comp_ranks_series
|
||||
from app.models import UniteEns
|
||||
from app.pe import pe_affichage
|
||||
from app.scodoc.codes_cursus import UE_SPORT
|
||||
|
||||
|
||||
class Moyenne:
|
||||
@ -157,8 +159,9 @@ class MoyennesTag:
|
||||
def __init__(
|
||||
self,
|
||||
tag: str,
|
||||
ues: list[UniteEns],
|
||||
ues: dict[int, UniteEns],
|
||||
notes_ues: pd.DataFrame,
|
||||
ues_inscr_parcours_df: pd.DataFrame
|
||||
# notes_gen: pd.Series,
|
||||
):
|
||||
"""Classe centralisant la synthèse des moyennes/classements d'une série
|
||||
@ -169,23 +172,41 @@ class MoyennesTag:
|
||||
tag: Un tag
|
||||
ues: La liste des UEs ayant servie au calcul de la moyenne
|
||||
notes_ues: Les moyennes (etudid x acronymes_ues) aux différentes UEs et pour le tag
|
||||
ues_inscr_parcours_df: Les inscriptions des etudid au UE
|
||||
# notes_gen: Une série de notes (moyenne) sous forme d'un pd.Series() (toutes UEs confondues)
|
||||
"""
|
||||
self.tag = tag
|
||||
"""Le tag associé aux moyennes"""
|
||||
|
||||
# Les UE
|
||||
self.ues: dict[int, UniteEns] = {ue.id: ue for ue in ues}
|
||||
self.ues: dict[int, UniteEns] = ues
|
||||
"""Les UEs sur lesquelles sont calculées les moyennes"""
|
||||
|
||||
colonnes = list(notes_ues.columns)
|
||||
acronymes = [self.ues[ue_id].acronyme for ue_id in colonnes]
|
||||
assert len(set(acronymes)) == len(colonnes), \
|
||||
"Deux UEs ne peuvent pas avoir le même acronyme"
|
||||
acronymes: list[str] = [self.ues[ue_id].acronyme for ue_id in self.ues]
|
||||
assert len(set(acronymes)) == len(
|
||||
colonnes
|
||||
), "Deux UEs ne peuvent pas avoir le même acronyme"
|
||||
|
||||
# Les inscriptions des etudids aux UEs
|
||||
self.ues_inscr_parcours_df: pd.DataFrame = ues_inscr_parcours_df
|
||||
"""Les inscriptions des etudids au UE en fonction de leur parcours"""
|
||||
|
||||
# Les coefficients à appliquer aux UEs pour la moyenne générale = ECTS
|
||||
self.ects = self.ues_inscr_parcours_df.fillna(0.0) * [
|
||||
ue.ects
|
||||
for ue in self.ues.values() # if ue.type != UE_SPORT <= déjà supprimé
|
||||
]
|
||||
# Les profils d'ects (pour debug)
|
||||
profils_ects = []
|
||||
for val in list(self.ects.values):
|
||||
if tuple(val) not in profils_ects:
|
||||
profils_ects.append(tuple(val))
|
||||
|
||||
# Les moyennes par UE
|
||||
self.notes_ues = notes_ues
|
||||
self.notes_ues: pd.DataFrame = notes_ues
|
||||
"""Les notes aux UEs (dataframe)"""
|
||||
self.notes_ues.columns = acronymes # remplace les ue.id par leur acronyme
|
||||
self.notes_ues.columns = acronymes # remplace les ue.id par leur acronyme
|
||||
self.moys_ues: dict[int, pd.DataFrame] = {}
|
||||
"""Les dataframes retraçant les moyennes/classements/statistiques des étudiants aux UEs"""
|
||||
for ue in self.ues.values(): # if ue.type != UE_SPORT:
|
||||
@ -193,11 +214,42 @@ class MoyennesTag:
|
||||
self.moys_ues[ue.acronyme] = Moyenne(notes)
|
||||
|
||||
# Les moyennes générales
|
||||
notes_gen = self.compute_moy_gen(self.notes_ues, self.ects)
|
||||
self.notes_gen = notes_gen
|
||||
"""Les notes générales (moyenne toutes UEs confonudes)"""
|
||||
self.moy_gen = Moyenne(notes_gen)
|
||||
"""Le dataframe retraçant les moyennes/classements/statistiques général"""
|
||||
|
||||
pe_affichage.pe_print(f"> MoyTag pour {tag} avec")
|
||||
pe_affichage.pe_print(f" - ues={acronymes}")
|
||||
pe_affichage.pe_print(f" - ects={profils_ects}")
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
"""Egalité de deux MoyenneTag lorsque leur tag sont identiques"""
|
||||
return self.tag == other.tag
|
||||
|
||||
def compute_moy_gen(
|
||||
self, moy_ues: pd.DataFrame, coeff_ues: pd.DataFrame
|
||||
) -> pd.Series:
|
||||
"""Calcule la moyenne générale (toutes UE confondus)
|
||||
pour le tag considéré, en pondérant les notes obtenues au UE
|
||||
par les crédits ECTS.
|
||||
|
||||
Args:
|
||||
moy_ues: Les moyennes etudids x acronymes_ues
|
||||
coeff_ues: Les coeff etudids x ueids
|
||||
"""
|
||||
|
||||
# Calcule la moyenne générale dans le semestre (pondérée par le ECTS)
|
||||
try:
|
||||
moy_gen_tag = comp.moy_sem.compute_sem_moys_apc_using_ects(
|
||||
moy_ues,
|
||||
coeff_ues,
|
||||
# formation_id=self.formsemestre.formation_id,
|
||||
skip_empty_ues=True,
|
||||
)
|
||||
except TypeError as e:
|
||||
raise TypeError("Pb dans le calcul de la moyenne toutes UEs confondues")
|
||||
|
||||
return moy_gen_tag
|
||||
|
@ -94,7 +94,7 @@ class RCSTag(TableTag):
|
||||
self.etuds = nt.etuds
|
||||
|
||||
# assert self.etuds == trajectoire.suivi # manque-t-il des étudiants ?
|
||||
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
||||
self.etats_civils = {etud.etudid: etud.nomprenom for etud in self.etuds}
|
||||
|
||||
self.tags_sorted = self.do_taglist()
|
||||
"""Tags extraits de tous les semestres"""
|
||||
@ -102,7 +102,7 @@ class RCSTag(TableTag):
|
||||
self.notes_cube = self.compute_notes_cube()
|
||||
"""Cube de notes"""
|
||||
|
||||
etudids = list(self.etudiants.keys())
|
||||
etudids = list(self.etats_civils.keys())
|
||||
self.notes = compute_tag_moy(self.notes_cube, etudids, self.tags_sorted)
|
||||
"""Calcul les moyennes par tag sous forme d'un dataframe"""
|
||||
|
||||
|
@ -70,19 +70,15 @@ class ResSemTag(TableTag):
|
||||
self.formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
|
||||
# Le nom du res_semestre taggué
|
||||
self.nom = self.get_repr(mode="long")
|
||||
self.nom = self.get_repr(verbose=True)
|
||||
|
||||
pe_affichage.pe_print(
|
||||
f"--> Résultats de Semestre taggués {self.nom}"
|
||||
)
|
||||
pe_affichage.pe_print(f"--> Résultats de semestre taggués {self.nom}")
|
||||
|
||||
# Les résultats du semestre
|
||||
self.nt = load_formsemestre_results(self.formsemestre)
|
||||
|
||||
# Les étudiants
|
||||
self.etuds = self.nt.etuds
|
||||
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
||||
self.etudids = list(self.etudiants.keys())
|
||||
# Les étudiants (etuds, états civils & etudis)
|
||||
self.add_etuds(self.nt.etuds)
|
||||
|
||||
# Les notes, les modules implémentés triés, les étudiants, les coeffs,
|
||||
# récupérés notamment de py:mod:`res_but`
|
||||
@ -109,12 +105,17 @@ class ResSemTag(TableTag):
|
||||
|
||||
for tag in tags_dict["personnalises"]:
|
||||
# pe_affichage.pe_print(f" -> Traitement du tag {tag}")
|
||||
infos_tag = tags_dict["personnalises"][tag]
|
||||
infos_tag = tags_dict["personnalises"][tag]
|
||||
moy_ues_tag = self.compute_moy_ues_tag(infos_tag)
|
||||
# moy_gen_tag = self.compute_moy_gen_tag(moy_ues_tag)
|
||||
|
||||
ues_dict = {ue.id: ue for ue in ues_hors_sport}
|
||||
self.moyennes_tags[tag] = MoyennesTag(
|
||||
tag, ues_hors_sport, moy_ues_tag # moy_gen_tag
|
||||
tag,
|
||||
ues_dict,
|
||||
moy_ues_tag,
|
||||
self.ues_inscr_parcours_df
|
||||
# moy_gen_tag
|
||||
)
|
||||
|
||||
# Ajoute les d'UE moyennes générales de BUT pour le semestre considéré
|
||||
@ -128,8 +129,10 @@ class ResSemTag(TableTag):
|
||||
)
|
||||
# moy_ues = self.nt.etud_moy_ue[ue_id]
|
||||
# moy_gen_but = self.nt.etud_moy_gen
|
||||
ues_dict = {ue.id: ue for ue in ues_hors_sport}
|
||||
|
||||
self.moyennes_tags["but"] = MoyennesTag(
|
||||
"but", ues_hors_sport, df_ues #, moy_gen_but
|
||||
"but", ues_dict, df_ues, self.ues_inscr_parcours_df # , moy_gen_but
|
||||
)
|
||||
|
||||
self.tags_sorted = self.get_all_tags()
|
||||
@ -144,11 +147,11 @@ class ResSemTag(TableTag):
|
||||
# f" => Traitement des tags {', '.join(self.tags_sorted)}"
|
||||
# )
|
||||
|
||||
def get_repr(self, mode="long"):
|
||||
def get_repr(self, verbose=False):
|
||||
"""Nom affiché pour le semestre taggué"""
|
||||
if mode == "short":
|
||||
if verbose:
|
||||
return f"{self.formsemestre} ({self.formsemestre_id})"
|
||||
else: # mode == "long"
|
||||
else:
|
||||
return pe_etudiant.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
||||
|
||||
def compute_moy_ues_tag(self, info_tag: dict[int, dict]) -> pd.DataFrame:
|
||||
@ -192,25 +195,6 @@ class ResSemTag(TableTag):
|
||||
)
|
||||
return moyennes_ues_tag
|
||||
|
||||
def compute_moy_gen_tag(self, moy_ues_tag: pd.DataFrame) -> pd.Series:
|
||||
"""Calcule la moyenne générale (toutes UE confondus)
|
||||
pour le tag considéré, en les pondérant par les crédits ECTS.
|
||||
"""
|
||||
# Les ects
|
||||
ects = self.ues_inscr_parcours_df.fillna(0.0) * [
|
||||
ue.ects for ue in self.ues if ue.type != UE_SPORT
|
||||
]
|
||||
|
||||
# Calcule la moyenne générale dans le semestre (pondérée par le ECTS)
|
||||
moy_gen_tag = comp.moy_sem.compute_sem_moys_apc_using_ects(
|
||||
moy_ues_tag,
|
||||
ects,
|
||||
formation_id=self.formsemestre.formation_id,
|
||||
skip_empty_ues=True,
|
||||
)
|
||||
|
||||
return moy_gen_tag
|
||||
|
||||
def _get_tags_dict(self):
|
||||
"""Renvoie les tags personnalisés (déduits des modules du semestre)
|
||||
et les tags automatiques ('but'), et toutes leurs informations,
|
||||
@ -272,8 +256,6 @@ class ResSemTag(TableTag):
|
||||
raise ScoValueError(message)
|
||||
|
||||
|
||||
|
||||
|
||||
def get_moduleimpl(modimpl_id) -> dict:
|
||||
"""Renvoie l'objet modimpl dont l'id est modimpl_id"""
|
||||
modimpl = db.session.get(ModuleImpl, modimpl_id)
|
||||
|
@ -49,7 +49,7 @@ from app.pe.pe_moytag import MoyennesTag
|
||||
|
||||
|
||||
class SemTag(TableTag):
|
||||
def __init__(self, rcs: RCS, semestres_taggues: dict[int, ResSemTag]):
|
||||
def __init__(self, rcs: RCS, res_sems_tags: dict[int, ResSemTag]):
|
||||
"""Calcule les moyennes/classements par tag à un RCS d'un seul semestre
|
||||
(ici semestre) de type 'Sx' (par ex. 'S1', 'S2', ...) :
|
||||
|
||||
@ -62,7 +62,7 @@ class SemTag(TableTag):
|
||||
|
||||
Args:
|
||||
rcs: Un RCS (identifié par un nom et l'id de son semestre terminal)
|
||||
semestres_taggues: Les données sur les semestres taggués
|
||||
res_sems_tags: Les données sur les résultats des semestres taggués
|
||||
"""
|
||||
TableTag.__init__(self)
|
||||
|
||||
@ -88,27 +88,20 @@ class SemTag(TableTag):
|
||||
self.semestres_aggreges = rcs.semestres_aggreges
|
||||
"""Les semestres aggrégés"""
|
||||
|
||||
self.semestres_tags_aggreges = {}
|
||||
"""Les semestres tags associés aux semestres aggrégés"""
|
||||
self.res_sems_tags = {}
|
||||
"""Les résultats des semestres taggués (limités aux semestres aggrégés)"""
|
||||
try:
|
||||
for frmsem_id in self.semestres_aggreges:
|
||||
self.semestres_tags_aggreges[frmsem_id] = semestres_taggues[frmsem_id]
|
||||
self.res_sems_tags[frmsem_id] = res_sems_tags[frmsem_id]
|
||||
except:
|
||||
raise ValueError("Semestres taggués manquants")
|
||||
raise ValueError("Résultats des semestres taggués manquants")
|
||||
|
||||
# Les données des étudiants
|
||||
self.etuds = nt.etuds
|
||||
"""Les étudiants"""
|
||||
self.etudids = [etud.etudid for etud in self.etuds]
|
||||
"""Les etudids"""
|
||||
self.etats_civils = {
|
||||
etudid: self.etuds[etudid].etat_civil for etudid in self.etudids
|
||||
}
|
||||
"""Les états civils"""
|
||||
# Les étudiants (etuds, états civils & etudis)
|
||||
self.add_etuds(nt.etuds)
|
||||
|
||||
# Les tags
|
||||
self.tags_sorted = self.comp_tags_list()
|
||||
"""Tags extraits du semestre terminal de l'aggrégat"""
|
||||
"""Tags (extraits uniquement du semestre terminal de l'aggrégat)"""
|
||||
|
||||
# Les UEs
|
||||
self.ues = self.comp_ues(tag="but")
|
||||
@ -116,20 +109,33 @@ class SemTag(TableTag):
|
||||
"""UEs extraites du semestre terminal de l'aggrégat (avec
|
||||
check de concordance sur les UE des semestres_aggrégés)"""
|
||||
|
||||
# Les inscriptions aux UEs
|
||||
self.ues_inscr_parcours_df = self.comp_ues_inscr_parcours(tag="but")
|
||||
"""Les inscriptions aux UEs (extraites uniquement du semestre terminal)"""
|
||||
|
||||
self.moyennes_tags: dict[str, MoyennesTag] = {}
|
||||
"""Moyennes/classements par tag (qu'ils soient personnalisés ou automatiques)"""
|
||||
|
||||
self.notes: dict[str, pd.DataFrame] = {}
|
||||
"""Les notes aux différents tags"""
|
||||
self.moyennes_tags: dict[str, pd.DataFrame] = {}
|
||||
"""Les notes aux UEs dans différents tags"""
|
||||
# Masque des inscriptions
|
||||
inscr_mask = self.ues_inscr_parcours_df.to_numpy()
|
||||
for tag in self.tags_sorted:
|
||||
# Cube de note
|
||||
notes_cube = self.compute_notes_ues_cube(tag, self.acronymes_ues)
|
||||
notes_cube = self.compute_notes_ues_cube(tag, self.acronymes_ues_sorted)
|
||||
|
||||
# Calcule des moyennes sous forme d'un dataframe"""
|
||||
self.notes[tag] = compute_notes_ues(notes_cube, self.etudids, self.acronymes_ues)
|
||||
|
||||
moys_ues = compute_notes_ues(
|
||||
notes_cube,
|
||||
self.etudids,
|
||||
self.acronymes_ues_sorted,
|
||||
inscr_mask,
|
||||
)
|
||||
# Les moyennes
|
||||
self.moyennes_tags[tag] = MoyennesTag(tag, self.notes[tag])
|
||||
self.moyennes_tags[tag] = MoyennesTag(tag,
|
||||
self.ues,
|
||||
moys_ues,
|
||||
self.ues_inscr_parcours_df)
|
||||
|
||||
def __eq__(self, other):
|
||||
"""Egalité de 2 RCS taggués sur la base de leur identifiant"""
|
||||
@ -147,7 +153,7 @@ class SemTag(TableTag):
|
||||
# Index du cube (etudids -> dim 0, ues -> dim 1, semestres -> dim2)
|
||||
etudids = [etud.etudid for etud in self.etuds]
|
||||
# acronymes_ues = sorted([ue.acronyme for ue in self.ues.values()])
|
||||
semestres_id = list(self.semestres_tags_aggreges.keys())
|
||||
semestres_id = list(self.res_sems_tags.keys())
|
||||
|
||||
dfs = {}
|
||||
|
||||
@ -156,10 +162,12 @@ class SemTag(TableTag):
|
||||
df = pd.DataFrame(np.nan, index=etudids, columns=acronymes_ues_sorted)
|
||||
|
||||
# Charge les notes du semestre tag
|
||||
sem_tag = self.semestres_tags_aggreges[frmsem_id]
|
||||
sem_tag = self.res_sems_tags[frmsem_id]
|
||||
moys_tag = sem_tag.moyennes_tags[tag]
|
||||
notes = moys_tag.notes_ues # dataframe etudids x ues
|
||||
acronymes_ues_sem = list(notes.columns) # les acronymes des UEs du semestre tag
|
||||
notes = moys_tag.notes_ues # dataframe etudids x ues
|
||||
acronymes_ues_sem = list(
|
||||
notes.columns
|
||||
) # les acronymes des UEs du semestre tag
|
||||
|
||||
# UEs communes à celles du SemTag (celles du dernier semestre du RCS)
|
||||
ues_communes = list(set(acronymes_ues_sorted) & set(acronymes_ues_sem))
|
||||
@ -168,7 +176,9 @@ class SemTag(TableTag):
|
||||
etudids_communs = df.index.intersection(notes.index)
|
||||
|
||||
# Recopie
|
||||
df.loc[etudids_communs, ues_communes] = notes.loc[etudids_communs, ues_communes]
|
||||
df.loc[etudids_communs, ues_communes] = notes.loc[
|
||||
etudids_communs, ues_communes
|
||||
]
|
||||
|
||||
# Supprime tout ce qui n'est pas numérique
|
||||
for col in df.columns:
|
||||
@ -182,7 +192,7 @@ class SemTag(TableTag):
|
||||
etudids_x_ues_x_semestres = np.stack(semestres_x_etudids_x_ues, axis=-1)
|
||||
return etudids_x_ues_x_semestres
|
||||
|
||||
def comp_tags_list(self):
|
||||
def comp_tags_list(self) -> list[str]:
|
||||
"""Récupère les tag du semestre taggué associé au semestre final du RCS
|
||||
|
||||
Returns:
|
||||
@ -190,7 +200,7 @@ class SemTag(TableTag):
|
||||
"""
|
||||
tags = []
|
||||
dernier_frmid = self.formsemestre_terminal.formsemestre_id
|
||||
dernier_semestre_tag = self.semestres_tags_aggreges[dernier_frmid]
|
||||
dernier_semestre_tag = self.res_sems_tags[dernier_frmid]
|
||||
tags = dernier_semestre_tag.tags_sorted
|
||||
pe_affichage.pe_print(f"* Tags : {', '.join(tags)}")
|
||||
return tags
|
||||
@ -203,12 +213,29 @@ class SemTag(TableTag):
|
||||
Un dictionnaire donnant les UEs
|
||||
"""
|
||||
dernier_frmid = self.formsemestre_terminal.formsemestre_id
|
||||
dernier_semestre_tag = self.semestres_tags_aggreges[dernier_frmid]
|
||||
dernier_semestre_tag = self.res_sems_tags[dernier_frmid]
|
||||
moy_tag = dernier_semestre_tag.moyennes_tags[tag]
|
||||
return moy_tag.ues # les UEs
|
||||
|
||||
def comp_ues_inscr_parcours(self, tag="but") -> pd.DataFrame:
|
||||
"""Récupère les informations d'inscription des étudiants aux UEs : ne
|
||||
conserve que les UEs du semestre terminal (pour les redoublants)
|
||||
|
||||
def compute_notes_ues(set_cube: np.array, etudids: list, acronymes_ues: list):
|
||||
Returns:
|
||||
Un dataFrame etudids x UE indiquant si un étudiant est inscrit à une UE
|
||||
"""
|
||||
dernier_frmid = self.formsemestre_terminal.formsemestre_id
|
||||
dernier_semestre_tag = self.res_sems_tags[dernier_frmid]
|
||||
moy_tag = dernier_semestre_tag.moyennes_tags[tag]
|
||||
return moy_tag.ues_inscr_parcours_df
|
||||
|
||||
|
||||
def compute_notes_ues(
|
||||
set_cube: np.array,
|
||||
etudids: list,
|
||||
acronymes_ues: list,
|
||||
inscr_mask: np.array,
|
||||
):
|
||||
"""Calcule la moyenne par UEs à un tag donné en prenant la note maximum (UE
|
||||
par UE) obtenue par un étudiant à un semestre.
|
||||
|
||||
@ -217,18 +244,27 @@ def compute_notes_ues(set_cube: np.array, etudids: list, acronymes_ues: list):
|
||||
(semestre_ids x etudids x UEs), des floats avec des NaN
|
||||
etudids: liste des étudiants (dim. 0 du cube)
|
||||
acronymes_ues: liste des acronymes des ues (dim. 1 du cube)
|
||||
inscr_mask: masque etudids x UE traduisant les inscriptions des
|
||||
étudiants aux UE (du semestre terminal)
|
||||
Returns:
|
||||
Un DataFrame avec pour columns les moyennes par ues,
|
||||
et pour rows les etudid
|
||||
"""
|
||||
nb_etuds, nb_ues, nb_semestres = set_cube.shape
|
||||
nb_etuds_mask, nb_ues_mask = inscr_mask.shape
|
||||
assert nb_etuds == len(etudids)
|
||||
assert nb_ues == len(acronymes_ues)
|
||||
assert nb_etuds == nb_etuds_mask
|
||||
assert nb_ues == nb_ues_mask
|
||||
|
||||
# Quelles entrées du cube contiennent des notes ?
|
||||
mask = ~np.isnan(set_cube)
|
||||
|
||||
# Enlève les NaN du cube pour les entrées manquantes
|
||||
# Entrées à garder dans le cube en fonction du mask d'inscription
|
||||
inscr_mask_3D = np.stack([inscr_mask]*nb_semestres, axis=-1)
|
||||
set_cube = set_cube*inscr_mask_3D
|
||||
|
||||
# Enlève les NaN du cube pour les entrées manquantes : NaN -> -1.0
|
||||
set_cube_no_nan = np.nan_to_num(set_cube, nan=-1.0)
|
||||
|
||||
# Les moyennes par ues
|
||||
|
@ -39,6 +39,8 @@ Created on Thu Sep 8 09:36:33 2016
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from app.models import Identite
|
||||
|
||||
TAGS_RESERVES = ["but"]
|
||||
|
||||
|
||||
@ -47,7 +49,23 @@ class TableTag(object):
|
||||
"""Classe centralisant différentes méthodes communes aux
|
||||
SemestreTag, TrajectoireTag, AggregatInterclassTag
|
||||
"""
|
||||
pass
|
||||
# Les étudiants
|
||||
self.etuds: list[Identite] = None # A venir
|
||||
"""Les étudiants"""
|
||||
self.etats_civils: dict[int, Identite] = None
|
||||
"""Les états civils"""
|
||||
self.etudids: list[int] = None
|
||||
"""Les etudids"""
|
||||
|
||||
def add_etuds(self, etuds: list[Identite]):
|
||||
"""Mémorise les informations sur les étudiants
|
||||
|
||||
Args:
|
||||
etuds: la liste des identités de l'étudiant
|
||||
"""
|
||||
self.etuds = etuds
|
||||
self.etats_civils = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
||||
self.etudids = list(self.etats_civils.keys())
|
||||
|
||||
def get_all_tags(self):
|
||||
"""Liste des tags de la table, triée par ordre alphabétique,
|
||||
@ -70,15 +88,23 @@ class TableTag(object):
|
||||
Le dataframe des notes et des classements
|
||||
"""
|
||||
|
||||
etudiants = self.etudiants
|
||||
etudiants = self.etats_civils
|
||||
df = pd.DataFrame.from_dict(etudiants, orient="index", columns=["nom"])
|
||||
|
||||
tags_tries = self.get_all_tags()
|
||||
for tag in tags_tries:
|
||||
moy_tag = self.moyennes_tags[tag]
|
||||
for acronyme in moy_tag.moys_ues:
|
||||
moy = moy_tag.moys_ues[acronyme] # une moyenne
|
||||
df = df.join(moy.synthese["notes"].rename(f"Moy {tag}-{acronyme}"))
|
||||
df = df.join(
|
||||
moy.synthese["classements"].rename(f"Class {tag}-{acronyme}")
|
||||
)
|
||||
moy_gen = moy_tag.moy_gen
|
||||
df = df.join(moy_gen.synthese["notes"].rename(f"Moy {tag}"))
|
||||
df = df.join(moy_gen.synthese["classements"].rename(f"Class {tag}"))
|
||||
df = df.join(moy_gen.synthese["notes"].rename(f"Moy {tag} (gen)"))
|
||||
df = df.join(moy_gen.synthese["classements"].rename(f"Class {tag} (gen)"))
|
||||
|
||||
df.sort_values(by=['nom'])
|
||||
|
||||
return df
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user