Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
4 changed files with 53 additions and 52 deletions
Showing only changes of commit cd8d73b41f - Show all commits

View File

@ -142,7 +142,9 @@ class EtudiantsJuryPE:
+ ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)]) + ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)])
) )
# Les abandons : # Les abandons :
# sorted([etudiants.cursus[etudid]['nom'] for etudid in etudiants.cursus if etudid not in etudiants.diplomes_ids]) self.abandons = sorted([self.cursus[etudid]['nom']
for etudid in self.cursus if etudid not in self.diplomes_ids])
def get_etudiants_diplomes(self) -> dict[int, Identite]: def get_etudiants_diplomes(self) -> dict[int, Identite]:
"""Identités des étudiants (sous forme d'un dictionnaire `{etudid: Identite(etudid)}` """Identités des étudiants (sous forme d'un dictionnaire `{etudid: Identite(etudid)}`

View File

@ -79,7 +79,7 @@ class JuryPE(object):
* juryEtudDict : dictionnaire récapitulant les étudiants participant au jury PE (données administratives + * juryEtudDict : dictionnaire récapitulant les étudiants participant au jury PE (données administratives +
celles des semestres valides à prendre en compte permettant le calcul des moyennes ... celles des semestres valides à prendre en compte permettant le calcul des moyennes ...
``{'etudid : { 'nom', 'prenom', 'civilite', 'diplome', '', }}`` ``{'etudid : { 'nom', 'prenom', 'civilite', 'diplome', '', }}``
a
Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue
et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif
""" """
@ -100,8 +100,6 @@ class JuryPE(object):
meme_programme: si True, impose un même programme pour tous les étudiants participant au jury, meme_programme: si True, impose un même programme pour tous les étudiants participant au jury,
si False, permet des programmes differents si False, permet des programmes differents
""" """
self.promoTagDict = {}
"L'année du diplome" "L'année du diplome"
self.diplome = diplome self.diplome = diplome
@ -113,8 +111,6 @@ class JuryPE(object):
self.zipdata = io.BytesIO() self.zipdata = io.BytesIO()
self.zipfile = ZipFile(self.zipdata, "w") self.zipfile = ZipFile(self.zipdata, "w")
"""Chargement des étudiants à prendre en compte dans le jury""" """Chargement des étudiants à prendre en compte dans le jury"""
pe_comp.pe_print( pe_comp.pe_print(
f"*** Recherche et chargement des étudiants diplômés en {self.diplome} pour la formation {self.formation_id}" f"*** Recherche et chargement des étudiants diplômés en {self.diplome} pour la formation {self.formation_id}"
@ -187,14 +183,19 @@ class JuryPE(object):
# Export des données => mode 1 seule feuille -> supprimé # Export des données => mode 1 seule feuille -> supprimé
pe_comp.pe_print("*** Export du jury de synthese") pe_comp.pe_print("*** Export du jury de synthese")
filename = "synthese_jury_" + str(self.diplome) + '.xls' filename = "synthese_jury_" + str(self.diplome) + ".xlsx"
with pd.ExcelWriter(filename, engine="openpyxl") as writer: with pd.ExcelWriter(filename, engine="openpyxl") as writer:
for onglet in self.synthese: for onglet in self.synthese:
df = self.synthese[onglet] df = self.synthese[onglet]
df.to_excel(writer, onglet, index=True, header=True) # écriture dans l'onglet df.to_excel(
writer, onglet, index=True, header=True
) # écriture dans l'onglet
# worksheet = writer.sheets[onglet] # l'on # worksheet = writer.sheets[onglet] # l'on
self.zipfile.write(filename) self.add_file_to_zip(
filename,
open(filename, "rb").read(),
)
"""Fin !!!! Tada :)""" """Fin !!!! Tada :)"""
@ -208,7 +209,7 @@ class JuryPE(object):
data: Les données du fichier data: Les données du fichier
path: Un dossier dans l'arborescence du zip path: Un dossier dans l'arborescence du zip
""" """
path_in_zip = os.path.join(self.nom_export_zip, path, filename) path_in_zip = os.path.join(path, filename) # self.nom_export_zip,
self.zipfile.writestr(path_in_zip, data) self.zipfile.writestr(path_in_zip, data)
def get_zipped_data(self): def get_zipped_data(self):
@ -231,7 +232,6 @@ class JuryPE(object):
tags = sorted(set(tags)) tags = sorted(set(tags))
return tags return tags
# **************************************************************************************************************** # # **************************************************************************************************************** #
# Méthodes pour la synthèse du juryPE # Méthodes pour la synthèse du juryPE
# ***************************************************************************************************************** # *****************************************************************************************************************
@ -251,7 +251,6 @@ class JuryPE(object):
synthese[tag] = self.df_tag(tag) synthese[tag] = self.df_tag(tag)
return synthese return synthese
def df_administratif(self): def df_administratif(self):
"""Synthétise toutes les données administratives des étudiants""" """Synthétise toutes les données administratives des étudiants"""
@ -273,7 +272,7 @@ class JuryPE(object):
"Age": pe_comp.calcul_age(etudiant.date_naissance), "Age": pe_comp.calcul_age(etudiant.date_naissance),
"Date d'entree": cursus["entree"], "Date d'entree": cursus["entree"],
"Date de diplome": cursus["diplome"], "Date de diplome": cursus["diplome"],
"Nbre de semestres": len(formsemestres) "Nbre de semestres": len(formsemestres),
} }
# Ajout des noms de semestres parcourus # Ajout des noms de semestres parcourus
@ -281,9 +280,11 @@ class JuryPE(object):
administratif[etudid] |= etapes administratif[etudid] |= etapes
"""Construction du dataframe""" """Construction du dataframe"""
df = pd.DataFrame.from_dict(administratif, orient='index') df = pd.DataFrame.from_dict(administratif, orient="index")
return df
"""Tri par nom/prénom"""
df.sort_values(by=["Nom", "Prenom"], inplace = True)
return df
def df_tag(self, tag): def df_tag(self, tag):
"""Génère le DataFrame synthétisant les moyennes/classements (groupe, """Génère le DataFrame synthétisant les moyennes/classements (groupe,
@ -299,7 +300,6 @@ class JuryPE(object):
etudids = list(self.diplomes_ids) etudids = list(self.diplomes_ids)
aggregats = pe_comp.TOUS_LES_PARCOURS aggregats = pe_comp.TOUS_LES_PARCOURS
donnees = {} donnees = {}
for etudid in etudids: for etudid in etudids:
@ -315,18 +315,21 @@ class JuryPE(object):
trajectoire = self.trajectoires.suivi[etudid][aggregat] trajectoire = self.trajectoires.suivi[etudid][aggregat]
"""Les moyennes par tag de cette trajectoire""" """Les moyennes par tag de cette trajectoire"""
if trajectoire: if trajectoire:
trajectoire_tagguee = self.trajectoires_tagguees[trajectoire.trajectoire_id] trajectoire_tagguee = self.trajectoires_tagguees[
trajectoire.trajectoire_id
]
bilan = trajectoire_tagguee.moyennes_tags[tag] bilan = trajectoire_tagguee.moyennes_tags[tag]
donnees[etudid] |= { donnees[etudid] |= {
f"{aggregat} notes ": f"{bilan['notes'].loc[etudid]:.1f}", f"{aggregat} notes ": f"{bilan['notes'].loc[etudid]:.1f}",
f"{aggregat} class. (groupe)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}", f"{aggregat} class. (groupe)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}",
f"{aggregat} min/moy/max (groupe)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}"} f"{aggregat} min/moy/max (groupe)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}",
}
else: else:
donnees[etudid] |= { donnees[etudid] |= {
f"{aggregat} notes ": "-", f"{aggregat} notes ": "-",
f"{aggregat} class. (groupe)": "-", f"{aggregat} class. (groupe)": "-",
f"{aggregat} min/moy/max (groupe)": "-" f"{aggregat} min/moy/max (groupe)": "-",
} }
"""L'interclassement""" """L'interclassement"""
@ -336,28 +339,28 @@ class JuryPE(object):
donnees[etudid] |= { donnees[etudid] |= {
f"{aggregat} class. (promo)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}", f"{aggregat} class. (promo)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}",
f"{aggregat} min/moy/max (promo)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}" f"{aggregat} min/moy/max (promo)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}",
} }
else: else:
donnees[etudid] |= { donnees[etudid] |= {
f"{aggregat} class. (promo)": "-", f"{aggregat} class. (promo)": "-",
f"{aggregat} min/moy/max (promo)": "-" f"{aggregat} min/moy/max (promo)": "-",
} }
# Fin de l'aggrégat # Fin de l'aggrégat
"""Construction du dataFrame"""
df = pd.DataFrame.from_dict(donnees, orient="index")
df = pd.DataFrame.from_dict(donnees, orient='index') """Tri par nom/prénom"""
df.sort_values(by=["Nom", "Prenom"], inplace = True)
return df return df
def table_syntheseJury(self, mode="singlesheet"): # was str_syntheseJury def table_syntheseJury(self, mode="singlesheet"): # was str_syntheseJury
"""Table(s) du jury """Table(s) du jury
mode: singlesheet ou multiplesheet pour export excel mode: singlesheet ou multiplesheet pour export excel
""" """
sT = SeqGenTable() # le fichier excel à générer sT = SeqGenTable() # le fichier excel à générer
if mode == "singlesheet": if mode == "singlesheet":
return sT.get_genTable("singlesheet") return sT.get_genTable("singlesheet")
else: else:

View File

@ -93,9 +93,6 @@ class TrajectoireTag(TableTag):
self.etuds = nt.etuds self.etuds = nt.etuds
# assert self.etuds == trajectoire.suivi # manque-t-il des étudiants ? # assert self.etuds == trajectoire.suivi # manque-t-il des étudiants ?
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.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
}
"""Les tags extraits de tous les semestres""" """Les tags extraits de tous les semestres"""
self.tags_sorted = self.do_taglist() self.tags_sorted = self.do_taglist()
@ -104,7 +101,7 @@ class TrajectoireTag(TableTag):
self.notes_cube = self.compute_notes_cube() self.notes_cube = self.compute_notes_cube()
"""Calcul les moyennes par tag sous forme d'un dataframe""" """Calcul les moyennes par tag sous forme d'un dataframe"""
etudids = self.get_etudids() etudids = list(self.etudiants.keys())
self.notes = compute_tag_moy(self.notes_cube, etudids, self.tags_sorted) self.notes = compute_tag_moy(self.notes_cube, etudids, self.tags_sorted)
"""Synthétise les moyennes/classements par tag""" """Synthétise les moyennes/classements par tag"""
@ -166,8 +163,7 @@ class TrajectoireTag(TableTag):
return etudids_x_tags_x_semestres return etudids_x_tags_x_semestres
def get_etudids(self):
return list(self.etudiants.keys())
def do_taglist(self): def do_taglist(self):
"""Synthétise les tags à partir des semestres (taggués) aggrégés """Synthétise les tags à partir des semestres (taggués) aggrégés

View File

@ -45,8 +45,8 @@ from app.scodoc import sco_formsemestre
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.pe import pe_tools from app.pe import pe_comp
from app.pe import pe_jurype from app.pe import pe_jury
from app.pe import pe_avislatex from app.pe import pe_avislatex
@ -75,7 +75,7 @@ def _pe_view_sem_recap_form(formsemestre_id):
return "\n".join(H) + html_sco_header.sco_footer() return "\n".join(H) + html_sco_header.sco_footer()
# L'année du diplome # L'année du diplome
diplome = pe_tools.get_annee_diplome_semestre(sem_base) diplome = pe_comp.get_annee_diplome_semestre(sem_base)
H = [ H = [
html_sco_header.sco_header(page_title="Avis de poursuite d'études"), html_sco_header.sco_header(page_title="Avis de poursuite d'études"),
@ -136,12 +136,12 @@ def pe_view_sem_recap(
) )
# L'année du diplome # L'année du diplome
diplome = pe_tools.get_annee_diplome_semestre(sem_base) diplome = pe_comp.get_annee_diplome_semestre(sem_base)
jury = pe_jurype.JuryPE(diplome, sem_base.formation.formation_id) jury = pe_jury.JuryPE(diplome, sem_base.formation.formation_id)
# Ajout avis LaTeX au même zip: # Ajout avis LaTeX au même zip:
etudids = list(jury.syntheseJury.keys()) # etudids = list(jury.syntheseJury.keys())
# Récupération du template latex, du footer latex et du tag identifiant les annotations relatives aux PE # Récupération du template latex, du footer latex et du tag identifiant les annotations relatives aux PE
# (chaines unicodes, html non quoté) # (chaines unicodes, html non quoté)
@ -187,11 +187,11 @@ def pe_view_sem_recap(
) )
# Ajout des annotations PE dans un fichier excel # Ajout des annotations PE dans un fichier excel
sT = pe_avislatex.table_syntheseAnnotationPE(jury.syntheseJury, tag_annotation_pe) # sT = pe_avislatex.table_syntheseAnnotationPE(jury.syntheseJury, tag_annotation_pe)
if sT: # if sT:
jury.add_file_to_zip( # jury.add_file_to_zip(
jury.nom_export_zip + "_annotationsPE" + scu.XLSX_SUFFIX, sT.excel() # jury.nom_export_zip + "_annotationsPE" + scu.XLSX_SUFFIX, sT.excel()
) # )
if False: if False:
latex_pages = {} # Dictionnaire de la forme nom_fichier => contenu_latex latex_pages = {} # Dictionnaire de la forme nom_fichier => contenu_latex