Compare commits
4 Commits
3e55391f7e
...
90c2516d01
Author | SHA1 | Date | |
---|---|---|---|
90c2516d01 | |||
340aa749b2 | |||
7a0b560d54 | |||
9e925aa500 |
@ -55,15 +55,17 @@ class EtudiantsJuryPE:
|
||||
def __init__(self):
|
||||
""" """
|
||||
|
||||
"Les identités des étudiants du jury"
|
||||
"Les identités des étudiants traités pour le jury"
|
||||
self.identites = {} # ex. ETUDINFO_DICT
|
||||
"Les cursus (semestres suivis, abandons, ...)"
|
||||
"Les cursus (semestres suivis, abandons, ...) des étudiants"
|
||||
self.cursus = {}
|
||||
"Les etudids des étudiants à considérer au jury"
|
||||
|
||||
"Les etudids des étudiants à considérer au jury (ceux qui seront effectivement diplômés)"
|
||||
self.etudiants_jury_ids = {}
|
||||
"Les etudids des étudiants dont il faut calculer les moyennes/classements"
|
||||
"Les etudids des étudiants dont il faut calculer les moyennes/classements (même si d'éventuels abandons)"
|
||||
self.etudiants_ids = {}
|
||||
"Les formsemestres dont il faut calculer les moyennes"
|
||||
|
||||
"Les formsemestres dont il faut calculer les moyennes par tag"
|
||||
self.formsemestres_jury_ids = {}
|
||||
|
||||
def find_etudiants(self, annee_diplome: int, formation_id: int):
|
||||
@ -75,38 +77,46 @@ class EtudiantsJuryPE:
|
||||
|
||||
Args:
|
||||
annee_diplome: L'année de diplomation
|
||||
formation_id: L'identifiant de la formation
|
||||
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 # formation_id,
|
||||
)
|
||||
cosemestres = pe_tools.get_cosemestres_diplomants(annee_diplome, None)
|
||||
pe_tools.pe_print(
|
||||
"1) Recherche des coSemestres -> %d trouvés" % len(cosemestres)
|
||||
)
|
||||
|
||||
"""Les étudiants inscrits dans les co-semestres (ceux du jury mais aussi d'autres ayant été réorientés ou ayant abandonnés)"""
|
||||
pe_tools.pe_print("2) Liste des étudiants dans les différents co-semestres")
|
||||
self.etudiants_ids = get_etudiants_dans_semestres(
|
||||
cosemestres
|
||||
) # étudiants faisant partie de tous les cosemestres
|
||||
pe_tools.pe_print(" => %d étudiants trouvés" % len(self.etudiants_ids))
|
||||
self.etudiants_ids = get_etudiants_dans_semestres(cosemestres)
|
||||
pe_tools.pe_print(
|
||||
" => %d étudiants trouvés dans les cosemestres" % len(self.etudiants_ids)
|
||||
)
|
||||
|
||||
# L'analyse des parcours étudiants pour déterminer leur année effective de diplome avec prise en compte des redoublements, des abandons, ....
|
||||
"""Analyse des parcours étudiants pour déterminer leur année effective de diplome
|
||||
avec prise en compte des redoublements, des abandons, ...."""
|
||||
pe_tools.pe_print("3) Analyse des parcours individuels des étudiants")
|
||||
|
||||
no_etud = 0
|
||||
for no_etud, etudid in enumerate(self.etudiants_ids):
|
||||
self.add_etudid(etudid, cosemestres)
|
||||
"""L'identité de l'étudiant"""
|
||||
identite = Identite.get_etud(etudid)
|
||||
self.identites[etudid] = identite
|
||||
|
||||
"""L'analyse de son cursus"""
|
||||
self.analyse_etat_etudiant(etudid, cosemestres)
|
||||
|
||||
"""L'analyse de son parcours pour atteindre chaque semestre de la formation"""
|
||||
self.analyse_parcours_etudiant_dans_semestres(etudid)
|
||||
|
||||
if (no_etud + 1) % 10 == 0:
|
||||
pe_tools.pe_print((no_etud + 1), " ", end="")
|
||||
no_etud += 1
|
||||
pe_tools.pe_print()
|
||||
|
||||
"""Les étudiants à prendre dans le diplôme, étudiants ayant abandonnés non compris"""
|
||||
self.etudiants_jury_ids = self.get_etudids(annee_diplome)
|
||||
self.etudiants_jury_ids = self.get_etudiants(annee_diplome)
|
||||
|
||||
"""Les étudiants dont il faut calculer les moyennes"""
|
||||
self.etudiants_ids = {etudid for etudid in self.cursus}
|
||||
@ -129,89 +139,48 @@ class EtudiantsJuryPE:
|
||||
+ ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)])
|
||||
)
|
||||
|
||||
def get_etudids(self, annee_diplome: int = None, ordre="aucun") -> list:
|
||||
"""Liste des etudid des étudiants 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é.
|
||||
|
||||
Si l'année de diplômation n'est pas précisée (None), inclus les étudiants réorientés
|
||||
ou ayant abandonné.
|
||||
|
||||
Si l'``ordre`` est précisé, trie la liste par ordre alphabétique de etat_civil
|
||||
|
||||
Args:
|
||||
annee_diplome: Année de diplomation visée pour le jury
|
||||
ordre: Un ordre de tri
|
||||
|
||||
Returns:
|
||||
Une liste contenant des ``etudids``
|
||||
|
||||
Note: ex JuryPE.get_etudids_du_jury()
|
||||
"""
|
||||
if annee_diplome:
|
||||
etudids = [
|
||||
etudid
|
||||
for (etudid, donnees) in self.cursus.items()
|
||||
if donnees["diplome"] == annee_diplome and not donnees["abandon"]
|
||||
]
|
||||
else:
|
||||
etudids = [
|
||||
etudid
|
||||
for (etudid, donnees) in self.cursus.items()
|
||||
]
|
||||
if ordre == "alphabetique": # Tri alphabétique
|
||||
etudidsAvecNom = [
|
||||
(etudid, etud["etat_civil"])
|
||||
for (etudid, etud) in self.cursus.items()
|
||||
if etudid in etudids
|
||||
]
|
||||
etudidsAvecNomTrie = sorted(etudidsAvecNom, key=lambda col: col[1])
|
||||
etudids = [etud[0] for etud in etudidsAvecNomTrie]
|
||||
return etudids
|
||||
|
||||
def get_etudiants(self, annee_diplome: int = None) -> dict[Identite]:
|
||||
def get_etudiants(self, annee_diplome: int) -> dict[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é.
|
||||
|
||||
Si l'année de diplômation n'est pas précisée (None), inclus les étudiants réorientés
|
||||
ou ayant abandonné.
|
||||
|
||||
Args:
|
||||
annee_diplome: Année de diplomation visée pour le jury
|
||||
|
||||
Returns:
|
||||
Un dictionnaire `{etudid: Identite(etudid)}`
|
||||
"""
|
||||
etudids = self.get_etudids(annee_diplome=annee_diplome)
|
||||
etudiants = {etudid: self.identites[etudids] for etudid in etudids}
|
||||
etudids = [
|
||||
etudid
|
||||
for etudid in self.cursus
|
||||
if self.cursus[etudid]["diplome"] == annee_diplome and self.cursus[etudid]["abandon"]
|
||||
]
|
||||
etudiants = {etudid: self.identites[etudid] for etudid in etudids}
|
||||
return etudiants
|
||||
|
||||
def add_etudid(self, etudid: int, cosemestres):
|
||||
"""Ajoute un étudiant à ceux qui devront être traités pendant le jury pouvant être :
|
||||
|
||||
* des étudiants sur lesquels le jury va statuer (année de diplômation du jury considéré)
|
||||
* des étudiants qui ne seront pas considérés dans le jury mais ont participé dans leur scolarité
|
||||
à un (ou plusieurs) semestres communs aux étudiants du jury (et impacteront les classements)
|
||||
def analyse_etat_etudiant(
|
||||
self, etudid: int, cosemestres: dict[int, FormSemestre]
|
||||
):
|
||||
"""Analyse le cursus d'un étudiant pouvant être :
|
||||
|
||||
L'ajout consiste :
|
||||
* l'un de ceux sur lesquels le jury va statuer (année de diplômation du jury considéré)
|
||||
* un étudiant qui ne sera pas considéré dans le jury mais qui a participé dans sa scolarité
|
||||
à un (ou plusieurs) semestres communs aux étudiants du jury (et impactera les classements)
|
||||
|
||||
* à insérer une entrée pour l'étudiant en mémorisant son identité,
|
||||
L'analyse consiste :
|
||||
|
||||
* à insérer une entrée dans ``self.cursus`` pour mémoriser son identité,
|
||||
avec son nom, prénom, etc...
|
||||
* à analyser son parcours, pour déterminer s'il n'a (ou non) abandonné l'IUT en cours de
|
||||
route (cf. clé abandon)
|
||||
* à chercher ses semestres valides (formsemestre_id) et ses années valides (formannee_id),
|
||||
c'est-à-dire ceux pour lesquels il faudra prendre en compte ses notes dans les calculs de
|
||||
moyenne (type 1A=S1+S2/2)
|
||||
|
||||
Args:
|
||||
etudid: L'etudid d'un étudiant, à ajouter à ceux traiter par le jury
|
||||
cosemestres: Dictionnaire {fid: Formsemestre(fid)} donnant accès aux cosemestres de même année de diplomation
|
||||
Note: ex JuryPE.add_etudid_to_jury()
|
||||
cosemestres: Dictionnaire {fid: Formsemestre(fid)} donnant accès aux cosemestres
|
||||
de même année de diplomation
|
||||
"""
|
||||
|
||||
"""L'identité de l'étudiant"""
|
||||
identite = Identite.get_etud(etudid)
|
||||
self.identites[etudid] = identite
|
||||
|
||||
"""Le cursus global de l'étudiant (restreint aux semestres APC)"""
|
||||
semestres_etudiant = {
|
||||
@ -225,38 +194,121 @@ class EtudiantsJuryPE:
|
||||
"etat_civil": identite.etat_civil, # Ajout à la table jury
|
||||
"diplome": annee_diplome(identite), # Le date prévisionnelle de son diplôme
|
||||
"formsemestres": semestres_etudiant, # les semestres de l'étudiant
|
||||
"semestres": {},
|
||||
"aggregats": {},
|
||||
}
|
||||
|
||||
""" Est-il réorienté / démissionnaire ou a-t-il arrêté volontairement sa formation ?"""
|
||||
self.cursus[etudid]["abandon"] = arret_de_formation(identite, cosemestres)
|
||||
|
||||
"""Tri des semestres par n° de semestre"""
|
||||
|
||||
def analyse_parcours_etudiant_dans_semestres(self, etudid):
|
||||
"""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.
|
||||
|
||||
La structure s'appuie sur les numéros de semestre: pour chaque Si, stocke :
|
||||
* le (ou les) formsemestres de numéro i qu'a suivi un étudiant (2 si redoublant)
|
||||
* le dernier semestre de numéro i qu'il a suivi (1 ou 0 si pas encore suivi)
|
||||
|
||||
Elle s'appuie également sur les aggrégats: pour chaque aggrégat (par ex, 3A=S1+S2+S3),
|
||||
identifie les semestres que l'étudiant 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, ...
|
||||
"""
|
||||
semestres_etudiant = self.cursus[etudid]["formsemestres"]
|
||||
|
||||
for nom_sem in pe_tools.TOUS_LES_SEMESTRES:
|
||||
i = int(nom_sem[1]) + 1 # le n° du semestre
|
||||
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
|
||||
} # les semestres de n°i de l'étudiant
|
||||
dernier_semestre_i = get_dernier_semestre(semestres_i)
|
||||
self.cursus[etudid][nom_sem] = dernier_semestre_i
|
||||
self.cursus[etudid]["aggregats"][nom_sem] = semestres_i
|
||||
self.cursus[etudid]["semestres"][nom_sem] = get_dernier_semestre(semestres_i)
|
||||
|
||||
"""Tri des semestres par aggrégat"""
|
||||
for parcours in pe_tools.TOUS_LES_AGGREGATS:
|
||||
"""L'aggrégat considéré"""
|
||||
noms_semestre_de_aggregat = pe_tools.PARCOURS[parcours]["aggregat"]
|
||||
|
||||
self.cursus[etudid][parcours] = {}
|
||||
for nom_sem in noms_semestre_de_aggregat:
|
||||
self.cursus[etudid][parcours] = (
|
||||
self.cursus[etudid][parcours] | self.cursus[etudid][nom_sem]
|
||||
)
|
||||
"""Tri des semestres par aggrégat et par semestre terminal"""
|
||||
for aggregat in pe_tools.TOUS_LES_AGGREGATS:
|
||||
self.cursus[etudid][aggregat] = {}
|
||||
"""L'aggrégat considéré (par ex: 3S), son nom de son semestre terminal (par ex: S3) et son numéro (par ex: 3)"""
|
||||
noms_semestre_de_aggregat = pe_tools.PARCOURS[aggregat]["aggregat"]
|
||||
nom_semestre_terminal = noms_semestre_de_aggregat[-1]
|
||||
numero_semestre_terminal = int(nom_semestre_terminal[-1])
|
||||
|
||||
if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2:
|
||||
pe_tools.pe_print(
|
||||
parcours + "=" + str(self.cursus[etudid][parcours]),
|
||||
end="",
|
||||
)
|
||||
"""Les semestres terminaux de l'aggrégat"""
|
||||
# formsemestres_terminal = self.cursus[etudid]["aggregats"][nom_semestre_terminal]
|
||||
# dernier_formsemestre_terminal = get_dernier_semestre(formsemestres_terminal) # le dernier en date
|
||||
dernier_formsemestre_terminal = self.cursus[etudid]["semestres"][nom_semestre_terminal]
|
||||
|
||||
# for formsem_id_term in formsemestres_terminal:
|
||||
if dernier_formsemestre_terminal: # ne considérant que le dernier
|
||||
formsem_id_term = list(dernier_formsemestre_terminal.keys())[0]
|
||||
|
||||
formsemestre_terminal = self.cursus[etudid]["formsemestres"][formsem_id_term]
|
||||
|
||||
"""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]
|
||||
if (
|
||||
semestre.semestre_id <= numero_semestre_terminal
|
||||
and semestre.date_fin <= formsemestre_terminal.date_fin
|
||||
):
|
||||
semestres_aggreges[fid] = semestre
|
||||
|
||||
self.cursus[etudid][aggregat][formsem_id_term] = semestres_aggreges
|
||||
|
||||
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 :
|
||||
|
||||
* 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.
|
||||
* les éventuelles situations de redoublement (par ex pour 1 étudiant ayant redoublé sa 2ème année :
|
||||
S1 + S2 + S3 (1ère session) et S1 + S2 + S3 + S4 + S3 (2ème session), en renvoyant les formsemestre_id du
|
||||
S3 (1ère session) et du S3 (2ème session)
|
||||
|
||||
Args:
|
||||
aggregat: L'aggrégat
|
||||
|
||||
Returns:
|
||||
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
|
||||
]
|
||||
return formsemestres_terminaux
|
||||
|
||||
def get_semestres_a_aggreger(self, aggregat: str, formsemestre_id_terminal: int):
|
||||
"""Pour un aggrégat donné associé à un formsemestre terminal cible, 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_tools.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
|
||||
|
||||
def get_formsemestres_jury(self, semestres_recherches=None):
|
||||
"""Ayant connaissance des étudiants dont il faut calculer les moyennes pour
|
||||
@ -310,7 +362,7 @@ class EtudiantsJuryPE:
|
||||
nom_sem = semestres_recherches
|
||||
semestres = {}
|
||||
for etudid in self.etudiants_ids:
|
||||
semestres = semestres | self.cursus[etudid][nom_sem]
|
||||
semestres = semestres | self.cursus[etudid]["aggregats"][nom_sem]
|
||||
return semestres
|
||||
else:
|
||||
raise ValueError(
|
||||
@ -368,25 +420,6 @@ def annee_diplome(identite: Identite) -> int:
|
||||
return None
|
||||
|
||||
|
||||
def semestres_etudiant(etudid: int, semestre_id=None):
|
||||
"""La liste des semestres BUT d'un étudiant
|
||||
pour un semestre_id (parmi 1, 2, 3, 4, 5, 6) donné
|
||||
en fonction de ses infos d'etud (cf. sco_etud.get_etud_info(etudid=etudid, filled=True)[0]),
|
||||
les semestres étant triés par ordre décroissant.
|
||||
Si semestre_id == None renvoie tous les semestres
|
||||
|
||||
NOTE:: ex:: JuryPE.get_semestresBUT_d_un_etudiant()
|
||||
TODO:: A revoir"""
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
nbre_semestres = int(pe_tools.AGGREGAT_DIPLOMANT[0]) # 6
|
||||
if semestre_id == None:
|
||||
sesSems = [
|
||||
sem for sem in etud["sems"] if 1 <= sem["semestre_id"] <= nbre_semestres
|
||||
]
|
||||
else:
|
||||
sesSems = [sem for sem in etud["sems"] if sem["semestre_id"] == semestre_id]
|
||||
return sesSems
|
||||
|
||||
|
||||
def arret_de_formation(identite: Identite, cosemestres: list[FormSemestre]) -> bool:
|
||||
"""Détermine si un étudiant a arrêté sa formation. Il peut s'agir :
|
||||
@ -447,9 +480,10 @@ def arret_de_formation(identite: Identite, cosemestres: list[FormSemestre]) -> b
|
||||
return False
|
||||
|
||||
|
||||
def get_dernier_semestre(semestres: dict[FormSemestre]):
|
||||
def get_dernier_semestre(semestres: dict[int, FormSemestre]):
|
||||
"""Renvoie le dernier semestre en date d'un dictionnaire
|
||||
de semestres de la forme {fid: FormSemestre(fid)
|
||||
de semestres de la forme {fid: FormSemestre(fid)}.
|
||||
La date prise en compte est celle marquant la **fin** des semestres.
|
||||
|
||||
Args:
|
||||
semestres: Un dictionnaire de semestres
|
||||
|
@ -48,11 +48,13 @@ import os
|
||||
from zipfile import ZipFile
|
||||
|
||||
import app.pe.pe_etudiant
|
||||
import app.pe.pe_settag_interclasse
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.comp.res_sem import load_formsemestre_results
|
||||
from app.models import Formation, FormSemestre
|
||||
from app.models.etudiants import Identite
|
||||
from app.pe.pe_semestretag import SemestreTag
|
||||
|
||||
from app.scodoc.gen_tables import GenTable, SeqGenTable
|
||||
import app.scodoc.sco_utils as scu
|
||||
@ -117,13 +119,6 @@ class JuryPE(object):
|
||||
meme_programme: si True, impose un même programme pour tous les étudiants participant au jury,
|
||||
si False, permet des programmes differents
|
||||
"""
|
||||
|
||||
self.semTagDict = (
|
||||
{}
|
||||
) # Les semestres taggués à la base des calculs de moyenne par tag
|
||||
self.setTagDict = (
|
||||
{}
|
||||
) # dictionnaire récapitulant les semTag impliqués dans le jury de la forme { 'formsemestre_id' : object Semestre_tag
|
||||
self.promoTagDict = {}
|
||||
|
||||
"L'année du diplome"
|
||||
@ -137,18 +132,45 @@ class JuryPE(object):
|
||||
self.zipdata = io.BytesIO()
|
||||
self.zipfile = ZipFile(self.zipdata, "w")
|
||||
|
||||
"Les informations sur les étudiants édités par le jury PE"
|
||||
self.etudiants = EtudiantsJuryPE() # Les infos sur les étudiants
|
||||
self.syntheseJury = {} # Le jury de synthèse
|
||||
|
||||
"""Chargement des étudiants à prendre en compte dans le jury"""
|
||||
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)
|
||||
|
||||
"""Calcul des moyennes pour le jury PE"""
|
||||
self.exe_calculs_juryPE()
|
||||
"""Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE"""
|
||||
self.semestres_taggues = compute_semestres_tag(self.etudiants)
|
||||
|
||||
if pe_tools.PE_DEBUG:
|
||||
"""Intègre le bilan des semestres taggués au zip final"""
|
||||
for fid in self.semestres_taggues:
|
||||
formsemestretag = self.semestres_taggues[fid]
|
||||
filename = formsemestretag.nom.replace(" ", "_") + ".csv"
|
||||
pe_tools.pe_print(f" - Export csv de {filename} ")
|
||||
self.add_file_to_zip(
|
||||
filename, formsemestretag.str_tagtable(), path="details_semestres"
|
||||
)
|
||||
|
||||
"""Génère les aggrégats de semestre (par ex: 1A, 3S, 5S) avec calcul
|
||||
des moyennes pour le jury"""
|
||||
self.aggregats_taggues = compute_aggregats_tag(self.etudiants, self.semestres_taggues)
|
||||
|
||||
if pe_tools.PE_DEBUG:
|
||||
"""Intègre le bilan des aggrégats de semestres au zip final"""
|
||||
for aggregat in self.aggregats_taggues:
|
||||
for fid in self.aggregats_taggues[aggregat]:
|
||||
set_tag = self.aggregats_taggues[aggregat][fid]
|
||||
filename = set_tag.nom.replace(" ", "_") + ".csv"
|
||||
pe_tools.pe_print(f" - Export csv de {filename} ")
|
||||
self.add_file_to_zip(
|
||||
filename, set_tag.str_tagtable(), path="details_semestres"
|
||||
)
|
||||
|
||||
"""Génère les interclassements par (nom d') aggrégat"""
|
||||
|
||||
|
||||
"""Synthèse des éléments du jury PE"""
|
||||
if False:
|
||||
@ -164,21 +186,35 @@ class JuryPE(object):
|
||||
filename = self.nom_export_zip + "_jurySyntheseDict" + scu.XLSX_SUFFIX
|
||||
self.xlsV2 = self.table_syntheseJury(mode="multiplesheet")
|
||||
if self.xlsV2:
|
||||
self.add_file_to_zip(filename, self.xlsV2.excel())
|
||||
pe_tools.add_file_to_zip(
|
||||
self.nom_export_zip, filename, self.xlsV2.excel()
|
||||
)
|
||||
|
||||
# Pour debug
|
||||
# self.syntheseJury = pe_tools.JURY_SYNTHESE_POUR_DEBUG #Un dictionnaire fictif pour debug
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def add_file_to_zip(self, filename, data, path=""):
|
||||
# Les interclassements
|
||||
# --------------------
|
||||
if pe_tools.PE_DEBUG:
|
||||
pe_tools.pe_print(
|
||||
"*** Création des interclassements au sein de la promo sur différentes combinaisons de semestres"
|
||||
)
|
||||
if False:
|
||||
self.get_promotags_in_jury()
|
||||
|
||||
def add_file_to_zip(self, filename: str, data, path=""):
|
||||
"""Add a file to our zip
|
||||
All files under NOM_EXPORT_ZIP/
|
||||
path may specify a subdirectory
|
||||
|
||||
Args:
|
||||
filename: Le nom du fichier à intégrer au zip
|
||||
data: Les données du fichier
|
||||
path: Un dossier dans l'arborescence du zip
|
||||
"""
|
||||
path_in_zip = os.path.join(self.nom_export_zip, path, filename)
|
||||
self.zipfile.writestr(path_in_zip, data)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_zipped_data(self):
|
||||
"""returns file-like data with a zip of all generated (CSV) files.
|
||||
Reset file cursor at the beginning !
|
||||
@ -189,191 +225,26 @@ class JuryPE(object):
|
||||
self.zipdata.seek(0)
|
||||
return self.zipdata
|
||||
|
||||
# **************************************************************************************************************** #
|
||||
# Lancement des différentes actions permettant le calcul du jury PE
|
||||
# **************************************************************************************************************** #
|
||||
def exe_calculs_juryPE(self):
|
||||
"""Centralise les élements de calcul des moyennes de poursuites
|
||||
d'études
|
||||
"""
|
||||
|
||||
"""Création des semestres taggués, de type 'S1', 'S2', ..."""
|
||||
pe_tools.pe_print("*** Création des semestres taggués")
|
||||
|
||||
formsemestres = self.etudiants.get_formsemestres_jury(
|
||||
semestres_recherches=pe_tools.TOUS_LES_SEMESTRES
|
||||
)
|
||||
for frmsem_id, formsemestre in formsemestres.items():
|
||||
"""Choix d'un nom pour le semestretag"""
|
||||
nom = "S%d %d %d-%d" % (
|
||||
formsemestre.semestre_id,
|
||||
formsemestre.formsemestre_id,
|
||||
formsemestre.date_debut.year,
|
||||
formsemestre.date_fin.year,
|
||||
)
|
||||
|
||||
pe_tools.pe_print(
|
||||
f" --> Semestre taggué {nom} sur la base de {formsemestre}"
|
||||
)
|
||||
|
||||
self.add_semestretag_in_jury(nom, frmsem_id)
|
||||
|
||||
# Les moyennes sur toute la scolarité
|
||||
# -----------------------------------
|
||||
if pe_tools.PE_DEBUG:
|
||||
pe_tools.pe_print(
|
||||
"*** Création des moyennes sur différentes combinaisons de semestres et différents groupes d'étudiant"
|
||||
)
|
||||
if False:
|
||||
self.get_settags_in_jury()
|
||||
if pe_tools.PE_DEBUG:
|
||||
for settagdict in self.setTagDict.values(): # Export
|
||||
for settag in settagdict.values():
|
||||
filename = self.nom_export_zip + semtag.nom + ".csv"
|
||||
self.add_file_to_zip(
|
||||
filename, semtag.str_tagtable(), path="details_semestres"
|
||||
)
|
||||
# self.export_juryPEDict()
|
||||
|
||||
# Les interclassements
|
||||
# --------------------
|
||||
if pe_tools.PE_DEBUG:
|
||||
pe_tools.pe_print(
|
||||
"*** Création des interclassements au sein de la promo sur différentes combinaisons de semestres"
|
||||
)
|
||||
if False:
|
||||
self.get_promotags_in_jury()
|
||||
|
||||
# **************************************************************************************************************** #
|
||||
# Traitements des semestres impliqués dans le jury
|
||||
# **************************************************************************************************************** #
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def add_semestretag_in_jury(self, nom: str, formsemestre_id: int):
|
||||
"""Ajoute (après création si nécessaire) un semtag dans `self.semTag` et
|
||||
charge également les données des étudiants (découverts avec ce semestre).
|
||||
|
||||
Args:
|
||||
nom: Le nom à donner au SemestrreTag
|
||||
formsemestre_id: L'identifiant d'un FormSemestre
|
||||
"""
|
||||
if formsemestre_id in self.semTagDict:
|
||||
return
|
||||
|
||||
"""Créé le SemestreTag et exécute les calculs de moyennes"""
|
||||
formsemestretag = pe_semestretag.SemestreTag(nom, formsemestre_id)
|
||||
|
||||
self.semTagDict[formsemestre_id] = formsemestretag
|
||||
|
||||
if pe_tools.PE_DEBUG:
|
||||
filename = nom.replace(" ", "_") + ".csv"
|
||||
pe_tools.pe_print(f" - Export csv de {filename} ")
|
||||
self.zipfile.writestr(filename, formsemestretag.str_tagtable())
|
||||
|
||||
# **************************************************************************************************************** #
|
||||
# Traitements des parcours impliquées dans le jury
|
||||
# **************************************************************************************************************** #
|
||||
|
||||
# # ----------------------------------------------------------------------------------------------------------------
|
||||
# def get_antags_in_jury(self, avec_affichage_debug=True ):
|
||||
# """Construit les settag associés aux années 1A et 2A du jury"""
|
||||
# lesAnnees = {'1A' : ['S1', 'S2'], '2A' : ['S3', 'S4'] }
|
||||
# for nom_annee in lesAnnees:
|
||||
# lesAidDesAnnees = self.get_anneeids_du_jury(annee= nom_annee) # les annee_ids des étudiants du jury
|
||||
# for aid in lesAidDesAnnees:
|
||||
# fidSemTagFinal = JuryPE.convert_aid_en_fid( aid )
|
||||
# lesEtudisDelAnnee = self.semTagDict[ fidSemTagFinal ].get_etudids() # les etudiants sont ceux inscrits dans le semestre final de l'année
|
||||
# parcoursDesEtudiants = { etudid : self.PARCOURSINFO_DICT[etudid] for etudid in lesEtudisDelAnnee } # les parcours des etudid aka quels semestres sont à prendre en compte
|
||||
#
|
||||
# lesFidsDesEtudiants = self.get_formsemestreids_du_jury(lesEtudisDelAnnee, nom_annee) # les formsemestres_id à prendre en compte pour les moyennes
|
||||
# # Manque-t-il des semtag associés ; si oui, les créé
|
||||
# pe_tools.pe_print(aid, lesFidsDesEtudiants)
|
||||
# for fid in lesFidsDesEtudiants:
|
||||
# self.add_semtags_in_jury(fid, avec_affichage_debug=avec_affichage_debug)
|
||||
# lesSemTagDesEtudiants = { fid: self.semTagDict[fid] for fid in lesFidsDesEtudiants }
|
||||
#
|
||||
# # Tous les semtag nécessaires pour ses étudiants avec ajout éventuel s'ils n'ont pas été chargés
|
||||
# pe_tools.pe_print(" -> Création de l'année tagguée " + str( aid ))
|
||||
# #settag_id, short_name, listeEtudId, groupe, listeSemAAggreger, ParcoursEtudDict, SemTagDict, with_comp_moy=True)
|
||||
# self.anTagDict[ aid ] = pe_settag.SetTag( aid, "Annee " + self.semTagDict[fidSemTagFinal].short_name, \
|
||||
# lesEtudisDelAnnee, 'groupe', lesAnnees[ nom_annee ], parcoursDesEtudiants, lesSemTagDesEtudiants )
|
||||
# self.anTagDict[ aid ].comp_data_settag() # calcul les moyennes
|
||||
|
||||
# **************************************************************************************************************** #
|
||||
# Traitements des moyennes sur différentes combinaisons de parcours 1A, 2A, 3S et 4S,
|
||||
# impliquées dans le jury
|
||||
# **************************************************************************************************************** #
|
||||
|
||||
def get_settags_in_jury(self):
|
||||
"""Calcule les moyennes sur la totalité du parcours (S1 jusqu'à S3 ou S4)
|
||||
en classant les étudiants au sein du semestre final du parcours (même S3, même S4, ...)
|
||||
"""
|
||||
|
||||
# Par groupe :
|
||||
# combinaisons = { 'S1' : ['S1'], 'S2' : ['S2'], 'S3' : ['S3'], 'S4' : ['S4'], \
|
||||
# '1A' : ['S1', 'S2'], '2A' : ['S3', 'S4'],
|
||||
# '3S' : ['S1', 'S2', 'S3'], '4S' : ['S1', 'S2', 'S3', 'S4'] }
|
||||
|
||||
# ---> sur 2 parcours DUT (cas S3 fini, cas S4 fini)
|
||||
|
||||
for i, nom in enumerate(pe_tools.TOUS_LES_AGGREGATS):
|
||||
parcours = pe_tools.PARCOURS[nom][
|
||||
"aggregat"
|
||||
] # La liste des noms de semestres (S1, S2, ...) impliqués dans l'aggrégat
|
||||
|
||||
# Recherche des parcours possibles par le biais de leur Fid final
|
||||
fids_finaux = self.get_formsemestreids_du_jury(
|
||||
self.etudiants.get_etudids(self.diplome), nom
|
||||
) # les formsemestre_ids validant finaux des étudiants du jury
|
||||
|
||||
if len(fids_finaux) > 0: # S'il existe des parcours validant
|
||||
pe_tools.pe_print("%d) Fusion %s avec" % (i + 1, nom))
|
||||
|
||||
if nom not in self.setTagDict:
|
||||
self.setTagDict[nom] = {}
|
||||
|
||||
for fid in fids_finaux:
|
||||
pe_tools.pe_print(" - semestre final %s" % (fid))
|
||||
settag = pe_settag.SetTag(
|
||||
nom, parcours=parcours
|
||||
) # Le set tag fusionnant les données
|
||||
etudiants = self.semTagDict[
|
||||
fid
|
||||
].get_etudids() # Les étudiants du sem final
|
||||
|
||||
# ajoute les étudiants au semestre
|
||||
settag.set_Etudiants(
|
||||
etudiants,
|
||||
self.etudiants.cursus,
|
||||
self.etudiants.identites,
|
||||
nom_sem_final=self.semTagDict[fid].nom,
|
||||
)
|
||||
|
||||
# manque-t-il des semestres ? Si oui, les ajoute au jurype puis au settag
|
||||
for ffid in settag.get_Fids_in_settag():
|
||||
if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 1:
|
||||
pe_tools.pe_print(
|
||||
" -> ajout du semestre tagué %s" % (ffid)
|
||||
)
|
||||
self.add_semestretag_in_jury(ffid)
|
||||
settag.set_SemTagDict(
|
||||
self.semTagDict
|
||||
) # ajoute les semestres au settag
|
||||
|
||||
settag.comp_data_settag() # Calcul les moyennes, les rangs, ..
|
||||
|
||||
self.setTagDict[nom][fid] = settag # Mémorise le résultat
|
||||
|
||||
else:
|
||||
pe_tools.pe_print("%d) Pas de fusion %s possible" % (i + 1, nom))
|
||||
|
||||
def get_promotags_in_jury(self):
|
||||
"""Calcule les aggrégats en interclassant les étudiants du jury (les moyennes ont déjà été calculées en amont)"""
|
||||
"""Interclasse les étudiants, (nom d') aggrégat par aggrégat,
|
||||
pour fournir un classement sur la promo.
|
||||
"""
|
||||
|
||||
lesEtudids = self.etudiants.get_etudids(self.diplome)
|
||||
|
||||
for i, nom in enumerate(pe_tools.PARCOURS.keys()):
|
||||
settag = pe_settag.SetTagInterClasse(nom, diplome=self.diplome)
|
||||
settag = app.pe.pe_settag_interclasse.SetTagInterClasse(
|
||||
nom, diplome=self.diplome
|
||||
)
|
||||
nbreEtudInscrits = settag.set_Etudiants(
|
||||
lesEtudids, self.etudiants.cursus, self.etudiants.identites
|
||||
)
|
||||
@ -383,9 +254,9 @@ class JuryPE(object):
|
||||
"%d) %s avec interclassement sur la promo" % (i + 1, nom)
|
||||
)
|
||||
if nom in pe_tools.TOUS_LES_SEMESTRES:
|
||||
settag.set_SetTagDict(self.semTagDict)
|
||||
settag.set_SetTagDict(self.semestres_taggues)
|
||||
else: # cas des aggrégats
|
||||
settag.set_SetTagDict(self.setTagDict[nom])
|
||||
settag.set_SetTagDict(self.aggregats_taggues[nom])
|
||||
settag.comp_data_settag()
|
||||
self.promoTagDict[nom] = settag
|
||||
else:
|
||||
@ -435,9 +306,11 @@ class JuryPE(object):
|
||||
self.etudiants.cursus[etudid][nom] != None
|
||||
): # Un parcours valide existe
|
||||
if nom in pe_tools.TOUS_LES_SEMESTRES:
|
||||
tagtable = self.semTagDict[self.etudiants.cursus[etudid][nom]]
|
||||
tagtable = self.semestres_taggues[
|
||||
self.etudiants.cursus[etudid][nom]
|
||||
]
|
||||
else:
|
||||
tagtable = self.setTagDict[nom][
|
||||
tagtable = self.aggregats_taggues[nom][
|
||||
self.etudiants.cursus[etudid][nom]
|
||||
]
|
||||
for tag in tagtable.get_all_tags():
|
||||
@ -467,7 +340,7 @@ class JuryPE(object):
|
||||
def get_parcoursIUT(self, etudid):
|
||||
"""Renvoie une liste d'infos sur les semestres du parcours d'un étudiant"""
|
||||
# etudinfo = self.ETUDINFO_DICT[etudid]
|
||||
sems = pe_etudiants.semestres_etudiant(etudid)
|
||||
sems = self.etudiants.semestres_etudiant(etudid)
|
||||
|
||||
infos = []
|
||||
for sem in sems:
|
||||
@ -505,8 +378,8 @@ class JuryPE(object):
|
||||
# les semestres et les aggrégats
|
||||
for nom_sem in pe_tools.TOUS_LES_PARCOURS:
|
||||
table = (
|
||||
self.semTagDict[donnees[nom_sem]].nom
|
||||
if donnees[nom_sem] in self.semTagDict
|
||||
self.semestres_taggues[donnees[nom_sem]].nom
|
||||
if donnees[nom_sem] in self.semestres_taggues
|
||||
else "manquant"
|
||||
)
|
||||
descr += [
|
||||
@ -746,7 +619,7 @@ class JuryPE(object):
|
||||
semtagid = self.etudiants.cursus[etudid][
|
||||
nom_sem
|
||||
] # le formsemestre_id du semestre taggué de l'étudiant
|
||||
semtag = self.semTagDict[semtagid]
|
||||
semtag = self.semestres_taggues[semtagid]
|
||||
chaine += "Semestre " + nom_sem + str(semtagid) + "\n"
|
||||
# le détail du calcul tag par tag
|
||||
# chaine += "Détail du calcul du tag\n"
|
||||
@ -772,3 +645,112 @@ class JuryPE(object):
|
||||
if annees_debut:
|
||||
return str(min(annees_debut))
|
||||
return ""
|
||||
|
||||
|
||||
def compute_semestres_tag(etudiants: EtudiantsJuryPE):
|
||||
"""Créé les semestres taggués, de type 'S1', 'S2', ..., pour un groupe d'étudiants donnés.
|
||||
Chaque semestre taggué est rattaché à l'un des FormSemestre faisant partie du cursus scolaire
|
||||
des étudiants (cf. attribut etudiants.cursus).
|
||||
En crééant le semestre taggué, sont calculées les moyennes/classements par tag associé.
|
||||
.
|
||||
|
||||
Args:
|
||||
etudiants: Un groupe d'étudiants participant au jury
|
||||
|
||||
Returns:
|
||||
Un dictionnaire {fid: SemestreTag(fid)}
|
||||
"""
|
||||
|
||||
"""Création des semestres taggués, de type 'S1', 'S2', ..."""
|
||||
pe_tools.pe_print("*** Création des semestres taggués")
|
||||
|
||||
formsemestres = etudiants.get_formsemestres_jury(
|
||||
semestres_recherches=pe_tools.TOUS_LES_SEMESTRES
|
||||
)
|
||||
|
||||
semestres_tags = {}
|
||||
for frmsem_id, formsemestre in formsemestres.items():
|
||||
"""Choix d'un nom pour le semestretag"""
|
||||
nom = "S%d %d %d-%d" % (
|
||||
formsemestre.semestre_id,
|
||||
frmsem_id,
|
||||
formsemestre.date_debut.year,
|
||||
formsemestre.date_fin.year,
|
||||
)
|
||||
|
||||
pe_tools.pe_print(f" --> Semestre taggué {nom} sur la base de {formsemestre}")
|
||||
|
||||
"""Créé le semestre_tag et exécute les calculs de moyennes"""
|
||||
formsemestretag = pe_semestretag.SemestreTag(nom, frmsem_id)
|
||||
|
||||
"""Stocke le semestre taggué"""
|
||||
semestres_tags[frmsem_id] = formsemestretag
|
||||
|
||||
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
|
||||
classements par tag pour chacune. Chaque combinaison (aggrégat) est identifiée
|
||||
par un formsemestre terminal.
|
||||
|
||||
Par exemple :
|
||||
|
||||
* 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.
|
||||
|
||||
Args:
|
||||
etudiants: Les données des étudiants
|
||||
semestres_tag: Les semestres tag (pour lesquels des moyennes par tag ont été calculés)
|
||||
|
||||
Return:
|
||||
Un dictionnaire de la forme {nom_aggregat: {fid_terminal: SetTag(fid_terminal)} }
|
||||
"""
|
||||
|
||||
pe_tools.pe_print(" *** Création des aggrégats ")
|
||||
|
||||
sets_tags = {}
|
||||
|
||||
for aggregat in 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]
|
||||
|
||||
pe_tools.pe_print(f"* {aggregat}: " + "+".join(noms_semestres_aggreges))
|
||||
|
||||
"""Les formsemestres terminaux des aggrégats"""
|
||||
formsemestres_terminal = etudiants.get_formsemestres_terminaux_aggregat(
|
||||
aggregat
|
||||
)
|
||||
|
||||
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,
|
||||
frmsem_id,
|
||||
formsemestre_terminal.date_debut.year,
|
||||
formsemestre_terminal.date_fin.year,
|
||||
)
|
||||
|
||||
"""Semestres à aggreger dans l'aggrégat ayant amené des étudiants jusqu'au formsemestre_terminal"""
|
||||
semestres_aggreges = etudiants.get_semestres_a_aggreger(aggregat, frmsem_id)
|
||||
|
||||
pe_tools.pe_print(" --> Fusion de :")
|
||||
for fid in semestres_aggreges:
|
||||
pe_tools.pe_print(str(semestres_aggreges[fid]))
|
||||
|
||||
"""Création du settag associé"""
|
||||
settag = pe_settag.SetTag(
|
||||
nom, formsemestre_terminal, semestres_aggreges, semestres_tag, etudiants
|
||||
)
|
||||
|
||||
settag.compute_notes_cube() # Calcul les moyennes, les rangs, ..
|
||||
|
||||
sets_tags[aggregat][fid] = settag # Mémorise le résultat
|
||||
|
||||
return sets_tags
|
||||
|
@ -95,10 +95,8 @@ class SemestreTag(pe_tagtable.TableTag):
|
||||
self.ues_inscr_parcours_df = self.nt.load_ues_inscr_parcours()
|
||||
self.dispense_ues = self.nt.dispense_ues
|
||||
|
||||
"""Les tags"""
|
||||
"""Les tags (en supprimant les tags réservés)"""
|
||||
self.tags = get_synthese_tags_semestre(self.nt.formsemestre)
|
||||
|
||||
"""Supprime les tags réservés"""
|
||||
for tag in pe_tagtable.TAGS_RESERVES:
|
||||
if tag in self.tags:
|
||||
del self.tags[tag]
|
||||
@ -132,6 +130,10 @@ class SemestreTag(pe_tagtable.TableTag):
|
||||
"nb_inscrits": len(moy_gen_but),
|
||||
}
|
||||
|
||||
"""Synthétise l'ensemble des moyennes dans un dataframe"""
|
||||
self.tags_sorted = sorted(self.moyennes_tags) # les tags par ordre alphabétique
|
||||
self.notes = self.df_tagtable() # Le dataframe synthétique des notes (=moyennes par tag)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_etudids(self):
|
||||
"""Renvoie la liste des etud_id des étudiants inscrits au semestre"""
|
||||
|
@ -35,9 +35,16 @@ Created on Fri Sep 9 09:15:05 2016
|
||||
|
||||
@author: barasc
|
||||
"""
|
||||
|
||||
from app.pe.pe_tools import pe_print, PE_DEBUG
|
||||
from app.comp import moy_sem
|
||||
from app.comp.res_sem import load_formsemestre_results
|
||||
from app.models import FormSemestre
|
||||
from app.pe.pe_semestretag import SemestreTag
|
||||
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):
|
||||
@ -50,275 +57,152 @@ 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).
|
||||
"""
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def __init__(self, nom_combinaison, parcours):
|
||||
pe_tagtable.TableTag.__init__(self, nom=nom_combinaison)
|
||||
self.combinaison = nom_combinaison
|
||||
self.parcours = parcours # Le groupe de semestres/parcours à aggréger
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
def set_Etudiants(
|
||||
self, etudiants: list[dict], juryPEDict, etudInfoDict, nom_sem_final=None
|
||||
def __init__(
|
||||
self,
|
||||
nom,
|
||||
formsemestre_terminal: FormSemestre,
|
||||
semestres_aggreges: dict[int, FormSemestre],
|
||||
semestres_taggues: dict[int, SemestreTag],
|
||||
donnees_etudiants: EtudiantsJuryPE,
|
||||
):
|
||||
"""Détermine la liste des étudiants à prendre en compte, en partant de
|
||||
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]
|
||||
pe_tagtable.TableTag.__init__(self, nom)
|
||||
|
||||
delta = len(etudiants) - len(self.inscrlist)
|
||||
if delta > 0:
|
||||
pe_print(self.nom + " -> " + str(delta) + " étudiants supprimés")
|
||||
"""Le formsemestre terminal et les semestres aggrégés"""
|
||||
self.formsemestre_terminal = formsemestre_terminal
|
||||
nt = load_formsemestre_results(formsemestre_terminal)
|
||||
self.semestres_aggreges = semestres_aggreges
|
||||
|
||||
# Le sous-ensemble des parcours
|
||||
self.parcoursDict = {etudid: juryPEDict[etudid] for etudid in self.identdict}
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
def get_Fids_in_settag(self):
|
||||
"""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
|
||||
"""Les semestres tags associés aux semestres aggrégés"""
|
||||
try:
|
||||
self.semestres_tags_aggreges = {
|
||||
frmsem_id: semestres_taggues[frmsem_id]
|
||||
for frmsem_id in semestres_taggues
|
||||
}
|
||||
)
|
||||
except:
|
||||
raise ValueError("Semestres taggués manquants")
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
def set_SemTagDict(self, SemTagDict):
|
||||
"""Mémorise les semtag nécessaires au jury."""
|
||||
self.SemTagDict = {fid: SemTagDict[fid] for fid in self.get_Fids_in_settag()}
|
||||
if PE_DEBUG >= 1:
|
||||
pe_print(" => %d semestres fusionnés" % len(self.SemTagDict))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def comp_data_settag(self):
|
||||
"""Calcule tous les données numériques relatives au settag"""
|
||||
# Attributs relatifs aux tag pour les modules pris en compte
|
||||
self.taglist = self.do_taglist() # la liste des tags
|
||||
self.do_tagdict() # le dico descriptif des tags
|
||||
# if PE_DEBUG >= 1: pe_print(" => Tags = " + ", ".join( self.taglist ))
|
||||
|
||||
# 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):
|
||||
return list(self.identdict.keys())
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def do_taglist(self):
|
||||
"""Parcourt les tags des semestres taggués et les synthétise sous la forme
|
||||
d'une liste en supprimant les doublons
|
||||
"""
|
||||
ensemble = []
|
||||
for semtag in self.SemTagDict.values():
|
||||
ensemble.extend(semtag.get_all_tags())
|
||||
return sorted(list(set(ensemble)))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def do_tagdict(self):
|
||||
"""Synthétise la liste des modules pris en compte dans le calcul d'un tag (pour analyse des résultats)"""
|
||||
self.tagdict = {}
|
||||
for semtag in self.SemTagDict.values():
|
||||
for tag in semtag.get_all_tags():
|
||||
if tag != "but":
|
||||
if tag not in self.tagdict:
|
||||
self.tagdict[tag] = {}
|
||||
for mod in semtag.tagdict[tag]:
|
||||
self.tagdict[tag][mod] = semtag.tagdict[tag][mod]
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_NotesEtCoeffsSetTagEtudiant(self, tag, etudid):
|
||||
"""Récupère tous les notes et les coeffs d'un étudiant relatives à un tag dans ses semestres valides et les renvoie dans un tuple (notes, coeffs)
|
||||
avec notes et coeffs deux listes"""
|
||||
lesSemsDeLEtudiant = [
|
||||
self.parcoursDict[etudid][nom_sem] for nom_sem in self.parcours
|
||||
] # peuvent être None
|
||||
|
||||
notes = [
|
||||
self.SemTagDict[fid].get_moy_from_resultats(tag, etudid)
|
||||
for fid in lesSemsDeLEtudiant
|
||||
if tag in self.SemTagDict[fid].taglist
|
||||
] # eventuellement None
|
||||
coeffs = [
|
||||
self.SemTagDict[fid].get_coeff_from_resultats(tag, etudid)
|
||||
for fid in lesSemsDeLEtudiant
|
||||
if tag in self.SemTagDict[fid].taglist
|
||||
]
|
||||
return (notes, coeffs)
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def comp_MoyennesSetTag(self, tag, force=False):
|
||||
"""Calcule et renvoie les "moyennes" des étudiants à un tag donné, en prenant en compte tous les semestres taggués
|
||||
de l'aggrégat, et leur coeff Par moyenne, s'entend une note moyenne, la somme des coefficients de pondération
|
||||
appliqué dans cette moyenne.
|
||||
|
||||
Force ou non le calcul de la moyenne lorsque des notes sont manquantes.
|
||||
|
||||
Renvoie les informations sous la forme d'une liste [etudid: (moy, somme_coeff_normalisée, rang), ...}
|
||||
"""
|
||||
# if tag not in self.get_all_tags() : return None
|
||||
|
||||
# Calcule les moyennes
|
||||
lesMoyennes = []
|
||||
for (
|
||||
etudid
|
||||
) in (
|
||||
self.get_etudids()
|
||||
): # Pour tous les étudiants non défaillants du semestre inscrits dans des modules relatifs au tag
|
||||
(notes, coeffs_norm) = self.get_NotesEtCoeffsSetTagEtudiant(
|
||||
tag, etudid
|
||||
) # lecture des notes associées au tag
|
||||
(moyenne, somme_coeffs) = pe_tagtable.moyenne_ponderee_terme_a_terme(
|
||||
notes, coeffs_norm, force=force
|
||||
)
|
||||
lesMoyennes += [
|
||||
(moyenne, somme_coeffs, etudid)
|
||||
] # Un tuple (pour classement résumant les données)
|
||||
return lesMoyennes
|
||||
|
||||
|
||||
class SetTagInterClasse(pe_tagtable.TableTag):
|
||||
"""Récupère les moyennes de SetTag aggrégeant un même parcours (par ex un ['S1', 'S2'] n'ayant pas fini au même S2
|
||||
pour fournir un interclassement sur un groupe d'étudiant => seul compte alors la promo
|
||||
nom_combinaison = 'S1' ou '1A'
|
||||
"""
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def __init__(self, nom_combinaison, diplome):
|
||||
pe_tagtable.TableTag.__init__(self, nom=f"{nom_combinaison}_{diplome or ''}")
|
||||
self.combinaison = nom_combinaison
|
||||
self.parcoursDict = {}
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
def set_Etudiants(self, etudiants, juryPEDict, etudInfoDict, nom_sem_final=None):
|
||||
"""Détermine la liste des étudiants à prendre en compte, en partant de
|
||||
la liste fournie en paramètre et en vérifiant que l'étudiant dispose bien d'un parcours valide pour la combinaison demandée.
|
||||
Renvoie le nombre d'étudiants effectivement inscrits."""
|
||||
if nom_sem_final:
|
||||
self.nom += "_" + nom_sem_final
|
||||
for etudid in etudiants:
|
||||
if juryPEDict[etudid][self.combinaison] != None:
|
||||
self.inscrlist.append(etudInfoDict[etudid])
|
||||
self.identdict[etudid] = etudInfoDict[etudid]
|
||||
self.parcoursDict[etudid] = juryPEDict[etudid]
|
||||
return len(self.inscrlist)
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
def get_Fids_in_settag(self):
|
||||
"""Renvoie la liste des semestres (les formsemestre_id finissant la combinaison par ex. '3S' dont les fid des S3) à prendre en compte
|
||||
pour les moyennes, en considérant tous les étudiants inscrits"""
|
||||
return list(
|
||||
{self.parcoursDict[etudid][self.combinaison] for etudid in self.identdict}
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
def set_SetTagDict(self, SetTagDict):
|
||||
"""Mémorise les settag nécessaires au jury."""
|
||||
self.SetTagDict = {
|
||||
fid: SetTagDict[fid] for fid in self.get_Fids_in_settag() if fid != None
|
||||
"""Les étudiants (état civil + cursus connu)"""
|
||||
self.etuds = nt.etuds
|
||||
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
||||
self.cursus = {
|
||||
etudid: donnees_etudiants.cursus[etudid] for etudid in self.etudiants
|
||||
}
|
||||
if PE_DEBUG >= 1:
|
||||
pe_print(" => %d semestres utilisés" % len(self.SetTagDict))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def comp_data_settag(self):
|
||||
"""Calcule tous les données numériques relatives au settag"""
|
||||
# Attributs relatifs aux tag pour les modules pris en compte
|
||||
self.taglist = self.do_taglist()
|
||||
"""Les tags extraits de tous les semestres"""
|
||||
self.tags_sorted = self.do_taglist()
|
||||
|
||||
# if PE_DEBUG >= 1: pe_print(" => Tags = " + ", ".join( self.taglist ))
|
||||
"""Construit le cube de notes"""
|
||||
self.notes_cube = self.compute_notes_cube()
|
||||
|
||||
# Calcul des moyennes de chaque étudiant par tag
|
||||
reussiteAjoutTag = {"OK": [], "KO": []}
|
||||
for tag in self.taglist:
|
||||
moyennes = self.get_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(
|
||||
" => Interclassement 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"])
|
||||
)
|
||||
"""Calcul les moyennes par tag sous forme d'un dataframe"""
|
||||
etudids = self.get_etudids()
|
||||
self.notes = compute_tag_moy(self.notes_cube, etudids, self.tags_sorted)
|
||||
|
||||
"""Synthétise les moyennes/classements par tag"""
|
||||
self.moyennes_tags = {}
|
||||
for tag in self.tags_sorted:
|
||||
moy_gen_tag = self.notes[tag]
|
||||
class_gen_tag = moy_sem.comp_ranks_series(moy_gen_tag)[1] # en int
|
||||
self.moyennes_tags[tag] = {
|
||||
"notes": moy_gen_tag,
|
||||
"classements": class_gen_tag,
|
||||
"min": moy_gen_tag.min(),
|
||||
"max": moy_gen_tag.max(),
|
||||
"moy": moy_gen_tag.mean(),
|
||||
"nb_inscrits": len(moy_gen_tag),
|
||||
}
|
||||
|
||||
def compute_notes_cube(self):
|
||||
"""Construit le cube de notes (etudid x tags x semestre_aggregé)
|
||||
nécessaire au calcul des moyennes de l'aggrégat
|
||||
"""
|
||||
nb_tags = len(self.tags_sorted)
|
||||
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=tags)
|
||||
|
||||
"""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
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_etudids(self):
|
||||
return list(self.identdict.keys())
|
||||
return list(self.etudiants.keys())
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def do_taglist(self):
|
||||
"""Parcourt les tags des semestres taggués et les synthétise sous la forme
|
||||
d'une liste en supprimant les doublons
|
||||
"""Synthétise les tags à partir des semestres (taggués) aggrégés
|
||||
|
||||
Returns:
|
||||
Une liste de tags triés par ordre alphabétique
|
||||
"""
|
||||
ensemble = []
|
||||
for settag in self.SetTagDict.values():
|
||||
ensemble.extend(settag.get_all_tags())
|
||||
return sorted(list(set(ensemble)))
|
||||
tags = []
|
||||
for frmsem_id in self.semestres_tags_aggreges:
|
||||
tags.extend(self.semestres_tags_aggreges[frmsem_id].tags_sorted)
|
||||
return sorted(set(tags))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_NotesEtCoeffsSetTagEtudiant(self, tag, etudid):
|
||||
"""Récupère tous les notes et les coeffs d'un étudiant relatives à un tag dans ses semestres valides et les renvoie dans un tuple (notes, coeffs)
|
||||
avec notes et coeffs deux listes"""
|
||||
leSetTagDeLetudiant = self.parcoursDict[etudid][self.combinaison]
|
||||
|
||||
note = self.SetTagDict[leSetTagDeLetudiant].get_moy_from_resultats(tag, etudid)
|
||||
coeff = self.SetTagDict[leSetTagDeLetudiant].get_coeff_from_resultats(
|
||||
tag, etudid
|
||||
)
|
||||
return (note, coeff)
|
||||
def compute_tag_moy(set_cube: np.array, etudids: list, tags: list):
|
||||
"""Calcul de la moyenne par tag sur plusieurs semestres.
|
||||
La moyenne est un nombre (note/20), ou NaN si pas de notes disponibles
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_MoyennesSetTag(self, tag, force=False):
|
||||
"""Renvoie les "moyennes" des étudiants à un tag donné, en prenant en compte tous les settag de l'aggrégat,
|
||||
et leur coeff Par moyenne, s'entend une note moyenne, la somme des coefficients de pondération
|
||||
appliqué dans cette moyenne.
|
||||
*Remarque* : Adaptation de moy_ue.compute_ue_moys_apc au cas des moyennes de tag
|
||||
par aggrégat de plusieurs semestres.
|
||||
|
||||
Force ou non le calcul de la moyenne lorsque des notes sont manquantes.
|
||||
Args:
|
||||
set_cube: notes moyennes aux modules ndarray
|
||||
(etuds x modimpls x UEs), des floats avec des NaN
|
||||
etudids: liste des étudiants (dim. 0 du cube)
|
||||
tags: liste des tags (dim. 1 du cube)
|
||||
Returns:
|
||||
Un DataFrame avec pour columns les moyennes par tags,
|
||||
et pour rows les etudid
|
||||
"""
|
||||
nb_etuds, nb_tags, nb_semestres = set_cube.shape
|
||||
assert nb_etuds == len(etudids)
|
||||
assert nb_tags == len(tags)
|
||||
|
||||
Renvoie les informations sous la forme d'une liste [etudid: (moy, somme_coeff_normalisée, rang), ...}
|
||||
"""
|
||||
# if tag not in self.get_all_tags() : return None
|
||||
# Quelles entrées du cube contiennent des notes ?
|
||||
mask = ~np.isnan(set_cube)
|
||||
|
||||
# Calcule les moyennes
|
||||
lesMoyennes = []
|
||||
for (
|
||||
etudid
|
||||
) in (
|
||||
self.get_etudids()
|
||||
): # Pour tous les étudiants non défaillants du semestre inscrits dans des modules relatifs au tag
|
||||
(moyenne, somme_coeffs) = self.get_NotesEtCoeffsSetTagEtudiant(
|
||||
tag, etudid
|
||||
) # lecture des notes associées au tag
|
||||
lesMoyennes += [
|
||||
(moyenne, somme_coeffs, etudid)
|
||||
] # Un tuple (pour classement résumant les données)
|
||||
return lesMoyennes
|
||||
# Enlève les NaN du cube pour les entrées manquantes
|
||||
set_cube_no_nan = np.nan_to_num(set_cube, nan=0.0)
|
||||
|
||||
# Les moyennes par tag
|
||||
with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN)
|
||||
etud_moy_tag = np.sum(set_cube_no_nan, axis=2) / np.sum(mask, axis=2)
|
||||
|
||||
# Le dataFrame
|
||||
etud_moy_tag_df = pd.DataFrame(
|
||||
etud_moy_tag,
|
||||
index=etudids, # les etudids
|
||||
columns=tags, # les tags
|
||||
)
|
||||
|
||||
return etud_moy_tag_df
|
||||
|
125
app/pe/pe_settag_interclasse.py
Normal file
125
app/pe/pe_settag_interclasse.py
Normal file
@ -0,0 +1,125 @@
|
||||
from app.pe import pe_tagtable
|
||||
from app.pe.pe_tools import PE_DEBUG, pe_print
|
||||
|
||||
|
||||
class SetTagInterClasse(pe_tagtable.TableTag):
|
||||
"""Récupère les moyennes de SetTag aggrégeant un même parcours (par ex un ['S1', 'S2']
|
||||
n'ayant pas fini au même S2
|
||||
pour fournir un interclassement sur un groupe d'étudiant => seul compte alors la promo
|
||||
nom_combinaison = 'S1' ou '1A'
|
||||
"""
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def __init__(self, nom_combinaison, diplome):
|
||||
pe_tagtable.TableTag.__init__(self, nom=f"{nom_combinaison}_{diplome or ''}")
|
||||
self.combinaison = nom_combinaison
|
||||
self.parcoursDict = {}
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
def set_Etudiants(self, etudiants, juryPEDict, etudInfoDict, nom_sem_final=None):
|
||||
"""Détermine la liste des étudiants à prendre en compte, en partant de
|
||||
la liste fournie en paramètre et en vérifiant que l'étudiant dispose bien d'un parcours valide pour la combinaison demandée.
|
||||
Renvoie le nombre d'étudiants effectivement inscrits."""
|
||||
if nom_sem_final:
|
||||
self.nom += "_" + nom_sem_final
|
||||
for etudid in etudiants:
|
||||
if juryPEDict[etudid][self.combinaison] != None:
|
||||
self.inscrlist.append(etudInfoDict[etudid])
|
||||
self.identdict[etudid] = etudInfoDict[etudid]
|
||||
self.parcoursDict[etudid] = juryPEDict[etudid]
|
||||
return len(self.inscrlist)
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
def get_Fids_in_settag(self):
|
||||
"""Renvoie la liste des semestres (les formsemestre_id finissant la combinaison par ex. '3S' dont les fid des S3) à prendre en compte
|
||||
pour les moyennes, en considérant tous les étudiants inscrits"""
|
||||
return list(
|
||||
{self.parcoursDict[etudid][self.combinaison] for etudid in self.identdict}
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
def set_SetTagDict(self, SetTagDict):
|
||||
"""Mémorise les settag nécessaires au jury."""
|
||||
self.SetTagDict = {
|
||||
fid: SetTagDict[fid] for fid in self.get_Fids_in_settag() if fid != None
|
||||
}
|
||||
if PE_DEBUG >= 1:
|
||||
pe_print(" => %d semestres utilisés" % len(self.SetTagDict))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def comp_data_settag(self):
|
||||
"""Calcule tous les données numériques relatives au settag"""
|
||||
# Attributs relatifs aux tag pour les modules pris en compte
|
||||
self.taglist = self.do_taglist()
|
||||
|
||||
# if PE_DEBUG >= 1: pe_print(" => Tags = " + ", ".join( self.taglist ))
|
||||
|
||||
# Calcul des moyennes de chaque étudiant par tag
|
||||
reussiteAjoutTag = {"OK": [], "KO": []}
|
||||
for tag in self.taglist:
|
||||
moyennes = self.get_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(
|
||||
" => Interclassement 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):
|
||||
return list(self.identdict.keys())
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def do_taglist(self):
|
||||
"""Parcourt les tags des semestres taggués et les synthétise sous la forme
|
||||
d'une liste en supprimant les doublons
|
||||
"""
|
||||
ensemble = []
|
||||
for settag in self.SetTagDict.values():
|
||||
ensemble.extend(settag.get_all_tags())
|
||||
return sorted(list(set(ensemble)))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_NotesEtCoeffsSetTagEtudiant(self, tag, etudid):
|
||||
"""Récupère tous les notes et les coeffs d'un étudiant relatives à un tag dans ses semestres valides et les renvoie dans un tuple (notes, coeffs)
|
||||
avec notes et coeffs deux listes"""
|
||||
leSetTagDeLetudiant = self.parcoursDict[etudid][self.combinaison]
|
||||
|
||||
note = self.SetTagDict[leSetTagDeLetudiant].get_moy_from_resultats(tag, etudid)
|
||||
coeff = self.SetTagDict[leSetTagDeLetudiant].get_coeff_from_resultats(
|
||||
tag, etudid
|
||||
)
|
||||
return (note, coeff)
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_MoyennesSetTag(self, tag, force=False):
|
||||
"""Renvoie les "moyennes" des étudiants à un tag donné, en prenant en compte tous les settag de l'aggrégat,
|
||||
et leur coeff Par moyenne, s'entend une note moyenne, la somme des coefficients de pondération
|
||||
appliqué dans cette moyenne.
|
||||
|
||||
Force ou non le calcul de la moyenne lorsque des notes sont manquantes.
|
||||
|
||||
Renvoie les informations sous la forme d'une liste [etudid: (moy, somme_coeff_normalisée, rang), ...}
|
||||
"""
|
||||
# if tag not in self.get_all_tags() : return None
|
||||
|
||||
# Calcule les moyennes
|
||||
lesMoyennes = []
|
||||
for (
|
||||
etudid
|
||||
) in (
|
||||
self.get_etudids()
|
||||
): # Pour tous les étudiants non défaillants du semestre inscrits dans des modules relatifs au tag
|
||||
(moyenne, somme_coeffs) = self.get_NotesEtCoeffsSetTagEtudiant(
|
||||
tag, etudid
|
||||
) # lecture des notes associées au tag
|
||||
lesMoyennes += [
|
||||
(moyenne, somme_coeffs, etudid)
|
||||
] # Un tuple (pour classement résumant les données)
|
||||
return lesMoyennes
|
@ -83,8 +83,11 @@ class TableTag(object):
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_all_tags(self):
|
||||
"""Renvoie la liste des tags du semestre triée par ordre alphabétique"""
|
||||
# return self.taglist
|
||||
"""Liste des tags de la table, triée par ordre alphabétique
|
||||
|
||||
Returns:
|
||||
Liste de tags triés par ordre alphabétique
|
||||
"""
|
||||
return sorted(self.moyennes_tags.keys())
|
||||
|
||||
|
||||
@ -270,6 +273,20 @@ class TableTag(object):
|
||||
str_moytag = classmethod(str_moytag)
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
def df_tagtable(self):
|
||||
"""Renvoie un dataframe (etudid x tag) listant toutes les moyennes par tags
|
||||
|
||||
Returns:
|
||||
Un dataframe etudids x tag (avec tag par ordre alphabétique)
|
||||
"""
|
||||
tags = self.get_all_tags()
|
||||
if tags:
|
||||
dict_series = {tag: self.moyennes_tags[tag]["notes"] for tag in tags}
|
||||
df = pd.DataFrame(dict_series)
|
||||
return df
|
||||
else:
|
||||
return None
|
||||
|
||||
def str_tagtable(self):
|
||||
"""Renvoie une chaine de caractère listant toutes les moyennes,
|
||||
les rangs des étudiants pour tous les tags."""
|
||||
|
@ -164,6 +164,10 @@ 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"""
|
||||
|
Loading…
Reference in New Issue
Block a user