2020-09-26 16:19:37 +02:00
|
|
|
# -*- mode: python -*-
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
#
|
|
|
|
# Gestion scolarite IUT
|
|
|
|
#
|
2023-12-31 23:04:06 +01:00
|
|
|
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
|
2020-09-26 16:19:37 +02:00
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
# Emmanuel Viennet emmanuel.viennet@viennet.net
|
|
|
|
#
|
|
|
|
##############################################################################
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
# Module "Avis de poursuite d'étude"
|
|
|
|
# conçu et développé par Cléo Baras (IUT de Grenoble)
|
|
|
|
##############################################################################
|
|
|
|
|
|
|
|
"""
|
|
|
|
Created on Fri Sep 9 09:15:05 2016
|
|
|
|
|
|
|
|
@author: barasc
|
|
|
|
"""
|
2024-01-20 16:34:38 +01:00
|
|
|
import datetime
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
# ----------------------------------------------------------
|
|
|
|
# Ensemble des fonctions et des classes
|
|
|
|
# permettant les calculs preliminaires (hors affichage)
|
|
|
|
# a l'edition d'un jury de poursuites d'etudes
|
|
|
|
# ----------------------------------------------------------
|
|
|
|
|
2021-08-31 20:18:50 +02:00
|
|
|
import io
|
2021-02-01 23:54:46 +01:00
|
|
|
import os
|
2021-08-31 20:18:50 +02:00
|
|
|
from zipfile import ZipFile
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2024-01-24 19:37:45 +01:00
|
|
|
|
2022-02-11 09:11:07 +01:00
|
|
|
from app.comp import res_sem
|
2022-03-27 22:25:00 +02:00
|
|
|
from app.comp.res_compat import NotesTableCompat
|
2024-01-20 16:34:38 +01:00
|
|
|
from app.comp.res_sem import load_formsemestre_results
|
2023-02-18 00:13:00 +01:00
|
|
|
from app.models import Formation, FormSemestre
|
2024-01-20 16:34:38 +01:00
|
|
|
from app.models.etudiants import Identite
|
2024-01-21 18:55:21 +01:00
|
|
|
from app.pe.pe_semestretag import SemestreTag
|
2024-01-24 19:37:45 +01:00
|
|
|
from app.pe.pe_interclasstag import AggregatInterclasseTag
|
|
|
|
from app.pe.pe_trajectoiretag import TrajectoireTag
|
2022-02-11 09:11:07 +01:00
|
|
|
|
2021-06-19 23:21:37 +02:00
|
|
|
from app.scodoc.gen_tables import GenTable, SeqGenTable
|
|
|
|
import app.scodoc.sco_utils as scu
|
2024-01-24 19:37:45 +01:00
|
|
|
from app.scodoc import codes_cursus
|
2021-09-26 10:01:20 +02:00
|
|
|
from app.pe import pe_tools
|
|
|
|
from app.pe import pe_semestretag
|
2024-01-20 16:34:38 +01:00
|
|
|
from app.pe.pe_etudiant import EtudiantsJuryPE
|
2024-01-24 19:37:45 +01:00
|
|
|
from app.pe.pe_trajectoire import TrajectoiresJuryPE, Trajectoire
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2023-12-31 23:04:06 +01:00
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
# ----------------------------------------------------------------------------------------
|
2021-08-21 00:24:51 +02:00
|
|
|
def comp_nom_semestre_dans_parcours(sem):
|
2020-09-26 16:19:37 +02:00
|
|
|
"""Le nom a afficher pour titrer un semestre
|
|
|
|
par exemple: "semestre 2 FI 2015"
|
|
|
|
"""
|
2023-02-18 00:13:00 +01:00
|
|
|
formation: Formation = Formation.query.get_or_404(sem["formation_id"])
|
|
|
|
parcours = codes_cursus.get_cursus_from_code(formation.type_parcours)
|
2020-09-26 16:19:37 +02:00
|
|
|
return "%s %s %s %s" % (
|
|
|
|
parcours.SESSION_NAME, # eg "semestre"
|
|
|
|
sem["semestre_id"], # eg 2
|
|
|
|
sem.get("modalite", ""), # eg FI ou FC
|
|
|
|
sem["annee_debut"], # eg 2015
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------------------
|
2021-07-09 23:31:16 +02:00
|
|
|
class JuryPE(object):
|
2024-01-16 06:19:49 +01:00
|
|
|
"""Classe mémorisant toutes les informations nécessaires pour établir un jury de PE.
|
|
|
|
Modèle basé sur NotesTable.
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2024-01-16 06:19:49 +01:00
|
|
|
Attributs :
|
2021-01-01 18:40:47 +01:00
|
|
|
|
2024-01-20 16:34:38 +01:00
|
|
|
* diplome : l'année d'obtention du diplome BUT et du jury de PE (généralement février XXXX)
|
2024-01-16 06:19:49 +01:00
|
|
|
* 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 ...
|
|
|
|
``{'etudid : { 'nom', 'prenom', 'civilite', 'diplome', '', }}``
|
|
|
|
|
|
|
|
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
|
2020-09-26 16:19:37 +02:00
|
|
|
"""
|
|
|
|
|
|
|
|
# Variables de classe décrivant les aggrégats, leur ordre d'apparition temporelle et
|
|
|
|
# leur affichage dans les avis latex
|
2024-01-16 06:19:49 +01:00
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
# ------------------------------------------------------------------------------------------------------------------
|
2024-01-20 16:34:38 +01:00
|
|
|
def __init__(self, diplome, formation_id):
|
2020-09-26 16:19:37 +02:00
|
|
|
"""
|
|
|
|
Création d'une table PE sur la base d'un semestre selectionné. De ce semestre est déduit :
|
|
|
|
1. l'année d'obtention du DUT,
|
|
|
|
2. tous les étudiants susceptibles à ce stade (au regard de leur parcours) d'être diplomés.
|
|
|
|
|
|
|
|
Args:
|
2024-01-16 09:21:02 +01:00
|
|
|
sem_base: le FormSemestre donnant le semestre à la base du jury PE
|
|
|
|
semBase: le dictionnaire sem donnant la base du jury (CB: TODO: A supprimer à long term)
|
2020-09-26 16:19:37 +02:00
|
|
|
meme_programme: si True, impose un même programme pour tous les étudiants participant au jury,
|
|
|
|
si False, permet des programmes differents
|
|
|
|
"""
|
|
|
|
self.promoTagDict = {}
|
|
|
|
|
2024-01-20 16:34:38 +01:00
|
|
|
"L'année du diplome"
|
|
|
|
self.diplome = diplome
|
|
|
|
|
|
|
|
"La formation associée au diplome"
|
|
|
|
self.formation_id = formation_id
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2024-01-20 16:34:38 +01:00
|
|
|
"Un zip où ranger les fichiers générés"
|
|
|
|
self.nom_export_zip = "Jury_PE_%s" % self.diplome
|
2021-08-31 20:18:50 +02:00
|
|
|
self.zipdata = io.BytesIO()
|
2020-09-26 16:19:37 +02:00
|
|
|
self.zipfile = ZipFile(self.zipdata, "w")
|
|
|
|
|
|
|
|
self.syntheseJury = {} # Le jury de synthèse
|
|
|
|
|
2024-01-20 16:34:38 +01:00
|
|
|
"""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}"
|
|
|
|
)
|
2024-01-23 18:44:44 +01:00
|
|
|
self.etudiants = EtudiantsJuryPE(self.diplome) # Les infos sur les étudiants
|
|
|
|
self.etudiants.find_etudiants(self.formation_id)
|
2024-01-20 16:34:38 +01:00
|
|
|
|
2024-01-21 18:55:21 +01:00
|
|
|
"""Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE"""
|
2024-01-24 19:37:45 +01:00
|
|
|
pe_tools.pe_print("*** Génère les semestres taggués")
|
2024-01-21 18:55:21 +01:00
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
"""Génère les trajectoires (combinaison de semestres suivis
|
|
|
|
par un étudiant pour atteindre le semestre final d'un aggrégat)
|
|
|
|
"""
|
2024-01-24 19:37:45 +01:00
|
|
|
pe_tools.pe_print(
|
|
|
|
"*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants"
|
|
|
|
)
|
2024-01-24 15:37:50 +01:00
|
|
|
self.trajectoires = TrajectoiresJuryPE(self.diplome)
|
|
|
|
self.trajectoires.cree_trajectoires(self.etudiants)
|
|
|
|
|
2024-01-24 19:37:45 +01:00
|
|
|
"""Génère les moyennes par tags des trajectoires"""
|
|
|
|
pe_tools.pe_print("*** Calcule les moyennes par tag des trajectoires possibles")
|
2024-01-24 15:37:50 +01:00
|
|
|
self.trajectoires_tagguees = compute_trajectoires_tag(
|
2024-01-24 19:37:45 +01:00
|
|
|
self.trajectoires, self.etudiants, self.semestres_taggues
|
2024-01-23 19:08:54 +01:00
|
|
|
)
|
2024-01-21 18:55:21 +01:00
|
|
|
|
|
|
|
if pe_tools.PE_DEBUG:
|
2024-01-24 19:37:45 +01:00
|
|
|
"""Intègre le bilan des trajectoires tagguées au zip final"""
|
|
|
|
for trajectoire_id in self.trajectoires_tagguees:
|
|
|
|
trajectoire_tagguee = self.trajectoires_tagguees[trajectoire_id]
|
|
|
|
filename = trajectoire_tagguee.get_repr().replace(" ", "_") + ".csv"
|
|
|
|
pe_tools.pe_print(f" - Export csv de {filename} ")
|
|
|
|
self.add_file_to_zip(
|
|
|
|
filename,
|
|
|
|
trajectoire_tagguee.str_tagtable(),
|
|
|
|
path="details_semestres",
|
|
|
|
)
|
2024-01-21 18:55:21 +01:00
|
|
|
|
2024-01-24 19:37:45 +01:00
|
|
|
"""Génère les interclassements (par promo et) par (nom d') aggrégat"""
|
|
|
|
pe_tools.pe_print("*** Génère les interclassements par aggrégat")
|
|
|
|
self.interclassements_taggues = compute_interclassements(
|
|
|
|
self.etudiants, self.trajectoires, self.trajectoires_tagguees
|
2024-01-23 19:08:54 +01:00
|
|
|
)
|
2024-01-24 19:37:45 +01:00
|
|
|
|
2024-01-23 19:08:54 +01:00
|
|
|
if pe_tools.PE_DEBUG:
|
2024-01-24 19:37:45 +01:00
|
|
|
"""Intègre le bilan des aggrégats (par promo) au zip final"""
|
|
|
|
for nom_aggregat in self.interclassements_taggues:
|
|
|
|
interclass_tag = self.interclassements_taggues[nom_aggregat]
|
|
|
|
filename = interclass_tag.get_repr().replace(" ", "_") + ".csv"
|
|
|
|
pe_tools.pe_print(f" - Export csv de {filename} ")
|
|
|
|
self.add_file_to_zip(
|
|
|
|
filename,
|
|
|
|
interclass_tag.str_tagtable(),
|
|
|
|
path="details_semestres",
|
|
|
|
)
|
2022-02-11 23:22:07 +01:00
|
|
|
|
2024-01-20 16:34:38 +01:00
|
|
|
"""Synthèse des éléments du jury PE"""
|
2024-01-24 19:37:45 +01:00
|
|
|
self.synthetise_juryPE()
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
# Export des données => mode 1 seule feuille -> supprimé
|
|
|
|
# filename = self.NOM_EXPORT_ZIP + "jurySyntheseDict_" + str(self.diplome) + '.xls'
|
|
|
|
# self.xls = self.table_syntheseJury(mode="singlesheet")
|
|
|
|
# self.add_file_to_zip(filename, self.xls.excel())
|
|
|
|
|
|
|
|
# Fabrique 1 fichier excel résultat avec 1 seule feuille => trop gros
|
2024-01-20 16:34:38 +01:00
|
|
|
if False:
|
|
|
|
filename = self.nom_export_zip + "_jurySyntheseDict" + scu.XLSX_SUFFIX
|
|
|
|
self.xlsV2 = self.table_syntheseJury(mode="multiplesheet")
|
|
|
|
if self.xlsV2:
|
2024-01-21 18:55:21 +01:00
|
|
|
pe_tools.add_file_to_zip(
|
|
|
|
self.nom_export_zip, filename, self.xlsV2.excel()
|
|
|
|
)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
# Pour debug
|
|
|
|
# self.syntheseJury = pe_tools.JURY_SYNTHESE_POUR_DEBUG #Un dictionnaire fictif pour debug
|
|
|
|
|
2024-01-21 18:55:21 +01:00
|
|
|
def add_file_to_zip(self, filename: str, data, path=""):
|
2020-09-26 16:19:37 +02:00
|
|
|
"""Add a file to our zip
|
|
|
|
All files under NOM_EXPORT_ZIP/
|
|
|
|
path may specify a subdirectory
|
2024-01-21 18:55:21 +01:00
|
|
|
|
|
|
|
Args:
|
|
|
|
filename: Le nom du fichier à intégrer au zip
|
|
|
|
data: Les données du fichier
|
|
|
|
path: Un dossier dans l'arborescence du zip
|
2020-09-26 16:19:37 +02:00
|
|
|
"""
|
2024-01-20 16:34:38 +01:00
|
|
|
path_in_zip = os.path.join(self.nom_export_zip, path, filename)
|
2020-09-26 16:19:37 +02:00
|
|
|
self.zipfile.writestr(path_in_zip, data)
|
|
|
|
|
|
|
|
def get_zipped_data(self):
|
2021-08-31 20:18:50 +02:00
|
|
|
"""returns file-like data with a zip of all generated (CSV) files.
|
|
|
|
Reset file cursor at the beginning !
|
|
|
|
"""
|
2020-09-26 16:19:37 +02:00
|
|
|
if self.zipfile:
|
|
|
|
self.zipfile.close()
|
|
|
|
self.zipfile = None
|
2021-08-31 20:18:50 +02:00
|
|
|
self.zipdata.seek(0)
|
|
|
|
return self.zipdata
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
# **************************************************************************************************************** #
|
2024-01-20 16:34:38 +01:00
|
|
|
# Traitements des semestres impliqués dans le jury
|
2020-09-26 16:19:37 +02:00
|
|
|
# **************************************************************************************************************** #
|
|
|
|
|
|
|
|
# **************************************************************************************************************** #
|
|
|
|
# Méthodes pour la synthèse du juryPE
|
|
|
|
# *****************************************************************************************************************
|
|
|
|
def synthetise_juryPE(self):
|
2024-01-24 19:37:45 +01:00
|
|
|
"""Synthétise tous les résultats du jury PE dans des dataframess"""
|
2020-09-26 16:19:37 +02:00
|
|
|
self.syntheseJury = {}
|
2024-01-20 16:34:38 +01:00
|
|
|
for etudid in self.etudiants.get_etudids(self.diplome):
|
2020-09-26 16:19:37 +02:00
|
|
|
etudinfo = self.ETUDINFO_DICT[etudid]
|
|
|
|
self.syntheseJury[etudid] = {
|
|
|
|
"nom": etudinfo["nom"],
|
|
|
|
"prenom": etudinfo["prenom"],
|
2021-02-13 17:28:55 +01:00
|
|
|
"civilite": etudinfo["civilite"],
|
2021-02-16 15:18:06 +01:00
|
|
|
"civilite_str": etudinfo["civilite_str"],
|
2020-09-26 16:19:37 +02:00
|
|
|
"age": str(pe_tools.calcul_age(etudinfo["date_naissance"])),
|
|
|
|
"lycee": etudinfo["nomlycee"]
|
|
|
|
+ (
|
|
|
|
" (" + etudinfo["villelycee"] + ")"
|
|
|
|
if etudinfo["villelycee"] != ""
|
|
|
|
else ""
|
|
|
|
),
|
|
|
|
"bac": etudinfo["bac"],
|
2022-07-29 16:19:40 +02:00
|
|
|
"code_nip": etudinfo["code_nip"], # pour la photo
|
2020-09-26 16:19:37 +02:00
|
|
|
"entree": self.get_dateEntree(etudid),
|
|
|
|
"promo": self.diplome,
|
|
|
|
}
|
|
|
|
# Le parcours
|
|
|
|
self.syntheseJury[etudid]["parcours"] = self.get_parcoursIUT(
|
|
|
|
etudid
|
|
|
|
) # liste des semestres
|
|
|
|
self.syntheseJury[etudid]["nbSemestres"] = len(
|
|
|
|
self.syntheseJury[etudid]["parcours"]
|
|
|
|
) # nombre de semestres
|
|
|
|
|
|
|
|
# Ses résultats
|
2024-01-20 16:34:38 +01:00
|
|
|
for nom in pe_tools.PARCOURS: # S1, puis S2, puis 1A
|
2020-09-26 16:19:37 +02:00
|
|
|
# dans le groupe : la table tagguée dans les semtag ou les settag si aggrégat
|
|
|
|
self.syntheseJury[etudid][nom] = {"groupe": {}, "promo": {}}
|
|
|
|
if (
|
2024-01-20 16:34:38 +01:00
|
|
|
self.etudiants.cursus[etudid][nom] != None
|
2020-09-26 16:19:37 +02:00
|
|
|
): # Un parcours valide existe
|
2024-01-20 16:34:38 +01:00
|
|
|
if nom in pe_tools.TOUS_LES_SEMESTRES:
|
2024-01-21 18:55:21 +01:00
|
|
|
tagtable = self.semestres_taggues[
|
|
|
|
self.etudiants.cursus[etudid][nom]
|
|
|
|
]
|
2020-09-26 16:19:37 +02:00
|
|
|
else:
|
2024-01-24 15:37:50 +01:00
|
|
|
tagtable = self.trajectoires_tagguees[nom][
|
2024-01-20 16:34:38 +01:00
|
|
|
self.etudiants.cursus[etudid][nom]
|
2020-09-26 16:19:37 +02:00
|
|
|
]
|
|
|
|
for tag in tagtable.get_all_tags():
|
|
|
|
self.syntheseJury[etudid][nom]["groupe"][
|
|
|
|
tag
|
|
|
|
] = tagtable.get_resultatsEtud(
|
|
|
|
tag, etudid
|
|
|
|
) # Le tuple des résultats
|
|
|
|
|
|
|
|
# interclassé dans la promo
|
|
|
|
tagtable = self.promoTagDict[nom]
|
|
|
|
for tag in tagtable.get_all_tags():
|
|
|
|
self.syntheseJury[etudid][nom]["promo"][
|
|
|
|
tag
|
|
|
|
] = tagtable.get_resultatsEtud(tag, etudid)
|
|
|
|
|
2024-01-16 15:51:22 +01:00
|
|
|
def get_dateEntree(self, etudid):
|
2020-09-26 16:19:37 +02:00
|
|
|
"""Renvoie l'année d'entrée de l'étudiant à l'IUT"""
|
2021-02-01 23:54:46 +01:00
|
|
|
# etudinfo = self.ETUDINFO_DICT[etudid]
|
2024-01-16 06:19:49 +01:00
|
|
|
semestres = self.get_semestresBUT_d_un_etudiant(etudid)
|
2022-08-30 11:09:13 +02:00
|
|
|
if semestres:
|
|
|
|
# le 1er sem à l'IUT
|
2022-09-08 09:48:19 +02:00
|
|
|
return semestres[0]["annee_debut"]
|
2022-08-30 11:09:13 +02:00
|
|
|
else:
|
|
|
|
return ""
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2024-01-16 15:51:22 +01:00
|
|
|
def get_parcoursIUT(self, etudid):
|
2021-01-01 18:40:47 +01:00
|
|
|
"""Renvoie une liste d'infos sur les semestres du parcours d'un étudiant"""
|
2021-02-01 23:54:46 +01:00
|
|
|
# etudinfo = self.ETUDINFO_DICT[etudid]
|
2024-01-21 18:55:21 +01:00
|
|
|
sems = self.etudiants.semestres_etudiant(etudid)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
infos = []
|
|
|
|
for sem in sems:
|
2021-08-21 00:24:51 +02:00
|
|
|
nomsem = comp_nom_semestre_dans_parcours(sem)
|
2020-09-26 16:19:37 +02:00
|
|
|
infos.append(
|
|
|
|
{
|
|
|
|
"nom_semestre_dans_parcours": nomsem,
|
|
|
|
"titreannee": sem["titreannee"],
|
|
|
|
"formsemestre_id": sem["formsemestre_id"], # utile dans le futur ?
|
|
|
|
}
|
|
|
|
)
|
|
|
|
return infos
|
|
|
|
|
|
|
|
# **************************************************************************************************************** #
|
|
|
|
# Méthodes d'affichage pour debug
|
|
|
|
# **************************************************************************************************************** #
|
2024-01-16 15:51:22 +01:00
|
|
|
def str_etudiants_in_jury(self, delim=";"):
|
2020-09-26 16:19:37 +02:00
|
|
|
# En tete:
|
|
|
|
entete = ["Id", "Nom", "Abandon", "Diplome"]
|
2024-01-20 16:34:38 +01:00
|
|
|
for nom_sem in pe_tools.TOUS_LES_PARCOURS:
|
2020-09-26 16:19:37 +02:00
|
|
|
entete += [nom_sem, "descr"]
|
|
|
|
chaine = delim.join(entete) + "\n"
|
|
|
|
|
2024-01-20 16:34:38 +01:00
|
|
|
for etudid in self.etudiants.cursus:
|
|
|
|
donnees = self.etudiants.cursus[etudid]
|
2020-09-26 16:19:37 +02:00
|
|
|
# pe_tools.pe_print(etudid, donnees)
|
|
|
|
# les infos générales
|
|
|
|
descr = [
|
|
|
|
etudid,
|
|
|
|
donnees["nom"],
|
|
|
|
str(donnees["abandon"]),
|
|
|
|
str(donnees["diplome"]),
|
|
|
|
]
|
|
|
|
|
2024-01-16 06:19:49 +01:00
|
|
|
# les semestres et les aggrégats
|
2024-01-20 16:34:38 +01:00
|
|
|
for nom_sem in pe_tools.TOUS_LES_PARCOURS:
|
2020-09-26 16:19:37 +02:00
|
|
|
table = (
|
2024-01-21 18:55:21 +01:00
|
|
|
self.semestres_taggues[donnees[nom_sem]].nom
|
|
|
|
if donnees[nom_sem] in self.semestres_taggues
|
2020-09-26 16:19:37 +02:00
|
|
|
else "manquant"
|
|
|
|
)
|
|
|
|
descr += [
|
|
|
|
donnees[nom_sem] if donnees[nom_sem] != None else "manquant",
|
|
|
|
table,
|
|
|
|
]
|
|
|
|
|
|
|
|
chaine += delim.join(descr) + "\n"
|
|
|
|
return chaine
|
|
|
|
|
|
|
|
#
|
|
|
|
def export_juryPEDict(self):
|
|
|
|
"""Export csv de self.PARCOURSINFO_DICT"""
|
|
|
|
fichier = "juryParcoursDict_" + str(self.diplome)
|
|
|
|
pe_tools.pe_print(" -> Export de " + fichier)
|
2024-01-20 16:34:38 +01:00
|
|
|
filename = self.nom_export_zip + fichier + ".csv"
|
2020-09-26 16:19:37 +02:00
|
|
|
self.zipfile.writestr(filename, self.str_etudiants_in_jury())
|
|
|
|
|
|
|
|
def get_allTagForAggregat(self, nom_aggregat):
|
|
|
|
"""Extrait du dictionnaire syntheseJury la liste des tags d'un semestre ou
|
2023-12-31 23:04:06 +01:00
|
|
|
d'un aggrégat donné par son nom (S1, S2, S3 ou S4, 1A, ...). Renvoie [] si aucun tag.
|
|
|
|
"""
|
2020-09-26 16:19:37 +02:00
|
|
|
taglist = set()
|
2024-01-20 16:34:38 +01:00
|
|
|
for etudid in self.etudiants.get_etudids():
|
2020-09-26 16:19:37 +02:00
|
|
|
taglist = taglist.union(
|
|
|
|
set(self.syntheseJury[etudid][nom_aggregat]["groupe"].keys())
|
|
|
|
)
|
|
|
|
taglist = taglist.union(
|
|
|
|
set(self.syntheseJury[etudid][nom_aggregat]["promo"].keys())
|
|
|
|
)
|
|
|
|
return list(taglist)
|
|
|
|
|
|
|
|
def get_allTagInSyntheseJury(self):
|
2024-01-16 06:19:49 +01:00
|
|
|
"""Extrait tous les tags du dictionnaire syntheseJury trié par
|
|
|
|
ordre alphabétique. [] si aucun tag"""
|
2020-09-26 16:19:37 +02:00
|
|
|
allTags = set()
|
2024-01-20 16:34:38 +01:00
|
|
|
for nom in pe_tools.TOUS_LES_PARCOURS:
|
2020-09-26 16:19:37 +02:00
|
|
|
allTags = allTags.union(set(self.get_allTagForAggregat(nom)))
|
|
|
|
return sorted(list(allTags)) if len(allTags) > 0 else []
|
|
|
|
|
2024-01-16 15:51:22 +01:00
|
|
|
def table_syntheseJury(self, mode="singlesheet"): # was str_syntheseJury
|
2020-09-26 16:19:37 +02:00
|
|
|
"""Table(s) du jury
|
|
|
|
mode: singlesheet ou multiplesheet pour export excel
|
|
|
|
"""
|
|
|
|
sT = SeqGenTable() # le fichier excel à générer
|
|
|
|
|
|
|
|
# Les etudids des étudiants à afficher, triés par ordre alphabétiques de nom+prénom
|
|
|
|
donnees_tries = sorted(
|
|
|
|
[
|
|
|
|
(
|
|
|
|
etudid,
|
|
|
|
self.syntheseJury[etudid]["nom"]
|
|
|
|
+ " "
|
|
|
|
+ self.syntheseJury[etudid]["prenom"],
|
|
|
|
)
|
|
|
|
for etudid in self.syntheseJury.keys()
|
|
|
|
],
|
|
|
|
key=lambda c: c[1],
|
|
|
|
)
|
|
|
|
etudids = [e[0] for e in donnees_tries]
|
|
|
|
if not etudids: # Si pas d'étudiants
|
|
|
|
T = GenTable(
|
|
|
|
columns_ids=["pas d'étudiants"],
|
|
|
|
rows=[],
|
|
|
|
titles={"pas d'étudiants": "pas d'étudiants"},
|
|
|
|
html_sortable=True,
|
2024-01-16 06:35:27 +01:00
|
|
|
xls_sheet_name="but",
|
2020-09-26 16:19:37 +02:00
|
|
|
)
|
2024-01-16 06:35:27 +01:00
|
|
|
sT.add_genTable("but", T)
|
2020-09-26 16:19:37 +02:00
|
|
|
return sT
|
|
|
|
|
|
|
|
# Si des étudiants
|
|
|
|
maxParcours = max(
|
|
|
|
[self.syntheseJury[etudid]["nbSemestres"] for etudid in etudids]
|
|
|
|
)
|
|
|
|
|
2021-02-13 17:28:55 +01:00
|
|
|
infos = ["civilite", "nom", "prenom", "age", "nbSemestres"]
|
2020-09-26 16:19:37 +02:00
|
|
|
entete = ["etudid"]
|
|
|
|
entete.extend(infos)
|
|
|
|
entete.extend(["P%d" % i for i in range(1, maxParcours + 1)])
|
|
|
|
champs = [
|
|
|
|
"note",
|
|
|
|
"class groupe",
|
|
|
|
"class promo",
|
|
|
|
"min/moy/max groupe",
|
|
|
|
"min/moy/max promo",
|
|
|
|
]
|
|
|
|
|
|
|
|
# Les aggrégats à afficher par ordre tel que indiqué dans le dictionnaire parcours
|
2024-01-20 16:34:38 +01:00
|
|
|
aggregats = list(pe_tools.PARCOURS.keys()) # ['S1', 'S2', ..., '1A', '4S']
|
2024-01-16 06:35:27 +01:00
|
|
|
# aggregats = sorted(
|
2024-01-20 16:34:38 +01:00
|
|
|
# aggregats, key=lambda t: pe_tools.PARCOURS[t]["ordre"]
|
2024-01-16 06:35:27 +01:00
|
|
|
# ) # Tri des aggrégats
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
if mode == "multiplesheet":
|
|
|
|
allSheets = (
|
|
|
|
self.get_allTagInSyntheseJury()
|
|
|
|
) # tous les tags de syntheseJuryDict
|
|
|
|
allSheets = sorted(allSheets) # Tri des tags par ordre alphabétique
|
2024-01-20 16:34:38 +01:00
|
|
|
for sem in pe_tools.TOUS_LES_PARCOURS:
|
2020-09-26 16:19:37 +02:00
|
|
|
entete.extend(["%s %s" % (sem, champ) for champ in champs])
|
|
|
|
else: # "singlesheet"
|
|
|
|
allSheets = ["singlesheet"]
|
2024-01-16 15:51:22 +01:00
|
|
|
for (
|
|
|
|
sem
|
|
|
|
) in (
|
2024-01-20 16:34:38 +01:00
|
|
|
pe_tools.TOUS_LES_PARCOURS
|
|
|
|
): # pe_tools.PARCOURS.keys() -> ['S1', 'S2', ..., '1A', '4S']
|
2020-09-26 16:19:37 +02:00
|
|
|
tags = self.get_allTagForAggregat(sem)
|
|
|
|
entete.extend(
|
|
|
|
["%s %s %s" % (sem, tag, champ) for tag in tags for champ in champs]
|
|
|
|
)
|
|
|
|
|
|
|
|
columns_ids = entete # les id et les titres de colonnes sont ici identiques
|
|
|
|
titles = {i: i for i in columns_ids}
|
|
|
|
|
|
|
|
for (
|
|
|
|
sheet
|
|
|
|
) in (
|
|
|
|
allSheets
|
|
|
|
): # Pour tous les sheets à générer (1 si singlesheet, autant que de tags si multiplesheet)
|
|
|
|
rows = []
|
|
|
|
for etudid in etudids:
|
|
|
|
e = self.syntheseJury[etudid]
|
|
|
|
# Les info générales:
|
|
|
|
row = {
|
|
|
|
"etudid": etudid,
|
2021-02-13 17:28:55 +01:00
|
|
|
"civilite": e["civilite"],
|
2020-09-26 16:19:37 +02:00
|
|
|
"nom": e["nom"],
|
|
|
|
"prenom": e["prenom"],
|
|
|
|
"age": e["age"],
|
|
|
|
"nbSemestres": e["nbSemestres"],
|
|
|
|
}
|
|
|
|
# Les parcours: P1, P2, ...
|
|
|
|
n = 1
|
|
|
|
for p in e["parcours"]:
|
|
|
|
row["P%d" % n] = p["titreannee"]
|
|
|
|
n += 1
|
|
|
|
# if self.syntheseJury[etudid]['nbSemestres'] < maxParcours:
|
|
|
|
# descr += delim.join( ['']*( maxParcours -self.syntheseJury[etudid]['nbSemestres']) ) + delim
|
2024-01-20 16:34:38 +01:00
|
|
|
for sem in aggregats: # pe_tools.PARCOURS.keys():
|
2020-09-26 16:19:37 +02:00
|
|
|
listeTags = (
|
|
|
|
self.get_allTagForAggregat(sem)
|
|
|
|
if mode == "singlesheet"
|
|
|
|
else [sheet]
|
|
|
|
)
|
|
|
|
for tag in listeTags:
|
|
|
|
if tag in self.syntheseJury[etudid][sem]["groupe"]:
|
|
|
|
resgroupe = self.syntheseJury[etudid][sem]["groupe"][
|
|
|
|
tag
|
|
|
|
] # tuple
|
|
|
|
else:
|
|
|
|
resgroupe = (None, None, None, None, None, None, None)
|
|
|
|
if tag in self.syntheseJury[etudid][sem]["promo"]:
|
|
|
|
respromo = self.syntheseJury[etudid][sem]["promo"][tag]
|
|
|
|
else:
|
|
|
|
respromo = (None, None, None, None, None, None, None)
|
|
|
|
|
|
|
|
# note = "%2.2f" % resgroupe[0] if isinstance(resgroupe[0], float) else str(resgroupe[0])
|
|
|
|
champ = (
|
|
|
|
"%s %s " % (sem, tag)
|
|
|
|
if mode == "singlesheet"
|
|
|
|
else "%s " % (sem)
|
|
|
|
)
|
2021-02-01 23:54:46 +01:00
|
|
|
row[champ + "note"] = scu.fmt_note(resgroupe[0])
|
2020-09-26 16:19:37 +02:00
|
|
|
row[champ + "class groupe"] = "%s / %s" % (
|
2024-01-16 06:35:27 +01:00
|
|
|
resgroupe[2] if resgroupe[2] else "-",
|
2024-01-16 15:51:22 +01:00
|
|
|
resgroupe[3] if resgroupe[3] else "-",
|
2020-09-26 16:19:37 +02:00
|
|
|
)
|
|
|
|
row[champ + "class promo"] = "%s / %s" % (
|
2024-01-16 06:35:27 +01:00
|
|
|
respromo[2] if respromo[2] else "-",
|
2024-01-16 15:51:22 +01:00
|
|
|
respromo[3] if respromo[3] else "-",
|
2020-09-26 16:19:37 +02:00
|
|
|
)
|
|
|
|
row[champ + "min/moy/max groupe"] = "%s / %s / %s" % tuple(
|
2024-01-16 06:35:27 +01:00
|
|
|
(scu.fmt_note(x) if x is not None else "-")
|
2024-01-16 15:51:22 +01:00
|
|
|
for x in (resgroupe[6], resgroupe[4], resgroupe[5])
|
2020-09-26 16:19:37 +02:00
|
|
|
)
|
|
|
|
row[champ + "min/moy/max promo"] = "%s / %s / %s" % tuple(
|
2024-01-16 06:35:27 +01:00
|
|
|
(scu.fmt_note(x) if x is not None else "-")
|
2021-02-01 23:54:46 +01:00
|
|
|
for x in (respromo[6], respromo[4], respromo[5])
|
2020-09-26 16:19:37 +02:00
|
|
|
)
|
|
|
|
rows.append(row)
|
|
|
|
|
|
|
|
T = GenTable(
|
|
|
|
columns_ids=columns_ids,
|
|
|
|
rows=rows,
|
|
|
|
titles=titles,
|
|
|
|
html_sortable=True,
|
|
|
|
xls_sheet_name=sheet,
|
|
|
|
)
|
|
|
|
sT.add_genTable(sheet, T)
|
|
|
|
|
|
|
|
if mode == "singlesheet":
|
|
|
|
return sT.get_genTable("singlesheet")
|
|
|
|
else:
|
|
|
|
return sT
|
|
|
|
|
|
|
|
# **************************************************************************************************************** #
|
|
|
|
# Méthodes de classe pour gestion d'un cache de données accélérant les calculs / intérêt à débattre
|
|
|
|
# **************************************************************************************************************** #
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------------------------------------------
|
2024-01-16 15:51:22 +01:00
|
|
|
def get_cache_etudInfo_d_un_etudiant(self, etudid):
|
2020-09-26 16:19:37 +02:00
|
|
|
"""Renvoie les informations sur le parcours d'un étudiant soit en les relisant depuis
|
|
|
|
ETUDINFO_DICT si mémorisée soit en les chargeant et en les mémorisant
|
2024-01-20 16:34:38 +01:00
|
|
|
|
|
|
|
TODO:: A supprimer à long terme
|
2020-09-26 16:19:37 +02:00
|
|
|
"""
|
|
|
|
if etudid not in self.ETUDINFO_DICT:
|
2024-01-20 16:34:38 +01:00
|
|
|
self.ETUDINFO_DICT[etudid] = Identite.get_etud(etudid=etudid)
|
|
|
|
# sco_etud.get_etud_info(
|
|
|
|
# etudid=etudid, filled=True
|
|
|
|
# ))[0]
|
2020-09-26 16:19:37 +02:00
|
|
|
return self.ETUDINFO_DICT[etudid]
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------------------------------------------
|
2024-01-16 15:51:22 +01:00
|
|
|
def get_cache_notes_d_un_semestre(self, formsemestre_id: int) -> NotesTableCompat:
|
2021-01-01 18:40:47 +01:00
|
|
|
"""Charge la table des notes d'un formsemestre"""
|
2023-03-20 11:17:38 +01:00
|
|
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
2022-02-11 23:12:40 +01:00
|
|
|
return res_sem.load_formsemestre_results(formsemestre)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------------------------------------------
|
2024-01-20 16:34:38 +01:00
|
|
|
def get_semestresBUT_d_un_etudiant(self, identite: Identite, semestre_id=None):
|
|
|
|
"""cf. pe_etudiant.semestres_etudiant()"""
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2024-01-20 16:34:38 +01:00
|
|
|
return None
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
# *********************************************
|
|
|
|
# Fonctions d'affichage pour debug
|
2024-01-16 15:51:22 +01:00
|
|
|
def get_resultat_d_un_etudiant(self, etudid):
|
2020-09-26 16:19:37 +02:00
|
|
|
chaine = ""
|
2024-01-20 16:34:38 +01:00
|
|
|
for nom_sem in pe_tools.TOUS_LES_SEMESTRES:
|
|
|
|
semtagid = self.etudiants.cursus[etudid][
|
2020-09-26 16:19:37 +02:00
|
|
|
nom_sem
|
|
|
|
] # le formsemestre_id du semestre taggué de l'étudiant
|
2024-01-21 18:55:21 +01:00
|
|
|
semtag = self.semestres_taggues[semtagid]
|
2021-08-10 17:12:10 +02:00
|
|
|
chaine += "Semestre " + nom_sem + str(semtagid) + "\n"
|
2020-09-26 16:19:37 +02:00
|
|
|
# le détail du calcul tag par tag
|
|
|
|
# chaine += "Détail du calcul du tag\n"
|
|
|
|
# chaine += "-----------------------\n"
|
|
|
|
# for tag in semtag.taglist:
|
|
|
|
# chaine += "Tag=" + tag + "\n"
|
|
|
|
# chaine += semtag.str_detail_resultat_d_un_tag(tag, etudid=etudid) + "\n"
|
|
|
|
# le bilan des tags
|
|
|
|
chaine += "Bilan des tags\n"
|
|
|
|
chaine += "--------------\n"
|
|
|
|
for tag in semtag.taglist:
|
|
|
|
chaine += (
|
|
|
|
tag + ";" + semtag.str_resTag_d_un_etudiant(tag, etudid) + "\n"
|
|
|
|
)
|
|
|
|
chaine += "\n"
|
|
|
|
return chaine
|
|
|
|
|
2022-04-20 12:23:43 +02:00
|
|
|
def get_date_entree_etudiant(self, etudid) -> str:
|
|
|
|
"""Renvoie la date d'entree d'un étudiant: "1996" """
|
|
|
|
annees_debut = [
|
|
|
|
int(sem["annee_debut"]) for sem in self.ETUDINFO_DICT[etudid]["sems"]
|
|
|
|
]
|
|
|
|
if annees_debut:
|
|
|
|
return str(min(annees_debut))
|
|
|
|
return ""
|
2024-01-21 18:55:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
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")
|
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
formsemestres = etudiants.get_formsemestres(
|
2024-01-21 18:55:21 +01:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2024-01-24 19:37:45 +01:00
|
|
|
def compute_trajectoires_tag(
|
|
|
|
trajectoires: TrajectoiresJuryPE,
|
|
|
|
etudiants: EtudiantsJuryPE,
|
|
|
|
semestres_taggues: dict[int, SemestreTag],
|
|
|
|
):
|
2024-01-24 15:37:50 +01:00
|
|
|
"""Créée les trajectoires tagguées (combinaison aggrégeant plusieurs semestres au sens
|
|
|
|
d'un aggrégat (par ex: '3S')),
|
|
|
|
en calculant les moyennes et les classements par tag pour chacune.
|
|
|
|
|
|
|
|
Pour rappel : Chaque trajectoire est identifiée un nom d'aggrégat et par un formsemestre terminal.
|
2024-01-21 18:55:21 +01:00
|
|
|
|
|
|
|
Par exemple :
|
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
* combinaisons '3S' : S1+S2+S3 en prenant en compte tous les S3 qu'ont fréquenté les
|
2024-01-21 18:55:21 +01:00
|
|
|
étudiants du jury PE. Ces S3 marquent les formsemestre terminal de chaque combinaison.
|
|
|
|
|
2024-01-23 18:44:44 +01:00
|
|
|
* combinaisons 'S2' : 1 seul S2 pour des étudiants n'ayant pas redoublé, 2 pour des redoublants (dont les
|
|
|
|
notes seront moyennées sur leur 2 semestres S2). Ces combinaisons ont pour formsemestre le dernier S2 en
|
|
|
|
date (le S2 redoublé par les redoublants est forcément antérieur)
|
|
|
|
|
|
|
|
|
2024-01-21 18:55:21 +01:00
|
|
|
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 ")
|
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
trajectoires_tagguees = {}
|
2024-01-21 18:55:21 +01:00
|
|
|
|
2024-01-24 19:37:45 +01:00
|
|
|
for trajectoire_id in trajectoires.trajectoires:
|
|
|
|
trajectoire = trajectoires.trajectoires[trajectoire_id]
|
2024-01-24 15:37:50 +01:00
|
|
|
nom = trajectoire.get_repr()
|
2024-01-21 18:55:21 +01:00
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
pe_tools.pe_print(f" --> Fusion {nom}")
|
2024-01-21 18:55:21 +01:00
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
"""Création de la trajectoire_tagguee associée"""
|
2024-01-24 19:37:45 +01:00
|
|
|
trajectoire_tagguee = TrajectoireTag(
|
|
|
|
nom, trajectoire, semestres_taggues, etudiants
|
|
|
|
)
|
2024-01-21 18:55:21 +01:00
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
"""Mémorise le résultat"""
|
|
|
|
trajectoires_tagguees[trajectoire_id] = trajectoire_tagguee
|
2024-01-21 18:55:21 +01:00
|
|
|
|
2024-01-24 15:37:50 +01:00
|
|
|
return trajectoires_tagguees
|
2024-01-21 18:55:21 +01:00
|
|
|
|
2024-01-23 19:08:54 +01:00
|
|
|
|
|
|
|
def compute_interclassements(
|
2024-01-24 19:37:45 +01:00
|
|
|
etudiants: EtudiantsJuryPE,
|
|
|
|
trajectoires_jury_pe: TrajectoiresJuryPE,
|
|
|
|
trajectoires_tagguees: dict[tuple, Trajectoire],
|
2024-01-23 19:08:54 +01:00
|
|
|
):
|
|
|
|
"""Interclasse les étudiants, (nom d') aggrégat par aggrégat,
|
2024-01-24 19:37:45 +01:00
|
|
|
pour fournir un classement sur la promo. Le classement est établi au regard du nombre
|
2024-01-23 19:08:54 +01:00
|
|
|
d'étudiants ayant participé au même aggrégat.
|
|
|
|
"""
|
2024-01-24 19:37:45 +01:00
|
|
|
pe_tools.pe_print(" Interclassement sur la promo")
|
2024-01-23 19:08:54 +01:00
|
|
|
|
2024-01-24 19:37:45 +01:00
|
|
|
aggregats_interclasses_taggues = {}
|
|
|
|
for nom_aggregat in pe_tools.TOUS_LES_SEMESTRES + pe_tools.TOUS_LES_AGGREGATS:
|
|
|
|
pe_tools.pe_print(f" --> {nom_aggregat}")
|
|
|
|
interclass = AggregatInterclasseTag(
|
|
|
|
nom_aggregat, etudiants, trajectoires_jury_pe, trajectoires_tagguees
|
2024-01-23 19:08:54 +01:00
|
|
|
)
|
2024-01-24 19:37:45 +01:00
|
|
|
aggregats_interclasses_taggues[nom_aggregat] = interclass
|
|
|
|
return aggregats_interclasses_taggues
|