Compare commits
2 Commits
86e8803c87
...
898270d2f0
Author | SHA1 | Date |
---|---|---|
Cléo Baras | 898270d2f0 | |
Cléo Baras | e28bfa34be |
|
@ -67,7 +67,8 @@ def get_code_latex_from_modele(fichier):
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def get_code_latex_from_scodoc_preference(formsemestre_id, champ="pe_avis_latex_tmpl"):
|
||||
def get_code_latex_from_scodoc_preference(formsemestre_id,
|
||||
champ="pe_avis_latex_tmpl"):
|
||||
"""
|
||||
Extrait le template (ou le tag d'annotation au regard du champ fourni) des préférences LaTeX
|
||||
et s'assure qu'il est renvoyé au format unicode
|
||||
|
@ -94,7 +95,9 @@ def get_tags_latex(code_latex):
|
|||
return []
|
||||
|
||||
|
||||
def comp_latex_parcourstimeline(etudiant, promo, taille=17):
|
||||
def comp_latex_parcourstimeline(etudiant,
|
||||
promo,
|
||||
taille=17):
|
||||
"""Interprète un tag dans un avis latex **parcourstimeline**
|
||||
et génère le code latex permettant de retracer le parcours d'un étudiant
|
||||
sous la forme d'une frise temporelle.
|
||||
|
@ -156,9 +159,11 @@ def interprete_tag_latex(tag):
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def get_code_latex_avis_etudiant(
|
||||
donnees_etudiant, un_avis_latex, annotationPE, footer_latex, prefs
|
||||
):
|
||||
def get_code_latex_avis_etudiant(donnees_etudiant,
|
||||
un_avis_latex,
|
||||
annotationPE,
|
||||
footer_latex,
|
||||
prefs):
|
||||
"""
|
||||
Renvoie le code latex permettant de générer l'avis d'un étudiant en utilisant ses
|
||||
donnees_etudiant contenu dans le dictionnaire de synthèse du jury PE et en suivant un
|
||||
|
@ -220,7 +225,8 @@ def get_code_latex_avis_etudiant(
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def get_annotation_PE(etudid, tag_annotation_pe):
|
||||
def get_annotation_PE(etudid,
|
||||
tag_annotation_pe):
|
||||
"""Renvoie l'annotation PE dans la liste de ces annotations ;
|
||||
Cette annotation est reconnue par la présence d'un tag **PE**
|
||||
(cf. .get_preferences -> pe_tag_annotation_avis_latex).
|
||||
|
@ -261,7 +267,11 @@ def get_annotation_PE(etudid, tag_annotation_pe):
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ):
|
||||
def str_from_syntheseJury(donnees_etudiant,
|
||||
aggregat,
|
||||
groupe,
|
||||
tag_scodoc,
|
||||
champ):
|
||||
"""Extrait du dictionnaire de synthèse du juryPE pour un étudiant donnée,
|
||||
une valeur indiquée par un champ ;
|
||||
si champ est une liste, renvoie la liste des valeurs extraites.
|
||||
|
@ -312,7 +322,8 @@ def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ)
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def get_bilanParTag(donnees_etudiant, groupe="groupe"):
|
||||
def get_bilanParTag(donnees_etudiant,
|
||||
groupe="groupe"):
|
||||
"""Renvoie le code latex d'un tableau récapitulant, pour tous les tags trouvés dans
|
||||
les données étudiants, ses résultats.
|
||||
result: chaine unicode
|
||||
|
@ -383,7 +394,12 @@ def get_bilanParTag(donnees_etudiant, groupe="groupe"):
|
|||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def get_avis_poursuite_par_etudiant(
|
||||
jury, etudid, template_latex, tag_annotation_pe, footer_latex, prefs
|
||||
jury,
|
||||
etudid,
|
||||
template_latex,
|
||||
tag_annotation_pe,
|
||||
footer_latex,
|
||||
prefs
|
||||
):
|
||||
"""Renvoie un nom de fichier et le contenu de l'avis latex d'un étudiant dont l'etudid est fourni.
|
||||
result: [ chaine unicode, chaine unicode ]
|
||||
|
@ -444,7 +460,8 @@ def get_templates_from_distrib(template="avis"):
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def table_syntheseAnnotationPE(syntheseJury, tag_annotation_pe):
|
||||
def table_syntheseAnnotationPE(syntheseJury,
|
||||
tag_annotation_pe):
|
||||
"""Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant"""
|
||||
sT = SeqGenTable() # le fichier excel à générer
|
||||
|
||||
|
|
|
@ -78,20 +78,24 @@ def comp_nom_semestre_dans_parcours(sem):
|
|||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
class JuryPE(object):
|
||||
"""Classe memorisant toutes les informations necessaires pour etablir un jury de PE. Modele
|
||||
base sur NotesTable
|
||||
"""Classe mémorisant toutes les informations nécessaires pour établir un jury de PE.
|
||||
Modèle basé sur NotesTable.
|
||||
|
||||
Attributs : - diplome : l'annee d'obtention du diplome DUT et du jury de PE (generalement fevrier XXXX)
|
||||
- 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
|
||||
Attributs :
|
||||
|
||||
* diplome : l'annee d'obtention du diplome BUT et du jury de PE (generalement fevrier XXXX)
|
||||
* 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
|
||||
"""
|
||||
|
||||
# Variables de classe décrivant les aggrégats, leur ordre d'apparition temporelle et
|
||||
# leur affichage dans les avis latex
|
||||
NBRE_SEMESTRES_PARCOURS = 6
|
||||
|
||||
PARCOURS = {
|
||||
"S1": {
|
||||
"aggregat": ["S1"],
|
||||
|
@ -105,6 +109,12 @@ class JuryPE(object):
|
|||
"affichage_court": "S2",
|
||||
"affichage_long": "Semestre 2",
|
||||
},
|
||||
"1A": {
|
||||
"aggregat": ["S1", "S2"],
|
||||
"ordre": 3,
|
||||
"affichage_court": "1A",
|
||||
"affichage_long": "1ère année",
|
||||
},
|
||||
"S3": {
|
||||
"aggregat": ["S3"],
|
||||
"ordre": 4,
|
||||
|
@ -117,12 +127,6 @@ class JuryPE(object):
|
|||
"affichage_court": "S4",
|
||||
"affichage_long": "Semestre 4",
|
||||
},
|
||||
"1A": {
|
||||
"aggregat": ["S1", "S2"],
|
||||
"ordre": 3,
|
||||
"affichage_court": "1A",
|
||||
"affichage_long": "1ère année",
|
||||
},
|
||||
"2A": {
|
||||
"aggregat": ["S3", "S4"],
|
||||
"ordre": 6,
|
||||
|
@ -133,16 +137,52 @@ class JuryPE(object):
|
|||
"aggregat": ["S1", "S2", "S3"],
|
||||
"ordre": 7,
|
||||
"affichage_court": "S1+S2+S3",
|
||||
"affichage_long": "DUT du semestre 1 au semestre 3",
|
||||
"affichage_long": "BUT du semestre 1 au semestre 3",
|
||||
},
|
||||
"4S": {
|
||||
"aggregat": ["S1", "S2", "S3", "S4"],
|
||||
"ordre": 8,
|
||||
"affichage_court": "DUT",
|
||||
"affichage_long": "DUT (tout semestre inclus)",
|
||||
"affichage_court": "BUT",
|
||||
"affichage_long": "BUT du semestre 1 au semestre 4",
|
||||
},
|
||||
"S5": {
|
||||
"aggregat": ["S5"],
|
||||
"ordre": 9,
|
||||
"affichage_court": "S5",
|
||||
"affichage_long": "Semestre 5",
|
||||
},
|
||||
"S6": {
|
||||
"aggregat": ["S6"],
|
||||
"ordre": 10,
|
||||
"affichage_court": "S6",
|
||||
"affichage_long": "Semestre 6",
|
||||
},
|
||||
"3A": {
|
||||
"aggregat": ["S5", "S6"],
|
||||
"ordre": 11,
|
||||
"affichage_court": "3A",
|
||||
"affichage_long": "3ème année",
|
||||
},
|
||||
"5S": {
|
||||
"aggregat": ["S1", "S2", "S3", "S4", "S5"],
|
||||
"ordre": 12,
|
||||
"affichage_court": "S1+S2+S3+S4+S5",
|
||||
"affichage_long": "BUT du semestre 1 au semestre 5",
|
||||
},
|
||||
"6S": {
|
||||
"aggregat": ["S1", "S2", "S3", "S4", "S5", "S6"],
|
||||
"ordre": 13,
|
||||
"affichage_court": "BUT",
|
||||
"affichage_long": "BUT (tout semestre inclus)",
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
AGGREGAT_DIPLOMANT = "6S" # aggrégat correspondant à la totalité des notes pour le diplôme
|
||||
TOUS_LES_SEMESTRES = PARCOURS["6S"]["aggregat"]
|
||||
TOUS_LES_AGGREGATS = [cle for cle in PARCOURS.keys() if not cle.startswith("S")]
|
||||
TOUS_LES_PARCOURS = list(PARCOURS.keys())
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def __init__(self, semBase):
|
||||
"""
|
||||
|
@ -268,7 +308,9 @@ class JuryPE(object):
|
|||
# **************************************************************************************************************** #
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_etudiants_in_jury(self, semBase, avec_meme_formation=False):
|
||||
def get_etudiants_in_jury(self,
|
||||
semBase,
|
||||
avec_meme_formation=False):
|
||||
"""
|
||||
Calcule la liste des étudiants à prendre en compte dans le jury et la renvoie sous la forme
|
||||
"""
|
||||
|
@ -314,7 +356,8 @@ class JuryPE(object):
|
|||
# ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_etudiants_dans_semestres(self, semsListe):
|
||||
def get_etudiants_dans_semestres(self,
|
||||
semsListe):
|
||||
"""Renvoie la liste des etudid des etudiants inscrits à l'un des semestres de la liste fournie en paramètre
|
||||
en supprimant les doublons (i.e. un même étudiant qui apparaîtra 2 fois)"""
|
||||
|
||||
|
@ -322,7 +365,7 @@ class JuryPE(object):
|
|||
for sem in semsListe: # pour chacun des semestres de la liste
|
||||
nt = self.get_cache_notes_d_un_semestre(sem["formsemestre_id"])
|
||||
etudiantsDuSemestre = (
|
||||
nt.get_etudids()
|
||||
[ins.etudid for ins in nt.formsemestre.inscriptions] # nt.get_etudids()
|
||||
) # identification des etudiants du semestre
|
||||
|
||||
if pe_tools.PE_DEBUG:
|
||||
|
@ -335,9 +378,10 @@ class JuryPE(object):
|
|||
return list(set(etudiants)) # suppression des doublons
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_etudids_du_jury(self, ordre="aucun"):
|
||||
def get_etudids_du_jury(self,
|
||||
ordre="aucun"):
|
||||
"""Renvoie la liste de tous les étudiants (concrètement leur etudid)
|
||||
participant au jury c'est à dire, ceux dont la date du 'jury' est self.diplome
|
||||
participant au jury c'est-à-dire, ceux dont la date du 'jury' est self.diplome
|
||||
et n'ayant pas abandonné.
|
||||
Si l'ordre est précisé, donne une liste etudid dont le nom, prenom trié par ordre alphabétique
|
||||
"""
|
||||
|
@ -359,14 +403,20 @@ class JuryPE(object):
|
|||
# ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def add_etudiants(self, etudid):
|
||||
"""Ajoute un étudiant (via son etudid) au dictionnaire de synthèse jurydict.
|
||||
def add_etudiants(self,
|
||||
etudid):
|
||||
"""Ajoute un étudiant connaissant son etudid au dictionnaire de synthèse jurydict.
|
||||
L'ajout consiste à :
|
||||
> insérer une entrée pour l'étudiant en mémorisant ses infos (get_etudInfo),
|
||||
avec son nom, prénom, etc...
|
||||
> à analyser son parcours, pour vérifier s'il n'a pas abandonné l'IUT en cours de route => 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)
|
||||
* insérer une entrée pour l'étudiant en mémorisant ses infos (get_etudInfo),
|
||||
avec son nom, prénom, etc...
|
||||
* à analyser son parcours, pour vérifier s'il n'a pas 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 au jury s'il respecte les critères précédents
|
||||
"""
|
||||
|
||||
if etudid not in self.PARCOURSINFO_DICT:
|
||||
|
@ -386,7 +436,7 @@ class JuryPE(object):
|
|||
# Sa date prévisionnelle de diplome
|
||||
self.PARCOURSINFO_DICT[etudid][
|
||||
"diplome"
|
||||
] = self.calcul_anneePromoDUT_d_un_etudiant(etudid)
|
||||
] = self.calcul_anneePromoBUT_d_un_etudiant(etudid)
|
||||
if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2:
|
||||
pe_tools.pe_print(
|
||||
"promo=" + str(self.PARCOURSINFO_DICT[etudid]["diplome"]), end=""
|
||||
|
@ -407,11 +457,10 @@ class JuryPE(object):
|
|||
# et s'ils existent quelles sont ses notes utiles ?
|
||||
sesFormsemestre_idValidants = [
|
||||
self.get_Fid_d_un_Si_valide_d_un_etudiant(etudid, nom_sem)
|
||||
for nom_sem in JuryPE.PARCOURS["4S"][
|
||||
"aggregat"
|
||||
] # Recherche du formsemestre_id de son Si valide (ou a défaut en cours)
|
||||
for nom_sem in JuryPE.TOUS_LES_SEMESTRES
|
||||
# Recherche du formsemestre_id de son Si valide (ou a défaut en cours)
|
||||
]
|
||||
for i, nom_sem in enumerate(JuryPE.PARCOURS["4S"]["aggregat"]):
|
||||
for i, nom_sem in enumerate(JuryPE.TOUS_LES_SEMESTRES):
|
||||
fid = sesFormsemestre_idValidants[i]
|
||||
self.PARCOURSINFO_DICT[etudid][nom_sem] = fid # ['formsemestre_id']
|
||||
if fid != None and pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2:
|
||||
|
@ -419,13 +468,11 @@ class JuryPE(object):
|
|||
# self.get_moyennesEtClassements_par_semestre_d_un_etudiant( etudid, fid )
|
||||
|
||||
# Quelles sont ses années validantes ('1A', '2A') et ses parcours (3S, 4S) validants ?
|
||||
for parcours in ["1A", "2A", "3S", "4S"]:
|
||||
lesSemsDuParcours = JuryPE.PARCOURS[parcours][
|
||||
"aggregat"
|
||||
] # les semestres du parcours : par ex. ['S1', 'S2', 'S3']
|
||||
for parcours in JuryPE.TOUS_LES_AGGREGATS:
|
||||
lesSemsDuParcours = JuryPE.PARCOURS[parcours]["aggregat"] # les semestres du parcours : par ex. ['S1', 'S2', 'S3']
|
||||
lesFidsValidantDuParcours = [
|
||||
sesFormsemestre_idValidants[
|
||||
JuryPE.PARCOURS["4S"]["aggregat"].index(nom_sem)
|
||||
JuryPE.TOUS_LES_SEMESTRES.index(nom_sem)
|
||||
]
|
||||
for nom_sem in lesSemsDuParcours # par ex. ['SEM4532', 'SEM567', ...]
|
||||
]
|
||||
|
@ -449,7 +496,8 @@ class JuryPE(object):
|
|||
# print
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def est_un_etudiant_reoriente_ou_demissionnaire(self, etudid):
|
||||
def est_un_etudiant_reoriente_ou_demissionnaire(self,
|
||||
etudid):
|
||||
"""Renvoie True si l'étudiant est réorienté (NAR) ou démissionnaire (DEM)"""
|
||||
from app.scodoc import sco_report
|
||||
|
||||
|
@ -469,13 +517,14 @@ class JuryPE(object):
|
|||
return reponse
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def est_un_etudiant_disparu(self, etudid):
|
||||
def est_un_etudiant_disparu(self,
|
||||
etudid):
|
||||
"""Renvoie True si l'étudiant n'a pas achevé la formation à l'IUT et a disparu des listes, sans
|
||||
pour autant avoir été indiqué NAR ou DEM ; recherche son dernier semestre validé et regarde s'il
|
||||
n'existe pas parmi les semestres existants dans scodoc un semestre postérieur (en terme de date de
|
||||
début) de n° au moins égal à celui de son dernier semestre valide dans lequel il aurait pu
|
||||
s'inscrire mais ne l'a pas fait."""
|
||||
sessems = self.get_semestresDUT_d_un_etudiant(
|
||||
sessems = self.get_semestresBUT_d_un_etudiant(
|
||||
etudid
|
||||
) # les semestres de l'étudiant
|
||||
sonDernierSidValide = self.get_dernier_semestre_id_valide_d_un_etudiant(etudid)
|
||||
|
@ -519,7 +568,8 @@ class JuryPE(object):
|
|||
# ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_dernier_semestre_id_valide_d_un_etudiant(self, etudid):
|
||||
def get_dernier_semestre_id_valide_d_un_etudiant(self,
|
||||
etudid):
|
||||
"""Renvoie le n° (semestre_id) du dernier semestre validé par un étudiant fourni par son etudid
|
||||
et None si aucun semestre n'a été validé
|
||||
"""
|
||||
|
@ -542,12 +592,14 @@ class JuryPE(object):
|
|||
# ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_Fid_d_un_Si_valide_d_un_etudiant(self, etudid, nom_semestre):
|
||||
def get_Fid_d_un_Si_valide_d_un_etudiant(self,
|
||||
etudid,
|
||||
nom_semestre):
|
||||
"""Récupère le formsemestre_id valide d'un étudiant fourni son etudid à un semestre DUT de n° semestre_id
|
||||
donné. Si le semestre est en cours (pas encore de jury), renvoie le formsemestre_id actuel.
|
||||
"""
|
||||
semestre_id = JuryPE.PARCOURS["4S"]["aggregat"].index(nom_semestre) + 1
|
||||
sesSi = self.get_semestresDUT_d_un_etudiant(
|
||||
semestre_id = JuryPE.TOUS_LES_SEMESTRES.index(nom_semestre) + 1
|
||||
sesSi = self.get_semestresBUT_d_un_etudiant(
|
||||
etudid, semestre_id
|
||||
) # extrait uniquement les Si par ordre temporel décroissant
|
||||
|
||||
|
@ -580,7 +632,8 @@ class JuryPE(object):
|
|||
Calcule les moyennes et les classements de chaque semestre par tag et les statistiques de ces semestres.
|
||||
"""
|
||||
lesFids = self.get_formsemestreids_du_jury(
|
||||
self.get_etudids_du_jury(), liste_semestres=["S1", "S2", "S3", "S4"]
|
||||
self.get_etudids_du_jury(),
|
||||
liste_semestres=JuryPE.TOUS_LES_SEMESTRES
|
||||
)
|
||||
for i, fid in enumerate(lesFids):
|
||||
if pe_tools.PE_DEBUG:
|
||||
|
@ -591,7 +644,8 @@ class JuryPE(object):
|
|||
self.add_semtags_in_jury(fid)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def add_semtags_in_jury(self, fid):
|
||||
def add_semtags_in_jury(self,
|
||||
fid):
|
||||
"""Crée si nécessaire un semtag et le mémorise dans self.semTag ;
|
||||
charge également les données des nouveaux étudiants qui en font partis.
|
||||
"""
|
||||
|
@ -623,7 +677,7 @@ class JuryPE(object):
|
|||
" - %d étudiants classés " % (nbinscrit)
|
||||
+ ": "
|
||||
+ ",".join(
|
||||
[etudid for etudid in self.semTagDict[fid].get_etudids()]
|
||||
[str(etudid) for etudid in self.semTagDict[fid].get_etudids()]
|
||||
)
|
||||
)
|
||||
if lesEtudidsManquants:
|
||||
|
@ -631,14 +685,16 @@ class JuryPE(object):
|
|||
" - dont %d étudiants manquants ajoutés aux données du jury"
|
||||
% (len(lesEtudidsManquants))
|
||||
+ ": "
|
||||
+ ", ".join(lesEtudidsManquants)
|
||||
+ ", ".join([str(etudid) for etudid in lesEtudidsManquants])
|
||||
)
|
||||
pe_tools.pe_print(" - Export csv")
|
||||
filename = self.NOM_EXPORT_ZIP + self.semTagDict[fid].nom + ".csv"
|
||||
self.zipfile.writestr(filename, self.semTagDict[fid].str_tagtable())
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------
|
||||
def get_formsemestreids_du_jury(self, etudids, liste_semestres="4S"):
|
||||
def get_formsemestreids_du_jury(self,
|
||||
etudids,
|
||||
liste_semestres="6S"):
|
||||
"""Renvoie la liste des formsemestre_id validants des étudiants en parcourant les semestres valides des étudiants mémorisés dans
|
||||
self.PARCOURSINFO_DICT.
|
||||
Les étudiants sont identifiés par leur etudic donnés dans la liste etudids (généralement self.get_etudids_in_jury() ).
|
||||
|
@ -723,8 +779,8 @@ class JuryPE(object):
|
|||
# '3S' : ['S1', 'S2', 'S3'], '4S' : ['S1', 'S2', 'S3', 'S4'] }
|
||||
|
||||
# ---> sur 2 parcours DUT (cas S3 fini, cas S4 fini)
|
||||
combinaisons = ["1A", "2A", "3S", "4S"]
|
||||
for i, nom in enumerate(combinaisons):
|
||||
|
||||
for i, nom in enumerate(JuryPE.TOUS_LES_AGGREGATS):
|
||||
parcours = JuryPE.PARCOURS[nom][
|
||||
"aggregat"
|
||||
] # La liste des noms de semestres (S1, S2, ...) impliqués dans l'aggrégat
|
||||
|
@ -793,7 +849,7 @@ class JuryPE(object):
|
|||
pe_tools.pe_print(
|
||||
"%d) %s avec interclassement sur la promo" % (i + 1, nom)
|
||||
)
|
||||
if nom in ["S1", "S2", "S3", "S4"]:
|
||||
if nom in JuryPE.TOUS_LES_SEMESTRES:
|
||||
settag.set_SetTagDict(self.semTagDict)
|
||||
else: # cas des aggrégats
|
||||
settag.set_SetTagDict(self.setTagDict[nom])
|
||||
|
@ -846,7 +902,7 @@ class JuryPE(object):
|
|||
if (
|
||||
self.PARCOURSINFO_DICT[etudid][nom] != None
|
||||
): # Un parcours valide existe
|
||||
if nom in ["S1", "S2", "S3", "S4"]:
|
||||
if nom in JuryPE.TOUS_LES_SEMESTRES:
|
||||
tagtable = self.semTagDict[self.PARCOURSINFO_DICT[etudid][nom]]
|
||||
else:
|
||||
tagtable = self.setTagDict[nom][
|
||||
|
@ -866,20 +922,22 @@ class JuryPE(object):
|
|||
tag
|
||||
] = tagtable.get_resultatsEtud(tag, etudid)
|
||||
|
||||
def get_dateEntree(self, etudid):
|
||||
def get_dateEntree(self,
|
||||
etudid):
|
||||
"""Renvoie l'année d'entrée de l'étudiant à l'IUT"""
|
||||
# etudinfo = self.ETUDINFO_DICT[etudid]
|
||||
semestres = self.get_semestresDUT_d_un_etudiant(etudid)
|
||||
semestres = self.get_semestresBUT_d_un_etudiant(etudid)
|
||||
if semestres:
|
||||
# le 1er sem à l'IUT
|
||||
return semestres[0]["annee_debut"]
|
||||
else:
|
||||
return ""
|
||||
|
||||
def get_parcoursIUT(self, etudid):
|
||||
def get_parcoursIUT(self,
|
||||
etudid):
|
||||
"""Renvoie une liste d'infos sur les semestres du parcours d'un étudiant"""
|
||||
# etudinfo = self.ETUDINFO_DICT[etudid]
|
||||
sems = self.get_semestresDUT_d_un_etudiant(etudid)
|
||||
sems = self.get_semestresBUT_d_un_etudiant(etudid)
|
||||
|
||||
infos = []
|
||||
for sem in sems:
|
||||
|
@ -896,10 +954,11 @@ class JuryPE(object):
|
|||
# **************************************************************************************************************** #
|
||||
# Méthodes d'affichage pour debug
|
||||
# **************************************************************************************************************** #
|
||||
def str_etudiants_in_jury(self, delim=";"):
|
||||
def str_etudiants_in_jury(self,
|
||||
delim=";"):
|
||||
# En tete:
|
||||
entete = ["Id", "Nom", "Abandon", "Diplome"]
|
||||
for nom_sem in ["S1", "S2", "S3", "S4", "1A", "2A", "3S", "4S"]:
|
||||
for nom_sem in JuryPE.TOUS_LES_PARCOURS:
|
||||
entete += [nom_sem, "descr"]
|
||||
chaine = delim.join(entete) + "\n"
|
||||
|
||||
|
@ -914,8 +973,8 @@ class JuryPE(object):
|
|||
str(donnees["diplome"]),
|
||||
]
|
||||
|
||||
# les semestres
|
||||
for nom_sem in ["S1", "S2", "S3", "S4", "1A", "2A", "3S", "4S"]:
|
||||
# les semestres et les aggrégats
|
||||
for nom_sem in JuryPE.TOUS_LES_PARCOURS:
|
||||
table = (
|
||||
self.semTagDict[donnees[nom_sem]].nom
|
||||
if donnees[nom_sem] in self.semTagDict
|
||||
|
@ -952,13 +1011,15 @@ class JuryPE(object):
|
|||
return list(taglist)
|
||||
|
||||
def get_allTagInSyntheseJury(self):
|
||||
"""Extrait tous les tags du dictionnaire syntheseJury trié par ordre alphabétique. [] si aucun tag"""
|
||||
"""Extrait tous les tags du dictionnaire syntheseJury trié par
|
||||
ordre alphabétique. [] si aucun tag"""
|
||||
allTags = set()
|
||||
for nom in JuryPE.PARCOURS.keys():
|
||||
for nom in JuryPE.TOUS_LES_PARCOURS:
|
||||
allTags = allTags.union(set(self.get_allTagForAggregat(nom)))
|
||||
return sorted(list(allTags)) if len(allTags) > 0 else []
|
||||
|
||||
def table_syntheseJury(self, mode="singlesheet"): # was str_syntheseJury
|
||||
def table_syntheseJury(self,
|
||||
mode="singlesheet"): # was str_syntheseJury
|
||||
"""Table(s) du jury
|
||||
mode: singlesheet ou multiplesheet pour export excel
|
||||
"""
|
||||
|
@ -984,9 +1045,9 @@ class JuryPE(object):
|
|||
rows=[],
|
||||
titles={"pas d'étudiants": "pas d'étudiants"},
|
||||
html_sortable=True,
|
||||
xls_sheet_name="but",
|
||||
xls_sheet_name="dut",
|
||||
)
|
||||
sT.add_genTable("but", T)
|
||||
sT.add_genTable("dut", T)
|
||||
return sT
|
||||
|
||||
# Si des étudiants
|
||||
|
@ -1120,7 +1181,8 @@ class JuryPE(object):
|
|||
# **************************************************************************************************************** #
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_cache_etudInfo_d_un_etudiant(self, etudid):
|
||||
def get_cache_etudInfo_d_un_etudiant(self,
|
||||
etudid):
|
||||
"""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
|
||||
"""
|
||||
|
@ -1133,7 +1195,8 @@ class JuryPE(object):
|
|||
# ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_cache_notes_d_un_semestre(self, formsemestre_id: int) -> NotesTableCompat:
|
||||
def get_cache_notes_d_un_semestre(self,
|
||||
formsemestre_id: int) -> NotesTableCompat:
|
||||
"""Charge la table des notes d'un formsemestre"""
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
return res_sem.load_formsemestre_results(formsemestre)
|
||||
|
@ -1141,24 +1204,28 @@ class JuryPE(object):
|
|||
# ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
def get_semestresDUT_d_un_etudiant(self, etudid, semestre_id=None):
|
||||
def get_semestresBUT_d_un_etudiant(self,
|
||||
etudid,
|
||||
semestre_id=None):
|
||||
"""Renvoie la liste des semestres DUT d'un étudiant
|
||||
pour un semestre_id (parmi 1,2,3,4) 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"""
|
||||
etud = self.get_cache_etudInfo_d_un_etudiant(etudid)
|
||||
nbre_semestres = int(JuryPE.AGGREGAT_DIPLOMANT[0]) # 6
|
||||
if semestre_id == None:
|
||||
sesSems = [sem for sem in etud["sems"] if 1 <= sem["semestre_id"] <= 4]
|
||||
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 calcul_anneePromoDUT_d_un_etudiant(self, etudid) -> int:
|
||||
def calcul_anneePromoBUT_d_un_etudiant(self,
|
||||
etudid) -> int:
|
||||
"""Calcule et renvoie la date de diplome prévue pour un étudiant fourni avec son etudid
|
||||
en fonction de ses semestres de scolarisation"""
|
||||
semestres = self.get_semestresDUT_d_un_etudiant(etudid)
|
||||
semestres = self.get_semestresBUT_d_un_etudiant(etudid)
|
||||
if semestres:
|
||||
return max([get_annee_diplome_semestre(sem) for sem in semestres])
|
||||
else:
|
||||
|
@ -1166,9 +1233,10 @@ class JuryPE(object):
|
|||
|
||||
# *********************************************
|
||||
# Fonctions d'affichage pour debug
|
||||
def get_resultat_d_un_etudiant(self, etudid):
|
||||
def get_resultat_d_un_etudiant(self,
|
||||
etudid):
|
||||
chaine = ""
|
||||
for nom_sem in ["S1", "S2", "S3", "S4"]:
|
||||
for nom_sem in JuryPE.TOUS_LES_SEMESTRES:
|
||||
semtagid = self.PARCOURSINFO_DICT[etudid][
|
||||
nom_sem
|
||||
] # le formsemestre_id du semestre taggué de l'étudiant
|
||||
|
@ -1207,27 +1275,37 @@ class JuryPE(object):
|
|||
# ----------------------------------------------------------------------------------------
|
||||
def get_annee_diplome_semestre(sem) -> int:
|
||||
"""Pour un semestre donne, décrit par le biais du dictionnaire sem usuel :
|
||||
sem = {'formestre_id': ..., 'semestre_id': ..., 'annee_debut': ...},
|
||||
à condition qu'il soit un semestre de formation DUT,
|
||||
predit l'annee à laquelle sera remis le diplome DUT des etudiants scolarisés dans le semestre
|
||||
|
||||
sem = {'formestre_id': ..., 'semestre_id': ..., 'annee_debut': ...}
|
||||
|
||||
à condition qu'il soit un semestre de formation BUT,
|
||||
predit l'annee à laquelle sera remis le diplome BUT des etudiants scolarisés dans le semestre
|
||||
(en supposant qu'il n'y ait plus de redoublement) et la renvoie sous la forme d'un int.
|
||||
Hypothese : les semestres de 1ere partie d'annee universitaire (comme des S1 ou des S3) s'etalent
|
||||
sur deux annees civiles - contrairement au semestre de seconde partie d'annee universitaire (comme
|
||||
des S2 ou des S4).
|
||||
|
||||
Les semestres de 1ère partie d'année (S1, S3, S5 ou S4, S6 pour des semestres décalés)
|
||||
s'étalent sur deux années civiles ; contrairement au semestre de seconde partie d'annee universitaire.
|
||||
|
||||
Par exemple :
|
||||
> S4 debutant en 2016 finissant en 2016 => diplome en 2016
|
||||
> S3 debutant en 2015 et finissant en 2016 => diplome en 2016
|
||||
> S3 (decale) debutant en 2015 et finissant en 2015 => diplome en 2016
|
||||
La regle de calcul utilise l'annee_fin du semestre sur le principe suivant :
|
||||
nbreSemRestant = nombre de semestres restant avant diplome
|
||||
nbreAnneeRestant = nombre d'annees restant avant diplome
|
||||
1 - delta = 0 si semestre de 1ere partie d'annee / 1 sinon
|
||||
decalage = active ou desactive un increment a prendre en compte en cas de semestre decale
|
||||
* S5 débutant en 2025 finissant en 2026 => diplome en 2026
|
||||
* S3 debutant en 2025 et finissant en 2026 => diplome en 2027
|
||||
* S5 décalé débutant en 2025 et finissant en 2025 => diplome en 2026
|
||||
* S3 decale débutant en 2025 et finissant en 2025 => diplome en 2027
|
||||
|
||||
La règle de calcul utilise l'``annee_fin`` du semestre sur le principe suivant :
|
||||
|
||||
* nbreSemRestant = nombre de semestres restant avant diplome
|
||||
* nbreAnneeRestant = nombre d'annees restant avant diplome
|
||||
* 1 - delta = 0 si semestre de 1ere partie d'annee / 1 sinon
|
||||
* decalage = active ou désactive un increment à prendre en compte en cas de semestre decale
|
||||
|
||||
Args:
|
||||
sem: Le semestre
|
||||
"""
|
||||
nbre_semestres = int(JuryPE.AGGREGAT_DIPLOMANT[0]) # 6
|
||||
if (
|
||||
1 <= sem["semestre_id"] <= 4
|
||||
): # Si le semestre est un semestre DUT => problème si formation DUT en 1 an ??
|
||||
nbreSemRestant = 4 - sem["semestre_id"]
|
||||
1 <= sem["semestre_id"] <= nbre_semestres
|
||||
): # Si le semestre est un semestre BUT => problème si formation BUT en 1 an ??
|
||||
nbreSemRestant = nbre_semestres - sem["semestre_id"]
|
||||
nbreAnRestant = nbreSemRestant // 2
|
||||
delta = int(sem["annee_fin"]) - int(sem["annee_debut"])
|
||||
decalage = nbreSemRestant % 2 # 0 si S4, 1 si S3, 0 si S2, 1 si S1
|
||||
|
@ -1239,7 +1317,8 @@ def get_annee_diplome_semestre(sem) -> int:
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
def get_cosemestres_diplomants(semBase, avec_meme_formation=False):
|
||||
def get_cosemestres_diplomants(semBase,
|
||||
avec_meme_formation=False):
|
||||
"""Partant d'un semestre de Base = {'formsemestre_id': ..., 'semestre_id': ..., 'annee_debut': ...},
|
||||
renvoie la liste de tous ses co-semestres (lui-meme inclus)
|
||||
Par co-semestre, s'entend les semestres :
|
||||
|
|
|
@ -78,7 +78,9 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||
# -----------------------------------------------------------------------------
|
||||
# Fonctions d'initialisation
|
||||
# -----------------------------------------------------------------------------
|
||||
def __init__(self, notetable, sem): # Initialisation sur la base d'une notetable
|
||||
def __init__(self,
|
||||
notetable,
|
||||
sem): # Initialisation sur la base d'une notetable
|
||||
"""Instantiation d'un objet SemestreTag à partir d'un tableau de note
|
||||
et des informations sur le semestre pour le dater
|
||||
"""
|
||||
|
@ -194,7 +196,9 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||
return tagdict
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def comp_MoyennesTag(self, tag, force=False) -> list:
|
||||
def comp_MoyennesTag(self,
|
||||
tag,
|
||||
force=False) -> list:
|
||||
"""Calcule et renvoie les "moyennes" de tous les étudiants du SemTag
|
||||
(non défaillants) à un tag donné, en prenant en compte
|
||||
tous les modimpl_id concerné par le tag, leur coeff et leur pondération.
|
||||
|
@ -232,7 +236,10 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||
]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_noteEtCoeff_modimpl(self, modimpl_id, etudid, profondeur=2):
|
||||
def get_noteEtCoeff_modimpl(self,
|
||||
modimpl_id,
|
||||
etudid,
|
||||
profondeur=2):
|
||||
"""Renvoie un couple donnant la note et le coeff normalisé d'un étudiant à un module d'id modimpl_id.
|
||||
La note et le coeff sont extraits :
|
||||
1) soit des données du semestre en normalisant le coefficient par rapport à la somme des coefficients des modules du semestre,
|
||||
|
@ -313,14 +320,17 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||
return (note, coeff_norm)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_ue_capitalisees(self, etudid) -> list[dict]:
|
||||
def get_ue_capitalisees(self,
|
||||
etudid) -> list[dict]:
|
||||
"""Renvoie la liste des capitalisation effectivement capitalisées par un étudiant"""
|
||||
if etudid in self.nt.validations.ue_capitalisees.index:
|
||||
return self.nt.validations.ue_capitalisees.loc[[etudid]].to_dict("records")
|
||||
return []
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_listesNotesEtCoeffsTagEtudiant(self, tag, etudid):
|
||||
def get_listesNotesEtCoeffsTagEtudiant(self,
|
||||
tag,
|
||||
etudid):
|
||||
"""Renvoie un triplet (notes, coeffs_norm, ponderations) où notes, coeff_norm et ponderation désignent trois listes
|
||||
donnant -pour un tag donné- les note, coeff et ponderation de chaque modimpl à prendre en compte dans
|
||||
le calcul de la moyenne du tag.
|
||||
|
@ -343,7 +353,10 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||
# -----------------------------------------------------------------------------
|
||||
# Fonctions d'affichage (et d'export csv) des données du semestre en mode debug
|
||||
# -----------------------------------------------------------------------------
|
||||
def str_detail_resultat_d_un_tag(self, tag, etudid=None, delim=";"):
|
||||
def str_detail_resultat_d_un_tag(self,
|
||||
tag,
|
||||
etudid=None,
|
||||
delim=";"):
|
||||
"""Renvoie une chaine de caractère décrivant les résultats d'étudiants à un tag :
|
||||
rappelle les notes obtenues dans les modules à prendre en compte, les moyennes et les rangs calculés.
|
||||
Si etudid=None, tous les étudiants inscrits dans le semestre sont pris en compte. Sinon seuls les étudiants indiqués sont affichés.
|
||||
|
@ -463,7 +476,8 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||
|
||||
|
||||
# *********************************************
|
||||
def comp_coeff_pond(coeffs, ponderations):
|
||||
def comp_coeff_pond(coeffs,
|
||||
ponderations):
|
||||
"""
|
||||
Applique une ponderation (indiquée dans la liste ponderations) à une liste de coefficients :
|
||||
ex: coeff = [2, 3, 1, None], ponderation = [1, 2, 0, 1] => [2*1, 3*2, 1*0, None]
|
||||
|
@ -499,7 +513,9 @@ def get_moduleimpl(modimpl_id) -> dict:
|
|||
|
||||
|
||||
# **********************************************
|
||||
def get_moy_ue_from_nt(nt, etudid, modimpl_id) -> float:
|
||||
def get_moy_ue_from_nt(nt,
|
||||
etudid,
|
||||
modimpl_id) -> float:
|
||||
"""Renvoie la moyenne de l'UE d'un etudid dans laquelle se trouve
|
||||
le module de modimpl_id
|
||||
"""
|
||||
|
|
|
@ -51,15 +51,19 @@ class SetTag(pe_tagtable.TableTag):
|
|||
"""
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def __init__(self, nom_combinaison, parcours):
|
||||
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 set_Etudiants(self,
|
||||
etudiants: list[dict],
|
||||
juryPEDict,
|
||||
etudInfoDict,
|
||||
nom_sem_final=None):
|
||||
"""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:
|
||||
|
@ -94,7 +98,8 @@ class SetTag(pe_tagtable.TableTag):
|
|||
)
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
def set_SemTagDict(self, SemTagDict):
|
||||
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:
|
||||
|
@ -152,7 +157,9 @@ class SetTag(pe_tagtable.TableTag):
|
|||
self.tagdict[tag][mod] = semtag.tagdict[tag][mod]
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_NotesEtCoeffsSetTagEtudiant(self, tag, etudid):
|
||||
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 = [
|
||||
|
@ -172,7 +179,9 @@ class SetTag(pe_tagtable.TableTag):
|
|||
return (notes, coeffs)
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def comp_MoyennesSetTag(self, tag, force=False):
|
||||
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.
|
||||
|
@ -203,19 +212,25 @@ class SetTag(pe_tagtable.TableTag):
|
|||
|
||||
|
||||
class SetTagInterClasse(pe_tagtable.TableTag):
|
||||
"""Récupère les moyennes de SetTag aggrégant un même parcours (par ex un ['S1', 'S2'] n'ayant pas fini au même S2
|
||||
"""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):
|
||||
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):
|
||||
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."""
|
||||
|
@ -237,7 +252,8 @@ class SetTagInterClasse(pe_tagtable.TableTag):
|
|||
)
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
def set_SetTagDict(self, SetTagDict):
|
||||
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
|
||||
|
@ -285,7 +301,9 @@ class SetTagInterClasse(pe_tagtable.TableTag):
|
|||
return sorted(list(set(ensemble)))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_NotesEtCoeffsSetTagEtudiant(self, tag, etudid):
|
||||
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]
|
||||
|
@ -297,7 +315,9 @@ class SetTagInterClasse(pe_tagtable.TableTag):
|
|||
return (note, coeff)
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def get_MoyennesSetTag(self, tag, force=False):
|
||||
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.
|
||||
|
|
|
@ -77,7 +77,9 @@ class TableTag(object):
|
|||
# *****************************************************************************************************************
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_moy_from_resultats(self, tag, etudid):
|
||||
def get_moy_from_resultats(self,
|
||||
tag,
|
||||
etudid):
|
||||
"""Renvoie la moyenne obtenue par un étudiant à un tag donné au regard du format de self.resultats"""
|
||||
return (
|
||||
self.resultats[tag][etudid][0]
|
||||
|
@ -86,7 +88,9 @@ class TableTag(object):
|
|||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_rang_from_resultats(self, tag, etudid):
|
||||
def get_rang_from_resultats(self,
|
||||
tag,
|
||||
etudid):
|
||||
"""Renvoie le rang à un tag d'un étudiant au regard du format de self.resultats"""
|
||||
return (
|
||||
self.rangs[tag][etudid]
|
||||
|
@ -95,7 +99,9 @@ class TableTag(object):
|
|||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_coeff_from_resultats(self, tag, etudid):
|
||||
def get_coeff_from_resultats(self,
|
||||
tag,
|
||||
etudid):
|
||||
"""Renvoie la somme des coeffs de pondération normalisée utilisés dans le calcul de la moyenne à un tag d'un étudiant
|
||||
au regard du format de self.resultats.
|
||||
"""
|
||||
|
@ -117,15 +123,18 @@ class TableTag(object):
|
|||
return len(self.inscrlist)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_moy_from_stats(self, tag):
|
||||
def get_moy_from_stats(self,
|
||||
tag):
|
||||
"""Renvoie la moyenne des notes calculées pour d'un tag donné"""
|
||||
return self.statistiques[tag][0] if tag in self.statistiques else None
|
||||
|
||||
def get_min_from_stats(self, tag):
|
||||
def get_min_from_stats(self,
|
||||
tag):
|
||||
"""Renvoie la plus basse des notes calculées pour d'un tag donné"""
|
||||
return self.statistiques[tag][1] if tag in self.statistiques else None
|
||||
|
||||
def get_max_from_stats(self, tag):
|
||||
def get_max_from_stats(self,
|
||||
tag):
|
||||
"""Renvoie la plus haute des notes calculées pour d'un tag donné"""
|
||||
return self.statistiques[tag][2] if tag in self.statistiques else None
|
||||
|
||||
|
@ -142,7 +151,9 @@ class TableTag(object):
|
|||
"min",
|
||||
)
|
||||
|
||||
def get_resultatsEtud(self, tag, etudid):
|
||||
def get_resultatsEtud(self,
|
||||
tag,
|
||||
etudid):
|
||||
"""Renvoie un tuple (note, coeff, rang, nb_inscrit, moy, min, max) synthétisant les résultats d'un étudiant
|
||||
à un tag donné. None sinon"""
|
||||
return (
|
||||
|
@ -164,7 +175,9 @@ class TableTag(object):
|
|||
# *****************************************************************************************************************
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def add_moyennesTag(self, tag, listMoyEtCoeff) -> bool:
|
||||
def add_moyennesTag(self,
|
||||
tag,
|
||||
listMoyEtCoeff) -> bool:
|
||||
"""
|
||||
Mémorise les moyennes, les coeffs de pondération et les etudid dans resultats
|
||||
avec calcul du rang
|
||||
|
@ -197,7 +210,8 @@ class TableTag(object):
|
|||
# Méthodes dévolues aux calculs de statistiques (min, max, moy) sur chaque moyenne taguée
|
||||
# *****************************************************************************************************************
|
||||
|
||||
def comp_stats_d_un_tag(self, tag):
|
||||
def comp_stats_d_un_tag(self,
|
||||
tag):
|
||||
"""
|
||||
Calcule la moyenne generale, le min, le max pour un tag donné,
|
||||
en ne prenant en compte que les moyennes significatives. Mémorise le resultat dans
|
||||
|
@ -221,7 +235,10 @@ class TableTag(object):
|
|||
# ************************************************************************
|
||||
# Méthodes dévolues aux affichages -> a revoir
|
||||
# ************************************************************************
|
||||
def str_resTag_d_un_etudiant(self, tag, etudid, delim=";"):
|
||||
def str_resTag_d_un_etudiant(self,
|
||||
tag,
|
||||
etudid,
|
||||
delim=";"):
|
||||
"""Renvoie une chaine de caractères (valable pour un csv)
|
||||
décrivant la moyenne et le rang d'un étudiant, pour un tag donné ;
|
||||
"""
|
||||
|
@ -236,14 +253,20 @@ class TableTag(object):
|
|||
)
|
||||
return moystr
|
||||
|
||||
def str_res_d_un_etudiant(self, etudid, delim=";"):
|
||||
def str_res_d_un_etudiant(self,
|
||||
etudid,
|
||||
delim=";"):
|
||||
"""Renvoie sur une ligne les résultats d'un étudiant à tous les tags (par ordre alphabétique)."""
|
||||
return delim.join(
|
||||
[self.str_resTag_d_un_etudiant(tag, etudid) for tag in self.get_all_tags()]
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def str_moytag(cls, moyenne, rang, nbinscrit, delim=";"):
|
||||
def str_moytag(cls,
|
||||
moyenne,
|
||||
rang,
|
||||
nbinscrit,
|
||||
delim=";"):
|
||||
"""Renvoie une chaine de caractères représentant une moyenne (float ou string) et un rang
|
||||
pour différents formats d'affichage : HTML, debug ligne de commande, csv"""
|
||||
moystr = (
|
||||
|
@ -256,7 +279,9 @@ class TableTag(object):
|
|||
str_moytag = classmethod(str_moytag)
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
def str_tagtable(self, delim=";", decimal_sep=","):
|
||||
def str_tagtable(self,
|
||||
delim=";",
|
||||
decimal_sep=","):
|
||||
"""Renvoie une chaine de caractère listant toutes les moyennes, les rangs des étudiants pour tous les tags."""
|
||||
entete = ["etudid", "nom", "prenom"]
|
||||
for tag in self.get_all_tags():
|
||||
|
@ -266,7 +291,7 @@ class TableTag(object):
|
|||
for etudid in self.identdict:
|
||||
descr = delim.join(
|
||||
[
|
||||
etudid,
|
||||
str(etudid),
|
||||
self.identdict[etudid]["nom"],
|
||||
self.identdict[etudid]["prenom"],
|
||||
]
|
||||
|
@ -288,7 +313,9 @@ class TableTag(object):
|
|||
|
||||
|
||||
# *********************************************
|
||||
def moyenne_ponderee_terme_a_terme(notes, coefs=None, force=False):
|
||||
def moyenne_ponderee_terme_a_terme(notes,
|
||||
coefs=None,
|
||||
force=False):
|
||||
"""
|
||||
Calcule la moyenne pondérée d'une liste de notes avec d'éventuels coeffs de pondération.
|
||||
Renvoie le résultat sous forme d'un tuple (moy, somme_coeff)
|
||||
|
|
|
@ -76,7 +76,8 @@ PE_LOCAL_FOOTER_TMPL = REP_LOCAL_AVIS + "local/modeles/un_footer.tex"
|
|||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def print_semestres_description(sems, avec_affichage_debug=False):
|
||||
def print_semestres_description(sems,
|
||||
avec_affichage_debug=False):
|
||||
"""Dediee a l'affichage d'un semestre pour debug du module"""
|
||||
|
||||
def chaine_semestre(sem):
|
||||
|
@ -119,7 +120,6 @@ def calcul_age(born):
|
|||
)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
def remove_accents(input_unicode_str):
|
||||
"""Supprime les accents d'une chaine unicode"""
|
||||
nfkd_form = unicodedata.normalize("NFKD", input_unicode_str)
|
||||
|
@ -166,7 +166,10 @@ def list_directory_filenames(path):
|
|||
return R
|
||||
|
||||
|
||||
def add_local_file_to_zip(zipfile, ziproot, pathname, path_in_zip):
|
||||
def add_local_file_to_zip(zipfile,
|
||||
ziproot,
|
||||
pathname,
|
||||
path_in_zip):
|
||||
"""Read pathname server file and add content to zip under path_in_zip"""
|
||||
rooted_path_in_zip = os.path.join(ziproot, path_in_zip)
|
||||
zipfile.write(filename=pathname, arcname=rooted_path_in_zip)
|
||||
|
@ -174,7 +177,8 @@ def add_local_file_to_zip(zipfile, ziproot, pathname, path_in_zip):
|
|||
# zipfile.writestr(rooted_path_in_zip, data)
|
||||
|
||||
|
||||
def add_refs_to_register(register, directory):
|
||||
def add_refs_to_register(register,
|
||||
directory):
|
||||
"""Ajoute les fichiers trouvés dans directory au registre (dictionaire) sous la forme
|
||||
filename => pathname
|
||||
"""
|
||||
|
@ -184,7 +188,8 @@ def add_refs_to_register(register, directory):
|
|||
register[filename] = pathname
|
||||
|
||||
|
||||
def add_pe_stuff_to_zip(zipfile, ziproot):
|
||||
def add_pe_stuff_to_zip(zipfile,
|
||||
ziproot):
|
||||
"""Add auxiliary files to (already opened) zip
|
||||
Put all local files found under config/doc_poursuites_etudes/local
|
||||
and config/doc_poursuites_etudes/distrib
|
||||
|
|
|
@ -106,39 +106,40 @@ def pe_view_sem_recap(
|
|||
# (chaines unicodes, html non quoté)
|
||||
template_latex = ""
|
||||
# template fourni via le formulaire Web
|
||||
if avis_tmpl_file:
|
||||
try:
|
||||
template_latex = avis_tmpl_file.read().decode("utf-8")
|
||||
except UnicodeDecodeError as e:
|
||||
raise ScoValueError(
|
||||
"Données (template) invalides (caractères non UTF8 ?)"
|
||||
) from e
|
||||
else:
|
||||
# template indiqué dans préférences ScoDoc ?
|
||||
template_latex = pe_avislatex.get_code_latex_from_scodoc_preference(
|
||||
formsemestre_id, champ="pe_avis_latex_tmpl"
|
||||
)
|
||||
if False:
|
||||
if avis_tmpl_file:
|
||||
try:
|
||||
template_latex = avis_tmpl_file.read().decode("utf-8")
|
||||
except UnicodeDecodeError as e:
|
||||
raise ScoValueError(
|
||||
"Données (template) invalides (caractères non UTF8 ?)"
|
||||
) from e
|
||||
else:
|
||||
# template indiqué dans préférences ScoDoc ?
|
||||
template_latex = pe_avislatex.get_code_latex_from_scodoc_preference(
|
||||
formsemestre_id, champ="pe_avis_latex_tmpl"
|
||||
)
|
||||
|
||||
template_latex = template_latex.strip()
|
||||
if not template_latex:
|
||||
# pas de preference pour le template: utilise fichier du serveur
|
||||
template_latex = pe_avislatex.get_templates_from_distrib("avis")
|
||||
template_latex = template_latex.strip()
|
||||
if not template_latex:
|
||||
# pas de preference pour le template: utilise fichier du serveur
|
||||
template_latex = pe_avislatex.get_templates_from_distrib("avis")
|
||||
|
||||
# Footer:
|
||||
footer_latex = ""
|
||||
# template fourni via le formulaire Web
|
||||
if footer_tmpl_file:
|
||||
footer_latex = footer_tmpl_file.read().decode("utf-8")
|
||||
else:
|
||||
footer_latex = pe_avislatex.get_code_latex_from_scodoc_preference(
|
||||
formsemestre_id, champ="pe_avis_latex_footer"
|
||||
)
|
||||
footer_latex = footer_latex.strip()
|
||||
if not footer_latex:
|
||||
# pas de preference pour le footer: utilise fichier du serveur
|
||||
footer_latex = pe_avislatex.get_templates_from_distrib(
|
||||
"footer"
|
||||
) # fallback: footer vides
|
||||
# Footer:
|
||||
footer_latex = ""
|
||||
# template fourni via le formulaire Web
|
||||
if footer_tmpl_file:
|
||||
footer_latex = footer_tmpl_file.read().decode("utf-8")
|
||||
else:
|
||||
footer_latex = pe_avislatex.get_code_latex_from_scodoc_preference(
|
||||
formsemestre_id, champ="pe_avis_latex_footer"
|
||||
)
|
||||
footer_latex = footer_latex.strip()
|
||||
if not footer_latex:
|
||||
# pas de preference pour le footer: utilise fichier du serveur
|
||||
footer_latex = pe_avislatex.get_templates_from_distrib(
|
||||
"footer"
|
||||
) # fallback: footer vides
|
||||
|
||||
tag_annotation_pe = pe_avislatex.get_code_latex_from_scodoc_preference(
|
||||
formsemestre_id, champ="pe_tag_annotation_avis_latex"
|
||||
|
@ -151,27 +152,29 @@ def pe_view_sem_recap(
|
|||
jury.NOM_EXPORT_ZIP + "_annotationsPE" + scu.XLSX_SUFFIX, sT.excel()
|
||||
)
|
||||
|
||||
latex_pages = {} # Dictionnaire de la forme nom_fichier => contenu_latex
|
||||
for etudid in etudids:
|
||||
[nom_fichier, contenu_latex] = pe_avislatex.get_avis_poursuite_par_etudiant(
|
||||
jury,
|
||||
etudid,
|
||||
template_latex,
|
||||
tag_annotation_pe,
|
||||
footer_latex,
|
||||
prefs,
|
||||
if False:
|
||||
latex_pages = {} # Dictionnaire de la forme nom_fichier => contenu_latex
|
||||
for etudid in etudids:
|
||||
[nom_fichier, contenu_latex] = pe_avislatex.get_avis_poursuite_par_etudiant(
|
||||
jury,
|
||||
etudid,
|
||||
template_latex,
|
||||
tag_annotation_pe,
|
||||
footer_latex,
|
||||
prefs,
|
||||
)
|
||||
jury.add_file_to_zip("avis/" + nom_fichier + ".tex", contenu_latex)
|
||||
latex_pages[nom_fichier] = contenu_latex # Sauvegarde dans un dico
|
||||
|
||||
# Nouvelle version : 1 fichier par étudiant avec 1 fichier appelant créée ci-dessous
|
||||
doc_latex = "\n% -----\n".join(
|
||||
["\\include{" + nom + "}" for nom in sorted(latex_pages.keys())]
|
||||
)
|
||||
jury.add_file_to_zip("avis/" + nom_fichier + ".tex", contenu_latex)
|
||||
latex_pages[nom_fichier] = contenu_latex # Sauvegarde dans un dico
|
||||
jury.add_file_to_zip("avis/avis_poursuite.tex", doc_latex)
|
||||
|
||||
# Nouvelle version : 1 fichier par étudiant avec 1 fichier appelant créée ci-dessous
|
||||
doc_latex = "\n% -----\n".join(
|
||||
["\\include{" + nom + "}" for nom in sorted(latex_pages.keys())]
|
||||
)
|
||||
jury.add_file_to_zip("avis/avis_poursuite.tex", doc_latex)
|
||||
# Ajoute image, LaTeX class file(s) and modeles
|
||||
pe_tools.add_pe_stuff_to_zip(jury.zipfile, jury.NOM_EXPORT_ZIP)
|
||||
|
||||
# Ajoute image, LaTeX class file(s) and modeles
|
||||
pe_tools.add_pe_stuff_to_zip(jury.zipfile, jury.NOM_EXPORT_ZIP)
|
||||
data = jury.get_zipped_data()
|
||||
|
||||
return send_file(
|
||||
|
|
Loading…
Reference in New Issue