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-20 16:34:38 +01:00
import app . pe . pe_etudiant
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
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-20 16:34:38 +01:00
from app . scodoc import (
codes_cursus ,
sco_formsemestre_inscriptions ,
) # codes_cursus.NEXT -> sem suivant
2021-06-21 10:17:16 +02:00
from app . scodoc import sco_etud
2024-01-20 16:34:38 +01:00
from app . scodoc import sco_report
2021-06-21 11:22:55 +02:00
from app . scodoc import sco_formsemestre
2021-09-26 10:01:20 +02:00
from app . pe import pe_tagtable
from app . pe import pe_tools
from app . pe import pe_semestretag
from app . pe import pe_settag
2024-01-20 16:34:38 +01:00
from app . pe . pe_etudiant import EtudiantsJuryPE
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
"""
2024-01-20 16:34:38 +01:00
2020-09-26 16:19:37 +02:00
self . semTagDict = (
{ }
) # Les semestres taggués à la base des calculs de moyenne par tag
self . setTagDict = (
{ }
) # dictionnaire récapitulant les semTag impliqués dans le jury de la forme { 'formsemestre_id' : object Semestre_tag
self . promoTagDict = { }
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 " )
2024-01-20 16:34:38 +01:00
" Les informations sur les étudiants édités par le jury PE "
self . etudiants = EtudiantsJuryPE ( ) # Les infos sur les étudiants
2020-09-26 16:19:37 +02:00
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 } "
)
self . etudiants . find_etudiants ( self . diplome , self . formation_id )
""" Calcul des moyennes pour le jury PE """
self . exe_calculs_juryPE ( )
2022-02-11 23:22:07 +01:00
2024-01-20 16:34:38 +01:00
""" Synthèse des éléments du jury PE """
if False :
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 :
self . add_file_to_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
# ------------------------------------------------------------------------------------------------------------------
def add_file_to_zip ( self , filename , data , path = " " ) :
""" Add a file to our zip
All files under NOM_EXPORT_ZIP /
path may specify a subdirectory
"""
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
# **************************************************************************************************************** #
# Lancement des différentes actions permettant le calcul du jury PE
# **************************************************************************************************************** #
2024-01-20 16:34:38 +01:00
def exe_calculs_juryPE ( self ) :
""" Centralise les élements de calcul des moyennes de poursuites
d ' études
"""
""" Création des semestres taggués, de type ' S1 ' , ' S2 ' , ... """
pe_tools . pe_print ( " *** Création des semestres taggués " )
formsemestres = self . etudiants . get_formsemestres_jury (
semestres_recherches = pe_tools . TOUS_LES_SEMESTRES
)
for frmsem_id , formsemestre in formsemestres . items ( ) :
""" Choix d ' un nom pour le semestretag """
nom = " S %d %d %d - %d " % (
formsemestre . semestre_id ,
formsemestre . formsemestre_id ,
formsemestre . date_debut . year ,
formsemestre . date_fin . year ,
)
2020-09-26 16:19:37 +02:00
pe_tools . pe_print (
2024-01-20 16:34:38 +01:00
f " --> Semestre taggué { nom } sur la base de { formsemestre } "
2020-09-26 16:19:37 +02:00
)
2024-01-20 16:34:38 +01:00
self . add_semestretag_in_jury ( nom , frmsem_id )
2020-09-26 16:19:37 +02:00
# Les moyennes sur toute la scolarité
# -----------------------------------
if pe_tools . PE_DEBUG :
pe_tools . pe_print (
" *** Création des moyennes sur différentes combinaisons de semestres et différents groupes d ' étudiant "
)
2024-01-20 16:34:38 +01:00
if False :
self . get_settags_in_jury ( )
if pe_tools . PE_DEBUG :
for settagdict in self . setTagDict . values ( ) : # Export
for settag in settagdict . values ( ) :
filename = self . nom_export_zip + semtag . nom + " .csv "
self . add_file_to_zip (
filename , semtag . str_tagtable ( ) , path = " details_semestres "
)
# self.export_juryPEDict()
2020-09-26 16:19:37 +02:00
# Les interclassements
# --------------------
if pe_tools . PE_DEBUG :
pe_tools . pe_print (
" *** Création des interclassements au sein de la promo sur différentes combinaisons de semestres "
)
2024-01-20 16:34:38 +01:00
if False :
self . get_promotags_in_jury ( )
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
# **************************************************************************************************************** #
# ------------------------------------------------------------------------------------------------------------------
2024-01-20 16:34:38 +01:00
def add_semestretag_in_jury ( self , nom : str , formsemestre_id : int ) :
""" Ajoute (après création si nécessaire) un semtag dans `self.semTag` et
charge également les données des étudiants ( découverts avec ce semestre ) .
2024-01-16 06:19:49 +01:00
Args :
2024-01-20 16:34:38 +01:00
nom : Le nom à donner au SemestrreTag
formsemestre_id : L ' identifiant d ' un FormSemestre
2020-09-26 16:19:37 +02:00
"""
2024-01-20 16:34:38 +01:00
if formsemestre_id in self . semTagDict :
return
2020-09-26 16:19:37 +02:00
2024-01-20 16:34:38 +01:00
""" Créé le SemestreTag et exécute les calculs de moyennes """
formsemestretag = pe_semestretag . SemestreTag ( nom , formsemestre_id )
2020-09-26 16:19:37 +02:00
2024-01-20 16:34:38 +01:00
self . semTagDict [ formsemestre_id ] = formsemestretag
2020-09-26 16:19:37 +02:00
2024-01-20 16:34:38 +01:00
if pe_tools . PE_DEBUG :
filename = nom . replace ( " " , " _ " ) + " .csv "
pe_tools . pe_print ( f " - Export csv de { filename } " )
self . zipfile . writestr ( filename , formsemestretag . str_tagtable ( ) )
2020-09-26 16:19:37 +02:00
# **************************************************************************************************************** #
# Traitements des parcours impliquées dans le jury
# **************************************************************************************************************** #
# # ----------------------------------------------------------------------------------------------------------------
# def get_antags_in_jury(self, avec_affichage_debug=True ):
# """Construit les settag associés aux années 1A et 2A du jury"""
# lesAnnees = {'1A' : ['S1', 'S2'], '2A' : ['S3', 'S4'] }
# for nom_annee in lesAnnees:
# lesAidDesAnnees = self.get_anneeids_du_jury(annee= nom_annee) # les annee_ids des étudiants du jury
# for aid in lesAidDesAnnees:
# fidSemTagFinal = JuryPE.convert_aid_en_fid( aid )
# lesEtudisDelAnnee = self.semTagDict[ fidSemTagFinal ].get_etudids() # les etudiants sont ceux inscrits dans le semestre final de l'année
# parcoursDesEtudiants = { etudid : self.PARCOURSINFO_DICT[etudid] for etudid in lesEtudisDelAnnee } # les parcours des etudid aka quels semestres sont à prendre en compte
#
# lesFidsDesEtudiants = self.get_formsemestreids_du_jury(lesEtudisDelAnnee, nom_annee) # les formsemestres_id à prendre en compte pour les moyennes
# # Manque-t-il des semtag associés ; si oui, les créé
# pe_tools.pe_print(aid, lesFidsDesEtudiants)
# for fid in lesFidsDesEtudiants:
# self.add_semtags_in_jury(fid, avec_affichage_debug=avec_affichage_debug)
# lesSemTagDesEtudiants = { fid: self.semTagDict[fid] for fid in lesFidsDesEtudiants }
#
# # Tous les semtag nécessaires pour ses étudiants avec ajout éventuel s'ils n'ont pas été chargés
# pe_tools.pe_print(" -> Création de l'année tagguée " + str( aid ))
# #settag_id, short_name, listeEtudId, groupe, listeSemAAggreger, ParcoursEtudDict, SemTagDict, with_comp_moy=True)
# self.anTagDict[ aid ] = pe_settag.SetTag( aid, "Annee " + self.semTagDict[fidSemTagFinal].short_name, \
# lesEtudisDelAnnee, 'groupe', lesAnnees[ nom_annee ], parcoursDesEtudiants, lesSemTagDesEtudiants )
# self.anTagDict[ aid ].comp_data_settag() # calcul les moyennes
# **************************************************************************************************************** #
# Traitements des moyennes sur différentes combinaisons de parcours 1A, 2A, 3S et 4S,
# impliquées dans le jury
# **************************************************************************************************************** #
def get_settags_in_jury ( self ) :
""" Calcule les moyennes sur la totalité du parcours (S1 jusqu ' à S3 ou S4)
2023-12-31 23:04:06 +01:00
en classant les étudiants au sein du semestre final du parcours ( même S3 , même S4 , . . . )
"""
2020-09-26 16:19:37 +02:00
# Par groupe :
# combinaisons = { 'S1' : ['S1'], 'S2' : ['S2'], 'S3' : ['S3'], 'S4' : ['S4'], \
# '1A' : ['S1', 'S2'], '2A' : ['S3', 'S4'],
# '3S' : ['S1', 'S2', 'S3'], '4S' : ['S1', 'S2', 'S3', 'S4'] }
# ---> sur 2 parcours DUT (cas S3 fini, cas S4 fini)
2024-01-16 06:19:49 +01:00
2024-01-20 16:34:38 +01:00
for i , nom in enumerate ( pe_tools . TOUS_LES_AGGREGATS ) :
parcours = pe_tools . PARCOURS [ nom ] [
2020-09-26 16:19:37 +02:00
" aggregat "
] # La liste des noms de semestres (S1, S2, ...) impliqués dans l'aggrégat
# Recherche des parcours possibles par le biais de leur Fid final
fids_finaux = self . get_formsemestreids_du_jury (
2024-01-20 16:34:38 +01:00
self . etudiants . get_etudids ( self . diplome ) , nom
2020-09-26 16:19:37 +02:00
) # les formsemestre_ids validant finaux des étudiants du jury
if len ( fids_finaux ) > 0 : # S'il existe des parcours validant
2024-01-20 16:34:38 +01:00
pe_tools . pe_print ( " %d ) Fusion %s avec " % ( i + 1 , nom ) )
2020-09-26 16:19:37 +02:00
if nom not in self . setTagDict :
self . setTagDict [ nom ] = { }
for fid in fids_finaux :
2024-01-20 16:34:38 +01:00
pe_tools . pe_print ( " - semestre final %s " % ( fid ) )
2020-09-26 16:19:37 +02:00
settag = pe_settag . SetTag (
nom , parcours = parcours
) # Le set tag fusionnant les données
etudiants = self . semTagDict [
fid
] . get_etudids ( ) # Les étudiants du sem final
# ajoute les étudiants au semestre
settag . set_Etudiants (
etudiants ,
2024-01-20 16:34:38 +01:00
self . etudiants . cursus ,
self . etudiants . identites ,
2020-09-26 16:19:37 +02:00
nom_sem_final = self . semTagDict [ fid ] . nom ,
)
# manque-t-il des semestres ? Si oui, les ajoute au jurype puis au settag
for ffid in settag . get_Fids_in_settag ( ) :
if pe_tools . PE_DEBUG and pe_tools . PE_DEBUG > = 1 :
pe_tools . pe_print (
2022-04-20 12:23:43 +02:00
" -> ajout du semestre tagué %s " % ( ffid )
2020-09-26 16:19:37 +02:00
)
2024-01-20 16:34:38 +01:00
self . add_semestretag_in_jury ( ffid )
2020-09-26 16:19:37 +02:00
settag . set_SemTagDict (
self . semTagDict
) # ajoute les semestres au settag
settag . comp_data_settag ( ) # Calcul les moyennes, les rangs, ..
self . setTagDict [ nom ] [ fid ] = settag # Mémorise le résultat
else :
2024-01-20 16:34:38 +01:00
pe_tools . pe_print ( " %d ) Pas de fusion %s possible " % ( i + 1 , nom ) )
2020-09-26 16:19:37 +02:00
def get_promotags_in_jury ( self ) :
""" Calcule les aggrégats en interclassant les étudiants du jury (les moyennes ont déjà été calculées en amont) """
2024-01-20 16:34:38 +01:00
lesEtudids = self . etudiants . get_etudids ( self . diplome )
2020-09-26 16:19:37 +02:00
2024-01-20 16:34:38 +01:00
for i , nom in enumerate ( pe_tools . PARCOURS . keys ( ) ) :
2020-09-26 16:19:37 +02:00
settag = pe_settag . SetTagInterClasse ( nom , diplome = self . diplome )
nbreEtudInscrits = settag . set_Etudiants (
2024-01-20 16:34:38 +01:00
lesEtudids , self . etudiants . cursus , self . etudiants . identites
2020-09-26 16:19:37 +02:00
)
if nbreEtudInscrits > 0 :
if pe_tools . PE_DEBUG :
pe_tools . pe_print (
2022-04-20 12:23:43 +02:00
" %d ) %s avec interclassement sur la promo " % ( i + 1 , nom )
2020-09-26 16:19:37 +02:00
)
2024-01-20 16:34:38 +01:00
if nom in pe_tools . TOUS_LES_SEMESTRES :
2020-09-26 16:19:37 +02:00
settag . set_SetTagDict ( self . semTagDict )
else : # cas des aggrégats
settag . set_SetTagDict ( self . setTagDict [ nom ] )
settag . comp_data_settag ( )
self . promoTagDict [ nom ] = settag
else :
2024-01-20 16:34:38 +01:00
pe_tools . pe_print (
" %d ) Pas d ' interclassement %s sur la promo faute de notes "
% ( i + 1 , nom )
)
2020-09-26 16:19:37 +02:00
# **************************************************************************************************************** #
# Méthodes pour la synthèse du juryPE
# *****************************************************************************************************************
def synthetise_juryPE ( self ) :
""" Synthétise tous les résultats du jury PE dans un dictionnaire """
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 :
tagtable = self . semTagDict [ self . etudiants . cursus [ etudid ] [ nom ] ]
2020-09-26 16:19:37 +02:00
else :
tagtable = self . setTagDict [ 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-20 16:34:38 +01:00
sems = pe_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 = (
self . semTagDict [ donnees [ nom_sem ] ] . nom
if donnees [ nom_sem ] in self . semTagDict
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
semtag = self . semTagDict [ 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 " "