forked from ScoDoc/ScoDoc
245 lines
10 KiB
Python
245 lines
10 KiB
Python
|
|
import app.pe.rcss.pe_rcf as pe_rcf
|
|
import app.pe.rcss.pe_rcrcf as pe_rcrcf
|
|
import app.pe.pe_etudiant as pe_etudiant
|
|
import app.pe.pe_comp as pe_comp
|
|
import app.pe.rcss.rcss_constantes as rcss_constantes
|
|
from app.models import FormSemestre
|
|
from app.pe import pe_affichage
|
|
|
|
|
|
class RCSsJuryPE:
|
|
"""Classe centralisant tous les regroupements cohérents de
|
|
semestres (RCS) des étudiants à prendre en compte dans un jury PE
|
|
|
|
Args:
|
|
annee_diplome: L'année de diplomation
|
|
"""
|
|
|
|
def __init__(self, annee_diplome: int):
|
|
self.annee_diplome = annee_diplome
|
|
"""Année de diplômation"""
|
|
|
|
self.rcss: dict[tuple(int, str): pe_rcf.RCF] = {}
|
|
"""Ensemble des RCS recensés"""
|
|
|
|
self.rcss_suivis: dict[int:dict] = {}
|
|
"""Dictionnaire associant, pour chaque étudiant et pour chaque type de RCS,
|
|
son RCS : {etudid: {nom_RCS: RCS}}"""
|
|
|
|
self.rcfs: dict[tuple(int, str) : pe_rcf.RCF] = {}
|
|
"""Ensemble des RCF recensés : {(nom_RCS, fid_terminal): RCF}"""
|
|
|
|
self.rcfs_suivis: dict[int:dict] = {}
|
|
"""Dictionnaire associant, pour chaque étudiant et pour chaque type de RCS,
|
|
son RCS : {etudid: {nom_RCS: RCF}}"""
|
|
|
|
self.rcrcfs: dict[tuple(int, str) : pe_rcrcf.RCRCF] = {}
|
|
"""Ensemble des RCS recensés : {(nom_RCS, fid_terminal): RCRCF}"""
|
|
|
|
self.rcrcfs_suivis: dict[int:str] = {}
|
|
"""Dictionnaire associant, pour chaque étudiant et pour chaque type de RCS,
|
|
son RCRCF : {etudid: {nom_RCS: RCSx}}"""
|
|
|
|
def cree_rcss(self, etudiants: pe_etudiant.EtudiantsJuryPE):
|
|
"""Créé tous les RCS, au regard du cursus des étudiants
|
|
analysés + les mémorise dans les données de l'étudiant
|
|
|
|
Args:
|
|
etudiants: Les étudiants à prendre en compte dans le Jury PE
|
|
"""
|
|
|
|
tous_les_aggregats = rcss_constantes.TOUS_LES_SEMESTRES + rcss_constantes.TOUS_LES_RCS_AVEC_PLUSIEURS_SEM
|
|
for etudid in etudiants.trajectoires:
|
|
self.rcss_suivis[etudid] = {
|
|
aggregat: None
|
|
for aggregat in tous_les_aggregats
|
|
}
|
|
|
|
for nom_rcs in 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 = rcss_constantes.TYPES_RCS[nom_rcs]["aggregat"]
|
|
nom_semestre_terminal = noms_semestre_de_aggregat[-1]
|
|
|
|
for etudid in etudiants.trajectoires:
|
|
# Le formsemestre terminal (dernier en date) associé au
|
|
# semestre marquant la fin de l'aggrégat
|
|
# (par ex: son dernier S3 en date)
|
|
trajectoire = etudiants.trajectoires[etudid][nom_semestre_terminal]
|
|
if trajectoire:
|
|
formsemestre_final = pe_etudiant.get_dernier_semestre_en_date(trajectoire)
|
|
|
|
# Ajout ou récupération du RCS associé
|
|
rcs_id = (nom_rcs, formsemestre_final.formsemestre_id)
|
|
if rcs_id not in self.rcss:
|
|
self.rcss[rcs_id] = pe_rcf.RCF(nom_rcs, formsemestre_final)
|
|
rcs = self.rcss[rcs_id]
|
|
|
|
# La liste des semestres de l'étudiant à prendre en compte
|
|
# pour cette trajectoire
|
|
semestres_a_aggreger = get_rcs_etudiant(
|
|
etudiants.trajectoires[etudid], formsemestre_final, nom_rcs
|
|
)
|
|
|
|
# Ajout des semestres au RCS
|
|
rcs.add_semestres_a_aggreger(semestres_a_aggreger)
|
|
|
|
# Mémorise le RCS suivi par l'étudiant
|
|
self.rcss_suivis[etudid][nom_rcs] = rcs
|
|
|
|
# Affichage pour debug
|
|
jeunes = list(enumerate(self.rcss_suivis))
|
|
for no_etud, etudid in jeunes[:20]:
|
|
pe_affichage.pe_print(f"--> {etudiants.identites[etudid].nomprenom} (#{etudid}) :")
|
|
for nom_rcs, rcs in self.rcss_suivis[etudid].items():
|
|
if rcs:
|
|
pe_affichage.pe_print(f" > RCS {nom_rcs}: {rcs.get_repr()}")
|
|
|
|
def cree_rcfs(self, etudiants: pe_etudiant.EtudiantsJuryPE):
|
|
"""Créé les RCFs en ne conservant dans les RCS que les regroupements
|
|
de type Sx"""
|
|
self.rcfs = {}
|
|
for rcs_id, rcs in self.rcss.items():
|
|
if rcs and rcs.nom in rcss_constantes.TOUS_LES_SEMESTRES:
|
|
self.rcfs[rcs_id] = rcs
|
|
|
|
for etudid in self.rcss_suivis:
|
|
for nom_rcs, rcs in self.rcss_suivis[etudid].items():
|
|
if rcs and nom_rcs in rcss_constantes.TOUS_LES_SEMESTRES:
|
|
if etudid not in self.rcfs_suivis:
|
|
self.rcfs_suivis[etudid] = {}
|
|
self.rcfs_suivis[etudid][nom_rcs] = rcs
|
|
|
|
# Affichage pour debug
|
|
jeunes = list(enumerate(self.rcfs_suivis))
|
|
for no_etud, etudid in jeunes[:20]:
|
|
pe_affichage.pe_print(f"-> {etudiants.identites[etudid].nomprenom} :")
|
|
for nom_rcs, rcs in self.rcfs_suivis[etudid].items():
|
|
if rcs:
|
|
pe_affichage.pe_print(f" > RCSValid {nom_rcs}: {rcs.get_repr()}")
|
|
else:
|
|
pe_affichage.pe_print(f" > RCSValid {nom_rcs}: <vide>")
|
|
|
|
def cree_rcrcfs(self, etudiants: pe_etudiant.EtudiantsJuryPE):
|
|
"""Créé tous les RCRCF, au regard du cursus des étudiants
|
|
analysés (trajectoires traduisant son parcours dans les
|
|
différents semestres) + les mémorise dans les données de l'étudiant
|
|
"""
|
|
|
|
# Pour tous les étudiants du jury
|
|
for etudid in self.rcss_suivis:
|
|
self.rcrcfs_suivis[etudid] = {}
|
|
|
|
for nom_rcs, rcf in self.rcfs_suivis[etudid].items(): # Pour chaque RCS
|
|
semestres_a_aggreger = rcf.semestres_aggreges
|
|
|
|
# Tri des semestres par rang
|
|
semestres_tries = pe_comp.tri_semestres_par_rang(semestres_a_aggreger)
|
|
|
|
# Récupére les RCFs de type Sx traduisant sa trajectoire
|
|
rcfs_a_aggreger = {}
|
|
for semestres_du_rang in semestres_tries.values():
|
|
if semestres_du_rang:
|
|
rcf_id = get_rcf_from_semestres_aggreges(
|
|
self.rcfs, semestres_du_rang
|
|
)
|
|
if not rcf_id:
|
|
raise ValueError(
|
|
"Il manque un RCF pour créer les RCRCFs dans cree_rcrcfs"
|
|
)
|
|
rcfs_a_aggreger[rcf_id] = self.rcfs[rcf_id]
|
|
|
|
# Ajout du RCRCF
|
|
if rcf_id not in self.rcrcfs:
|
|
self.rcrcfs[rcf_id] = pe_rcrcf.RCRCF(rcf_id, rcf.formsemestre_final)
|
|
rcrcf = self.rcrcfs[rcf_id]
|
|
|
|
# Ajout des RCFs au RCRCF
|
|
rcrcf.add_rcfs_a_aggreger(rcfs_a_aggreger)
|
|
|
|
# Mémoire la trajectoire RCRCF suivie par l'étudiant
|
|
nom_rcs = rcrcf.nom
|
|
self.rcrcfs_suivis[etudid][nom_rcs] = rcrcf
|
|
|
|
# Affichage pour debug
|
|
jeunes = list(enumerate(self.rcrcfs_suivis))
|
|
for no_etud, etudid in jeunes[:20]:
|
|
pe_affichage.pe_print(f"-> {etudiants.identites[etudid].nomprenom} :")
|
|
for nom_rcs, rcs in self.rcrcfs_suivis[etudid].items():
|
|
if rcs:
|
|
pe_affichage.pe_print(f" > RCRCF {nom_rcs}: {rcs.get_repr()}")
|
|
else:
|
|
pe_affichage.pe_print(f" > RCRCF {nom_rcs}: <vide> !!! ")
|
|
|
|
|
|
|
|
def get_rcs_etudiant(
|
|
semestres: dict[int:FormSemestre], formsemestre_final: FormSemestre, nom_rcs: str
|
|
) -> dict[int, FormSemestre]:
|
|
"""Ensemble des semestres parcourus (trajectoire)
|
|
par un étudiant dans le cadre
|
|
d'un RCS de type Sx, iA ou iS et ayant pour semestre terminal `formsemestre_final`.
|
|
|
|
Par ex: pour un RCS "3S", dont le formsemestre_terminal est un S3, regroupe
|
|
le ou les S1 qu'il a suivi (1 ou 2 si redoublement) + le ou les S2 + le ou les S3.
|
|
|
|
Les semestres parcourus sont antérieurs (en terme de date de fin)
|
|
au formsemestre_terminal.
|
|
|
|
Args:
|
|
cursus: Dictionnaire {fid: Formsemestre} donnant l'ensemble des semestres
|
|
dans lesquels l'étudiant a été inscrit
|
|
formsemestre_final: le semestre final visé
|
|
nom_rcs: Nom du RCS visé
|
|
"""
|
|
numero_semestre_terminal = formsemestre_final.semestre_id
|
|
# semestres_significatifs = self.get_semestres_significatifs(etudid)
|
|
semestres_significatifs = {}
|
|
for i in range(1, pe_comp.NBRE_SEMESTRES_DIPLOMANT + 1):
|
|
semestres_significatifs = semestres_significatifs | semestres[f"S{i}"]
|
|
|
|
if nom_rcs.startswith("S"): # les semestres
|
|
numero_semestres_possibles = [numero_semestre_terminal]
|
|
elif nom_rcs.endswith("A"): # les années
|
|
numero_semestres_possibles = [
|
|
int(sem[-1]) for sem in rcss_constantes.TYPES_RCS[nom_rcs]["aggregat"]
|
|
]
|
|
assert numero_semestre_terminal in numero_semestres_possibles
|
|
else: # les xS = tous les semestres jusqu'à Sx (eg S1, S2, S3 pour un S3 terminal)
|
|
numero_semestres_possibles = list(range(1, numero_semestre_terminal + 1))
|
|
|
|
semestres_aggreges = {}
|
|
for fid, semestre in semestres_significatifs.items():
|
|
# Semestres parmi ceux de n° possibles & qui lui sont antérieurs
|
|
if (
|
|
semestre.semestre_id in numero_semestres_possibles
|
|
and semestre.date_fin <= formsemestre_final.date_fin
|
|
):
|
|
semestres_aggreges[fid] = semestre
|
|
return semestres_aggreges
|
|
|
|
|
|
def get_rcf_from_semestres_aggreges(
|
|
rcfs: dict[(str, int):pe_rcf.RCF], semestres_a_aggreges: list[FormSemestre]
|
|
) -> (str, int):
|
|
"""Partant d'un dictionnaire de RCFs (de la forme
|
|
``{ (nom_rcs, fid): RCF }, et connaissant une liste
|
|
de (form)semestres à aggréger, renvoie l'identifiant
|
|
(nom_rcs, fid) du RCFs qui lui correspond (c'est à dire celui dont
|
|
les semestres_aggregés par le RCF sont les même que les
|
|
semestres_a_aggreger.
|
|
|
|
Returns:
|
|
rcf_id: L'identifiant du RCF trouvé
|
|
"""
|
|
fids_semestres_a_aggreger = set(
|
|
[frms.formsemestre_id for frms in semestres_a_aggreges]
|
|
)
|
|
for rcf_id, rcf in rcfs.items():
|
|
fids_rcf = set(rcf.semestres_aggreges)
|
|
if fids_rcf == fids_semestres_a_aggreger:
|
|
return rcf_id
|
|
return None
|
|
|