forked from ScoDoc/ScoDoc
Export Excel : Ajoute un tableur donnant les informations par étudiants
This commit is contained in:
parent
66fbb0afbc
commit
78eeb9c67f
@ -1,5 +1,3 @@
|
|||||||
from app.models import Formation, FormSemestre
|
|
||||||
from app.scodoc import codes_cursus
|
|
||||||
from app import log
|
from app import log
|
||||||
|
|
||||||
PE_DEBUG = 0
|
PE_DEBUG = 0
|
||||||
@ -9,73 +7,13 @@ if not PE_DEBUG:
|
|||||||
def pe_print(*a, **kw):
|
def pe_print(*a, **kw):
|
||||||
# kw is ignored. log always add a newline
|
# kw is ignored. log always add a newline
|
||||||
log(" ".join(a))
|
log(" ".join(a))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pe_print = print # print function
|
pe_print = print # print function
|
||||||
|
|
||||||
# Affichage dans le tableur pe en cas d'absence de notes
|
# Affichage dans le tableur pe en cas d'absence de notes
|
||||||
SANS_NOTE = "-"
|
SANS_NOTE = "-"
|
||||||
|
NOM_STAT_GROUPE = "statistiques du groupe"
|
||||||
def nom_semestre_etape(semestre: FormSemestre, avec_fid=False) -> str:
|
NOM_STAT_PROMO = "statistiques de la promo"
|
||||||
"""Nom d'un semestre à afficher dans le descriptif des étapes de la scolarité
|
|
||||||
d'un étudiant.
|
|
||||||
|
|
||||||
Par ex: Pour un S2, affiche ``"Semestre 2 FI S014-2015 (129)"`` avec :
|
|
||||||
|
|
||||||
* 2 le numéro du semestre,
|
|
||||||
* FI la modalité,
|
|
||||||
* 2014-2015 les dates
|
|
||||||
|
|
||||||
Args:
|
|
||||||
semestre: Un ``FormSemestre``
|
|
||||||
avec_fid: Ajoute le n° du semestre à la description
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
La chaine de caractères décrivant succintement le semestre
|
|
||||||
"""
|
|
||||||
formation: Formation = semestre.formation
|
|
||||||
parcours = codes_cursus.get_cursus_from_code(formation.type_parcours)
|
|
||||||
|
|
||||||
description = [
|
|
||||||
parcours.SESSION_NAME.capitalize(),
|
|
||||||
str(semestre.semestre_id),
|
|
||||||
semestre.modalite, # eg FI ou FC
|
|
||||||
f"{semestre.date_debut.year}-{semestre.date_fin.year}",
|
|
||||||
]
|
|
||||||
if avec_fid:
|
|
||||||
description.append(f"({semestre.formsemestre_id})")
|
|
||||||
|
|
||||||
return " ".join(description)
|
|
||||||
|
|
||||||
|
|
||||||
def etapes_du_cursus(semestres: dict[int, FormSemestre], nbre_etapes_max: int) -> list[str]:
|
|
||||||
"""Partant d'un dictionnaire de semestres (qui retrace
|
|
||||||
la scolarité d'un étudiant), liste les noms des
|
|
||||||
semestres (en version abbrégée)
|
|
||||||
qu'un étudiant a suivi au cours de sa scolarité à l'IUT.
|
|
||||||
Les noms des semestres sont renvoyés dans un dictionnaire
|
|
||||||
``{"etape i": nom_semestre_a_etape_i}``
|
|
||||||
avec i variant jusqu'à nbre_semestres_max. (S'il n'y a pas de semestre à l'étape i,
|
|
||||||
le nom affiché est vide.
|
|
||||||
|
|
||||||
La fonction suppose la liste des semestres triées par ordre
|
|
||||||
décroissant de date.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
semestres: une liste de ``FormSemestre``
|
|
||||||
nbre_etapes_max: le nombre d'étapes max prise en compte
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Une liste de nom de semestre (dans le même ordre que les ``semestres``)
|
|
||||||
|
|
||||||
See also:
|
|
||||||
app.pe.pe_affichage.nom_semestre_etape
|
|
||||||
"""
|
|
||||||
assert len(semestres) <= nbre_etapes_max
|
|
||||||
|
|
||||||
noms = [nom_semestre_etape(sem, avec_fid=False) for (fid, sem) in semestres.items()]
|
|
||||||
noms = noms[::-1] # trie par ordre croissant
|
|
||||||
|
|
||||||
dico = {f"Etape {i+1}": "" for i in range(nbre_etapes_max)}
|
|
||||||
for (i, nom) in enumerate(noms): # Charge les noms de semestres
|
|
||||||
dico[f"Etape {i+1}"] = nom
|
|
||||||
return dico
|
|
||||||
|
@ -37,8 +37,9 @@ Created on 17/01/2024
|
|||||||
"""
|
"""
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from app.models import FormSemestre, Identite
|
from app.models import FormSemestre, Identite, Formation
|
||||||
from app.pe import pe_comp, pe_affichage
|
from app.pe import pe_comp, pe_affichage
|
||||||
|
from app.scodoc import codes_cursus
|
||||||
|
|
||||||
|
|
||||||
class EtudiantsJuryPE:
|
class EtudiantsJuryPE:
|
||||||
@ -467,7 +468,7 @@ class EtudiantsJuryPE:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Ajout des noms de semestres parcourus
|
# Ajout des noms de semestres parcourus
|
||||||
etapes = pe_affichage.etapes_du_cursus(formsemestres, nbre_semestres_max)
|
etapes = etapes_du_cursus(formsemestres, nbre_semestres_max)
|
||||||
administratif[etudid] |= etapes
|
administratif[etudid] |= etapes
|
||||||
|
|
||||||
# Construction du dataframe
|
# Construction du dataframe
|
||||||
@ -647,3 +648,71 @@ def get_dernier_semestre_en_date(semestres: dict[int, FormSemestre]) -> FormSeme
|
|||||||
dernier_semestre = semestres[fid]
|
dernier_semestre = semestres[fid]
|
||||||
return dernier_semestre
|
return dernier_semestre
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def etapes_du_cursus(
|
||||||
|
semestres: dict[int, FormSemestre], nbre_etapes_max: int
|
||||||
|
) -> list[str]:
|
||||||
|
"""Partant d'un dictionnaire de semestres (qui retrace
|
||||||
|
la scolarité d'un étudiant), liste les noms des
|
||||||
|
semestres (en version abbrégée)
|
||||||
|
qu'un étudiant a suivi au cours de sa scolarité à l'IUT.
|
||||||
|
Les noms des semestres sont renvoyés dans un dictionnaire
|
||||||
|
``{"etape i": nom_semestre_a_etape_i}``
|
||||||
|
avec i variant jusqu'à nbre_semestres_max. (S'il n'y a pas de semestre à l'étape i,
|
||||||
|
le nom affiché est vide.
|
||||||
|
|
||||||
|
La fonction suppose la liste des semestres triées par ordre
|
||||||
|
décroissant de date.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
semestres: une liste de ``FormSemestre``
|
||||||
|
nbre_etapes_max: le nombre d'étapes max prise en compte
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Une liste de nom de semestre (dans le même ordre que les ``semestres``)
|
||||||
|
|
||||||
|
See also:
|
||||||
|
app.pe.pe_affichage.nom_semestre_etape
|
||||||
|
"""
|
||||||
|
assert len(semestres) <= nbre_etapes_max
|
||||||
|
|
||||||
|
noms = [nom_semestre_etape(sem, avec_fid=False) for (fid, sem) in semestres.items()]
|
||||||
|
noms = noms[::-1] # trie par ordre croissant
|
||||||
|
|
||||||
|
dico = {f"Etape {i+1}": "" for i in range(nbre_etapes_max)}
|
||||||
|
for i, nom in enumerate(noms): # Charge les noms de semestres
|
||||||
|
dico[f"Etape {i+1}"] = nom
|
||||||
|
return dico
|
||||||
|
|
||||||
|
|
||||||
|
def nom_semestre_etape(semestre: FormSemestre, avec_fid=False) -> str:
|
||||||
|
"""Nom d'un semestre à afficher dans le descriptif des étapes de la scolarité
|
||||||
|
d'un étudiant.
|
||||||
|
|
||||||
|
Par ex: Pour un S2, affiche ``"Semestre 2 FI S014-2015 (129)"`` avec :
|
||||||
|
|
||||||
|
* 2 le numéro du semestre,
|
||||||
|
* FI la modalité,
|
||||||
|
* 2014-2015 les dates
|
||||||
|
|
||||||
|
Args:
|
||||||
|
semestre: Un ``FormSemestre``
|
||||||
|
avec_fid: Ajoute le n° du semestre à la description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
La chaine de caractères décrivant succintement le semestre
|
||||||
|
"""
|
||||||
|
formation: Formation = semestre.formation
|
||||||
|
parcours = codes_cursus.get_cursus_from_code(formation.type_parcours)
|
||||||
|
|
||||||
|
description = [
|
||||||
|
parcours.SESSION_NAME.capitalize(),
|
||||||
|
str(semestre.semestre_id),
|
||||||
|
semestre.modalite, # eg FI ou FC
|
||||||
|
f"{semestre.date_debut.year}-{semestre.date_fin.year}",
|
||||||
|
]
|
||||||
|
if avec_fid:
|
||||||
|
description.append(f"({semestre.formsemestre_id})")
|
||||||
|
|
||||||
|
return " ".join(description)
|
||||||
|
@ -48,6 +48,9 @@ from zipfile import ZipFile
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
from app.pe import pe_comp
|
||||||
|
from app.pe.pe_affichage import NOM_STAT_PROMO, SANS_NOTE, NOM_STAT_GROUPE
|
||||||
|
|
||||||
from app.pe.pe_tabletags import TableTag
|
from app.pe.pe_tabletags import TableTag
|
||||||
from app.scodoc.gen_tables import SeqGenTable
|
from app.scodoc.gen_tables import SeqGenTable
|
||||||
from app.pe.pe_etudiant import EtudiantsJuryPE
|
from app.pe.pe_etudiant import EtudiantsJuryPE
|
||||||
@ -119,7 +122,9 @@ class JuryPE(object):
|
|||||||
self._gen_xls_semestre_taggues(zipfile)
|
self._gen_xls_semestre_taggues(zipfile)
|
||||||
self._gen_xls_trajectoires(zipfile)
|
self._gen_xls_trajectoires(zipfile)
|
||||||
self._gen_xls_aggregats(zipfile)
|
self._gen_xls_aggregats(zipfile)
|
||||||
self._gen_xls_synthese(zipfile)
|
self._gen_xls_synthese_jury_par_tag(zipfile)
|
||||||
|
self._gen_xls_synthese_par_etudiant(zipfile)
|
||||||
|
|
||||||
|
|
||||||
# Fin !!!! Tada :)
|
# Fin !!!! Tada :)
|
||||||
|
|
||||||
@ -237,13 +242,13 @@ class JuryPE(object):
|
|||||||
path="details",
|
path="details",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _gen_xls_synthese(self, zipfile: ZipFile):
|
def _gen_xls_synthese_jury_par_tag(self, zipfile: ZipFile):
|
||||||
"""Synthèse des éléments du jury PE"""
|
"""Synthèse des éléments du jury PE tag par tag"""
|
||||||
# Synthèse des éléments du jury PE
|
# Synthèse des éléments du jury PE
|
||||||
self.synthese = self.synthetise_juryPE()
|
self.synthese = self.synthetise_jury_par_tags()
|
||||||
|
|
||||||
# Export des données => mode 1 seule feuille -> supprimé
|
# Export des données => mode 1 seule feuille -> supprimé
|
||||||
pe_affichage.pe_print("*** Export du jury de synthese")
|
pe_affichage.pe_print("*** Export du jury de synthese par tags")
|
||||||
output = io.BytesIO()
|
output = io.BytesIO()
|
||||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
output, engine="openpyxl"
|
output, engine="openpyxl"
|
||||||
@ -254,7 +259,27 @@ class JuryPE(object):
|
|||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
self.add_file_to_zip(
|
self.add_file_to_zip(
|
||||||
zipfile, f"synthese_jury_{self.diplome}.xlsx", output.read()
|
zipfile, f"synthese_jury_{self.diplome}_par_tag.xlsx", output.read()
|
||||||
|
)
|
||||||
|
|
||||||
|
def _gen_xls_synthese_par_etudiant(self, zipfile: ZipFile):
|
||||||
|
"""Synthèse des éléments du jury PE, étudiant par étudiant"""
|
||||||
|
# Synthèse des éléments du jury PE
|
||||||
|
synthese = self.synthetise_jury_par_etudiants()
|
||||||
|
|
||||||
|
# Export des données => mode 1 seule feuille -> supprimé
|
||||||
|
pe_affichage.pe_print("*** Export du jury de synthese par étudiants")
|
||||||
|
output = io.BytesIO()
|
||||||
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
|
output, engine="openpyxl"
|
||||||
|
) as writer:
|
||||||
|
for onglet, df in synthese.items():
|
||||||
|
# écriture dans l'onglet:
|
||||||
|
df.to_excel(writer, onglet, index=True, header=True)
|
||||||
|
output.seek(0)
|
||||||
|
|
||||||
|
self.add_file_to_zip(
|
||||||
|
zipfile, f"synthese_jury_{self.diplome}_par_etudiant.xlsx", output.read()
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_file_to_zip(self, zipfile: ZipFile, filename: str, data, path=""):
|
def add_file_to_zip(self, zipfile: ZipFile, filename: str, data, path=""):
|
||||||
@ -292,10 +317,11 @@ class JuryPE(object):
|
|||||||
# Méthodes pour la synthèse du juryPE
|
# Méthodes pour la synthèse du juryPE
|
||||||
# *****************************************************************************************************************
|
# *****************************************************************************************************************
|
||||||
|
|
||||||
def synthetise_juryPE(self):
|
def synthetise_jury_par_tags(self) -> dict[pd.DataFrame]:
|
||||||
"""Synthétise tous les résultats du jury PE dans des dataframes"""
|
"""Synthétise tous les résultats du jury PE dans des dataframes,
|
||||||
|
dont les onglets sont les tags"""
|
||||||
|
|
||||||
pe_affichage.pe_print("*** Synthèse finale des moyennes ***")
|
pe_affichage.pe_print("*** Synthèse finale des moyennes par tag***")
|
||||||
|
|
||||||
synthese = {}
|
synthese = {}
|
||||||
pe_affichage.pe_print(" -> Synthèse des données administratives")
|
pe_affichage.pe_print(" -> Synthèse des données administratives")
|
||||||
@ -332,65 +358,102 @@ class JuryPE(object):
|
|||||||
}
|
}
|
||||||
|
|
||||||
for aggregat in aggregats:
|
for aggregat in aggregats:
|
||||||
|
# Le dictionnaire par défaut des moyennes
|
||||||
|
donnees[etudid] |= get_defaut_dict_synthese_aggregat(aggregat, self.diplome)
|
||||||
|
|
||||||
# La trajectoire de l'étudiant sur l'aggrégat
|
# La trajectoire de l'étudiant sur l'aggrégat
|
||||||
trajectoire = self.trajectoires.suivi[etudid][aggregat]
|
trajectoire = self.trajectoires.suivi[etudid][aggregat]
|
||||||
|
|
||||||
# La note de l'étudiant (chargement à venir)
|
|
||||||
note = np.nan
|
|
||||||
|
|
||||||
# L'affichage de l'aggrégat dans le tableur excel
|
|
||||||
descr = pe_comp.PARCOURS[aggregat]["descr"]
|
|
||||||
# Les moyennes par tag de cette trajectoire
|
|
||||||
donnees[etudid] |= {
|
|
||||||
(descr, "", "note"): pe_affichage.SANS_NOTE,
|
|
||||||
(descr, "statistique du groupe", "class."): pe_affichage.SANS_NOTE,
|
|
||||||
(descr, "statistique du groupe", "min"): pe_affichage.SANS_NOTE,
|
|
||||||
(descr, "statistique du groupe", "moy"): pe_affichage.SANS_NOTE,
|
|
||||||
(descr, "statistique du groupe", "max"): pe_affichage.SANS_NOTE,
|
|
||||||
}
|
|
||||||
if trajectoire:
|
if trajectoire:
|
||||||
trajectoire_tagguee = self.trajectoires_tagguees[
|
trajectoire_tagguee = self.trajectoires_tagguees[
|
||||||
trajectoire.trajectoire_id
|
trajectoire.trajectoire_id
|
||||||
]
|
]
|
||||||
if tag in trajectoire_tagguee.moyennes_tags:
|
else:
|
||||||
bilan = trajectoire_tagguee.moyennes_tags[tag]
|
trajectoire_tagguee = None
|
||||||
note = TableTag.get_note_for_df(bilan, etudid)
|
|
||||||
if note != np.nan:
|
|
||||||
donnees[etudid] |= {
|
|
||||||
(descr, "", "note"): note,
|
|
||||||
(descr, "statistique du groupe", "class."): TableTag.get_class_for_df(bilan, etudid),
|
|
||||||
(descr, "statistique du groupe", "min"): TableTag.get_min_for_df(bilan),
|
|
||||||
(descr, "statistique du groupe", "moy"): TableTag.get_moy_for_df(bilan),
|
|
||||||
(descr, "statistique du groupe", "max"): TableTag.get_max_for_df(bilan)
|
|
||||||
}
|
|
||||||
|
|
||||||
"""L'interclassement"""
|
# L'interclassement
|
||||||
interclass = self.interclassements_taggues[aggregat]
|
interclass = self.interclassements_taggues[aggregat]
|
||||||
donnees[etudid] |= {
|
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "class."): pe_affichage.SANS_NOTE,
|
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "min"): pe_affichage.SANS_NOTE,
|
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "moy"): pe_affichage.SANS_NOTE,
|
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "max"): pe_affichage.SANS_NOTE,
|
|
||||||
}
|
|
||||||
if tag in interclass.moyennes_tags:
|
|
||||||
bilan = interclass.moyennes_tags[tag]
|
|
||||||
|
|
||||||
if note != np.nan:
|
# Injection des données dans un dictionnaire
|
||||||
donnees[etudid] |= {
|
donnees[etudid] |= get_dict_synthese_aggregat(aggregat, trajectoire_tagguee, interclass, etudid, tag, self.diplome)
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "class."): TableTag.get_class_for_df(bilan, etudid),
|
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "min"): TableTag.get_min_for_df(bilan),
|
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "moy"): TableTag.get_moy_for_df(bilan),
|
|
||||||
(descr, f"statistique de la promotion {self.diplome}", "max"): TableTag.get_max_for_df(bilan)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fin de l'aggrégat
|
# Fin de l'aggrégat
|
||||||
# Construction du dataFrame
|
# Construction du dataFrame
|
||||||
df = pd.DataFrame.from_dict(donnees, orient="index")
|
df = pd.DataFrame.from_dict(donnees, orient="index")
|
||||||
|
|
||||||
# Tri par nom/prénom
|
# Tri par nom/prénom
|
||||||
df.sort_values(by=[("Identité", "", "Nom"), ("Identité", "", "Prenom")], inplace=True)
|
df.sort_values(
|
||||||
|
by=[("Identité", "", "Nom"), ("Identité", "", "Prenom")], inplace=True
|
||||||
|
)
|
||||||
return df
|
return df
|
||||||
|
|
||||||
|
def synthetise_jury_par_etudiants(self) -> dict[pd.DataFrame]:
|
||||||
|
"""Synthétise tous les résultats du jury PE dans des dataframes,
|
||||||
|
dont les onglets sont les étudiants"""
|
||||||
|
pe_affichage.pe_print("*** Synthèse finale des moyennes par étudiants***")
|
||||||
|
|
||||||
|
synthese = {}
|
||||||
|
pe_affichage.pe_print(" -> Synthèse des données administratives")
|
||||||
|
synthese["administratif"] = self.etudiants.df_administratif(self.diplomes_ids)
|
||||||
|
|
||||||
|
etudids = list(self.diplomes_ids)
|
||||||
|
|
||||||
|
for etudid in etudids:
|
||||||
|
etudiant = self.etudiants.identites[etudid]
|
||||||
|
nom = etudiant.nom
|
||||||
|
prenom = etudiant.prenom[0] # initial du prénom
|
||||||
|
|
||||||
|
onglet = f"{nom} {prenom}. ({etudid})"
|
||||||
|
if len(onglet) > 32: # limite sur la taille des onglets
|
||||||
|
fin_onglet = f"{prenom}. ({etudid})"
|
||||||
|
onglet = f"{nom[:32-len(fin_onglet)-2]}." + fin_onglet
|
||||||
|
|
||||||
|
pe_affichage.pe_print(f" -> Synthèse de l'étudiant {etudid}")
|
||||||
|
synthese[onglet] = self.df_synthese_etudiant(etudid)
|
||||||
|
return synthese
|
||||||
|
|
||||||
|
def df_synthese_etudiant(self, etudid: int) -> pd.DataFrame:
|
||||||
|
"""Créé un DataFrame pour un étudiant donné par son etudid, retraçant
|
||||||
|
toutes ses moyennes aux différents tag et aggrégats"""
|
||||||
|
tags = self.do_tags_list(self.interclassements_taggues)
|
||||||
|
aggregats = pe_comp.TOUS_LES_PARCOURS
|
||||||
|
|
||||||
|
donnees = {}
|
||||||
|
|
||||||
|
for tag in tags:
|
||||||
|
# Une ligne pour le tag
|
||||||
|
donnees[tag] = {("", "", "tag"): tag}
|
||||||
|
|
||||||
|
for aggregat in aggregats:
|
||||||
|
# Le dictionnaire par défaut des moyennes
|
||||||
|
donnees[tag] |= get_defaut_dict_synthese_aggregat(aggregat, self.diplome)
|
||||||
|
|
||||||
|
# La trajectoire de l'étudiant sur l'aggrégat
|
||||||
|
trajectoire = self.trajectoires.suivi[etudid][aggregat]
|
||||||
|
if trajectoire:
|
||||||
|
trajectoire_tagguee = self.trajectoires_tagguees[
|
||||||
|
trajectoire.trajectoire_id
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
trajectoire_tagguee = None
|
||||||
|
|
||||||
|
# L'interclassement
|
||||||
|
interclass = self.interclassements_taggues[aggregat]
|
||||||
|
|
||||||
|
# Injection des données dans un dictionnaire
|
||||||
|
donnees[tag] |= get_dict_synthese_aggregat(aggregat, trajectoire_tagguee, interclass, etudid, tag, self.diplome)
|
||||||
|
|
||||||
|
|
||||||
|
# Fin de l'aggrégat
|
||||||
|
# Construction du dataFrame
|
||||||
|
df = pd.DataFrame.from_dict(donnees, orient="index")
|
||||||
|
|
||||||
|
# Tri par nom/prénom
|
||||||
|
df.sort_values(
|
||||||
|
by=[("", "", "tag")], inplace=True
|
||||||
|
)
|
||||||
|
return df
|
||||||
|
|
||||||
def compute_semestres_tag(etudiants: EtudiantsJuryPE) -> dict:
|
def compute_semestres_tag(etudiants: EtudiantsJuryPE) -> dict:
|
||||||
"""Créé les semestres taggués, de type 'S1', 'S2', ..., pour un groupe d'étudiants donnés.
|
"""Créé les semestres taggués, de type 'S1', 'S2', ..., pour un groupe d'étudiants donnés.
|
||||||
@ -485,3 +548,121 @@ def compute_interclassements(
|
|||||||
aggregats_interclasses_taggues[nom_aggregat] = interclass
|
aggregats_interclasses_taggues[nom_aggregat] = interclass
|
||||||
return aggregats_interclasses_taggues
|
return aggregats_interclasses_taggues
|
||||||
|
|
||||||
|
|
||||||
|
def get_defaut_dict_synthese_aggregat(aggregat: str, diplome: int) -> dict:
|
||||||
|
"""Renvoie le dictionnaire de synthèse (à intégrer dans
|
||||||
|
un tableur excel) pour décrire les résultats d'un aggrégat"""
|
||||||
|
# L'affichage de l'aggrégat dans le tableur excel
|
||||||
|
descr = pe_comp.PARCOURS[aggregat]["descr"]
|
||||||
|
|
||||||
|
nom_stat_promo = f"{NOM_STAT_PROMO} {diplome}"
|
||||||
|
donnees = {
|
||||||
|
(descr, "", "note"): SANS_NOTE,
|
||||||
|
# Les stat du groupe
|
||||||
|
(descr, NOM_STAT_GROUPE, "class."): SANS_NOTE,
|
||||||
|
(descr, NOM_STAT_GROUPE, "min"): SANS_NOTE,
|
||||||
|
(descr, NOM_STAT_GROUPE, "moy"): SANS_NOTE,
|
||||||
|
(descr, NOM_STAT_GROUPE, "max"): SANS_NOTE,
|
||||||
|
# Les stats de l'interclassement dans la promo
|
||||||
|
(descr, nom_stat_promo, "class."): SANS_NOTE,
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
nom_stat_promo,
|
||||||
|
"min",
|
||||||
|
): SANS_NOTE,
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
nom_stat_promo,
|
||||||
|
"moy",
|
||||||
|
): SANS_NOTE,
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
nom_stat_promo,
|
||||||
|
"max",
|
||||||
|
): SANS_NOTE,
|
||||||
|
}
|
||||||
|
return donnees
|
||||||
|
|
||||||
|
|
||||||
|
def get_dict_synthese_aggregat(
|
||||||
|
aggregat: str,
|
||||||
|
trajectoire_tagguee: TrajectoireTag,
|
||||||
|
interclassement_taggue: AggregatInterclasseTag,
|
||||||
|
etudid: int,
|
||||||
|
tag: str,
|
||||||
|
diplome: int
|
||||||
|
):
|
||||||
|
"""Renvoie le dictionnaire (à intégrer au tableur excel de synthese)
|
||||||
|
traduisant les résultats (moy/class) d'un étudiant à une trajectoire tagguée associée
|
||||||
|
à l'aggrégat donné et pour un tag donné"""
|
||||||
|
donnees = {}
|
||||||
|
# L'affichage de l'aggrégat dans le tableur excel
|
||||||
|
descr = pe_comp.PARCOURS[aggregat]["descr"]
|
||||||
|
|
||||||
|
# La note de l'étudiant (chargement à venir)
|
||||||
|
note = np.nan
|
||||||
|
|
||||||
|
# Les données de la trajectoire tagguée pour le tag considéré
|
||||||
|
if trajectoire_tagguee and tag in trajectoire_tagguee.moyennes_tags:
|
||||||
|
bilan = trajectoire_tagguee.moyennes_tags[tag]
|
||||||
|
|
||||||
|
# La moyenne de l'étudiant
|
||||||
|
note = TableTag.get_note_for_df(bilan, etudid)
|
||||||
|
|
||||||
|
# Statistiques sur le groupe
|
||||||
|
if note != np.nan:
|
||||||
|
# Les moyennes de cette trajectoire
|
||||||
|
donnees |= {
|
||||||
|
(descr, "", "note"): note,
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
NOM_STAT_GROUPE,
|
||||||
|
"class.",
|
||||||
|
): TableTag.get_class_for_df(bilan, etudid),
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
NOM_STAT_GROUPE,
|
||||||
|
"min",
|
||||||
|
): TableTag.get_min_for_df(bilan),
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
NOM_STAT_GROUPE,
|
||||||
|
"moy",
|
||||||
|
): TableTag.get_moy_for_df(bilan),
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
NOM_STAT_GROUPE,
|
||||||
|
"max",
|
||||||
|
): TableTag.get_max_for_df(bilan),
|
||||||
|
}
|
||||||
|
|
||||||
|
# L'interclassement
|
||||||
|
if tag in interclassement_taggue.moyennes_tags:
|
||||||
|
bilan = interclassement_taggue.moyennes_tags[tag]
|
||||||
|
|
||||||
|
if note != np.nan:
|
||||||
|
nom_stat_promo = f"{NOM_STAT_PROMO} {diplome}"
|
||||||
|
|
||||||
|
donnees |= {
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
nom_stat_promo,
|
||||||
|
"class.",
|
||||||
|
): TableTag.get_class_for_df(bilan, etudid),
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
nom_stat_promo,
|
||||||
|
"min",
|
||||||
|
): TableTag.get_min_for_df(bilan),
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
nom_stat_promo,
|
||||||
|
"moy",
|
||||||
|
): TableTag.get_moy_for_df(bilan),
|
||||||
|
(
|
||||||
|
descr,
|
||||||
|
nom_stat_promo,
|
||||||
|
"max",
|
||||||
|
): TableTag.get_max_for_df(bilan),
|
||||||
|
}
|
||||||
|
return donnees
|
||||||
|
@ -35,7 +35,7 @@ Created on Fri Sep 9 09:15:05 2016
|
|||||||
|
|
||||||
@author: barasc
|
@author: barasc
|
||||||
"""
|
"""
|
||||||
|
import app.pe.pe_etudiant
|
||||||
from app import db, log
|
from app import db, log
|
||||||
from app.comp import res_sem, moy_ue, moy_sem
|
from app.comp import res_sem, moy_ue, moy_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
@ -133,7 +133,7 @@ class SemestreTag(TableTag):
|
|||||||
|
|
||||||
def get_repr(self):
|
def get_repr(self):
|
||||||
"""Nom affiché pour le semestre taggué"""
|
"""Nom affiché pour le semestre taggué"""
|
||||||
return pe_affichage.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
return app.pe.pe_etudiant.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
||||||
|
|
||||||
def compute_moyenne_tag(self, tag: str) -> list:
|
def compute_moyenne_tag(self, tag: str) -> list:
|
||||||
"""Calcule la moyenne des étudiants pour le tag indiqué,
|
"""Calcule la moyenne des étudiants pour le tag indiqué,
|
||||||
|
Loading…
Reference in New Issue
Block a user