forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -78,7 +78,7 @@ class RCSTag(pe_tabletags.TableTag):
|
||||
"""Le fid du semestre final"""
|
||||
|
||||
# Affichage pour debug
|
||||
pe_affichage.pe_print(f"-> {self.get_repr(verbose=True)}")
|
||||
pe_affichage.pe_print(f"*** {self.get_repr(verbose=True)}")
|
||||
|
||||
# Les données aggrégés (RCRCF + SxTags
|
||||
self.semXs_aggreges: dict[(str, int) : pe_rcsemx.RCSemX] = rcsemx.semXs_aggreges
|
||||
@ -103,25 +103,26 @@ class RCSTag(pe_tabletags.TableTag):
|
||||
# Les compétences (extraites de tous les Sxtags)
|
||||
self.acronymes_ues_to_competences = self._do_acronymes_to_competences()
|
||||
"""L'association acronyme d'UEs -> compétence (extraites des SxTag aggrégés)"""
|
||||
pe_affichage.pe_print(
|
||||
f"* Association UEs -> compétences : {self.acronymes_ues_to_competences}"
|
||||
)
|
||||
|
||||
self.competences_sorted = sorted(
|
||||
set(self.acronymes_ues_to_competences.values())
|
||||
)
|
||||
|
||||
"""Compétences (triées par nom, extraites des SxTag aggrégés)"""
|
||||
pe_affichage.pe_print(f"* Compétences : {', '.join(self.competences_sorted)}")
|
||||
self._aff_comp_et_ues_debug()
|
||||
# pe_affichage.pe_print(f"--> Compétences : {', '.join(self.competences_sorted)}")
|
||||
|
||||
# Les tags
|
||||
self.tags_sorted = self._do_taglist()
|
||||
"""Tags extraits de tous les SxTag aggrégés"""
|
||||
pe_affichage.pe_print(f"* Tags : {', '.join(self.tags_sorted)}")
|
||||
aff_tag = ["👜" + tag for tag in self.tags_sorted]
|
||||
pe_affichage.pe_print(f"--> Tags : {', '.join(aff_tag)}")
|
||||
|
||||
# Les moyennes
|
||||
self.moyennes_tags: dict[str, pe_moytag.MoyennesTag] = {}
|
||||
|
||||
"""Synthétise les moyennes/classements par tag (qu'ils soient personnalisé ou de compétences)"""
|
||||
for tag in self.tags_sorted:
|
||||
pe_affichage.pe_print(f"--> Moyennes du tag 👜{tag}")
|
||||
# Cube de notes (etudids_sorted x compétences_sorted x sxstags)
|
||||
notes_df, notes_cube = self.compute_notes_comps_cube(
|
||||
tag, self.etudids_sorted, self.competences_sorted, self.sxstags
|
||||
@ -143,6 +144,8 @@ class RCSTag(pe_tabletags.TableTag):
|
||||
matrice_coeffs_moy_gen = compute_coeffs_competences(
|
||||
coeffs_cube, notes_cube, self.etudids_sorted, self.competences_sorted
|
||||
)
|
||||
self.__aff_profil_coeffs(matrice_coeffs_moy_gen)
|
||||
|
||||
# Mémorise les moyennes et les coeff associés
|
||||
self.moyennes_tags[tag] = pe_moytag.MoyennesTag(
|
||||
tag,
|
||||
@ -308,6 +311,42 @@ class RCSTag(pe_tabletags.TableTag):
|
||||
dict_competences |= sxtag.acronymes_ues_to_competences
|
||||
return dict_competences
|
||||
|
||||
def _aff_comp_et_ues_debug(self):
|
||||
"""Affichage pour debug"""
|
||||
aff_comp = []
|
||||
|
||||
for comp in self.competences_sorted:
|
||||
liste = []
|
||||
for acro in self.acronymes_ues_to_competences:
|
||||
if self.acronymes_ues_to_competences[acro] == comp:
|
||||
liste += ["📍" + acro]
|
||||
aff_comp += [f" 💡{comp} (⇔ {', '.join(liste)})"]
|
||||
pe_affichage.pe_print(f"--> Compétences :")
|
||||
pe_affichage.pe_print("\n".join(aff_comp))
|
||||
|
||||
def __aff_profil_coeffs(self, matrice_coeffs_moy_gen):
|
||||
"""Extrait de la matrice des coeffs, les différents types d'inscription
|
||||
et de coefficients (appelés profil) des étudiants et les affiche
|
||||
(pour debug)
|
||||
"""
|
||||
|
||||
# Les profils des coeffs d'UE (pour debug)
|
||||
profils = []
|
||||
for i in matrice_coeffs_moy_gen.index:
|
||||
val = matrice_coeffs_moy_gen.loc[i].fillna("-")
|
||||
val = " | ".join([str(v) for v in val])
|
||||
if val not in profils:
|
||||
profils += [val]
|
||||
|
||||
# L'affichage
|
||||
if len(profils) > 1:
|
||||
profils_aff = "\n" + "\n".join([" " * 10 + prof for prof in profils])
|
||||
else:
|
||||
profils_aff = "\n".join(profils)
|
||||
pe_affichage.pe_print(
|
||||
f" > Moyenne calculée avec pour coeffs (de compétences) : {profils_aff}"
|
||||
)
|
||||
|
||||
|
||||
def compute_coeffs_competences(
|
||||
coeff_cube: np.array,
|
||||
|
@ -66,7 +66,7 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
||||
# Le nom du res_semestre taggué
|
||||
self.nom = self.get_repr(verbose=True)
|
||||
|
||||
pe_affichage.pe_print(f"--> ResultatsSemestreBUT taggués {self.nom}")
|
||||
pe_affichage.pe_print(f"*** ResSemBUTTag du {self.nom}")
|
||||
|
||||
# Les étudiants (etuds, états civils & etudis) ajouté
|
||||
self.add_etuds(self.etuds)
|
||||
@ -100,9 +100,11 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
||||
list(set(self.acronymes_ues_to_competences.values()))
|
||||
)
|
||||
"""Les compétences triées par nom"""
|
||||
self._aff_ue_et_comp_debug()
|
||||
|
||||
# Les tags personnalisés et auto:
|
||||
tags_dict = self._get_tags_dict()
|
||||
self._aff_tags_debug(tags_dict)
|
||||
self._check_tags(tags_dict)
|
||||
|
||||
# Les coefficients pour le calcul de la moyenne générale, donnés par
|
||||
@ -111,6 +113,7 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
||||
self.ues_inscr_parcours_df, self.ues_standards
|
||||
)
|
||||
"""DataFrame indiquant les coeffs des UEs par ordre alphabétique d'acronyme"""
|
||||
self.__aff_profil_coeffs()
|
||||
|
||||
# Les capitalisations (mask etuids x acronyme_ue valant True si capitalisée, False sinon)
|
||||
self.capitalisations = self._get_capitalisations(self.ues_standards)
|
||||
@ -291,7 +294,6 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
||||
dict_tags["personnalises"] = get_synthese_tags_personnalises_semestre(
|
||||
self.formsemestre
|
||||
)
|
||||
noms_tags_perso = sorted(list(set(dict_tags["personnalises"].keys())))
|
||||
|
||||
# Les tags automatiques
|
||||
# Déduit des compétences
|
||||
@ -300,16 +302,25 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
||||
|
||||
# BUT
|
||||
dict_tags["auto"] = {"but": {}}
|
||||
return dict_tags
|
||||
|
||||
def _aff_ue_et_comp_debug(self):
|
||||
"""Affichage pour debug"""
|
||||
aff_comp = []
|
||||
for acro in self.acronymes_sorted:
|
||||
aff_comp += [f"📍{acro} (∈ 💡{self.acronymes_ues_to_competences[acro]})"]
|
||||
pe_affichage.pe_print(f"--> UEs/Compétences : {', '.join(aff_comp)}")
|
||||
|
||||
def _aff_tags_debug(self, dict_tags):
|
||||
"""Affichage pour debug"""
|
||||
noms_tags_perso = sorted(list(set(dict_tags["personnalises"].keys())))
|
||||
noms_tags_auto = sorted(list(set(dict_tags["auto"].keys()))) # + noms_tags_comp
|
||||
aff_tags_auto = ", ".join([f"👜{nom}" for nom in noms_tags_auto])
|
||||
aff_tags_perso = ", ".join([f"👜{nom}" for nom in noms_tags_perso])
|
||||
# Affichage
|
||||
pe_affichage.pe_print(
|
||||
f"* Tags du programme de formation : {aff_tags_perso} + "
|
||||
+ f"Tags automatiques : {aff_tags_auto}"
|
||||
f"""--> Tags du programme de formation : {aff_tags_perso} + Automatiques : {aff_tags_auto}"""
|
||||
)
|
||||
return dict_tags
|
||||
|
||||
def _check_tags(self, dict_tags):
|
||||
"""Vérifie l'unicité des tags"""
|
||||
@ -336,6 +347,29 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
||||
"""
|
||||
raise ScoValueError(message)
|
||||
|
||||
def __aff_profil_coeffs(self):
|
||||
"""Extrait de la matrice des coeffs, les différents types d'inscription
|
||||
et de coefficients (appelés profil) des étudiants et les affiche
|
||||
(pour debug)
|
||||
"""
|
||||
|
||||
# Les profils des coeffs d'UE (pour debug)
|
||||
profils = []
|
||||
for i in self.matrice_coeffs_moy_gen.index:
|
||||
val = self.matrice_coeffs_moy_gen.loc[i].fillna("-")
|
||||
val = " | ".join([str(v) for v in val])
|
||||
if val not in profils:
|
||||
profils += [val]
|
||||
|
||||
# L'affichage
|
||||
if len(profils) > 1:
|
||||
profils_aff = "\n" + "\n".join([" " * 10 + prof for prof in profils])
|
||||
else:
|
||||
profils_aff = "\n".join(profils)
|
||||
pe_affichage.pe_print(
|
||||
f"--> Moyenne générale calculée avec pour coeffs d'UEs : {profils_aff}"
|
||||
)
|
||||
|
||||
|
||||
def get_synthese_tags_personnalises_semestre(formsemestre: FormSemestre):
|
||||
"""Etant données les implémentations des modules du semestre (modimpls),
|
||||
|
@ -116,12 +116,13 @@ class SxTag(pe_tabletags.TableTag):
|
||||
"""Les etudids triés"""
|
||||
|
||||
# Affichage
|
||||
pe_affichage.pe_print(f"--> {self.get_repr(verbose=True)}")
|
||||
pe_affichage.pe_print(f"*** {self.get_repr(verbose=True)}")
|
||||
|
||||
# Les tags
|
||||
self.tags_sorted = self.ressembuttag_final.tags_sorted
|
||||
"""Tags (extraits du ReSemBUTTag final)"""
|
||||
pe_affichage.pe_print(f"* Tags : {', '.join(self.tags_sorted)}")
|
||||
aff_tag = ["👜" + tag for tag in self.tags_sorted]
|
||||
pe_affichage.pe_print(f"--> Tags : {', '.join(aff_tag)}")
|
||||
|
||||
# Les UE données par leur acronyme
|
||||
self.acronymes_sorted = self.ressembuttag_final.acronymes_sorted
|
||||
@ -134,10 +135,13 @@ class SxTag(pe_tabletags.TableTag):
|
||||
"""L'association acronyme d'UEs -> compétence"""
|
||||
self.competences_sorted = sorted(self.acronymes_ues_to_competences.values())
|
||||
"""Les compétences triées par nom"""
|
||||
self._aff_ue_et_comp_debug()
|
||||
|
||||
# Les coeffs pour la moyenne générale (traduisant également l'inscription
|
||||
# des étudiants aux UEs) (etudids_sorted x acronymes_ues_sorted)
|
||||
self.matrice_coeffs_moy_gen = self.ressembuttag_final.matrice_coeffs_moy_gen
|
||||
"""La matrice des coeffs pour la moyenne générale"""
|
||||
self.__aff_profil_coeffs()
|
||||
|
||||
# Masque des inscriptions et des capitalisations
|
||||
self.masque_df = None
|
||||
@ -153,10 +157,13 @@ class SxTag(pe_tabletags.TableTag):
|
||||
# Les moyennes par tag
|
||||
self.moyennes_tags: dict[str, pd.DataFrame] = {}
|
||||
"""Moyennes aux UEs (identifiées par leur acronyme) des différents tags"""
|
||||
if self.tags_sorted:
|
||||
pe_affichage.pe_print("--> Calcul des moyennes par tags :")
|
||||
|
||||
for tag in self.tags_sorted:
|
||||
# Y-a-t-il des notes ?
|
||||
if not self.has_notes(tag):
|
||||
pe_affichage.pe_print(f"> MoyTag 🏷{tag} actuellement sans ◯ notes")
|
||||
pe_affichage.pe_print(f" > MoyTag 👜{tag} actuellement sans notes")
|
||||
matrice_moys_ues = pd.DataFrame(
|
||||
np.nan, index=self.etudids_sorted, columns=self.acronymes_sorted
|
||||
)
|
||||
@ -198,17 +205,24 @@ class SxTag(pe_tabletags.TableTag):
|
||||
(pour debug)
|
||||
"""
|
||||
|
||||
# Les profils d'ects (pour debug)
|
||||
profils_ects = []
|
||||
# Les profils des coeffs d'UE (pour debug)
|
||||
profils = []
|
||||
for i in self.matrice_coeffs_moy_gen.index:
|
||||
val = tuple(self.matrice_coeffs_moy_gen.loc[i].fillna("x"))
|
||||
if tuple(val) not in profils_ects:
|
||||
profils_ects.append(tuple(val))
|
||||
val = self.matrice_coeffs_moy_gen.loc[i].fillna("-")
|
||||
val = " | ".join([str(v) for v in val])
|
||||
if val not in profils:
|
||||
profils += [val]
|
||||
|
||||
# L'affichage
|
||||
if len(profils) > 1:
|
||||
profils_aff = "\n" + "\n".join([" " * 10 + prof for prof in profils])
|
||||
else:
|
||||
profils_aff = "\n".join(profils)
|
||||
|
||||
# L'affichage
|
||||
ues = ", ".join(self.acronymes_sorted)
|
||||
pe_affichage.pe_print(
|
||||
f"> MoyTag 🏷{tag} avec " + f"ues={ues} " + f"inscr/ects={profils_ects}"
|
||||
f" > MoyTag 👜{tag} pour UES: {ues} avec pour coeffs : {profils_aff}"
|
||||
)
|
||||
|
||||
def has_notes(self, tag):
|
||||
@ -243,8 +257,16 @@ class SxTag(pe_tabletags.TableTag):
|
||||
# affichage = [str(fid) for fid in self.ressembuttags]
|
||||
return f"SXTag {self.nom_rcs}#{self.fid_final}"
|
||||
|
||||
def _aff_ue_et_comp_debug(self):
|
||||
"""Affichage pour debug"""
|
||||
aff_comp = []
|
||||
for acro in self.acronymes_sorted:
|
||||
aff_comp += [f"📍{acro} (∈ 💡{self.acronymes_ues_to_competences[acro]})"]
|
||||
pe_affichage.pe_print(f"--> UEs/Compétences : {', '.join(aff_comp)}")
|
||||
|
||||
def _aff_capitalisations(self):
|
||||
"""Affichage des capitalisations du sxtag pour debug"""
|
||||
aff_cap = []
|
||||
for etud in self.etuds:
|
||||
cap = []
|
||||
for frmsem_id in self.ressembuttags:
|
||||
@ -253,8 +275,32 @@ class SxTag(pe_tabletags.TableTag):
|
||||
if self.masque_df[frmsem_id].loc[etud.etudid, accr] > 0.0:
|
||||
cap += [accr]
|
||||
if cap:
|
||||
aff_cap += [f" > {etud.nomprenom} : {', '.join(cap)}"]
|
||||
if aff_cap:
|
||||
pe_affichage.pe_print(f"--> ⚠️ Capitalisations :")
|
||||
pe_affichage.pe_print("\n".join(aff_cap))
|
||||
|
||||
def __aff_profil_coeffs(self):
|
||||
"""Extrait de la matrice des coeffs, les différents types d'inscription
|
||||
et de coefficients (appelés profil) des étudiants et les affiche
|
||||
(pour debug)
|
||||
"""
|
||||
|
||||
# Les profils des coeffs d'UE (pour debug)
|
||||
profils = []
|
||||
for i in self.matrice_coeffs_moy_gen.index:
|
||||
val = self.matrice_coeffs_moy_gen.loc[i].fillna("-")
|
||||
val = " | ".join([str(v) for v in val])
|
||||
if val not in profils:
|
||||
profils += [val]
|
||||
|
||||
# L'affichage
|
||||
if len(profils) > 1:
|
||||
profils_aff = "\n" + "\n".join([" " * 10 + prof for prof in profils])
|
||||
else:
|
||||
profils_aff = "\n".join(profils)
|
||||
pe_affichage.pe_print(
|
||||
f" ⚠ Capitalisation de {etud.etat_civil} : {', '.join(cap)}"
|
||||
f"--> Moyenne générale calculée avec pour coeffs d'UEs : {profils_aff}"
|
||||
)
|
||||
|
||||
|
||||
|
@ -43,6 +43,7 @@ from app.pe import pe_comp, pe_affichage
|
||||
from app.scodoc import codes_cursus
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.comp.res_sem import load_formsemestre_results
|
||||
import warnings
|
||||
|
||||
|
||||
class EtudiantsJuryPE:
|
||||
@ -100,10 +101,10 @@ class EtudiantsJuryPE:
|
||||
self.cosemestres = cosemestres
|
||||
|
||||
pe_affichage.pe_print(
|
||||
f"1) Recherche des coSemestres -> {len(cosemestres)} trouvés"
|
||||
f"1) Recherche des cosemestres -> {len(cosemestres)} trouvés"
|
||||
)
|
||||
|
||||
pe_affichage.pe_print("2) Liste des étudiants dans les différents co-semestres")
|
||||
pe_affichage.pe_print("2) Liste des étudiants dans les différents cosemestres")
|
||||
self.etudiants_ids = get_etudiants_dans_semestres(cosemestres)
|
||||
pe_affichage.pe_print(
|
||||
f" => {len(self.etudiants_ids)} étudiants trouvés dans les cosemestres"
|
||||
@ -135,23 +136,16 @@ class EtudiantsJuryPE:
|
||||
# Les identifiants des étudiants ayant redoublés ou ayant abandonnés
|
||||
|
||||
# Synthèse
|
||||
pe_affichage.pe_print(f"4) Bilan")
|
||||
pe_affichage.pe_print(
|
||||
f" => {len(self.etudiants_diplomes)} étudiants à diplômer en {self.annee_diplome}"
|
||||
f"--> {len(self.etudiants_diplomes)} étudiants à diplômer en {self.annee_diplome}"
|
||||
)
|
||||
nbre_abandons = len(self.etudiants_ids) - len(self.etudiants_diplomes)
|
||||
assert nbre_abandons == len(self.abandons_ids)
|
||||
|
||||
pe_affichage.pe_print(
|
||||
f" => {nbre_abandons} étudiants traités mais non diplômés (redoublement, réorientation, abandon)"
|
||||
f"--> {nbre_abandons} étudiants traités mais non diplômés (redoublement, réorientation, abandon)"
|
||||
)
|
||||
# pe_affichage.pe_print(
|
||||
# " => quelques étudiants futurs diplômés : "
|
||||
# + ", ".join([str(etudid) for etudid in list(self.etudiants_diplomes)[:10]])
|
||||
# )
|
||||
# pe_affichage.pe_print(
|
||||
# " => semestres dont il faut calculer les moyennes : "
|
||||
# + ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)])
|
||||
# )
|
||||
|
||||
def get_etudiants_diplomes(self) -> dict[int, Identite]:
|
||||
"""Identités des étudiants (sous forme d'un dictionnaire `{etudid: Identite(etudid)}`
|
||||
@ -240,6 +234,7 @@ class EtudiantsJuryPE:
|
||||
if self.cursus[etudid]["diplome"] == self.annee_diplome:
|
||||
# Est-il démissionnaire : charge son dernier semestre pour connaitre son état ?
|
||||
dernier_semes_etudiant = formsemestres[0]
|
||||
with warnings.catch_warnings():
|
||||
res = load_formsemestre_results(dernier_semes_etudiant)
|
||||
etud_etat = res.get_etud_etat(etudid)
|
||||
if etud_etat == scu.DEMISSION:
|
||||
@ -547,45 +542,11 @@ def arret_de_formation(etud: Identite, cosemestres: dict[int, FormSemestre]) ->
|
||||
pe_affichage.pe_print(
|
||||
f"--> ⛔ {etud.etat_civil} ({etud.etudid}), non inscrit dans {affichage} amenant à diplômation"
|
||||
)
|
||||
else:
|
||||
pe_affichage.pe_print(f"--> ✅ {etud.etat_civil} ({etud.etudid})")
|
||||
|
||||
return est_demissionnaire
|
||||
|
||||
# # Son dernier semestre APC en date
|
||||
# dernier_formsemestre = get_dernier_semestre_en_date(semestres_apc)
|
||||
# numero_dernier_formsemestre = dernier_formsemestre.semestre_id
|
||||
#
|
||||
# # Les numéro de semestres possible dans lesquels il pourrait s'incrire
|
||||
# # semestre impair => passage de droit en semestre pair suivant (effet de l'annualisation)
|
||||
# if numero_dernier_formsemestre % 2 == 1:
|
||||
# numeros_possibles = list(
|
||||
# range(numero_dernier_formsemestre + 1, pe_comp.NBRE_SEMESTRES_DIPLOMANT)
|
||||
# )
|
||||
# # semestre pair => passage en année supérieure ou redoublement
|
||||
# else: #
|
||||
# numeros_possibles = list(
|
||||
# range(
|
||||
# max(numero_dernier_formsemestre - 1, 1),
|
||||
# pe_comp.NBRE_SEMESTRES_DIPLOMANT,
|
||||
# )
|
||||
# )
|
||||
#
|
||||
# # Y-a-t-il des cosemestres dans lesquels il aurait pu s'incrire ?
|
||||
# formsestres_superieurs_possibles = []
|
||||
# for fid, sem in cosemestres.items(): # Les semestres ayant des inscrits
|
||||
# if (
|
||||
# fid != dernier_formsemestre.formsemestre_id
|
||||
# and sem.semestre_id in numeros_possibles
|
||||
# and sem.date_debut.year >= dernier_formsemestre.date_debut.year
|
||||
# ):
|
||||
# # date de debut des semestres possibles postérieur au dernier semestre de l'étudiant
|
||||
# # et de niveau plus élevé que le dernier semestre valide de l'étudiant
|
||||
# formsestres_superieurs_possibles.append(fid)
|
||||
#
|
||||
# if len(formsestres_superieurs_possibles) > 0:
|
||||
# return True
|
||||
#
|
||||
# return False
|
||||
|
||||
|
||||
def etapes_du_cursus(
|
||||
semestres: dict[int, FormSemestre], nbre_etapes_max: int
|
||||
@ -650,6 +611,6 @@ def nom_semestre_etape(semestre: FormSemestre, avec_fid=False) -> str:
|
||||
f"{semestre.date_debut.year}-{semestre.date_fin.year}",
|
||||
]
|
||||
if avec_fid:
|
||||
description.append(f"({semestre.formsemestre_id})")
|
||||
description.append(f"(#{semestre.formsemestre_id})")
|
||||
|
||||
return " ".join(description)
|
||||
|
@ -91,11 +91,14 @@ class JuryPE(object):
|
||||
)
|
||||
# Chargement des étudiants à prendre en compte dans le jury
|
||||
pe_affichage.pe_print(
|
||||
f"""*** Recherche des étudiants diplômés 🎓 en {self.diplome}"""
|
||||
f"""***********************************************************\n"""
|
||||
f"""*** Recherche des étudiants diplômés 🎓 en {self.diplome}\n"""
|
||||
f"""***********************************************************\n"""
|
||||
)
|
||||
self.etudiants = pe_etudiant.EtudiantsJuryPE(
|
||||
self.diplome
|
||||
) # Les infos sur les étudiants
|
||||
|
||||
# Les infos sur les étudiants
|
||||
self.etudiants = pe_etudiant.EtudiantsJuryPE(self.diplome)
|
||||
"""Les informations sur les étudiants du jury PE"""
|
||||
self.etudiants.find_etudiants()
|
||||
self.diplomes_ids = self.etudiants.diplomes_ids
|
||||
|
||||
@ -153,13 +156,14 @@ class JuryPE(object):
|
||||
def _gen_xls_ressembuttags(self, zipfile: ZipFile):
|
||||
"""Calcule les moyennes par tag des résultats des Semestres BUT"""
|
||||
pe_affichage.pe_print(
|
||||
"*** Génère les ResSemBUTTag (résultats des semestres BUT taggués)"
|
||||
f"""*************************************************************************\n"""
|
||||
f"""*** Génère les ResSemBUTTag (ResSemestreBUT taggués)\n"""
|
||||
f"""*************************************************************************"""
|
||||
)
|
||||
|
||||
# Tous les formsestres des étudiants
|
||||
formsemestres = get_formsemestres_etudiants(self.etudiants)
|
||||
pe_affichage.pe_print(
|
||||
f"--> {len(formsemestres)} résultats de semestres à considérer"
|
||||
)
|
||||
pe_affichage.pe_print(f"1) Génère les {len(formsemestres)} ResSemBUTTag")
|
||||
|
||||
self.ressembuttags = {}
|
||||
for frmsem_id, formsemestre in formsemestres.items():
|
||||
@ -167,6 +171,7 @@ class JuryPE(object):
|
||||
self.ressembuttags[frmsem_id] = pe_ressemtag.ResSemBUTTag(formsemestre)
|
||||
|
||||
# Intègre le bilan des semestres taggués au zip final
|
||||
pe_affichage.pe_print(f"2) Bilan")
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||
output, engine="openpyxl"
|
||||
@ -174,13 +179,14 @@ class JuryPE(object):
|
||||
onglets = []
|
||||
for res_sem_tag in self.ressembuttags.values():
|
||||
onglet = res_sem_tag.get_repr(verbose=True)
|
||||
onglets += []
|
||||
onglet = onglet.replace("Semestre ", "S")
|
||||
onglets += ["📊" + onglet]
|
||||
df = res_sem_tag.to_df()
|
||||
# Conversion colonnes en multiindex
|
||||
df = convert_colonnes_to_multiindex(df)
|
||||
# écriture dans l'onglet
|
||||
df.to_excel(writer, onglet, index=True, header=True)
|
||||
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||
pe_affichage.pe_print(f"--> Export excel de {', '.join(onglets)}")
|
||||
output.seek(0)
|
||||
|
||||
self.add_file_to_zip(
|
||||
@ -196,10 +202,13 @@ class JuryPE(object):
|
||||
RCS (par ex: 'S2' ou '3S').
|
||||
"""
|
||||
pe_affichage.pe_print(
|
||||
"*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants"
|
||||
"***************************************************************************\n"
|
||||
"*** Génère les trajectoires (≠tes combinaisons de semestres) des étudiants"
|
||||
"***************************************************************************\n"
|
||||
)
|
||||
|
||||
self.rcss_jury.cree_trajectoires(self.etudiants)
|
||||
self.rcss_jury._aff_trajectoires(self.etudiants)
|
||||
|
||||
def _gen_semXs(self):
|
||||
"""Génère les SemXs (trajectoires/combinaisons de semestre de même rang x)
|
||||
@ -218,10 +227,13 @@ class JuryPE(object):
|
||||
"""
|
||||
# Génère les moyennes des RCS de type Sx
|
||||
pe_affichage.pe_print(
|
||||
"*** Calcule les moyennes des SxTag (moyennes d'un SemX/RCS de type Sx)"
|
||||
"***************************************************************************\n"
|
||||
"*** Calcule les moyennes des SxTag (moyennes d'un RCS de type Sx)"
|
||||
"***************************************************************************\n"
|
||||
)
|
||||
|
||||
# Les SxTag (moyenne de Sx par UE)
|
||||
pe_affichage.pe_print("1) Calcul des moyennes")
|
||||
self.sxtags = {}
|
||||
for rcf_id, rcf in self.rcss_jury.semXs.items():
|
||||
# SxTag traduisant le RCF
|
||||
@ -229,6 +241,7 @@ class JuryPE(object):
|
||||
self.sxtags[sxtag_id] = pe_sxtag.SxTag(sxtag_id, rcf, self.ressembuttags)
|
||||
|
||||
# Intègre le bilan des semestres taggués au zip final
|
||||
pe_affichage.pe_print("2) Bilan")
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||
output, engine="openpyxl"
|
||||
@ -240,10 +253,10 @@ class JuryPE(object):
|
||||
df = sxtag.to_df()
|
||||
# Conversion colonnes en multiindex
|
||||
df = convert_colonnes_to_multiindex(df)
|
||||
onglets += [onglet]
|
||||
onglets += ["📊" + onglet]
|
||||
# écriture dans l'onglet
|
||||
df.to_excel(writer, onglet, index=True, header=True)
|
||||
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||
pe_affichage.pe_print(f"--> Export excel de {', '.join(onglets)}")
|
||||
|
||||
output.seek(0)
|
||||
if onglets:
|
||||
@ -258,8 +271,10 @@ class JuryPE(object):
|
||||
"""Génère les regroupements cohérents de RCFs qu'ont suivi chaque étudiant"""
|
||||
|
||||
pe_affichage.pe_print(
|
||||
"*** Génère les RCSemX (regroupements cohérents de données"
|
||||
" extraites des SemX) amenant du S1 à un semestre final***"
|
||||
"""******************************************************************************\n"""
|
||||
"""*** Génère les RCSemX (regroupements cohérents de données extraites des SemX)\n"""
|
||||
"""*** amenant du S1 à un semestre final\n"""
|
||||
"""******************************************************************************"""
|
||||
)
|
||||
self.rcss_jury.cree_rcsemxs(self.etudiants)
|
||||
self.rcss_jury._aff_rcsemxs_suivis(self.etudiants)
|
||||
@ -284,7 +299,11 @@ class JuryPE(object):
|
||||
"""
|
||||
|
||||
# Génère les moyennes des RCS de type Sx
|
||||
pe_affichage.pe_print("*** Calcule les moyennes des RC de RCFS")
|
||||
pe_affichage.pe_print(
|
||||
"""****************************************************\n"""
|
||||
"""*** Génère les moyennes associées aux RCSemX \n"""
|
||||
"""****************************************************"""
|
||||
)
|
||||
|
||||
self.rcss_tags = {}
|
||||
for rcs_id, rcsemx in self.rcss_jury.rcsemxs.items():
|
||||
|
@ -93,15 +93,19 @@ class RCSsJuryPE:
|
||||
# Mémorise le RCS suivi par l'étudiant
|
||||
self.trajectoires_suivies[etudid][nom_rcs] = rcs
|
||||
|
||||
def _aff_trajectoires(self, etudiants: pe_etudiant.EtudiantsJuryPE):
|
||||
"""Affiche les chemins trouvés pour debug"""
|
||||
# Affichage pour debug
|
||||
jeunes = list(enumerate(self.trajectoires_suivies))
|
||||
for no_etud, etudid in jeunes[:20]:
|
||||
for no_etud, etudid in jeunes:
|
||||
etat = "⛔" if etudid in etudiants.abandons_ids else "✅"
|
||||
|
||||
pe_affichage.pe_print(
|
||||
f"--> {etudiants.identites[etudid].nomprenom} (#{etudid}) :"
|
||||
f"--> {etat} {etudiants.identites[etudid].nomprenom} (#{etudid}) :"
|
||||
)
|
||||
for nom_rcs, rcs in self.trajectoires_suivies[etudid].items():
|
||||
if rcs:
|
||||
pe_affichage.pe_print(f" > RCS {nom_rcs}: {rcs.get_repr()}")
|
||||
pe_affichage.pe_print(f" > RCS ⏯️{nom_rcs}: {rcs.get_repr()}")
|
||||
|
||||
def cree_semxs(self, etudiants: pe_etudiant.EtudiantsJuryPE):
|
||||
"""Créé les les SemXs (trajectoires/combinaisons de semestre de même rang x),
|
||||
@ -126,16 +130,26 @@ class RCSsJuryPE:
|
||||
def _aff_semxs_suivis(self, etudiants: pe_etudiant.EtudiantsJuryPE):
|
||||
"""Affichage des SemX pour debug"""
|
||||
jeunes = list(enumerate(self.semXs_suivis))
|
||||
vides = []
|
||||
for no_etud, etudid in jeunes[:20]:
|
||||
pe_affichage.pe_print(f"-> {etudiants.identites[etudid].nomprenom} :")
|
||||
|
||||
for no_etud, etudid in jeunes:
|
||||
etat = "⛔" if etudid in etudiants.abandons_ids else "✅"
|
||||
pe_affichage.pe_print(
|
||||
f"--> {etat} {etudiants.identites[etudid].nomprenom} :"
|
||||
)
|
||||
for nom_rcs, rcs in self.semXs_suivis[etudid].items():
|
||||
if rcs:
|
||||
pe_affichage.pe_print(f" > SemX {nom_rcs}: {rcs.get_repr()}")
|
||||
else:
|
||||
pe_affichage.pe_print(f" > SemX ⏯️{nom_rcs}: {rcs.get_repr()}")
|
||||
|
||||
vides = []
|
||||
for nom_rcs in pe_rcs.TOUS_LES_SEMESTRES:
|
||||
les_semX_suivis = []
|
||||
for no_etud, etudid in jeunes:
|
||||
if self.semXs_suivis[etudid][nom_rcs]:
|
||||
les_semX_suivis.append(self.semXs_suivis[etudid][nom_rcs])
|
||||
if not les_semX_suivis:
|
||||
vides += [nom_rcs]
|
||||
vides = sorted(list(set(vides)))
|
||||
pe_affichage.pe_print(f"-> ⚠ SemX vides : {', '.join(vides)}")
|
||||
pe_affichage.pe_print(f"⚠️ SemX sans données : {', '.join(vides)}")
|
||||
|
||||
def cree_rcsemxs(self, etudiants: pe_etudiant.EtudiantsJuryPE):
|
||||
"""Créé tous les RCSemXs, au regard du cursus des étudiants
|
||||
@ -146,6 +160,7 @@ class RCSsJuryPE:
|
||||
self.rcsemxs = {}
|
||||
|
||||
# Pour tous les étudiants du jury
|
||||
pas_de_semestres = []
|
||||
for etudid in self.trajectoires_suivies:
|
||||
self.rcsemxs_suivis[etudid] = {
|
||||
nom_rcs: None for nom_rcs in pe_rcs.TOUS_LES_RCS_AVEC_PLUSIEURS_SEM
|
||||
@ -160,6 +175,7 @@ class RCSsJuryPE:
|
||||
|
||||
# Pour chaque aggréggat de type xA ou Sx
|
||||
tous_les_agregats = pe_rcs.TOUS_LES_RCS
|
||||
|
||||
for nom_rcs in tous_les_agregats:
|
||||
trajectoire = self.trajectoires_suivies[etudid][nom_rcs]
|
||||
if not trajectoire:
|
||||
@ -183,9 +199,9 @@ class RCSsJuryPE:
|
||||
for Sx in noms_sems_aggregat:
|
||||
semestres_etudiants = etudiants.cursus[etudid][Sx]
|
||||
if not semestres_etudiants:
|
||||
pe_affichage.pe_print(
|
||||
f"-> ⚠ Pas de semestres {Sx} pour {etudiants.identites[etudid].etat_civil}"
|
||||
)
|
||||
pas_de_semestres += [
|
||||
f"{Sx} pour {etudiants.identites[etudid].nomprenom}"
|
||||
]
|
||||
else:
|
||||
semx_id = get_semx_from_semestres_aggreges(
|
||||
self.semXs, semestres_etudiants
|
||||
@ -204,20 +220,37 @@ class RCSsJuryPE:
|
||||
# Mémoire du RCSemX aux informations de suivi de l'étudiant
|
||||
self.rcsemxs_suivis[etudid][nom_rcs] = rcsemx
|
||||
|
||||
# Affichage des étudiants pour lesquels il manque un semestre
|
||||
pas_de_semestres = sorted(set(pas_de_semestres))
|
||||
if pas_de_semestres:
|
||||
pe_affichage.pe_print("⚠️ Semestres manquants :")
|
||||
pe_affichage.pe_print(
|
||||
"\n".join([" " * 10 + psd for psd in pas_de_semestres])
|
||||
)
|
||||
|
||||
def _aff_rcsemxs_suivis(self, etudiants):
|
||||
"""Affiche les RCSemX suivis par les étudiants"""
|
||||
# Affichage pour debug
|
||||
jeunes = list(enumerate(self.rcsemxs_suivis.keys()))
|
||||
vides = []
|
||||
for no_etud, etudid in jeunes:
|
||||
if etudid not in etudiants.abandons_ids:
|
||||
pe_affichage.pe_print(f"-> {etudiants.identites[etudid].nomprenom} :")
|
||||
etat = "⛔" if etudid in etudiants.abandons_ids else "✅"
|
||||
pe_affichage.pe_print(
|
||||
f"-> {etat} {etudiants.identites[etudid].nomprenom} :"
|
||||
)
|
||||
for nom_rcs, rcs in self.rcsemxs_suivis[etudid].items():
|
||||
if rcs:
|
||||
pe_affichage.pe_print(f" > RCSemX {nom_rcs}: {rcs.get_repr()}")
|
||||
else:
|
||||
vides += [f"{nom_rcs}"]
|
||||
pe_affichage.pe_print(f"-> ⚠ RCSemX vides : {', '.join(list(set(vides)))}")
|
||||
pe_affichage.pe_print(f" > RCSemX ⏯️{nom_rcs}: {rcs.get_repr()}")
|
||||
|
||||
vides = []
|
||||
for nom_rcs in pe_rcs.TOUS_LES_RCS:
|
||||
les_rcssemX_suivis = []
|
||||
for no_etud, etudid in jeunes:
|
||||
if self.rcsemxs_suivis[etudid][nom_rcs]:
|
||||
les_rcssemX_suivis.append(self.rcsemxs_suivis[etudid][nom_rcs])
|
||||
if not les_rcssemX_suivis:
|
||||
vides += [nom_rcs]
|
||||
vides = sorted(list(set(vides)))
|
||||
pe_affichage.pe_print(f"⚠️ RCSemX vides : {', '.join(vides)}")
|
||||
|
||||
|
||||
def get_rcs_etudiant(
|
||||
|
Loading…
Reference in New Issue
Block a user