import app.pe.pe_comp as pe_comp from app.models import FormSemestre from app.pe.pe_etudiant import EtudiantsJuryPE, get_dernier_semestre_en_date class Trajectoire: """Modélise, pour un aggrégat visé (par ex: 'S2', '3S', '2A') et un ensemble d'étudiants donnés, la combinaison des formsemestres des étudiants amenant à un semestre terminal visé. Si l'aggrégat est un semestre de type Si, elle stocke le (ou les) formsemestres de numéro i qu'ont suivis l'étudiant pour atteindre le Si (en général 1 si personnes n'a redoublé, mais 2 s'il y a des redoublants) Pour des aggrégats de type iS ou iA (par ex, 3A=S1+S2+S3), elle identifie les semestres que les étudiants ont suivis pour les amener jusqu'au semestre terminal de la trajectoire (par ex: ici un S3). Ces semestres peuvent être : * des S1+S2+S1+S2+S3 si redoublement de la 1ère année * des S1+S2+(année de césure)+S3 si césure, ... """ def __init__(self, nom_aggregat: str, semestre_final: FormSemestre): """Modélise un ensemble de formsemestres d'étudiants amenant à un semestre terminal Args: nom_aggregat: Un nom d'aggrégat (par ex: '5S') semestre_final: Le semestre final de l'aggrégat """ self.nom = nom_aggregat self.semestre_final = semestre_final self.trajectoire_id = (nom_aggregat, semestre_final.formsemestre_id) """Les semestres à aggréger""" self.semestres_aggreges = {} def add_semestres_a_aggreger(self, semestres: dict[int: FormSemestre]): """Ajoute des semestres au semestre à aggréger Args: semestres: Dictionnaire ``{fid: FormSemestre(fid)} à ajouter`` """ self.semestres_aggreges = self.semestres_aggreges | semestres def get_repr(self): """Représentation textuelle d'une trajectoire basée sur ses semestres aggrégés""" noms = [] for fid in self.semestres_aggreges: semestre = self.semestres_aggreges[fid] noms.append(f"S{semestre.semestre_id}({fid})") noms = sorted(noms) repr = f"{self.nom} ({self.semestre_final.formsemestre_id}) {self.semestre_final.date_fin.year}" if noms: repr += " - " + "+".join(noms) return repr class TrajectoiresJuryPE: """Centralise toutes les trajectoires du jury PE""" def __init__(self, annee_diplome: int): """ Args: annee_diplome: L'année de diplomation """ self.annee_diplome = annee_diplome """Toutes les trajectoires possibles""" self.trajectoires: dict[tuple: Trajectoire] = {} """Quelle trajectoires pour quel étudiant : dictionnaire {etudid: {nom_aggregat: Trajectoire}}""" self.suivi: dict[int: str] = {} def cree_trajectoires(self, etudiants: EtudiantsJuryPE): """Créé toutes les trajectoires, au regard du cursus des étudiants analysés + les mémorise dans les données de l'étudiant """ for nom_aggregat in pe_comp.TOUS_LES_SEMESTRES + pe_comp.TOUS_LES_AGGREGATS: """L'aggrégat considéré (par ex: 3S=S1+S2+S3), son nom de son semestre terminal (par ex: S3) et son numéro (par ex: 3)""" noms_semestre_de_aggregat = pe_comp.PARCOURS[nom_aggregat]["aggregat"] nom_semestre_terminal = noms_semestre_de_aggregat[-1] for etudid in etudiants.cursus: if etudid not in self.suivi: self.suivi[etudid] = {aggregat: None for aggregat in pe_comp.TOUS_LES_SEMESTRES + pe_comp.TOUS_LES_AGGREGATS} """Le formsemestre terminal (dernier en date) associé au semestre marquant la fin de l'aggrégat (par ex: son dernier S3 en date)""" semestres = etudiants.cursus[etudid][nom_semestre_terminal] if semestres: formsemestre_final = get_dernier_semestre_en_date(semestres) """Ajout ou récupération de la trajectoire""" trajectoire_id = (nom_aggregat, formsemestre_final.formsemestre_id) if trajectoire_id not in self.trajectoires: trajectoire = Trajectoire(nom_aggregat, formsemestre_final) self.trajectoires[trajectoire_id] = trajectoire else: trajectoire = self.trajectoires[trajectoire_id] """La liste des semestres de l'étudiant à prendre en compte pour cette trajectoire""" semestres_a_aggreger = etudiants.get_trajectoire(etudid, formsemestre_final) """Ajout des semestres à la trajectoire""" trajectoire.add_semestres_a_aggreger(semestres_a_aggreger) """Mémoire la trajectoire suivie par l'étudiant""" self.suivi[etudid][nom_aggregat] = trajectoire """Vérifications""" # dernier_semestre_aggregat = get_dernier_semestre_en_date(semestres_aggreges) # assert dernier_semestre_aggregat == formsemestre_terminal def get_trajectoires_etudid(trajectoires, etudid): """Fonction pour débuggage: renvoie la liste des trajectoires_id des trajectoires suivies par un étudiant """ if etudid not in trajectoires.suivi: pe_comp.pe_print(f"{etudid} fait-il bien partie du jury ?") liste = [] for aggregat in pe_comp.TOUS_LES_PARCOURS: trajet = trajectoires.suivi[etudid][aggregat] if trajet: liste.append(trajet.trajectoire_id) return liste def get_semestres_a_aggreger(self, aggregat: str, formsemestre_id_terminal: int): """Pour un nom d'aggrégat donné (par ex: 'S3') et un semestre terminal cible identifié par son formsemestre_id (par ex: 'S3 2022-2023'), renvoie l'ensemble des semestres à prendre en compte dans l'aggrégat sous la forme d'un dictionnaire {fid: FormSemestre(fid)}. Fusionne les cursus individuels des étudiants, dont le cursus correspond à l'aggrégat visé. Args: aggregat: Un aggrégat (par ex. 1A, 2A, 3S, 6S) formsemestre_id_terminal: L'identifiant du formsemestre terminal de l'aggrégat, devant correspondre au dernier semestre de l'aggrégat """ noms_semestres_aggreges = pe_comp.PARCOURS[aggregat]["aggregat"] formsemestres = {} for etudid in self.cursus: cursus_etudiant = self.cursus[etudid][aggregat] if formsemestre_id_terminal in cursus_etudiant: formsemestres_etudiant = cursus_etudiant[formsemestre_id_terminal] formsemestres = formsemestres | formsemestres_etudiant return formsemestres