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
Showing only changes of commit 7a0b560d54 - Show all commits

View File

@ -35,9 +35,16 @@ Created on Fri Sep 9 09:15:05 2016
@author: barasc @author: barasc
""" """
from app.comp.res_sem import load_formsemestre_results
from app.models import FormSemestre
from app.pe.pe_semestretag import SemestreTag
from app.pe.pe_tools import pe_print, PE_DEBUG from app.pe.pe_tools import pe_print, PE_DEBUG
from app.pe import pe_tagtable from app.pe import pe_tagtable
import pandas as pd
import numpy as np
from app.pe.pe_etudiant import EtudiantsJuryPE
class SetTag(pe_tagtable.TableTag): class SetTag(pe_tagtable.TableTag):
@ -50,80 +57,88 @@ class SetTag(pe_tagtable.TableTag):
un etudiant non inscrit dans un S1 mais dans un S2 et un S3 n'est pas pris en compte). un etudiant non inscrit dans un S1 mais dans un S2 et un S3 n'est pas pris en compte).
""" """
# ------------------------------------------------------------------------------------------------------------------- def __init__(
def __init__(self, nom_combinaison, parcours): self,
pe_tagtable.TableTag.__init__(self, nom=nom_combinaison) nom,
self.combinaison = nom_combinaison formsemestre_terminal: FormSemestre,
self.parcours = parcours # Le groupe de semestres/parcours à aggréger semestres_aggreges: dict[int, FormSemestre],
semestres_taggues: dict[int, SemestreTag],
# ------------------------------------------------------------------------------------------- donnees_etudiants: EtudiantsJuryPE,
def set_Etudiants(
self, etudiants: list[dict], juryPEDict, etudInfoDict, nom_sem_final=None
): ):
"""Détermine la liste des étudiants à prendre en compte, en partant de pe_tagtable.TableTag.__init__(self, nom)
la liste en paramètre et en vérifiant qu'ils ont tous un parcours valide."""
if nom_sem_final:
self.nom += "_" + nom_sem_final
for etudid in etudiants:
parcours_incomplet = (
sum([juryPEDict[etudid][nom_sem] is None for nom_sem in self.parcours])
> 0
) # manque-t-il des formsemestre_id validant aka l'étudiant n'a pas été inscrit dans tous les semestres de l'aggrégat
if not parcours_incomplet:
self.inscrlist.append(etudInfoDict[etudid])
self.identdict[etudid] = etudInfoDict[etudid]
delta = len(etudiants) - len(self.inscrlist) """Le formsemestre terminal et les semestres aggrégés"""
if delta > 0: self.formsemestre_terminal = formsemestre_terminal
pe_print(self.nom + " -> " + str(delta) + " étudiants supprimés") nt = load_formsemestre_results(formsemestre_terminal)
self.semestres_aggreges = semestres_aggreges
# Le sous-ensemble des parcours """Les semestres tags associés aux semestres aggrégés"""
self.parcoursDict = {etudid: juryPEDict[etudid] for etudid in self.identdict} try:
self.semestres_tags_aggreges = {
# ------------------------------------------------------------------------------------------- frmsem_id: semestres_taggues[frmsem_id]
def get_Fids_in_settag(self): for frmsem_id in semestres_taggues
"""Renvoie la liste des semestres (leur formsemestre_id) à prendre en compte
pour le calcul des moyennes, en considérant tous les étudiants inscrits et
tous les semestres de leur parcours"""
return list(
{
self.parcoursDict[etudid][nom_sem]
for etudid in self.identdict
for nom_sem in self.parcours
} }
) except:
raise ValueError("Semestres taggués manquants")
# --------------------------------------------------------------------------------------------- """Les étudiants (état civil + cursus connu)"""
def set_SemTagDict(self, SemTagDict): self.etuds = nt.etuds
"""Mémorise les semtag nécessaires au jury.""" self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
self.SemTagDict = {fid: SemTagDict[fid] for fid in self.get_Fids_in_settag()} self.cursus = {
if PE_DEBUG >= 1: etudid: donnees_etudiants.cursus[etudid] for etudid in self.etudiants
pe_print(" => %d semestres fusionnés" % len(self.SemTagDict)) }
"""Les tags extraits de tous les semestres"""
self.tags_sorted = self.do_taglist()
"""Construit le cube de notes"""
self.notes_cube = {}
"""Les moyennes par tag"""
self.moyennes_tags = {}
# ------------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------------
def comp_data_settag(self): def compute_notes_cube(self):
"""Calcule tous les données numériques relatives au settag""" """Construit le cube de notes (etudid x tags x semestre_aggregé)
# Attributs relatifs aux tag pour les modules pris en compte nécessaire au calcul des moyennes de l'aggrégat
self.taglist = self.do_taglist() # la liste des tags """
self.do_tagdict() # le dico descriptif des tags nb_tags = len(self.tags_sorted)
# if PE_DEBUG >= 1: pe_print(" => Tags = " + ", ".join( self.taglist )) nb_etudiants = len(self.etuds)
nb_semestres = len(self.semestres_tags_aggreges)
"""Index du cube (etudids -> dim 0, tags -> dim 1)"""
etudids = [etud.etudid for etud in self.etuds]
tags = self.tags_sorted
semestres_id = list(self.semestres_tags_aggreges.keys())
dfs = {}
for frmsem_id in semestres_id:
"""Partant d'un dataframe vierge"""
df = pd.DataFrame(np.nan, index=etudids, columns=self.tags_sorted)
"""Charge les notes du semestre tag"""
notes = self.semestres_tags_aggreges[frmsem_id].notes
"""Les étudiants & les tags commun au dataframe final et aux notes du semestre)"""
etudids_communs = df.index.intersection(notes.index)
tags_communs = df.columns.intersection(notes.columns)
"""Injecte les notes par tag"""
df.loc[etudids_communs, tags_communs] = notes.loc[
etudids_communs, tags_communs
]
"""Stocke le df"""
dfs[frmsem_id] = df
"""Réunit les notes sous forme d'un cube etdids x tags x semestres"""
semestres_x_etudids_x_tags = [dfs[fid].values for fid in dfs]
etudids_x_tags_x_semestres = np.stack(semestres_x_etudids_x_tags, axis=-1)
return etudids_x_tags_x_semestres
# Calcul des moyennes de chaque étudiant par tag
reussiteAjoutTag = {"OK": [], "KO": []}
for tag in self.taglist:
moyennes = self.comp_MoyennesSetTag(tag, force=False)
res = self.add_moyennesTag(tag, moyennes) # pas de notes => pas de moyenne
reussiteAjoutTag["OK" if res else "KO"].append(tag)
if len(reussiteAjoutTag["OK"]) > 0 and PE_DEBUG:
pe_print(
" => Fusion de %d tags : " % (len(reussiteAjoutTag["OK"]))
+ ", ".join(reussiteAjoutTag["OK"])
)
if len(reussiteAjoutTag["KO"]) > 0 and PE_DEBUG:
pe_print(
" => %d tags manquants : " % (len(reussiteAjoutTag["KO"]))
+ ", ".join(reussiteAjoutTag["KO"])
)
# ------------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------------
def get_etudids(self): def get_etudids(self):
@ -131,13 +146,15 @@ class SetTag(pe_tagtable.TableTag):
# ------------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------------
def do_taglist(self): def do_taglist(self):
"""Parcourt les tags des semestres taggués et les synthétise sous la forme """Synthétise les tags à partir des semestres (taggués) aggrégés
d'une liste en supprimant les doublons
Returns:
Une liste de tags triés par ordre alphabétique
""" """
ensemble = [] tags = []
for semtag in self.SemTagDict.values(): for frmsem_id in self.semestres_tags_aggreges:
ensemble.extend(semtag.get_all_tags()) tags.extend(self.semestres_tags_aggreges[frmsem_id].tags_sorted)
return sorted(list(set(ensemble))) return sorted(set(tags))
# ------------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------------
def do_tagdict(self): def do_tagdict(self):