Adaptation diverses pour la gestion des aggrégats (dont les redoublements de semestre)
This commit is contained in:
parent
8b3efe9dad
commit
e3cde87a0f
@ -52,8 +52,14 @@ import datetime
|
||||
class EtudiantsJuryPE:
|
||||
"""Classe centralisant la gestion des étudiants à prendre en compte dans un jury de PE"""
|
||||
|
||||
def __init__(self):
|
||||
""" """
|
||||
def __init__(self, annee_diplome: int):
|
||||
"""
|
||||
|
||||
Args:
|
||||
annee_diplome: L'année de diplomation
|
||||
"""
|
||||
|
||||
self.annee_diplome = annee_diplome
|
||||
|
||||
"Les identités des étudiants traités pour le jury"
|
||||
self.identites = {} # ex. ETUDINFO_DICT
|
||||
@ -70,21 +76,20 @@ class EtudiantsJuryPE:
|
||||
"Les formsemestres dont il faut calculer les moyennes par tag"
|
||||
self.formsemestres_jury_ids = {}
|
||||
|
||||
def find_etudiants(self, annee_diplome: int, formation_id: int):
|
||||
def find_etudiants(self, formation_id: int):
|
||||
"""Liste des étudiants à prendre en compte dans le jury PE, en les recherchant
|
||||
de manière automatique par rapport à leur année de diplomation ``annee_diplome``
|
||||
dans la formation ``formation_id``.
|
||||
|
||||
Les données obtenues sont stockées dans les attributs de EtudiantsJuryPE.
|
||||
|
||||
Args:
|
||||
annee_diplome: L'année de diplomation
|
||||
|
||||
formation_id: L'identifiant de la formation (inutilisé)
|
||||
|
||||
*Remarque* : ex: JuryPE.get_etudiants_in_jury()
|
||||
"""
|
||||
"Les cosemestres donnant lieu à même année de diplome"
|
||||
cosemestres = pe_tools.get_cosemestres_diplomants(annee_diplome, None)
|
||||
cosemestres = pe_tools.get_cosemestres_diplomants(self.annee_diplome, None)
|
||||
self.cosemestres = cosemestres
|
||||
pe_tools.pe_print(
|
||||
"1) Recherche des coSemestres -> %d trouvés" % len(cosemestres)
|
||||
@ -119,7 +124,7 @@ class EtudiantsJuryPE:
|
||||
pe_tools.pe_print()
|
||||
|
||||
"""Les étudiants à prendre dans le diplôme, étudiants ayant abandonnés non compris"""
|
||||
self.diplomes_ids = self.get_etudiants(annee_diplome)
|
||||
self.diplomes_ids = self.get_etudiants_diplomes()
|
||||
|
||||
"""Les étudiants dont il faut calculer les moyennes"""
|
||||
self.etudiants_ids = {etudid for etudid in self.identites}
|
||||
@ -129,11 +134,13 @@ class EtudiantsJuryPE:
|
||||
|
||||
# Synthèse
|
||||
pe_tools.pe_print(
|
||||
f" => {len(self.diplomes_ids)} étudiants à diplômer en {annee_diplome}"
|
||||
f" => {len(self.diplomes_ids)} étudiants à diplômer en {self.annee_diplome}"
|
||||
)
|
||||
nbre_abandons = len(self.etudiants_ids) - len(self.diplomes_ids)
|
||||
pe_tools.pe_print(f" => {nbre_abandons} étudiants éliminer pour abandon")
|
||||
pe_tools.pe_print(f" => {len(self.formsemestres_jury_ids)} semestres dont il faut calculer la moyenne")
|
||||
pe_tools.pe_print(
|
||||
f" => {len(self.formsemestres_jury_ids)} semestres dont il faut calculer la moyenne"
|
||||
)
|
||||
pe_tools.pe_print(
|
||||
f" => quelques étudiants futurs diplômés : "
|
||||
+ ", ".join([str(etudid) for etudid in list(self.diplomes_ids)[:10]])
|
||||
@ -142,14 +149,14 @@ class EtudiantsJuryPE:
|
||||
f" => semestres dont il faut calculer les moyennes : "
|
||||
+ ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)])
|
||||
)
|
||||
# Les abandons :
|
||||
# sorted([etudiants.cursus[etudid]['nom'] for etudid in etudiants.cursus if etudid not in etudiants.diplomes_ids])
|
||||
|
||||
def get_etudiants(self, annee_diplome: int) -> dict[Identite]:
|
||||
def get_etudiants_diplomes(self) -> dict[int, Identite]:
|
||||
"""Identités des étudiants (sous forme d'un dictionnaire `{etudid: Identite(etudid)}`
|
||||
qui vont être à traiter au jury PE pour
|
||||
l'année de diplômation donnée et n'ayant ni été réorienté, ni abandonné.
|
||||
|
||||
Args:
|
||||
annee_diplome: Année de diplomation visée pour le jury
|
||||
|
||||
Returns:
|
||||
Un dictionnaire `{etudid: Identite(etudid)}`
|
||||
@ -157,7 +164,7 @@ class EtudiantsJuryPE:
|
||||
etudids = [
|
||||
etudid
|
||||
for etudid in self.cursus
|
||||
if self.cursus[etudid]["diplome"] == annee_diplome
|
||||
if self.cursus[etudid]["diplome"] == self.annee_diplome
|
||||
and self.cursus[etudid]["abandon"] == False
|
||||
]
|
||||
etudiants = {etudid: self.identites[etudid] for etudid in etudids}
|
||||
@ -203,7 +210,7 @@ class EtudiantsJuryPE:
|
||||
""" Est-il réorienté / démissionnaire ou a-t-il arrêté volontairement sa formation ?"""
|
||||
self.cursus[etudid]["abandon"] = arret_de_formation(identite, cosemestres)
|
||||
|
||||
def analyse_parcours_etudiant_dans_semestres(self, etudid):
|
||||
def analyse_parcours_etudiant_dans_semestres(self, etudid: int):
|
||||
"""Structure les informations sur les semestres suivis par un
|
||||
étudiant, pour identifier les semestres qui seront pris en compte lors de ses calculs
|
||||
de moyennes PE.
|
||||
@ -220,21 +227,60 @@ class EtudiantsJuryPE:
|
||||
a suivi pour l'amener jusqu'au semestre terminal de l'aggrégat. Ce parcours peut être :
|
||||
** S1+S2+S1+S2+S3 si redoublement de la 1ère année
|
||||
** S1+S2+(année de césure)+S3 si césure, ...
|
||||
|
||||
Par ex: M. N..z (redoublant en 2ème année) au moment de son 2ème S3 :
|
||||
{'1A': {26: {18: <FormSemestre 18 BUT Réseaux et Télécommunications semestre 1 FI 2021-2022>,
|
||||
26: <FormSemestre 26 BUT Réseaux et Télécommunications semestre 2 FI 2022>}},
|
||||
'2A': {79: {18: <FormSemestre 18 BUT Réseaux et Télécommunications semestre 1 FI 2021-2022>,
|
||||
26: <FormSemestre 26 BUT Réseaux et Télécommunications semestre 2 FI 2022>,
|
||||
56: <FormSemestre 56 BUT Réseaux et Télécommunications semestre 3 FI 2022-2023>,
|
||||
79: <FormSemestre 79 BUT Réseaux et Télécommunications semestre 4 FI 2023>}},
|
||||
'3A': {},
|
||||
'3S': {112: {18: <FormSemestre 18 BUT Réseaux et Télécommunications semestre 1 FI 2021-2022>,
|
||||
26: <FormSemestre 26 BUT Réseaux et Télécommunications semestre 2 FI 2022>,
|
||||
56: <FormSemestre 56 BUT Réseaux et Télécommunications semestre 3 FI 2022-2023>,
|
||||
112: <FormSemestre 112 BUT Réseaux et Télécommunications 2023 semestre 3 FI 2023-2024>}},
|
||||
'4S': {79: {18: <FormSemestre 18 BUT Réseaux et Télécommunications semestre 1 FI 2021-2022>,
|
||||
26: <FormSemestre 26 BUT Réseaux et Télécommunications semestre 2 FI 2022>,
|
||||
56: <FormSemestre 56 BUT Réseaux et Télécommunications semestre 3 FI 2022-2023>,
|
||||
79: <FormSemestre 79 BUT Réseaux et Télécommunications semestre 4 FI 2023>}},
|
||||
'5S': {},
|
||||
'6S': {},
|
||||
'S1': {18: {18: <FormSemestre 18 BUT Réseaux et Télécommunications semestre 1 FI 2021-2022>}},
|
||||
'S2': {26: {26: <FormSemestre 26 BUT Réseaux et Télécommunications semestre 2 FI 2022>}},
|
||||
'S3': {112: {56: <FormSemestre 56 BUT Réseaux et Télécommunications semestre 3 FI 2022-2023>,
|
||||
112: <FormSemestre 112 BUT Réseaux et Télécommunications 2023 semestre 3 FI 2023-2024>}},
|
||||
'S4': {79: {79: <FormSemestre 79 BUT Réseaux et Télécommunications semestre 4 FI 2023>}},
|
||||
'S5': {},
|
||||
'S6': {}
|
||||
}
|
||||
"""
|
||||
semestres_etudiant = self.cursus[etudid]["formsemestres"]
|
||||
|
||||
"""Ne conserve que les semestres qui l'auraient amené à être diplomé l'année visée"""
|
||||
semestres_significatifs = {}
|
||||
for fid in semestres_etudiant:
|
||||
semestre = semestres_etudiant[fid]
|
||||
if pe_tools.get_annee_diplome_semestre(semestre) <= self.annee_diplome:
|
||||
semestres_significatifs[fid] = semestre
|
||||
|
||||
self.aggregats[etudid] = {}
|
||||
|
||||
"""Tri des semestres par numéro de semestre"""
|
||||
for nom_sem in pe_tools.TOUS_LES_SEMESTRES:
|
||||
i = int(nom_sem[1]) # le n° du semestre
|
||||
semestres_i = {
|
||||
fid: semestres_etudiant[fid]
|
||||
for fid in semestres_etudiant
|
||||
if semestres_etudiant[fid].semestre_id == i
|
||||
fid: semestres_significatifs[fid]
|
||||
for fid in semestres_significatifs
|
||||
if semestres_significatifs[fid].semestre_id == i
|
||||
} # les semestres de n°i de l'étudiant
|
||||
self.aggregats[etudid][nom_sem] = semestres_i
|
||||
self.cursus[etudid][nom_sem] = get_dernier_semestre(semestres_i)
|
||||
dernier_semestre_i = get_dernier_semestre(semestres_i)
|
||||
self.cursus[etudid][nom_sem] = dernier_semestre_i
|
||||
self.aggregats[etudid][nom_sem] = {}
|
||||
if dernier_semestre_i:
|
||||
fid_dernier_semestre_i = list(dernier_semestre_i.keys())[0]
|
||||
self.aggregats[etudid][nom_sem][fid_dernier_semestre_i] = semestres_i
|
||||
|
||||
|
||||
"""Tri des semestres par aggrégat et par semestre terminal"""
|
||||
for aggregat in pe_tools.TOUS_LES_AGGREGATS:
|
||||
@ -258,8 +304,8 @@ class EtudiantsJuryPE:
|
||||
|
||||
"""Semestres de n° inférieur (pax ex: des S1, S2, S3 pour un S3 terminal) et qui lui sont antérieurs"""
|
||||
semestres_aggreges = {}
|
||||
for fid in self.cursus[etudid]["formsemestres"]:
|
||||
semestre = self.cursus[etudid]["formsemestres"][fid]
|
||||
for fid in semestres_significatifs:
|
||||
semestre = semestres_significatifs[fid]
|
||||
if (
|
||||
semestre.semestre_id <= numero_semestre_terminal
|
||||
and semestre.date_fin <= formsemestre_terminal.date_fin
|
||||
@ -273,8 +319,9 @@ class EtudiantsJuryPE:
|
||||
assert dernier_semestre_aggregat == dernier_formsemestre_terminal
|
||||
|
||||
def get_formsemestres_terminaux_aggregat(self, aggregat: str):
|
||||
"""Pour un aggrégat donné, ensemble des formsemestres terminaux possibles pour l'aggrégat (pour l'aggrégat '3S'
|
||||
incluant S1+S2+S3, a pour semestre terminal S3). Ces formsemestres traduisent :
|
||||
"""Pour un aggrégat donné, ensemble des formsemestres terminaux possibles pour l'aggrégat
|
||||
(pour l'aggrégat '3S' incluant S1+S2+S3, a pour semestre terminal S3).
|
||||
Ces formsemestres traduisent :
|
||||
|
||||
* les différents parcours des étudiants liés par exemple au choix de modalité (par ex: S1 FI + S2 FI + S3 FI
|
||||
ou S1 FI + S2 FI + S3 UFA), en renvoyant les formsemestre_id du S3 FI et du S3 UFA.
|
||||
@ -289,15 +336,15 @@ class EtudiantsJuryPE:
|
||||
Un dictionnaire {fid: FormSemestre(fid)}
|
||||
"""
|
||||
formsemestres_terminaux = {}
|
||||
for etudid in self.cursus:
|
||||
"""Les formsemestre_id des semestres terminaux"""
|
||||
fids = self.cursus[etudid][aggregat].keys()
|
||||
"""Pour chaque identifiant de semestre terminal, récupère le formsemestre associé"""
|
||||
for fid in fids:
|
||||
if fid not in formsemestres_terminaux:
|
||||
formsemestres_terminaux[fid] = self.cursus[etudid][aggregat][fid][
|
||||
fid
|
||||
]
|
||||
for etudid in self.aggregats:
|
||||
if self.aggregats[etudid][aggregat]:
|
||||
print(self.aggregats[etudid][aggregat])
|
||||
"""Le formsemestre_id du semestre terminal de l'étudiant (s'il existe)"""
|
||||
fid = list(self.aggregats[etudid][aggregat].keys())[0]
|
||||
"""Le formsemestre associé (en le prenant dans l'aggrégat)"""
|
||||
formsemestres_terminaux[fid] = self.aggregats[etudid][aggregat][fid][
|
||||
fid
|
||||
]
|
||||
return formsemestres_terminaux
|
||||
|
||||
def get_semestres_a_aggreger(self, aggregat: str, formsemestre_id_terminal: int):
|
||||
@ -373,7 +420,9 @@ class EtudiantsJuryPE:
|
||||
nom_sem = semestres_recherches
|
||||
semestres = {}
|
||||
for etudid in self.etudiants_ids:
|
||||
semestres = semestres | self.aggregats[etudid][nom_sem]
|
||||
for sem_terminal in self.aggregats[etudid]:
|
||||
for sem in self.aggregats[etudid][sem_terminal]:
|
||||
semestres = semestres | self.aggregats[etudid][sem_terminal][sem]
|
||||
return semestres
|
||||
else:
|
||||
raise ValueError(
|
||||
|
@ -138,8 +138,8 @@ class JuryPE(object):
|
||||
pe_tools.pe_print(
|
||||
f"*** Recherche et chargement des étudiants diplômés en {self.diplome} pour la formation {self.formation_id}"
|
||||
)
|
||||
self.etudiants = EtudiantsJuryPE() # Les infos sur les étudiants
|
||||
self.etudiants.find_etudiants(self.diplome, self.formation_id)
|
||||
self.etudiants = EtudiantsJuryPE(self.diplome) # Les infos sur les étudiants
|
||||
self.etudiants.find_etudiants(self.formation_id)
|
||||
|
||||
"""Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE"""
|
||||
self.semestres_taggues = compute_semestres_tag(self.etudiants)
|
||||
@ -689,10 +689,8 @@ def compute_semestres_tag(etudiants: EtudiantsJuryPE):
|
||||
return semestres_tags
|
||||
|
||||
|
||||
def compute_aggregats_tag(
|
||||
self, etudiants: EtudiantsJuryPE, semestres_tag: dict[SemestreTag]
|
||||
):
|
||||
"""Créé les combinaisons de semestres (aggrégat), en calculant les moyennes et les
|
||||
def compute_aggregats_tag(etudiants: EtudiantsJuryPE, semestres_tag: dict[SemestreTag]):
|
||||
"""Créé les combinaisons de semestres (aggrégats), en calculant les moyennes et les
|
||||
classements par tag pour chacune. Chaque combinaison (aggrégat) est identifiée
|
||||
par un formsemestre terminal.
|
||||
|
||||
@ -701,6 +699,11 @@ def compute_aggregats_tag(
|
||||
* combinaisons '3S' : S1+S2+S3 en prenant en compte tous les S3 qu'ont fréquentés les
|
||||
étudiants du jury PE. Ces S3 marquent les formsemestre terminal de chaque combinaison.
|
||||
|
||||
* combinaisons 'S2' : 1 seul S2 pour des étudiants n'ayant pas redoublé, 2 pour des redoublants (dont les
|
||||
notes seront moyennées sur leur 2 semestres S2). Ces combinaisons ont pour formsemestre le dernier S2 en
|
||||
date (le S2 redoublé par les redoublants est forcément antérieur)
|
||||
|
||||
|
||||
Args:
|
||||
etudiants: Les données des étudiants
|
||||
semestres_tag: Les semestres tag (pour lesquels des moyennes par tag ont été calculés)
|
||||
@ -713,12 +716,15 @@ def compute_aggregats_tag(
|
||||
|
||||
sets_tags = {}
|
||||
|
||||
for aggregat in pe_tools.TOUS_LES_AGGREGATS:
|
||||
for aggregat in pe_tools.TOUS_LES_SEMESTRES + pe_tools.TOUS_LES_AGGREGATS:
|
||||
sets_tags[aggregat] = {}
|
||||
|
||||
"""Semestres aggrégés"""
|
||||
noms_semestres_aggreges = pe_tools.PARCOURS[aggregat]["aggregat"]
|
||||
nom_semestre_terminal = noms_semestres_aggreges[-1]
|
||||
if aggregat in pe_tools.TOUS_LES_SEMESTRES: # par ex. 'S2'
|
||||
noms_semestres_aggreges = [ aggregat ]
|
||||
else: # par ex. "5S"
|
||||
noms_semestres_aggreges = pe_tools.PARCOURS[aggregat]["aggregat"]
|
||||
nom_semestre_terminal = noms_semestres_aggreges[-1]
|
||||
|
||||
pe_tools.pe_print(f"* {aggregat}: " + "+".join(noms_semestres_aggreges))
|
||||
|
||||
@ -730,9 +736,10 @@ def compute_aggregats_tag(
|
||||
for frmsem_id in formsemestres_terminal:
|
||||
formsemestre_terminal = formsemestres_terminal[frmsem_id]
|
||||
"""Nom du set_tag"""
|
||||
nom = "Aggrégat S%d %d %d-%d" % (
|
||||
formsemestre_terminal.semestre_id,
|
||||
nom = "Aggrégat %s %d %s %d-%d" % (
|
||||
aggregat,
|
||||
frmsem_id,
|
||||
"+".join(noms_semestres_aggreges),
|
||||
formsemestre_terminal.date_debut.year,
|
||||
formsemestre_terminal.date_fin.year,
|
||||
)
|
||||
|
@ -170,37 +170,6 @@ TOUS_LES_SEMESTRES = PARCOURS[AGGREGAT_DIPLOMANT]["aggregat"]
|
||||
TOUS_LES_AGGREGATS = [cle for cle in PARCOURS.keys() if not cle.startswith("S")]
|
||||
TOUS_LES_PARCOURS = list(PARCOURS.keys())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def print_semestres_description(sems, avec_affichage_debug=False):
|
||||
"""Dediee a l'affichage d'un semestre pour debug du module"""
|
||||
|
||||
def chaine_semestre(sem):
|
||||
desc = (
|
||||
"S"
|
||||
+ str(sem["semestre_id"])
|
||||
+ " "
|
||||
+ sem["modalite"]
|
||||
+ " "
|
||||
+ sem["anneescolaire"]
|
||||
)
|
||||
desc += " (" + sem["annee_debut"] + "/" + sem["annee_fin"] + ") "
|
||||
desc += str(sem["formation_id"]) + " / " + str(sem["formsemestre_id"])
|
||||
desc += " - " + sem["titre_num"]
|
||||
return desc
|
||||
|
||||
if avec_affichage_debug == True:
|
||||
if isinstance(sems, list):
|
||||
for sem in sems:
|
||||
pe_print(chaine_semestre(sem))
|
||||
else:
|
||||
pe_print(chaine_semestre(sems))
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def calcul_age(born):
|
||||
"""Calcule l'age à partir de la date de naissance sous forme d'une chaine de caractère 'jj/mm/aaaa'.
|
||||
|
Loading…
Reference in New Issue
Block a user