forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -98,7 +98,7 @@ class EtudiantsJuryPE:
|
|||||||
pe_tools.pe_print("3) Analyse des parcours individuels des étudiants")
|
pe_tools.pe_print("3) Analyse des parcours individuels des étudiants")
|
||||||
|
|
||||||
no_etud = 0
|
no_etud = 0
|
||||||
for (no_etud, etudid) in enumerate(self.etudiants_ids):
|
for no_etud, etudid in enumerate(self.etudiants_ids):
|
||||||
self.add_etudid(etudid, cosemestres)
|
self.add_etudid(etudid, cosemestres)
|
||||||
if (no_etud + 1) % 10 == 0:
|
if (no_etud + 1) % 10 == 0:
|
||||||
pe_tools.pe_print((no_etud + 1), " ", end="")
|
pe_tools.pe_print((no_etud + 1), " ", end="")
|
||||||
@ -115,15 +115,27 @@ class EtudiantsJuryPE:
|
|||||||
self.formsemestres_jury_ids = self.get_formsemestres_jury()
|
self.formsemestres_jury_ids = self.get_formsemestres_jury()
|
||||||
|
|
||||||
# Synthèse
|
# Synthèse
|
||||||
pe_tools.pe_print(f" => {len(self.etudiants_jury_ids)} étudiants à diplômer en {annee_diplome}")
|
pe_tools.pe_print(
|
||||||
|
f" => {len(self.etudiants_jury_ids)} étudiants à diplômer en {annee_diplome}"
|
||||||
|
)
|
||||||
nbre_abandons = len(self.etudiants_ids) - len(self.etudiants_ids)
|
nbre_abandons = len(self.etudiants_ids) - len(self.etudiants_ids)
|
||||||
pe_tools.pe_print(f" => {nbre_abandons} étudiants éliminer pour abandon")
|
pe_tools.pe_print(f" => {nbre_abandons} étudiants éliminer pour abandon")
|
||||||
pe_tools.pe_print(f" => quelques étudiants futurs diplômés : " + ", ".join([str(etudid) for etudid in list(self.etudiants_jury_ids)[:10]]))
|
pe_tools.pe_print(
|
||||||
|
f" => quelques étudiants futurs diplômés : "
|
||||||
|
+ ", ".join([str(etudid) for etudid in list(self.etudiants_jury_ids)[:10]])
|
||||||
|
)
|
||||||
|
pe_tools.pe_print(
|
||||||
|
f" => semestres dont il faut calculer les moyennes : "
|
||||||
|
+ ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)])
|
||||||
|
)
|
||||||
|
|
||||||
def get_etudids(self, annee_diplome: int, ordre="aucun") -> list:
|
def get_etudids(self, annee_diplome: int = None, ordre="aucun") -> list:
|
||||||
"""Liste des etudid des étudiants qui vont être à traiter au jury PE pour
|
"""Liste des etudid des étudiants qui vont être à traiter au jury PE pour
|
||||||
l'année de diplômation donnée et n'ayant ni été réorienté, ni abandonné.
|
l'année de diplômation donnée et n'ayant ni été réorienté, ni abandonné.
|
||||||
|
|
||||||
|
Si l'année de diplômation n'est pas précisée (None), inclus les étudiants réorientés
|
||||||
|
ou ayant abandonné.
|
||||||
|
|
||||||
Si l'``ordre`` est précisé, trie la liste par ordre alphabétique de etat_civil
|
Si l'``ordre`` est précisé, trie la liste par ordre alphabétique de etat_civil
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -135,11 +147,17 @@ class EtudiantsJuryPE:
|
|||||||
|
|
||||||
Note: ex JuryPE.get_etudids_du_jury()
|
Note: ex JuryPE.get_etudids_du_jury()
|
||||||
"""
|
"""
|
||||||
|
if annee_diplome:
|
||||||
etudids = [
|
etudids = [
|
||||||
etudid
|
etudid
|
||||||
for (etudid, donnees) in self.cursus.items()
|
for (etudid, donnees) in self.cursus.items()
|
||||||
if donnees["diplome"] == annee_diplome and not donnees["abandon"]
|
if donnees["diplome"] == annee_diplome and not donnees["abandon"]
|
||||||
]
|
]
|
||||||
|
else:
|
||||||
|
etudids = [
|
||||||
|
etudid
|
||||||
|
for (etudid, donnees) in self.cursus.items()
|
||||||
|
]
|
||||||
if ordre == "alphabetique": # Tri alphabétique
|
if ordre == "alphabetique": # Tri alphabétique
|
||||||
etudidsAvecNom = [
|
etudidsAvecNom = [
|
||||||
(etudid, etud["etat_civil"])
|
(etudid, etud["etat_civil"])
|
||||||
@ -150,6 +168,24 @@ class EtudiantsJuryPE:
|
|||||||
etudids = [etud[0] for etud in etudidsAvecNomTrie]
|
etudids = [etud[0] for etud in etudidsAvecNomTrie]
|
||||||
return etudids
|
return etudids
|
||||||
|
|
||||||
|
def get_etudiants(self, annee_diplome: int = None) -> dict[Identite]:
|
||||||
|
"""Identités des étudiants (sous forme d'un dictionnaire `{etudid: Identite(etudid)}`
|
||||||
|
qui vont être à traiter au jury PE pour
|
||||||
|
l'année de diplômation donnée et n'ayant ni été réorienté, ni abandonné.
|
||||||
|
|
||||||
|
Si l'année de diplômation n'est pas précisée (None), inclus les étudiants réorientés
|
||||||
|
ou ayant abandonné.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
annee_diplome: Année de diplomation visée pour le jury
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Un dictionnaire `{etudid: Identite(etudid)}`
|
||||||
|
"""
|
||||||
|
etudids = self.get_etudids(annee_diplome=annee_diplome)
|
||||||
|
etudiants = {etudid: self.identites[etudids] for etudid in etudids}
|
||||||
|
return etudiants
|
||||||
|
|
||||||
def add_etudid(self, etudid: int, cosemestres):
|
def add_etudid(self, etudid: int, cosemestres):
|
||||||
"""Ajoute un étudiant à ceux qui devront être traités pendant le jury pouvant être :
|
"""Ajoute un étudiant à ceux qui devront être traités pendant le jury pouvant être :
|
||||||
|
|
||||||
@ -173,35 +209,37 @@ class EtudiantsJuryPE:
|
|||||||
Note: ex JuryPE.add_etudid_to_jury()
|
Note: ex JuryPE.add_etudid_to_jury()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
"""L'identité de l'étudiant"""
|
"""L'identité de l'étudiant"""
|
||||||
identite = Identite.get_etud(etudid)
|
identite = Identite.get_etud(etudid)
|
||||||
self.identites[etudid] = identite
|
self.identites[etudid] = identite
|
||||||
|
|
||||||
"""Le cursus global de l'étudiant"""
|
"""Le cursus global de l'étudiant (restreint aux semestres APC)"""
|
||||||
semestres_etudiant = {
|
semestres_etudiant = {
|
||||||
frmsem.formsemestre_id: frmsem for frmsem in identite.get_formsemestres()
|
frmsem.formsemestre_id: frmsem
|
||||||
|
for frmsem in identite.get_formsemestres()
|
||||||
|
if frmsem.formation.is_apc()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cursus[etudid] = {
|
self.cursus[etudid] = {
|
||||||
"etudid": etudid, # les infos sur l'étudiant
|
"etudid": etudid, # les infos sur l'étudiant
|
||||||
"etat_civil": identite.etat_civil, # Ajout à la table jury
|
"etat_civil": identite.etat_civil, # Ajout à la table jury
|
||||||
"diplome": annee_diplome(identite), # Le date prévisionnelle de son diplôme
|
"diplome": annee_diplome(identite), # Le date prévisionnelle de son diplôme
|
||||||
"formsemestres": semestres_etudiant # les semestres de l'étudiant
|
"formsemestres": semestres_etudiant, # les semestres de l'étudiant
|
||||||
}
|
}
|
||||||
|
|
||||||
""" Est-il réorienté / démissionnaire ou a-t-il arrêté volontairement sa formation ?"""
|
""" Est-il réorienté / démissionnaire ou a-t-il arrêté volontairement sa formation ?"""
|
||||||
self.cursus[etudid]["abandon"] = arret_de_formation(
|
self.cursus[etudid]["abandon"] = arret_de_formation(identite, cosemestres)
|
||||||
identite, cosemestres
|
|
||||||
)
|
|
||||||
|
|
||||||
"""Tri des semestres par n° de semestre"""
|
"""Tri des semestres par n° de semestre"""
|
||||||
for nom_sem in pe_tools.TOUS_LES_SEMESTRES:
|
for nom_sem in pe_tools.TOUS_LES_SEMESTRES:
|
||||||
numero_sem = int(nom_sem[1]) + 1
|
i = int(nom_sem[1]) + 1 # le n° du semestre
|
||||||
self.cursus[etudid][nom_sem] = {fid: semestres_etudiant[fid]
|
semestres_i = {
|
||||||
|
fid: semestres_etudiant[fid]
|
||||||
for fid in semestres_etudiant
|
for fid in semestres_etudiant
|
||||||
if semestres_etudiant[fid].semestre_id == numero_sem}
|
if semestres_etudiant[fid].semestre_id == i
|
||||||
|
} # les semestres de n°i de l'étudiant
|
||||||
|
dernier_semestre_i = get_dernier_semestre(semestres_i)
|
||||||
|
self.cursus[etudid][nom_sem] = dernier_semestre_i
|
||||||
|
|
||||||
"""Tri des semestres par aggrégat"""
|
"""Tri des semestres par aggrégat"""
|
||||||
for parcours in pe_tools.TOUS_LES_AGGREGATS:
|
for parcours in pe_tools.TOUS_LES_AGGREGATS:
|
||||||
@ -210,7 +248,9 @@ class EtudiantsJuryPE:
|
|||||||
|
|
||||||
self.cursus[etudid][parcours] = {}
|
self.cursus[etudid][parcours] = {}
|
||||||
for nom_sem in noms_semestre_de_aggregat:
|
for nom_sem in noms_semestre_de_aggregat:
|
||||||
self.cursus[etudid][parcours] = self.cursus[etudid][parcours] | self.cursus[etudid][nom_sem]
|
self.cursus[etudid][parcours] = (
|
||||||
|
self.cursus[etudid][parcours] | self.cursus[etudid][nom_sem]
|
||||||
|
)
|
||||||
|
|
||||||
if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2:
|
if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2:
|
||||||
pe_tools.pe_print(
|
pe_tools.pe_print(
|
||||||
@ -218,20 +258,64 @@ class EtudiantsJuryPE:
|
|||||||
end="",
|
end="",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_formsemestres_jury(self, semestres_recherches=None):
|
||||||
def get_formsemestres_jury(self):
|
|
||||||
"""Ayant connaissance des étudiants dont il faut calculer les moyennes pour
|
"""Ayant connaissance des étudiants dont il faut calculer les moyennes pour
|
||||||
le jury PE (attribut `self.etudiant_ids), renvoie l'ensemble des formsemestres
|
le jury PE (attribut `self.etudiant_ids) et de leur cursus,
|
||||||
de leur cursus, dont il faudra calculer la moyenne.
|
renvoie un dictionnaire `{fid: FormSemestre(fid)}`
|
||||||
|
contenant l'ensemble des formsemestres de leur cursus, dont il faudra calculer
|
||||||
|
la moyenne. Les formsemestres sont limités à ceux indiqués dans ``semestres_recherches``.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
semestres_recherches: Une liste ou une chaine de caractères parmi :
|
||||||
|
|
||||||
|
* None : pour obtenir tous les formsemestres du jury
|
||||||
|
* 'Si' : pour obtenir les semestres de n° i (par ex. 'S1')
|
||||||
|
* 'iA' : pour obtenir les semestres de l'année i (par ex. '1A' donne ['S1, 'S2'])
|
||||||
|
* '3S', '4S' : pour obtenir les combinaisons de semestres définies par les aggrégats
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Un ensemble de formsemestres
|
Un dictionnaire de la forme {fid: FormSemestre(fid)}
|
||||||
|
|
||||||
|
Remarque:
|
||||||
|
Une liste de la forme `[ 'Si', 'iA' , ... ]` (combinant les formats précédents) est possible.
|
||||||
"""
|
"""
|
||||||
formsemestres = {}
|
if semestres_recherches is None:
|
||||||
|
"""Appel récursif pour obtenir tous les semestres (validants)"""
|
||||||
|
semestres = self.get_formsemestres_jury(pe_tools.AGGREGAT_DIPLOMANT)
|
||||||
|
return semestres
|
||||||
|
elif isinstance(semestres_recherches, list):
|
||||||
|
"""Appel récursif sur tous les éléments de la liste"""
|
||||||
|
semestres = {}
|
||||||
|
for elmt in semestres_recherches:
|
||||||
|
semestres_elmt = self.get_formsemestres_jury(elmt)
|
||||||
|
semestres = semestres | semestres_elmt
|
||||||
|
return semestres
|
||||||
|
elif (
|
||||||
|
isinstance(semestres_recherches, str)
|
||||||
|
and semestres_recherches in pe_tools.TOUS_LES_AGGREGATS
|
||||||
|
):
|
||||||
|
"""Cas d'un aggrégat avec appel récursif sur toutes les entrées de l'aggrégat"""
|
||||||
|
semestres = self.get_formsemestres_jury(
|
||||||
|
pe_tools.PARCOURS[semestres_recherches]["aggregat"]
|
||||||
|
)
|
||||||
|
return semestres
|
||||||
|
elif (
|
||||||
|
isinstance(semestres_recherches, str)
|
||||||
|
and semestres_recherches in pe_tools.TOUS_LES_SEMESTRES
|
||||||
|
):
|
||||||
|
"""semestres_recherches est un nom de semestre de type S1,
|
||||||
|
pour une recherche parmi les étudiants à prendre en compte
|
||||||
|
dans le jury (diplômé et redoublants non diplômé)
|
||||||
|
"""
|
||||||
|
nom_sem = semestres_recherches
|
||||||
|
semestres = {}
|
||||||
for etudid in self.etudiants_ids:
|
for etudid in self.etudiants_ids:
|
||||||
formsem_etudid = set(self.cursus[etudid].keys())
|
semestres = semestres | self.cursus[etudid][nom_sem]
|
||||||
formsemestres = formsemestres | formsem_etudid
|
return semestres
|
||||||
return formsemestres
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"Probleme de paramètres d'appel dans get_formsemestreids_du_jury"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_etudiants_dans_semestres(semestres: dict[FormSemestre]) -> set:
|
def get_etudiants_dans_semestres(semestres: dict[FormSemestre]) -> set:
|
||||||
@ -249,7 +333,7 @@ def get_etudiants_dans_semestres(semestres: dict[FormSemestre]) -> set:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
etudiants_ids = set()
|
etudiants_ids = set()
|
||||||
for (fid, sem) in semestres.items(): # pour chacun des semestres de la liste
|
for fid, sem in semestres.items(): # pour chacun des semestres de la liste
|
||||||
etudiants_du_sem = {ins.etudid for ins in sem.inscriptions}
|
etudiants_du_sem = {ins.etudid for ins in sem.inscriptions}
|
||||||
|
|
||||||
pe_print(f" --> {sem} : {len(etudiants_du_sem)} etudiants")
|
pe_print(f" --> {sem} : {len(etudiants_du_sem)} etudiants")
|
||||||
@ -361,3 +445,28 @@ def arret_de_formation(identite: Identite, cosemestres: list[FormSemestre]) -> b
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_dernier_semestre(semestres: dict[FormSemestre]):
|
||||||
|
"""Renvoie le dernier semestre en date d'un dictionnaire
|
||||||
|
de semestres de la forme {fid: FormSemestre(fid)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
semestres: Un dictionnaire de semestres
|
||||||
|
|
||||||
|
Return:
|
||||||
|
Un dictionnaire {fid: FormSemestre(fid)} contenant le semestre le plus récent
|
||||||
|
"""
|
||||||
|
if semestres:
|
||||||
|
fid_dernier_semestre = list(semestres.keys())[0]
|
||||||
|
dernier_semestre = {fid_dernier_semestre: semestres[fid_dernier_semestre]}
|
||||||
|
for fid in semestres:
|
||||||
|
if (
|
||||||
|
semestres[fid].date_fin
|
||||||
|
> dernier_semestre[fid_dernier_semestre].date_fin
|
||||||
|
):
|
||||||
|
dernier_semestre = {fid: semestres[fid]}
|
||||||
|
fid_dernier_semestre = fid
|
||||||
|
return dernier_semestre
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -37,110 +37,100 @@ Created on Fri Sep 9 09:15:05 2016
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem, inscr_mod, moy_ue, moy_sem
|
||||||
|
from app.comp.res_common import ResultatsSemestre
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import FormSemestre
|
from app.comp.res_sem import load_formsemestre_results
|
||||||
|
from app.models import FormSemestre, Identite, DispenseUE
|
||||||
from app.models.moduleimpls import ModuleImpl
|
from app.models.moduleimpls import ModuleImpl
|
||||||
from app.pe import pe_tagtable
|
from app.pe import pe_tagtable
|
||||||
|
from app.pe import pe_tools
|
||||||
|
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus, sco_preferences
|
||||||
from app.scodoc import sco_tag_module
|
from app.scodoc import sco_tag_module
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
from app.scodoc.codes_cursus import UE_SPORT
|
||||||
|
|
||||||
|
|
||||||
class SemestreTag(pe_tagtable.TableTag):
|
class SemestreTag(pe_tagtable.TableTag):
|
||||||
"""Un SemestreTag représente un tableau de notes (basé sur notesTable)
|
"""Un SemestreTag représente les résultats des étudiants à un semestre, en donnant
|
||||||
modélisant les résultats des étudiants sous forme de moyennes par tag.
|
accès aux moyennes par tag.
|
||||||
|
Il s'appuie principalement sur FormSemestre et sur ResultatsSemestreBUT.
|
||||||
Attributs récupérés via des NotesTables :
|
|
||||||
- nt: le tableau de notes du semestre considéré
|
|
||||||
- nt.inscrlist: étudiants inscrits à ce semestre, par ordre alphabétique (avec demissions)
|
|
||||||
- nt.identdict: { etudid : ident }
|
|
||||||
- liste des moduleimpl { ... 'module_id', ...}
|
|
||||||
|
|
||||||
Attributs supplémentaires :
|
|
||||||
- inscrlist/identdict: étudiants inscrits hors démissionnaires ou défaillants
|
|
||||||
- _tagdict : Dictionnaire résumant les tags et les modules du semestre auxquels ils sont liés
|
|
||||||
|
|
||||||
|
|
||||||
Attributs hérités de TableTag :
|
|
||||||
- nom :
|
|
||||||
- resultats: {tag: { etudid: (note_moy, somme_coff), ...} , ...}
|
|
||||||
- rang
|
|
||||||
- statistiques
|
|
||||||
|
|
||||||
Redéfinition :
|
|
||||||
- get_etudids() : les etudids des étudiants non défaillants ni démissionnaires
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Fonctions d'initialisation
|
# Fonctions d'initialisation
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
def __init__(self, notetable, sem): # Initialisation sur la base d'une notetable
|
def __init__(self, nom: str, formsemestre_id: int):
|
||||||
"""Instantiation d'un objet SemestreTag à partir d'un tableau de note
|
"""
|
||||||
et des informations sur le semestre pour le dater
|
Args:
|
||||||
|
nom: Nom à donner au SemestreTag
|
||||||
|
formsemestre_id: Identifiant du FormSemestre sur lequel il se base
|
||||||
"""
|
"""
|
||||||
pe_tagtable.TableTag.__init__(
|
pe_tagtable.TableTag.__init__(
|
||||||
self,
|
self,
|
||||||
nom="S%d %s %s-%s"
|
nom=nom
|
||||||
% (
|
|
||||||
sem["semestre_id"],
|
|
||||||
"ENEPS"
|
|
||||||
if "ENEPS" in sem["titre"]
|
|
||||||
else "UFA"
|
|
||||||
if "UFA" in sem["titre"]
|
|
||||||
else "FI",
|
|
||||||
sem["annee_debut"],
|
|
||||||
sem["annee_fin"],
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
"""Le semestre"""
|
||||||
|
self.formsemestre_id = formsemestre_id
|
||||||
|
self.formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||||
|
|
||||||
# Les attributs spécifiques
|
"""Les résultats du semestre"""
|
||||||
self.nt = notetable
|
self.nt = load_formsemestre_results(self.formsemestre)
|
||||||
|
|
||||||
# Les attributs hérités : la liste des étudiants
|
"""Les étudiants"""
|
||||||
self.inscrlist = [
|
self.etuds = self.nt.etuds
|
||||||
etud
|
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
||||||
for etud in self.nt.inscrlist
|
|
||||||
if self.nt.get_etud_etat(etud["etudid"]) == scu.INSCRIT
|
|
||||||
]
|
|
||||||
self.identdict = {
|
|
||||||
etudid: ident
|
|
||||||
for (etudid, ident) in self.nt.identdict.items()
|
|
||||||
if etudid in self.get_etudids()
|
|
||||||
} # Liste des étudiants non démissionnaires et non défaillants
|
|
||||||
|
|
||||||
# Les modules pris en compte dans le calcul des moyennes par tag => ceux des UE standards
|
"""Les notes, les modules implémentés triés, les étudiants, les coeffs,
|
||||||
self.modimpls = [
|
récupérés notamment de py:mod:`res_but`
|
||||||
modimpl
|
"""
|
||||||
for modimpl in self.nt.formsemestre.modimpls_sorted
|
self.sem_cube = self.nt.sem_cube
|
||||||
if modimpl.module.ue.type == codes_cursus.UE_STANDARD
|
self.modimpls_sorted = self.nt.formsemestre.modimpls_sorted
|
||||||
] # la liste des modules (objet modimpl)
|
self.modimpl_coefs_df = self.nt.modimpl_coefs_df
|
||||||
self.somme_coeffs = sum(
|
|
||||||
[
|
|
||||||
modimpl.module.coefficient
|
|
||||||
for modimpl in self.modimpls
|
|
||||||
if modimpl.module.coefficient is not None
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
"""Les inscriptions au module et les dispenses d'UE"""
|
||||||
def comp_data_semtag(self):
|
self.modimpl_inscr_df = self.nt.modimpl_inscr_df
|
||||||
"""Calcule tous les données numériques associées au semtag"""
|
self.ues = self.nt.ues
|
||||||
# Attributs relatifs aux tag pour les modules pris en compte
|
self.ues_inscr_parcours_df = self.nt.load_ues_inscr_parcours()
|
||||||
self.tagdict = (
|
self.dispense_ues = self.nt.dispense_ues
|
||||||
self.do_tagdict()
|
|
||||||
) # Dictionnaire résumant les tags et les données (normalisées) des modules du semestre auxquels ils sont liés
|
|
||||||
|
|
||||||
# Calcul des moyennes de chaque étudiant puis ajoute la moyenne au sens "DUT"
|
"""Les tags"""
|
||||||
for tag in self.tagdict:
|
self.tags = get_synthese_tags_semestre(self.nt.formsemestre)
|
||||||
self.add_moyennesTag(tag, self.comp_MoyennesTag(tag, force=True))
|
|
||||||
self.add_moyennesTag("but", self.get_moyennes_DUT())
|
"""Supprime les tags réservés"""
|
||||||
self.taglist = sorted(
|
for tag in pe_tagtable.TAGS_RESERVES:
|
||||||
list(self.tagdict.keys()) + ["but"]
|
if tag in self.tags:
|
||||||
) # actualise la liste des tags
|
del self.tags[tag]
|
||||||
|
|
||||||
|
"""Calcul des moyennes & les classements de chaque étudiant à chaque tag"""
|
||||||
|
self.moyennes_tags = {}
|
||||||
|
|
||||||
|
for tag in self.tags:
|
||||||
|
pe_tools.pe_print(f" -> Traitement du tag {tag}")
|
||||||
|
moy_gen_tag = self.compute_moyenne_tag(tag)
|
||||||
|
class_gen_tag = moy_sem.comp_ranks_series(moy_gen_tag)[1] # en int
|
||||||
|
self.moyennes_tags[tag] = {
|
||||||
|
"notes": moy_gen_tag,
|
||||||
|
"classements": class_gen_tag,
|
||||||
|
"min": moy_gen_tag.min(),
|
||||||
|
"max": moy_gen_tag.max(),
|
||||||
|
"moy": moy_gen_tag.mean(),
|
||||||
|
"nb_inscrits": len(moy_gen_tag),
|
||||||
|
}
|
||||||
|
|
||||||
|
"""Ajoute les moyennes générales de BUT pour le semestre considéré"""
|
||||||
|
pe_tools.pe_print(f" -> Traitement du tag but")
|
||||||
|
moy_gen_but = self.nt.etud_moy_gen
|
||||||
|
class_gen_but = self.nt.etud_moy_gen_ranks_int
|
||||||
|
self.moyennes_tags["but"] = {
|
||||||
|
"notes": moy_gen_but,
|
||||||
|
"classements": class_gen_but,
|
||||||
|
"min": moy_gen_but.min(),
|
||||||
|
"max": moy_gen_but.max(),
|
||||||
|
"moy": moy_gen_but.mean(),
|
||||||
|
"nb_inscrits": len(moy_gen_but),
|
||||||
|
}
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
def get_etudids(self):
|
def get_etudids(self):
|
||||||
@ -148,89 +138,64 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||||||
return [etud["etudid"] for etud in self.inscrlist]
|
return [etud["etudid"] for etud in self.inscrlist]
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
def do_tagdict(self):
|
def compute_moyenne_tag(self, tag: str) -> list:
|
||||||
"""Parcourt les modimpl du semestre (instance des modules d'un programme) et synthétise leurs données sous la
|
"""Calcule la moyenne des étudiants pour le tag indiqué,
|
||||||
forme d'un dictionnaire reliant les tags saisis dans le programme aux
|
pour ce SemestreTag.
|
||||||
données des modules qui les concernent, à savoir les modimpl_id, les module_id, le code du module, le coeff,
|
|
||||||
la pondération fournie avec le tag (par défaut 1 si non indiquée).
|
|
||||||
{ tagname1 : { modimpl_id1 : { 'module_id' : ..., 'coeff' : ..., 'coeff_norm' : ..., 'ponderation' : ..., 'module_code' : ..., 'ue_xxx' : ...},
|
|
||||||
modimpl_id2 : ....
|
|
||||||
},
|
|
||||||
tagname2 : ...
|
|
||||||
}
|
|
||||||
Renvoie le dictionnaire ainsi construit.
|
|
||||||
|
|
||||||
Rq: choix fait de repérer les modules par rapport à leur modimpl_id (valable uniquement pour un semestre), car
|
Sont pris en compte les modules implémentés associés au tag,
|
||||||
correspond à la majorité des calculs de moyennes pour les étudiants
|
avec leur éventuel coefficient de **repondération**, en utilisant les notes
|
||||||
(seuls ceux qui ont capitalisé des ue auront un régime de calcul différent).
|
chargées pour ce SemestreTag.
|
||||||
"""
|
|
||||||
tagdict = {}
|
|
||||||
|
|
||||||
for modimpl in []: # CB: désactive la recherche des tags -> self.modimpls:
|
|
||||||
modimpl_id = modimpl.id
|
|
||||||
# liste des tags pour le modimpl concerné:
|
|
||||||
tags = sco_tag_module.module_tag_list(modimpl.module.id)
|
|
||||||
|
|
||||||
for (
|
|
||||||
tag
|
|
||||||
) in tags: # tag de la forme "mathématiques", "théorie", "pe:0", "maths:2"
|
|
||||||
[tagname, ponderation] = sco_tag_module.split_tagname_coeff(
|
|
||||||
tag
|
|
||||||
) # extrait un tagname et un éventuel coefficient de pondération (par defaut: 1)
|
|
||||||
# tagname = tagname
|
|
||||||
if tagname not in tagdict: # Ajout d'une clé pour le tag
|
|
||||||
tagdict[tagname] = {}
|
|
||||||
|
|
||||||
# Ajout du modimpl au tagname considéré
|
|
||||||
tagdict[tagname][modimpl_id] = {
|
|
||||||
"module_id": modimpl.module.id, # les données sur le module
|
|
||||||
"coeff": modimpl.module.coefficient, # le coeff du module dans le semestre
|
|
||||||
"ponderation": ponderation, # la pondération demandée pour le tag sur le module
|
|
||||||
"module_code": modimpl.module.code, # le code qui doit se retrouver à l'identique dans des ue capitalisee
|
|
||||||
"ue_id": modimpl.module.ue.id, # les données sur l'ue
|
|
||||||
"ue_code": modimpl.module.ue.ue_code,
|
|
||||||
"ue_acronyme": modimpl.module.ue.acronyme,
|
|
||||||
}
|
|
||||||
return tagdict
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
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.
|
|
||||||
Force ou non le calcul de la moyenne lorsque des notes sont manquantes.
|
Force ou non le calcul de la moyenne lorsque des notes sont manquantes.
|
||||||
|
|
||||||
Renvoie les informations sous la forme d'une liste
|
Renvoie les informations sous la forme d'une liste
|
||||||
[ (moy, somme_coeff_normalise, etudid), ...]
|
[ (moy, somme_coeff_normalise, etudid), ...]
|
||||||
"""
|
"""
|
||||||
lesMoyennes = []
|
|
||||||
for etudid in self.get_etudids():
|
|
||||||
(
|
|
||||||
notes,
|
|
||||||
coeffs_norm,
|
|
||||||
ponderations,
|
|
||||||
) = self.get_listesNotesEtCoeffsTagEtudiant(
|
|
||||||
tag, etudid
|
|
||||||
) # les notes associées au tag
|
|
||||||
coeffs = comp_coeff_pond(
|
|
||||||
coeffs_norm, ponderations
|
|
||||||
) # les coeff pondérés par les tags
|
|
||||||
(moyenne, somme_coeffs) = pe_tagtable.moyenne_ponderee_terme_a_terme(
|
|
||||||
notes, coeffs, force=force
|
|
||||||
)
|
|
||||||
lesMoyennes += [
|
|
||||||
(moyenne, somme_coeffs, etudid)
|
|
||||||
] # Un tuple (pour classement résumant les données)
|
|
||||||
return lesMoyennes
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
"""Adaptation du mask de calcul des moyennes au tag visé"""
|
||||||
def get_moyennes_DUT(self):
|
modimpls_mask = [
|
||||||
"""Lit les moyennes DUT du semestre pour tous les étudiants
|
modimpl.module.ue.type != UE_SPORT
|
||||||
et les renvoie au même format que comp_MoyennesTag"""
|
for modimpl in self.formsemestre.modimpls_sorted
|
||||||
return [
|
|
||||||
(self.nt.etud_moy_gen[etudid], 1.0, etudid) for etudid in self.get_etudids()
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
"""Désactive tous les modules qui ne sont pas pris en compte pour ce tag"""
|
||||||
|
for i, modimpl in enumerate(self.formsemestre.modimpls_sorted):
|
||||||
|
if modimpl.moduleimpl_id not in self.tags[tag]:
|
||||||
|
modimpls_mask[i] = False
|
||||||
|
|
||||||
|
"""Applique la pondération des coefficients"""
|
||||||
|
modimpl_coefs_ponderes_df = self.modimpl_coefs_df.copy()
|
||||||
|
for modimpl_id in self.tags[tag]:
|
||||||
|
ponderation = self.tags[tag][modimpl_id]["ponderation"]
|
||||||
|
modimpl_coefs_ponderes_df[modimpl_id] *= ponderation
|
||||||
|
|
||||||
|
"""Calcule les moyennes pour le tag visé dans chaque UE (dataframe etudid x ues)"""
|
||||||
|
moyennes_ues_tag = moy_ue.compute_ue_moys_apc(
|
||||||
|
self.sem_cube,
|
||||||
|
self.etuds,
|
||||||
|
self.formsemestre.modimpls_sorted,
|
||||||
|
self.modimpl_inscr_df,
|
||||||
|
modimpl_coefs_ponderes_df,
|
||||||
|
modimpls_mask,
|
||||||
|
self.dispense_ues,
|
||||||
|
block=self.formsemestre.block_moyennes,
|
||||||
|
)
|
||||||
|
|
||||||
|
"""Les ects"""
|
||||||
|
ects = self.ues_inscr_parcours_df.fillna(0.0) * [
|
||||||
|
ue.ects for ue in self.ues if ue.type != UE_SPORT
|
||||||
|
]
|
||||||
|
|
||||||
|
"""Calcule la moyenne générale dans le semestre (pondérée par le ECTS)"""
|
||||||
|
moy_gen_tag = moy_sem.compute_sem_moys_apc_using_ects(
|
||||||
|
moyennes_ues_tag,
|
||||||
|
ects,
|
||||||
|
formation_id=self.formsemestre.formation_id,
|
||||||
|
skip_empty_ues=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
return moy_gen_tag
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
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.
|
"""Renvoie un couple donnant la note et le coeff normalisé d'un étudiant à un module d'id modimpl_id.
|
||||||
@ -319,27 +284,6 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||||||
return self.nt.validations.ue_capitalisees.loc[[etudid]].to_dict("records")
|
return self.nt.validations.ue_capitalisees.loc[[etudid]].to_dict("records")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
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.
|
|
||||||
Les notes et coeff_norm sont extraits grâce à SemestreTag.get_noteEtCoeff_modimpl (donc dans semestre courant ou UE capitalisée).
|
|
||||||
Les pondérations sont celles déclarées avec le tag (cf. _tagdict)."""
|
|
||||||
|
|
||||||
notes = []
|
|
||||||
coeffs_norm = []
|
|
||||||
ponderations = []
|
|
||||||
for moduleimpl_id, modimpl in self.tagdict[
|
|
||||||
tag
|
|
||||||
].items(): # pour chaque module du semestre relatif au tag
|
|
||||||
(note, coeff_norm) = self.get_noteEtCoeff_modimpl(moduleimpl_id, etudid)
|
|
||||||
if note != None:
|
|
||||||
notes.append(note)
|
|
||||||
coeffs_norm.append(coeff_norm)
|
|
||||||
ponderations.append(modimpl["ponderation"])
|
|
||||||
return (notes, coeffs_norm, ponderations)
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Fonctions d'affichage (et d'export csv) des données du semestre en mode debug
|
# Fonctions d'affichage (et d'export csv) des données du semestre en mode debug
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@ -435,8 +379,9 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||||||
return chaine
|
return chaine
|
||||||
|
|
||||||
def str_tagsModulesEtCoeffs(self):
|
def str_tagsModulesEtCoeffs(self):
|
||||||
"""Renvoie une chaine affichant la liste des tags associés au semestre, les modules qui les concernent et les coeffs de pondération.
|
"""Renvoie une chaine affichant la liste des tags associés au semestre,
|
||||||
Plus concrêtement permet d'afficher le contenu de self._tagdict"""
|
les modules qui les concernent et les coeffs de pondération.
|
||||||
|
Plus concrètement permet d'afficher le contenu de self._tagdict"""
|
||||||
chaine = "Semestre %s d'id %d" % (self.nom, id(self)) + "\n"
|
chaine = "Semestre %s d'id %d" % (self.nom, id(self)) + "\n"
|
||||||
chaine += " -> somme de coeffs: " + str(self.somme_coeffs) + "\n"
|
chaine += " -> somme de coeffs: " + str(self.somme_coeffs) + "\n"
|
||||||
taglist = self.get_all_tags()
|
taglist = self.get_all_tags()
|
||||||
@ -463,25 +408,6 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||||||
|
|
||||||
|
|
||||||
# *********************************************
|
# *********************************************
|
||||||
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]
|
|
||||||
Les coeff peuvent éventuellement être None auquel cas None est conservé ;
|
|
||||||
Les pondérations sont des floattants
|
|
||||||
"""
|
|
||||||
if (
|
|
||||||
coeffs == None
|
|
||||||
or ponderations == None
|
|
||||||
or not isinstance(coeffs, list)
|
|
||||||
or not isinstance(ponderations, list)
|
|
||||||
or len(coeffs) != len(ponderations)
|
|
||||||
):
|
|
||||||
raise ValueError("Erreur de paramètres dans comp_coeff_pond")
|
|
||||||
return [
|
|
||||||
(None if coeffs[i] == None else coeffs[i] * ponderations[i])
|
|
||||||
for i in range(len(coeffs))
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@ -509,3 +435,58 @@ def get_moy_ue_from_nt(nt, etudid, modimpl_id) -> float:
|
|||||||
if ue_status is None:
|
if ue_status is None:
|
||||||
return None
|
return None
|
||||||
return ue_status["moy"]
|
return ue_status["moy"]
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
def get_synthese_tags_semestre(formsemestre: FormSemestre):
|
||||||
|
"""Etant données les implémentations des modules du semestre (modimpls),
|
||||||
|
synthétise les tags les concernant (tags saisis dans le programme pédagogique)
|
||||||
|
en les associant aux modimpls qui les concernent (modimpl_id, module_id,
|
||||||
|
le code du module, coeff et pondération fournie avec le tag (par défaut 1 si non indiquée)).
|
||||||
|
|
||||||
|
{ tagname1: { modimpl_id1: { 'module_id': ...,
|
||||||
|
'coeff': ...,
|
||||||
|
'coeff_norm': ...,
|
||||||
|
'ponderation': ...,
|
||||||
|
'module_code': ...,
|
||||||
|
'ue_xxx': ...},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Args:
|
||||||
|
formsemestre: Le formsemestre à la base de la recherche des tags
|
||||||
|
"""
|
||||||
|
synthese_tags = {}
|
||||||
|
|
||||||
|
"""Instance des modules du semestre"""
|
||||||
|
modimpls = formsemestre.modimpls_sorted
|
||||||
|
|
||||||
|
for modimpl in modimpls:
|
||||||
|
modimpl_id = modimpl.id
|
||||||
|
|
||||||
|
"""Liste des tags pour le module concerné"""
|
||||||
|
tags = sco_tag_module.module_tag_list(modimpl.module.id)
|
||||||
|
|
||||||
|
"""Traitement des tags recensés, chacun pouvant étant de la forme
|
||||||
|
"mathématiques", "théorie", "pe:0", "maths:2"
|
||||||
|
"""
|
||||||
|
for tag in tags:
|
||||||
|
"""Extraction du nom du tag et du coeff de pondération"""
|
||||||
|
(tagname, ponderation) = sco_tag_module.split_tagname_coeff(tag)
|
||||||
|
|
||||||
|
"""Ajout d'une clé pour le tag"""
|
||||||
|
if tagname not in synthese_tags:
|
||||||
|
synthese_tags[tagname] = {}
|
||||||
|
|
||||||
|
"""Ajout du module (modimpl) au tagname considéré"""
|
||||||
|
synthese_tags[tagname][modimpl_id] = {
|
||||||
|
"modimpl": modimpl, # les données sur le module
|
||||||
|
# "coeff": modimpl.module.coefficient, # le coeff du module dans le semestre
|
||||||
|
"ponderation": ponderation, # la pondération demandée pour le tag sur le module
|
||||||
|
# "module_code": modimpl.module.code, # le code qui doit se retrouver à l'identique dans des ue capitalisee
|
||||||
|
# "ue_id": modimpl.module.ue.id, # les données sur l'ue
|
||||||
|
# "ue_code": modimpl.module.ue.ue_code,
|
||||||
|
# "ue_acronyme": modimpl.module.ue.acronyme,
|
||||||
|
}
|
||||||
|
|
||||||
|
return synthese_tags
|
||||||
|
@ -41,36 +41,52 @@ import datetime
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
|
||||||
|
TAGS_RESERVES = ["but"]
|
||||||
|
|
||||||
|
|
||||||
class TableTag(object):
|
class TableTag(object):
|
||||||
"""
|
"""
|
||||||
Classe mémorisant les moyennes des étudiants à différents tag et permettant de calculer les rangs et les statistiques :
|
Classe mémorisant les moyennes des étudiants à différents tags et permettant de
|
||||||
- nom : Nom représentatif des données de la Table
|
calculer des rangs et des statistiques.
|
||||||
- inscrlist : Les étudiants inscrits dans le TagTag avec leur information de la forme :
|
|
||||||
|
Ses attributs sont:
|
||||||
|
|
||||||
|
* nom : Nom représentatif des données de la Table
|
||||||
|
* inscrlist : Les étudiants inscrits dans le TagTag avec leur information de la forme :
|
||||||
{ etudid : dictionnaire d'info extrait de Scodoc, ...}
|
{ etudid : dictionnaire d'info extrait de Scodoc, ...}
|
||||||
- taglist : Liste triée des noms des tags
|
* taglist : Liste triée des noms des tags
|
||||||
- resultats : Dictionnaire donnant les notes-moyennes de chaque étudiant par tag et la somme commulée
|
* resultats : Dictionnaire donnant les notes-moyennes de chaque étudiant par tag et la somme commulée
|
||||||
des coeff utilisées dans le calcul de la moyenne pondérée, sous la forme :
|
des coeff utilisées dans le calcul de la moyenne pondérée, sous la forme :
|
||||||
{ tag : { etudid: (note_moy, somme_coeff_norm),
|
{ tag : { etudid: (note_moy, somme_coeff_norm),
|
||||||
...}
|
...}
|
||||||
- rangs : Dictionnaire donnant les rang par tag de chaque étudiant de la forme :
|
* rangs : Dictionnaire donnant les rang par tag de chaque étudiant de la forme :
|
||||||
{ tag : {etudid: rang, ...} }
|
{ tag : {etudid: rang, ...} }
|
||||||
- nbinscrits : Nombre d'inscrits dans le semestre (pas de distinction entre les tags)
|
* nbinscrits : Nombre d'inscrits dans le semestre (pas de distinction entre les tags)
|
||||||
- statistiques : Dictionnaire donnant les stastitiques (moyenne, min, max) des résultats par tag de la forme :
|
* statistiques : Dictionnaire donnant les statistiques (moyenne, min, max) des résultats par tag de la forme :
|
||||||
{ tag : (moy, min, max), ...}
|
{ tag : (moy, min, max), ...}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, nom=""):
|
def __init__(self, nom: str):
|
||||||
|
"""Les attributs basiques des TagTable, qui seront initialisés
|
||||||
|
dans les classes dérivées
|
||||||
|
"""
|
||||||
self.nom = nom
|
self.nom = nom
|
||||||
self.inscrlist = []
|
"""Les étudiants"""
|
||||||
self.identdict = {}
|
self.etudiants = {}
|
||||||
self.taglist = []
|
"""Les moyennes par tag"""
|
||||||
|
self.moyennes_tags = {}
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------------------
|
||||||
|
def get_all_tags(self):
|
||||||
|
"""Renvoie la liste des tags du semestre triée par ordre alphabétique"""
|
||||||
|
# return self.taglist
|
||||||
|
return sorted(self.moyennes_tags.keys())
|
||||||
|
|
||||||
self.resultats = {}
|
|
||||||
self.rangs = {}
|
|
||||||
self.statistiques = {}
|
|
||||||
|
|
||||||
# *****************************************************************************************************************
|
# *****************************************************************************************************************
|
||||||
# Accesseurs
|
# Accesseurs
|
||||||
@ -80,8 +96,8 @@ 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"""
|
"""Renvoie la moyenne obtenue par un étudiant à un tag donné au regard du format de self.resultats"""
|
||||||
return (
|
return (
|
||||||
self.resultats[tag][etudid][0]
|
self.moyennes_tags[tag][etudid][0]
|
||||||
if tag in self.resultats and etudid in self.resultats[tag]
|
if tag in self.moyennes_tags and etudid in self.moyennes_tags[tag]
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -90,7 +106,7 @@ class TableTag(object):
|
|||||||
"""Renvoie le rang à un tag d'un étudiant au regard du format de self.resultats"""
|
"""Renvoie le rang à un tag d'un étudiant au regard du format de self.resultats"""
|
||||||
return (
|
return (
|
||||||
self.rangs[tag][etudid]
|
self.rangs[tag][etudid]
|
||||||
if tag in self.resultats and etudid in self.resultats[tag]
|
if tag in self.moyennes_tags and etudid in self.moyennes_tags[tag]
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -100,16 +116,11 @@ class TableTag(object):
|
|||||||
au regard du format de self.resultats.
|
au regard du format de self.resultats.
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
self.resultats[tag][etudid][1]
|
self.moyennes_tags[tag][etudid][1]
|
||||||
if tag in self.resultats and etudid in self.resultats[tag]
|
if tag in self.moyennes_tags and etudid in self.moyennes_tags[tag]
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------
|
|
||||||
def get_all_tags(self):
|
|
||||||
"""Renvoie la liste des tags du semestre triée par ordre alphabétique"""
|
|
||||||
# return self.taglist
|
|
||||||
return sorted(self.resultats.keys())
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------
|
||||||
def get_nbinscrits(self):
|
def get_nbinscrits(self):
|
||||||
@ -170,10 +181,12 @@ class TableTag(object):
|
|||||||
avec calcul du rang
|
avec calcul du rang
|
||||||
:param tag: Un tag
|
:param tag: Un tag
|
||||||
:param listMoyEtCoeff: Une liste donnant [ (moy, coeff, etudid) ]
|
:param listMoyEtCoeff: Une liste donnant [ (moy, coeff, etudid) ]
|
||||||
|
|
||||||
|
TODO:: Inutile maintenant ?
|
||||||
"""
|
"""
|
||||||
# ajout des moyennes au dictionnaire résultat
|
# ajout des moyennes au dictionnaire résultat
|
||||||
if listMoyEtCoeff:
|
if listMoyEtCoeff:
|
||||||
self.resultats[tag] = {
|
self.moyennes_tags[tag] = {
|
||||||
etudid: (moyenne, somme_coeffs)
|
etudid: (moyenne, somme_coeffs)
|
||||||
for (moyenne, somme_coeffs, etudid) in listMoyEtCoeff
|
for (moyenne, somme_coeffs, etudid) in listMoyEtCoeff
|
||||||
}
|
}
|
||||||
@ -204,11 +217,12 @@ class TableTag(object):
|
|||||||
self.statistiques
|
self.statistiques
|
||||||
"""
|
"""
|
||||||
stats = ("-NA-", "-", "-")
|
stats = ("-NA-", "-", "-")
|
||||||
if tag not in self.resultats:
|
if tag not in self.moyennes_tags:
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
notes = [
|
notes = [
|
||||||
self.get_moy_from_resultats(tag, etudid) for etudid in self.resultats[tag]
|
self.get_moy_from_resultats(tag, etudid)
|
||||||
|
for etudid in self.moyennes_tags[tag]
|
||||||
] # les notes du tag
|
] # les notes du tag
|
||||||
notes_valides = [
|
notes_valides = [
|
||||||
note for note in notes if isinstance(note, float) and note != None
|
note for note in notes if isinstance(note, float) and note != None
|
||||||
@ -225,7 +239,7 @@ class TableTag(object):
|
|||||||
"""Renvoie une chaine de caractères (valable pour un csv)
|
"""Renvoie une chaine de caractères (valable pour un csv)
|
||||||
décrivant la moyenne et le rang d'un étudiant, pour un tag donné ;
|
décrivant la moyenne et le rang d'un étudiant, pour un tag donné ;
|
||||||
"""
|
"""
|
||||||
if tag not in self.get_all_tags() or etudid not in self.resultats[tag]:
|
if tag not in self.get_all_tags() or etudid not in self.moyennes_tags[tag]:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
moystr = TableTag.str_moytag(
|
moystr = TableTag.str_moytag(
|
||||||
@ -256,30 +270,18 @@ class TableTag(object):
|
|||||||
str_moytag = classmethod(str_moytag)
|
str_moytag = classmethod(str_moytag)
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
def str_tagtable(self, delim=";", decimal_sep=","):
|
def str_tagtable(self):
|
||||||
"""Renvoie une chaine de caractère listant toutes les moyennes, les rangs des étudiants pour tous les tags."""
|
"""Renvoie une chaine de caractère listant toutes les moyennes,
|
||||||
entete = ["etudid", "nom", "prenom"]
|
les rangs des étudiants pour tous les tags."""
|
||||||
|
|
||||||
|
etudiants = self.etudiants
|
||||||
|
df = pd.DataFrame.from_dict(etudiants, orient="index", columns=["nom"])
|
||||||
|
|
||||||
for tag in self.get_all_tags():
|
for tag in self.get_all_tags():
|
||||||
entete += [titre + "_" + tag for titre in ["note", "rang", "nb_inscrit"]]
|
df = df.join(self.moyennes_tags[tag]["notes"].rename(f"moy {tag}"))
|
||||||
chaine = delim.join(entete) + "\n"
|
df = df.join(self.moyennes_tags[tag]["classements"].rename(f"class {tag}"))
|
||||||
|
|
||||||
for etudid in self.identdict:
|
return df.to_csv(sep=";")
|
||||||
descr = delim.join(
|
|
||||||
[
|
|
||||||
str(etudid),
|
|
||||||
self.identdict[etudid]["nom"],
|
|
||||||
self.identdict[etudid]["prenom"],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
descr += delim + self.str_res_d_un_etudiant(etudid, delim)
|
|
||||||
chaine += descr + "\n"
|
|
||||||
|
|
||||||
# Ajout des stats ... à faire
|
|
||||||
|
|
||||||
if decimal_sep != ".":
|
|
||||||
return chaine.replace(".", decimal_sep)
|
|
||||||
else:
|
|
||||||
return chaine
|
|
||||||
|
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
@ -292,24 +292,35 @@ def get_etud_tagged_modules(etudid, tagname):
|
|||||||
return R
|
return R
|
||||||
|
|
||||||
|
|
||||||
def split_tagname_coeff(tag, separateur=":"):
|
def split_tagname_coeff(tag: str, separateur=":") -> tuple[str, float]:
|
||||||
"""Découpe un tag saisi par un utilisateur pour en extraire un tagname
|
"""Découpage d'un tag, tel que saisi par un utilisateur dans le programme,
|
||||||
(chaine de caractère correspondant au tag)
|
pour en extraire :
|
||||||
et un éventuel coefficient de pondération, avec le séparateur fourni (par défaut ":").
|
|
||||||
Renvoie le résultat sous la forme d'une liste [tagname, pond] où pond est un float
|
|
||||||
|
|
||||||
Auteur: CB
|
* son _nom de tag_ (tagname) (chaine de caractère correspondant au tag)
|
||||||
|
* un éventuel coefficient de pondération, avec le séparateur fourni (par défaut ":").
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tag: La saisie utilisateur du tag dans le programme
|
||||||
|
separateur: Le séparateur des informations dans la saisie utilisateur
|
||||||
|
|
||||||
|
Return:
|
||||||
|
Tuple (tagname, coeff_de_ponderation) extrait de la saisie utilisateur
|
||||||
|
(avec coeff_de_ponderation=1.0 si non mentionné)
|
||||||
|
|
||||||
|
Author:
|
||||||
|
Cléo Baras
|
||||||
"""
|
"""
|
||||||
if separateur in tag:
|
if separateur in tag:
|
||||||
temp = tag.split(":")
|
temp = tag.split(":")
|
||||||
try:
|
try:
|
||||||
pond = float(temp[1])
|
pond = float(temp[1])
|
||||||
return [temp[0], pond]
|
return (temp[0], pond)
|
||||||
except:
|
except:
|
||||||
return [tag, 1.0] # renvoie tout le tag si le découpage à échouer
|
"""Renvoie tout le tag si le découpage à échouer"""
|
||||||
|
return (tag, 1.0)
|
||||||
else:
|
else:
|
||||||
# initialise le coeff de pondération à 1 lorsqu'aucun coeff de pondération n'est indiqué dans le tag
|
"""initialise le coeff de pondération à 1 lorsqu'aucun coeff de pondération n'est indiqué dans le tag"""
|
||||||
return [tag, 1.0]
|
return (tag, 1.0)
|
||||||
|
|
||||||
|
|
||||||
"""Tests:
|
"""Tests:
|
||||||
|
Loading…
Reference in New Issue
Block a user