forked from ScoDoc/ScoDoc
Relecture + améliorations diverses (dont tri systématique par etudids_sorted, acronymes_sorted, competences_sorted) des dataframes
This commit is contained in:
parent
8de1a44583
commit
83059cd995
@ -60,6 +60,7 @@ from app.pe.pe_rcstag import RCSTag
|
|||||||
from app.pe.pe_ressemtag import ResSemBUTTag
|
from app.pe.pe_ressemtag import ResSemBUTTag
|
||||||
from app.pe.pe_interclasstag import RCSInterclasseTag
|
from app.pe.pe_interclasstag import RCSInterclasseTag
|
||||||
import app.pe.pe_rcss_jury as pe_rcss_jury
|
import app.pe.pe_rcss_jury as pe_rcss_jury
|
||||||
|
import app.pe.rcss.rcss_constantes as rcss_constantes
|
||||||
|
|
||||||
|
|
||||||
class JuryPE(object):
|
class JuryPE(object):
|
||||||
@ -107,6 +108,7 @@ class JuryPE(object):
|
|||||||
self._gen_xls_diplomes(zipfile)
|
self._gen_xls_diplomes(zipfile)
|
||||||
self._gen_xls_ressembuttags(zipfile)
|
self._gen_xls_ressembuttags(zipfile)
|
||||||
self._gen_rcss()
|
self._gen_rcss()
|
||||||
|
self._gen_rcsf()
|
||||||
self._gen_xls_sxtags(zipfile)
|
self._gen_xls_sxtags(zipfile)
|
||||||
self._gen_rcrcfs()
|
self._gen_rcrcfs()
|
||||||
self._gen_xls_rcrcss_tags(zipfile)
|
self._gen_xls_rcrcss_tags(zipfile)
|
||||||
@ -166,11 +168,14 @@ class JuryPE(object):
|
|||||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
output, engine="openpyxl"
|
output, engine="openpyxl"
|
||||||
) as writer:
|
) as writer:
|
||||||
|
onglets = []
|
||||||
for res_sem_tag in self.ressembuttags.values():
|
for res_sem_tag in self.ressembuttags.values():
|
||||||
onglet = res_sem_tag.get_repr(verbose=False)
|
onglet = res_sem_tag.get_repr(verbose=True)
|
||||||
|
onglets += []
|
||||||
df = res_sem_tag.df_moyennes_et_classements()
|
df = res_sem_tag.df_moyennes_et_classements()
|
||||||
# écriture dans l'onglet
|
# écriture dans l'onglet
|
||||||
df.to_excel(writer, onglet, index=True, header=True)
|
df.to_excel(writer, onglet, index=True, header=True)
|
||||||
|
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
self.add_file_to_zip(
|
self.add_file_to_zip(
|
||||||
@ -190,16 +195,19 @@ class JuryPE(object):
|
|||||||
|
|
||||||
self.rcss_jury.cree_rcss(self.etudiants)
|
self.rcss_jury.cree_rcss(self.etudiants)
|
||||||
|
|
||||||
def _gen_xls_sxtags(self, zipfile: ZipFile):
|
def _gen_rcsf(self):
|
||||||
"""Génère les semestres taggués en s'appuyant sur les RCS de type Sx (pour
|
"""Génère les RCF, regroupement de semestres de type Sx pour préparer
|
||||||
identifier les redoublements impactant les semestres taggués).
|
le calcul des moyennes par Sx"""
|
||||||
"""
|
|
||||||
# Génère les regroupements de semestres de type Sx
|
# Génère les regroupements de semestres de type Sx
|
||||||
pe_affichage.pe_print(
|
pe_affichage.pe_print(
|
||||||
"*** Génère les RCSValid (RCS de même Sx donnant lieu à validation du semestre)"
|
"*** Génère les RCSValid (RCS de même Sx donnant lieu à validation du semestre)"
|
||||||
)
|
)
|
||||||
self.rcss_jury.cree_rcfs(self.etudiants)
|
self.rcss_jury.cree_rcfs(self.etudiants)
|
||||||
|
|
||||||
|
def _gen_xls_sxtags(self, zipfile: ZipFile):
|
||||||
|
"""Génère les semestres taggués en s'appuyant sur les RCF de type Sx (pour
|
||||||
|
identifier les redoublements impactant les semestres taggués).
|
||||||
|
"""
|
||||||
# Génère les moyennes des RCS de type Sx
|
# Génère les moyennes des RCS de type Sx
|
||||||
pe_affichage.pe_print("*** Calcule les moyennes des SxTag")
|
pe_affichage.pe_print("*** Calcule les moyennes des SxTag")
|
||||||
|
|
||||||
@ -216,11 +224,15 @@ class JuryPE(object):
|
|||||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
output, engine="openpyxl"
|
output, engine="openpyxl"
|
||||||
) as writer:
|
) as writer:
|
||||||
|
onglets = []
|
||||||
for sxtag in self.sxtags.values():
|
for sxtag in self.sxtags.values():
|
||||||
onglet = sxtag.get_repr(verbose=False)
|
onglet = sxtag.get_repr(verbose=False)
|
||||||
|
onglets += [onglet]
|
||||||
df = sxtag.df_moyennes_et_classements()
|
df = sxtag.df_moyennes_et_classements()
|
||||||
# écriture dans l'onglet
|
# écriture dans l'onglet
|
||||||
df.to_excel(writer, onglet, index=True, header=True)
|
df.to_excel(writer, onglet, index=True, header=True)
|
||||||
|
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||||
|
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
self.add_file_to_zip(
|
self.add_file_to_zip(
|
||||||
@ -269,11 +281,14 @@ class JuryPE(object):
|
|||||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
output, engine="openpyxl"
|
output, engine="openpyxl"
|
||||||
) as writer:
|
) as writer:
|
||||||
|
onglets = []
|
||||||
for rcs_tag in self.rcss_tags.values():
|
for rcs_tag in self.rcss_tags.values():
|
||||||
onglet = rcs_tag.get_repr(verbose=False)
|
onglet = rcs_tag.get_repr(verbose=False)
|
||||||
|
onglets += [onglet]
|
||||||
df = rcs_tag.df_moyennes_et_classements()
|
df = rcs_tag.df_moyennes_et_classements()
|
||||||
# écriture dans l'onglet
|
# écriture dans l'onglet
|
||||||
df.to_excel(writer, onglet, index=True, header=True)
|
df.to_excel(writer, onglet, index=True, header=True)
|
||||||
|
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
self.add_file_to_zip(
|
self.add_file_to_zip(
|
||||||
@ -296,12 +311,16 @@ class JuryPE(object):
|
|||||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
output, engine="openpyxl"
|
output, engine="openpyxl"
|
||||||
) as writer:
|
) as writer:
|
||||||
|
onglets = []
|
||||||
for interclass_tag in self.interclassements_taggues.values():
|
for interclass_tag in self.interclassements_taggues.values():
|
||||||
if interclass_tag.significatif: # Avec des notes
|
if interclass_tag.significatif: # Avec des notes
|
||||||
onglet = interclass_tag.get_repr()
|
onglet = interclass_tag.get_repr()
|
||||||
|
onglets += [onglet]
|
||||||
df = interclass_tag.df_moyennes_et_classements()
|
df = interclass_tag.df_moyennes_et_classements()
|
||||||
# écriture dans l'onglet
|
# écriture dans l'onglet
|
||||||
df.to_excel(writer, onglet, index=True, header=True)
|
df.to_excel(writer, onglet, index=True, header=True)
|
||||||
|
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||||
|
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
self.add_file_to_zip(
|
self.add_file_to_zip(
|
||||||
@ -322,9 +341,12 @@ class JuryPE(object):
|
|||||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
output, engine="openpyxl"
|
output, engine="openpyxl"
|
||||||
) as writer:
|
) as writer:
|
||||||
|
onglets = []
|
||||||
for onglet, df in self.synthese.items():
|
for onglet, df in self.synthese.items():
|
||||||
|
onglets += [onglet]
|
||||||
# écriture dans l'onglet:
|
# écriture dans l'onglet:
|
||||||
df.to_excel(writer, onglet, index=True, header=True)
|
df.to_excel(writer, onglet, index=True, header=True)
|
||||||
|
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
self.add_file_to_zip(
|
self.add_file_to_zip(
|
||||||
@ -342,9 +364,12 @@ class JuryPE(object):
|
|||||||
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated
|
||||||
output, engine="openpyxl"
|
output, engine="openpyxl"
|
||||||
) as writer:
|
) as writer:
|
||||||
|
onglets = []
|
||||||
for onglet, df in synthese.items():
|
for onglet, df in synthese.items():
|
||||||
|
onglets += [onglet]
|
||||||
# écriture dans l'onglet:
|
# écriture dans l'onglet:
|
||||||
df.to_excel(writer, onglet, index=True, header=True)
|
df.to_excel(writer, onglet, index=True, header=True)
|
||||||
|
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
self.add_file_to_zip(
|
self.add_file_to_zip(
|
||||||
@ -433,7 +458,7 @@ class JuryPE(object):
|
|||||||
|
|
||||||
# Ajout des aggrégats
|
# Ajout des aggrégats
|
||||||
for aggregat in pe_rcs.TOUS_LES_RCS:
|
for aggregat in pe_rcs.TOUS_LES_RCS:
|
||||||
descr = app.pe.rcss.constantes.TYPES_RCS[aggregat]["descr"]
|
descr = rcss_constantes.TYPES_RCS[aggregat]["descr"]
|
||||||
|
|
||||||
# Les trajectoires (tagguées) suivies par les étudiants pour l'aggrégat et le tag
|
# Les trajectoires (tagguées) suivies par les étudiants pour l'aggrégat et le tag
|
||||||
# considéré
|
# considéré
|
||||||
|
@ -3,9 +3,7 @@ import pandas as pd
|
|||||||
|
|
||||||
from app import comp
|
from app import comp
|
||||||
from app.comp.moy_sem import comp_ranks_series
|
from app.comp.moy_sem import comp_ranks_series
|
||||||
from app.models import UniteEns
|
|
||||||
from app.pe import pe_affichage
|
from app.pe import pe_affichage
|
||||||
from app.scodoc.codes_cursus import UE_SPORT
|
|
||||||
|
|
||||||
|
|
||||||
class Moyenne:
|
class Moyenne:
|
||||||
@ -24,12 +22,12 @@ class Moyenne:
|
|||||||
"""Classe centralisant la synthèse des moyennes/classements d'une série
|
"""Classe centralisant la synthèse des moyennes/classements d'une série
|
||||||
de notes :
|
de notes :
|
||||||
|
|
||||||
* des "notes": la Serie pandas des notes (float),
|
* des "notes" : la Serie pandas des notes (float),
|
||||||
* des "classements": la Serie pandas des classements (float),
|
* des "classements" : la Serie pandas des classements (float),
|
||||||
* des "min": la note minimum,
|
* des "min" : la note minimum,
|
||||||
* des "max": la note maximum,
|
* des "max" : la note maximum,
|
||||||
* des "moy": la moyenne,
|
* des "moy" : la moyenne,
|
||||||
* des "nb_inscrits": le nombre d'étudiants ayant une note,
|
* des "nb_inscrits" : le nombre d'étudiants ayant une note,
|
||||||
"""
|
"""
|
||||||
self.notes = notes
|
self.notes = notes
|
||||||
"""Les notes"""
|
"""Les notes"""
|
||||||
@ -171,7 +169,7 @@ class MoyennesTag:
|
|||||||
tag: Un tag
|
tag: Un tag
|
||||||
matrice_notes: Les moyennes (etudid x acronymes_ues ou etudid x compétences) aux différentes UEs ou compétences
|
matrice_notes: Les moyennes (etudid x acronymes_ues ou etudid x compétences) aux différentes UEs ou compétences
|
||||||
matrice_coeffs: Les coeff à appliquer pour le calcul de la moyenne générale
|
matrice_coeffs: Les coeff à appliquer pour le calcul de la moyenne générale
|
||||||
# notes_gen: Une série de notes (moyenne) sous forme d'un pd.Series() (toutes UEs confondues)
|
# notes_gen: Une série de notes (moyenne) sous forme d'un ``pd.Series`` (toutes UEs confondues)
|
||||||
"""
|
"""
|
||||||
self.tag = tag
|
self.tag = tag
|
||||||
"""Le tag associé aux moyennes"""
|
"""Le tag associé aux moyennes"""
|
||||||
@ -207,7 +205,7 @@ class MoyennesTag:
|
|||||||
ont des notes
|
ont des notes
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True si a des notes, False sinon
|
True si la moytag a des notes, False sinon
|
||||||
"""
|
"""
|
||||||
notes = self.matrice_notes
|
notes = self.matrice_notes
|
||||||
nbre_nan = notes.isna().sum().sum()
|
nbre_nan = notes.isna().sum().sum()
|
||||||
|
@ -152,7 +152,8 @@ class RCSsJuryPE:
|
|||||||
|
|
||||||
# Ajout du RCRCF
|
# Ajout du RCRCF
|
||||||
if rcf_id not in self.rcrcfs:
|
if rcf_id not in self.rcrcfs:
|
||||||
self.rcrcfs[rcf_id] = pe_rcrcf.RCRCF(rcf_id, rcf.formsemestre_final)
|
rcf_nom = rcf_id[0]
|
||||||
|
self.rcrcfs[rcf_id] = pe_rcrcf.RCRCF(rcf_nom, rcf.formsemestre_final)
|
||||||
rcrcf = self.rcrcfs[rcf_id]
|
rcrcf = self.rcrcfs[rcf_id]
|
||||||
|
|
||||||
# Ajout des RCFs au RCRCF
|
# Ajout des RCFs au RCRCF
|
||||||
|
@ -37,6 +37,7 @@ Created on Fri Sep 9 09:15:05 2016
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from app.comp.res_sem import load_formsemestre_results
|
from app.comp.res_sem import load_formsemestre_results
|
||||||
|
from app.models import FormSemestre
|
||||||
from app.pe import pe_affichage
|
from app.pe import pe_affichage
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -49,7 +50,7 @@ from app.pe.pe_moytag import MoyennesTag
|
|||||||
|
|
||||||
|
|
||||||
class RCSTag(TableTag):
|
class RCSTag(TableTag):
|
||||||
def __init__(self, rcrcf: pe_rcs.RCS, sxstags: dict[(str, int): pe_sxtag.SxTag]):
|
def __init__(self, rcrcf: pe_rcs.RCS, sxstags: dict[(str, int) : pe_sxtag.SxTag]):
|
||||||
"""Calcule les moyennes par tag (orientées compétences)
|
"""Calcule les moyennes par tag (orientées compétences)
|
||||||
d'un regroupement de SxTag
|
d'un regroupement de SxTag
|
||||||
(RCRCF), pour extraire les classements par tag pour un
|
(RCRCF), pour extraire les classements par tag pour un
|
||||||
@ -71,17 +72,18 @@ class RCSTag(TableTag):
|
|||||||
self.nom = self.get_repr()
|
self.nom = self.get_repr()
|
||||||
"""Représentation textuelle du RCS taggué"""
|
"""Représentation textuelle du RCS taggué"""
|
||||||
|
|
||||||
self.formsemestre_terminal = rcrcf.formsemestre_final
|
# Les données du semestre final
|
||||||
"""Le formsemestre terminal"""
|
self.formsemestre_terminal: FormSemestre = rcrcf.formsemestre_final
|
||||||
|
"""Le semestre final"""
|
||||||
|
self.fid_final: int = rcrcf.formsemestre_final.formsemestre_id
|
||||||
|
"""Le fid du semestre final"""
|
||||||
|
|
||||||
|
# Affichage pour debug
|
||||||
pe_affichage.pe_print(f"-> {self.get_repr(verbose=True)}")
|
pe_affichage.pe_print(f"-> {self.get_repr(verbose=True)}")
|
||||||
|
|
||||||
# Les résultats du formsemestre terminal
|
# Les données aggrégés (RCRCF + SxTags
|
||||||
nt = load_formsemestre_results(self.formsemestre_terminal)
|
|
||||||
|
|
||||||
self.rcfs_aggreges = rcrcf.rcfs_aggreges
|
self.rcfs_aggreges = rcrcf.rcfs_aggreges
|
||||||
"""Les RCFs aggrégés"""
|
"""Les RCFs aggrégés"""
|
||||||
|
|
||||||
self.sxstags = {}
|
self.sxstags = {}
|
||||||
"""Les SxTag associés aux RCF aggrégés"""
|
"""Les SxTag associés aux RCF aggrégés"""
|
||||||
try:
|
try:
|
||||||
@ -91,41 +93,57 @@ class RCSTag(TableTag):
|
|||||||
raise ValueError("Semestres SxTag manquants")
|
raise ValueError("Semestres SxTag manquants")
|
||||||
|
|
||||||
# Les étudiants (etuds, états civils & etudis)
|
# Les étudiants (etuds, états civils & etudis)
|
||||||
self.etuds = nt.etuds
|
sxtag_final = self.sxstags[self.rcs_id]
|
||||||
self.add_etuds(nt.etuds)
|
self.etuds = sxtag_final.etuds
|
||||||
|
"""Les étudiants (extraits du semestre final)"""
|
||||||
|
self.add_etuds(self.etuds)
|
||||||
self.etudids_sorted = sorted(self.etudids)
|
self.etudids_sorted = sorted(self.etudids)
|
||||||
"""Etudids triés"""
|
"""Les étudids triés"""
|
||||||
|
|
||||||
# Les compétences (extraites de tous les Sxtags)
|
# Les compétences (extraites de tous les Sxtags)
|
||||||
self.association_ues_comp = self.mapping_ue_competences()
|
self.acronymes_ues_to_competences = self._do_acronymes_to_competences()
|
||||||
"""Association indiquant pour chaque UE , quelle compétence lui correspond"""
|
"""L'association acronyme d'UEs -> compétence (extraites des SxTag aggrégés)"""
|
||||||
pe_affichage.pe_print(f"* Association UEs -> compétences : {self.association_ues_comp}")
|
pe_affichage.pe_print(
|
||||||
|
f"* Association UEs -> compétences : {self.acronymes_ues_to_competences}"
|
||||||
self.competences_sorted = self.do_complist()
|
)
|
||||||
"""Compétences (triées) extraites de tous les SxTag aggrégés"""
|
self.competences_sorted = sorted(self.acronymes_ues_to_competences.values())
|
||||||
|
"""Compétences (triées par nom, extraites des SxTag aggrégés)"""
|
||||||
pe_affichage.pe_print(f"* Compétences : {', '.join(self.competences_sorted)}")
|
pe_affichage.pe_print(f"* Compétences : {', '.join(self.competences_sorted)}")
|
||||||
|
|
||||||
# Les tags
|
# Les tags
|
||||||
self.tags_sorted = self.do_taglist()
|
self.tags_sorted = self._do_taglist()
|
||||||
"""Tags extraits de tous les SxTag aggrégés"""
|
"""Tags extraits de tous les SxTag aggrégés"""
|
||||||
pe_affichage.pe_print(f"* Tags : {', '.join(self.tags_sorted)}")
|
pe_affichage.pe_print(f"* Tags : {', '.join(self.tags_sorted)}")
|
||||||
|
|
||||||
# Les moyennes
|
# Les moyennes
|
||||||
self.moyennes_tags: dict[str, MoyennesTag] = {}
|
self.moyennes_tags: dict[str, MoyennesTag] = {}
|
||||||
"""Synthétise les moyennes/classements par tag (qu'ils soient personnalisé ou de compétences)"""
|
"""Synthétise les moyennes/classements par tag (qu'ils soient personnalisé ou de compétences)"""
|
||||||
|
|
||||||
for tag in self.tags_sorted:
|
for tag in self.tags_sorted:
|
||||||
# Cube de note
|
# Cube de notes (etudids_sorted x compétences_sorted x sxstags)
|
||||||
notes_cube, coeffs_cube = self.compute_notes_comps_cube(tag, self.etudids_sorted, self.competences_sorted)
|
notes_df, notes_cube = self.compute_notes_comps_cube(
|
||||||
|
tag, self.etudids_sorted, self.competences_sorted, self.sxstags
|
||||||
# Calcule des moyennes/coeffs sous forme d'un dataframe"""
|
)
|
||||||
moys_competences, coeffs_competences = compute_notes_competences(
|
# Calcule des moyennes/coeffs sous forme d'un dataframe"""
|
||||||
notes_cube, coeffs_cube, self.etudids_sorted, self.competences_sorted
|
moys_competences = compute_notes_competences(
|
||||||
|
notes_cube, self.etudids_sorted, self.competences_sorted
|
||||||
|
)
|
||||||
|
# Cube de coeffs pour la moyenne générale,
|
||||||
|
# traduisant les inscriptions des étudiants aux UEs (etudids_sorted x compétences_sorted x sxstags)
|
||||||
|
coeffs_df, coeffs_cube = self.compute_coeffs_comps_cube(
|
||||||
|
tag,
|
||||||
|
self.etudids_sorted,
|
||||||
|
self.competences_sorted,
|
||||||
|
self.sxstags,
|
||||||
|
)
|
||||||
|
# Calcule la synthèse des coefficients à prendre en compte pour la moyenne
|
||||||
|
# générale
|
||||||
|
matrice_coeffs_moy_gen = compute_coeffs_competences(
|
||||||
|
coeffs_cube, notes_cube, self.etudids_sorted, self.competences_sorted
|
||||||
|
)
|
||||||
|
# Mémorise les moyennes et les coeff associés
|
||||||
|
self.moyennes_tags[tag] = MoyennesTag(
|
||||||
|
tag, moys_competences, matrice_coeffs_moy_gen
|
||||||
)
|
)
|
||||||
|
|
||||||
# Les moyennes
|
|
||||||
self.moyennes_tags[tag] = MoyennesTag(tag, moys_competences,
|
|
||||||
coeffs_competences)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""Egalité de 2 RCS taggués sur la base de leur identifiant"""
|
"""Egalité de 2 RCS taggués sur la base de leur identifiant"""
|
||||||
@ -139,107 +157,200 @@ class RCSTag(TableTag):
|
|||||||
else:
|
else:
|
||||||
return f"{self.__class__.__name__} ({self.rcs_id})"
|
return f"{self.__class__.__name__} ({self.rcs_id})"
|
||||||
|
|
||||||
def compute_notes_comps_cube(self, tag, etudids_sorted: list[int], competences_sorted: list[str]):
|
def compute_notes_comps_cube(
|
||||||
"""Pour un tag donné, construit :
|
self,
|
||||||
* le cube de notes (etudid x competences x SxTag) nécessaire au calcul des moyennes,
|
tag,
|
||||||
en remplaçant les données d'UE (obtenus du SxTag) par les compétences
|
etudids_sorted: list[int],
|
||||||
* le cube de coeffs (etudid x competences x SxTag) (traduisant les inscriptions)
|
competences_sorted: list[str],
|
||||||
appliqué au calcul des différents SxTag
|
sxstags: dict[(str, int) : pe_sxtag.SxTag],
|
||||||
|
):
|
||||||
|
"""Pour un tag donné, construit le cube de notes (etudid x competences x SxTag)
|
||||||
|
nécessaire au calcul des moyennes,
|
||||||
|
en remplaçant les données d'UE (obtenus du SxTag) par les compétences
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tag: Le tag visé
|
tag: Le tag visé
|
||||||
etudids_sorted: Les etudis triés
|
etudids_sorted: Les etudis triés (dim 0)
|
||||||
competences_sorted: Les compétences triées
|
competences_sorted: Les compétences triées (dim 1)
|
||||||
|
sxstags: Les SxTag à réunir
|
||||||
"""
|
"""
|
||||||
# nb_tags = len(self.tags_sorted)
|
|
||||||
# nb_etudiants = len(self.etuds)
|
|
||||||
# nb_semestres = len(self.semestres_tags_aggreges)
|
|
||||||
|
|
||||||
# Index du cube (etudids -> dim 0, tags -> dim 1)
|
|
||||||
# etudids = [etud.etudid for etud in self.etuds]
|
|
||||||
# competences_sorted = self.competences_sorted
|
|
||||||
sxstags_ids = list(self.sxstags.keys())
|
|
||||||
|
|
||||||
notes_dfs = {}
|
notes_dfs = {}
|
||||||
coeffs_dfs = {}
|
|
||||||
|
|
||||||
for sxtag_id, sxtag in self.sxstags.items():
|
for sxtag_id, sxtag in sxstags.items():
|
||||||
# Partant d'un dataframe vierge
|
# Partant d'un dataframe vierge
|
||||||
notes_df = pd.DataFrame(np.nan, index=etudids_sorted, columns=competences_sorted)
|
notes_df = pd.DataFrame(
|
||||||
coeffs_df = pd.DataFrame(np.nan, index=etudids_sorted, columns=competences_sorted)
|
np.nan, index=etudids_sorted, columns=competences_sorted
|
||||||
|
)
|
||||||
|
# Charge les notes du semestre tag (copie car changement de nom de colonnes à venir)
|
||||||
moys_tag = sxtag.moyennes_tags[tag]
|
moys_tag = sxtag.moyennes_tags[tag]
|
||||||
|
|
||||||
# Charge les notes et les coeffs du semestre tag
|
|
||||||
notes = moys_tag.matrice_notes.copy() # avec une copie
|
notes = moys_tag.matrice_notes.copy() # avec une copie
|
||||||
coeffs = moys_tag.matrice_coeffs_moy_gen.copy() # les coeffs
|
|
||||||
|
|
||||||
# Traduction des UE en compétences
|
# Traduction des acronymes d'UE en compétences
|
||||||
ues_columns_df = notes.columns
|
acronymes_ues_columns = notes.columns
|
||||||
comp_associes_aux_ues = [self.association_ues_comp[ue] for ue in ues_columns_df]
|
acronymes_to_comps = [
|
||||||
notes.columns = comp_associes_aux_ues
|
self.acronymes_ues_to_competences[acro]
|
||||||
coeffs.columns = comp_associes_aux_ues
|
for acro in acronymes_ues_columns
|
||||||
|
]
|
||||||
|
notes.columns = acronymes_to_comps
|
||||||
|
|
||||||
# Les étudiants et les compétences communes
|
# Les étudiants et les compétences communes
|
||||||
etudids_communs, comp_communes = pe_comp.find_index_and_columns_communs(notes_df, notes)
|
etudids_communs, comp_communes = pe_comp.find_index_and_columns_communs(
|
||||||
|
notes_df, notes
|
||||||
|
)
|
||||||
|
|
||||||
# Recopie des notes et des coeffs
|
# Recopie des notes et des coeffs
|
||||||
notes_df.loc[etudids_communs, comp_communes] = notes.loc[
|
notes_df.loc[etudids_communs, comp_communes] = notes.loc[
|
||||||
etudids_communs, comp_communes
|
etudids_communs, comp_communes
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Supprime tout ce qui n'est pas numérique
|
||||||
|
# for col in notes_df.columns:
|
||||||
|
# notes_df[col] = pd.to_numeric(notes_df[col], errors="coerce")
|
||||||
|
|
||||||
|
# Stocke les dfs
|
||||||
|
notes_dfs[sxtag_id] = notes_df
|
||||||
|
|
||||||
|
"""Réunit les notes sous forme d'un cube etudids x competences x semestres"""
|
||||||
|
sxtag_x_etudids_x_comps = [notes_dfs[sxtag_id] for sxtag_id in sxstags]
|
||||||
|
notes_etudids_x_comps_x_sxtag = np.stack(sxtag_x_etudids_x_comps, axis=-1)
|
||||||
|
|
||||||
|
return notes_dfs, notes_etudids_x_comps_x_sxtag
|
||||||
|
|
||||||
|
def compute_coeffs_comps_cube(
|
||||||
|
self,
|
||||||
|
tag,
|
||||||
|
etudids_sorted: list[int],
|
||||||
|
competences_sorted: list[str],
|
||||||
|
sxstags: dict[(str, int) : pe_sxtag.SxTag],
|
||||||
|
):
|
||||||
|
"""Pour un tag donné, construit
|
||||||
|
le cube de coeffs (etudid x competences x SxTag) (traduisant les inscriptions
|
||||||
|
des étudiants aux UEs en fonction de leur parcours)
|
||||||
|
qui s'applique aux différents SxTag
|
||||||
|
en remplaçant les données d'UE (obtenus du SxTag) par les compétences
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tag: Le tag visé
|
||||||
|
etudids_sorted: Les etudis triés
|
||||||
|
competences_sorted: Les compétences triées
|
||||||
|
sxstags: Les SxTag à réunir
|
||||||
|
"""
|
||||||
|
coeffs_dfs = {}
|
||||||
|
|
||||||
|
for sxtag_id, sxtag in sxstags.items():
|
||||||
|
# Partant d'un dataframe vierge
|
||||||
|
coeffs_df = pd.DataFrame(
|
||||||
|
np.nan, index=etudids_sorted, columns=competences_sorted
|
||||||
|
)
|
||||||
|
|
||||||
|
moys_tag = sxtag.moyennes_tags[tag]
|
||||||
|
|
||||||
|
# Charge les notes et les coeffs du semestre tag
|
||||||
|
coeffs = moys_tag.matrice_coeffs_moy_gen.copy() # les coeffs
|
||||||
|
|
||||||
|
# Traduction des acronymes d'UE en compétences
|
||||||
|
acronymes_ues_columns = coeffs.columns
|
||||||
|
acronymes_to_comps = [
|
||||||
|
self.acronymes_ues_to_competences[acro]
|
||||||
|
for acro in acronymes_ues_columns
|
||||||
|
]
|
||||||
|
coeffs.columns = acronymes_to_comps
|
||||||
|
|
||||||
|
# Les étudiants et les compétences communes
|
||||||
|
etudids_communs, comp_communes = pe_comp.find_index_and_columns_communs(
|
||||||
|
coeffs_df, coeffs
|
||||||
|
)
|
||||||
|
|
||||||
|
# Recopie des notes et des coeffs
|
||||||
coeffs_df.loc[etudids_communs, comp_communes] = coeffs.loc[
|
coeffs_df.loc[etudids_communs, comp_communes] = coeffs.loc[
|
||||||
etudids_communs, comp_communes
|
etudids_communs, comp_communes
|
||||||
]
|
]
|
||||||
|
|
||||||
# Supprime tout ce qui n'est pas numérique
|
|
||||||
for col in notes_df.columns:
|
|
||||||
notes_df[col] = pd.to_numeric(notes_df[col], errors="coerce")
|
|
||||||
|
|
||||||
# Stocke les dfs
|
# Stocke les dfs
|
||||||
notes_dfs[sxtag_id] = notes_df
|
|
||||||
coeffs_dfs[sxtag_id] = coeffs_df
|
coeffs_dfs[sxtag_id] = coeffs_df
|
||||||
|
|
||||||
"""Réunit les notes sous forme d'un cube etudids x competences x semestres"""
|
|
||||||
sxtag_x_etudids_x_comps = [notes_dfs[fid].values for fid in notes_dfs]
|
|
||||||
notes_etudids_x_comps_x_sxtag = np.stack(sxtag_x_etudids_x_comps, axis=-1)
|
|
||||||
|
|
||||||
"""Réunit les coeffs sous forme d'un cube etudids x competences x semestres"""
|
"""Réunit les coeffs sous forme d'un cube etudids x competences x semestres"""
|
||||||
sxtag_x_etudids_x_comps = [coeffs_dfs[fid].values for fid in notes_dfs]
|
sxtag_x_etudids_x_comps = [coeffs_dfs[sxtag_id] for sxtag_id in sxstags]
|
||||||
coeffs_etudids_x_comps_x_sxtag = np.stack(sxtag_x_etudids_x_comps, axis=-1)
|
coeffs_etudids_x_comps_x_sxtag = np.stack(sxtag_x_etudids_x_comps, axis=-1)
|
||||||
|
|
||||||
return notes_etudids_x_comps_x_sxtag, coeffs_etudids_x_comps_x_sxtag
|
return coeffs_dfs, coeffs_etudids_x_comps_x_sxtag
|
||||||
|
|
||||||
def do_taglist(self):
|
def _do_taglist(self) -> list[str]:
|
||||||
"""Synthétise les tags à partir des Sxtags aggrégés
|
"""Synthétise les tags à partir des Sxtags aggrégés.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Une liste de tags triés par ordre alphabétique
|
Liste de tags triés par ordre alphabétique
|
||||||
"""
|
"""
|
||||||
tags = []
|
tags = []
|
||||||
for frmsem_id in self.sxstags:
|
for frmsem_id in self.sxstags:
|
||||||
tags.extend(self.sxstags[frmsem_id].tags_sorted)
|
tags.extend(self.sxstags[frmsem_id].tags_sorted)
|
||||||
return sorted(set(tags))
|
return sorted(set(tags))
|
||||||
|
|
||||||
def mapping_ue_competences(self):
|
def _do_acronymes_to_competences(self) -> dict[str:str]:
|
||||||
"""Dictionnaire {ue: competences} extrait des SxTags"""
|
"""Synthétise l'association complète {acronyme_ue: competences}
|
||||||
|
extraite de toutes les données/associations des SxTags
|
||||||
|
aggrégés.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Un dictionnaire {'acronyme_ue' : 'compétences'}
|
||||||
|
"""
|
||||||
dict_competences = {}
|
dict_competences = {}
|
||||||
for sxtag_id, sxtag in self.sxstags.items():
|
for sxtag_id, sxtag in self.sxstags.items():
|
||||||
comp = sxtag.competences
|
dict_competences |= sxtag.acronymes_ues_to_competences
|
||||||
dict_competences |= comp
|
|
||||||
return dict_competences
|
return dict_competences
|
||||||
|
|
||||||
def do_complist(self):
|
|
||||||
"""Synthétise les compétences à partir des Sxtags aggrégés"""
|
def compute_coeffs_competences(
|
||||||
dict_competences = self.mapping_ue_competences()
|
coeff_cube: np.array,
|
||||||
return sorted(set(dict_competences.values()))
|
set_cube: np.array,
|
||||||
|
etudids_sorted: list,
|
||||||
|
competences_sorted: list,
|
||||||
|
):
|
||||||
|
"""Calcule les coeffs à utiliser pour la moyenne générale (toutes compétences
|
||||||
|
confondues), en fonction des notes (set_cube) aggrégées.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
coeffs_cube: coeffs impliqués dans la moyenne générale (semestres par semestres)
|
||||||
|
set_cube: notes moyennes aux modules ndarray
|
||||||
|
(etuds x UEs|compétences x sxtags), des floats avec des NaN
|
||||||
|
etudids_sorted: liste des étudiants (dim. 0 du cube)
|
||||||
|
competences_sorted: list
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Un DataFrame de coefficients (etudids_sorted x compétences_sorted)
|
||||||
|
"""
|
||||||
|
nb_etuds, nb_comps, nb_semestres = set_cube.shape
|
||||||
|
assert nb_etuds == len(etudids_sorted)
|
||||||
|
assert nb_comps == len(competences_sorted)
|
||||||
|
|
||||||
|
# Quelles entrées du cube contiennent des notes ?
|
||||||
|
mask = ~np.isnan(set_cube)
|
||||||
|
|
||||||
|
# Enlève les NaN du cube de notes pour les entrées manquantes
|
||||||
|
coeffs_cube_no_nan = np.nan_to_num(coeff_cube, nan=0.0)
|
||||||
|
|
||||||
|
# Retire les coefficients associées à des données sans notes
|
||||||
|
coeffs_cube_no_nan = coeffs_cube_no_nan * mask
|
||||||
|
|
||||||
|
# Somme les coefficients (correspondant à des notes)
|
||||||
|
coeff_tag = np.sum(coeffs_cube_no_nan, axis=2)
|
||||||
|
|
||||||
|
# Le dataFrame des coeffs
|
||||||
|
coeffs_df = pd.DataFrame(
|
||||||
|
coeff_tag, index=etudids_sorted, columns=competences_sorted
|
||||||
|
)
|
||||||
|
# Remet à Nan les coeffs à 0
|
||||||
|
coeffs_df.fillna(np.nan)
|
||||||
|
|
||||||
|
return coeffs_df
|
||||||
|
|
||||||
|
|
||||||
def compute_notes_competences(
|
def compute_notes_competences(
|
||||||
set_cube: np.array, coeff_cube: np.array, etudids_sorted: list, competences_sorted: list
|
set_cube: np.array,
|
||||||
|
etudids_sorted: list,
|
||||||
|
competences_sorted: list,
|
||||||
):
|
):
|
||||||
"""Calcule:
|
"""Calcule la moyenne par compétences (à un tag donné) sur plusieurs semestres (partant du set_cube).
|
||||||
* la moyenne par compétences à un tag donné sur plusieurs semestres (partant du set_cube).
|
|
||||||
* la somme des coeffs à utiliser pour la moyenne générale.
|
|
||||||
|
|
||||||
La moyenne est un nombre (note/20), ou NaN si pas de notes disponibles
|
La moyenne est un nombre (note/20), ou NaN si pas de notes disponibles
|
||||||
|
|
||||||
@ -249,7 +360,6 @@ def compute_notes_competences(
|
|||||||
Args:
|
Args:
|
||||||
set_cube: notes moyennes aux modules ndarray
|
set_cube: notes moyennes aux modules ndarray
|
||||||
(etuds x UEs|compétences x sxtags), des floats avec des NaN
|
(etuds x UEs|compétences x sxtags), des floats avec des NaN
|
||||||
coeffs_cube: somme des coeffs impliqués dans la moyennes
|
|
||||||
etudids_sorted: liste des étudiants (dim. 0 du cube)
|
etudids_sorted: liste des étudiants (dim. 0 du cube)
|
||||||
competences_sorted: list
|
competences_sorted: list
|
||||||
tags: liste des tags (dim. 1 du cube)
|
tags: liste des tags (dim. 1 du cube)
|
||||||
@ -266,13 +376,10 @@ def compute_notes_competences(
|
|||||||
|
|
||||||
# Enlève les NaN du cube de notes pour les entrées manquantes
|
# Enlève les NaN du cube de notes pour les entrées manquantes
|
||||||
set_cube_no_nan = np.nan_to_num(set_cube, nan=0.0)
|
set_cube_no_nan = np.nan_to_num(set_cube, nan=0.0)
|
||||||
coeffs_cube_no_nan = np.nan_to_num(coeff_cube, nan=0.0)
|
|
||||||
|
|
||||||
# Les moyennes par tag
|
# Les moyennes par tag
|
||||||
with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN)
|
with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN)
|
||||||
etud_moy_tag = np.sum(set_cube_no_nan, axis=2) / np.sum(mask, axis=2)
|
etud_moy_tag = np.sum(set_cube_no_nan, axis=2) / np.sum(mask, axis=2)
|
||||||
# La somme des coeffs
|
|
||||||
coeff_tag = np.sum(coeffs_cube_no_nan, axis=2)
|
|
||||||
|
|
||||||
# Le dataFrame des notes moyennes
|
# Le dataFrame des notes moyennes
|
||||||
etud_moy_tag_df = pd.DataFrame(
|
etud_moy_tag_df = pd.DataFrame(
|
||||||
@ -282,7 +389,4 @@ def compute_notes_competences(
|
|||||||
)
|
)
|
||||||
etud_moy_tag_df.fillna(np.nan)
|
etud_moy_tag_df.fillna(np.nan)
|
||||||
|
|
||||||
coeffs_df = pd.DataFrame(coeff_tag, index=etudids_sorted, columns=competences_sorted)
|
return etud_moy_tag_df
|
||||||
coeffs_df.fillna(np.nan)
|
|
||||||
|
|
||||||
return etud_moy_tag_df, coeffs_df
|
|
||||||
|
@ -41,7 +41,7 @@ from app import db, ScoValueError
|
|||||||
from app import comp
|
from app import comp
|
||||||
from app.comp.res_but import ResultatsSemestreBUT
|
from app.comp.res_but import ResultatsSemestreBUT
|
||||||
from app.comp.res_sem import load_formsemestre_results
|
from app.comp.res_sem import load_formsemestre_results
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre, UniteEns
|
||||||
from app.models.moduleimpls import ModuleImpl
|
from app.models.moduleimpls import ModuleImpl
|
||||||
import app.pe.pe_affichage as pe_affichage
|
import app.pe.pe_affichage as pe_affichage
|
||||||
import app.pe.pe_etudiant as pe_etudiant
|
import app.pe.pe_etudiant as pe_etudiant
|
||||||
@ -55,7 +55,7 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
|||||||
"""
|
"""
|
||||||
Un ResSemBUTTag représente les résultats des étudiants à un semestre, en donnant
|
Un ResSemBUTTag représente les résultats des étudiants à un semestre, en donnant
|
||||||
accès aux moyennes par tag.
|
accès aux moyennes par tag.
|
||||||
Il s'appuie principalement sur FormSemestre et sur ResultatsSemestreBUT.
|
Il s'appuie principalement sur un ResultatsSemestreBUT.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, formsemestre: FormSemestre):
|
def __init__(self, formsemestre: FormSemestre):
|
||||||
@ -69,51 +69,59 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
|||||||
# Le nom du res_semestre taggué
|
# Le nom du res_semestre taggué
|
||||||
self.nom = self.get_repr(verbose=True)
|
self.nom = self.get_repr(verbose=True)
|
||||||
|
|
||||||
pe_affichage.pe_print(f"--> Résultats de semestre taggués {self.nom}")
|
pe_affichage.pe_print(f"--> ResultatsSemestreBUT taggués {self.nom}")
|
||||||
|
|
||||||
# Les étudiants (etuds, états civils & etudis) ajouté
|
# Les étudiants (etuds, états civils & etudis) ajouté
|
||||||
self.add_etuds(self.etuds)
|
self.add_etuds(self.etuds)
|
||||||
self.etudids_sorted = sorted(self.etudids)
|
self.etudids_sorted = sorted(self.etudids)
|
||||||
|
"""Les etudids des étudiants du ResultatsSemestreBUT triés"""
|
||||||
|
|
||||||
# Les UEs (et les dispenses d'UE)
|
# Les UEs (et les dispenses d'UE)
|
||||||
# self.ues
|
self.ues_standards: list[UniteEns] = [
|
||||||
ues_standards = [ue for ue in self.ues if ue.type == sco_codes.UE_STANDARD]
|
ue for ue in self.ues if ue.type == sco_codes.UE_STANDARD
|
||||||
|
]
|
||||||
|
"""Liste des UEs standards du ResultatsSemestreBUT"""
|
||||||
|
|
||||||
# Les UEs en fonction des parcours
|
# Les UEs en fonction des parcours
|
||||||
self.ues_inscr_parcours_df = self.load_ues_inscr_parcours()
|
self.ues_inscr_parcours_df = self.load_ues_inscr_parcours()
|
||||||
|
"""Les inscriptions des étudiants aux UEs du parcours"""
|
||||||
# Les compétences associées aux UEs (définies par les acronymes)
|
|
||||||
self.competences = {}
|
|
||||||
"""L'association acronyme d'UEs -> compétence"""
|
|
||||||
for ue in self.ues:
|
|
||||||
if ue.type == sco_codes.UE_STANDARD:
|
|
||||||
assert ue.niveau_competence, ScoValueError(
|
|
||||||
"Des UEs ne sont pas rattachées à des compétences"
|
|
||||||
)
|
|
||||||
nom = ue.niveau_competence.competence.titre
|
|
||||||
self.competences[ue.acronyme] = nom
|
|
||||||
|
|
||||||
# Les acronymes des UEs
|
# Les acronymes des UEs
|
||||||
self.ues_to_acronymes = {ue.id: ue.acronyme for ue in ues_standards}
|
self.ues_to_acronymes = {ue.id: ue.acronyme for ue in self.ues_standards}
|
||||||
self.acronymes_sorted = sorted(self.ues_to_acronymes.values())
|
self.acronymes_sorted = sorted(self.ues_to_acronymes.values())
|
||||||
"""Les acronymes de UE triés par ordre alphabétique"""
|
"""Les acronymes de UE triés par ordre alphabétique"""
|
||||||
|
|
||||||
|
# Les compétences associées aux UEs (définies par les acronymes)
|
||||||
|
self.acronymes_ues_to_competences = {}
|
||||||
|
"""L'association acronyme d'UEs -> compétence"""
|
||||||
|
for ue in self.ues_standards:
|
||||||
|
assert ue.niveau_competence, ScoValueError(
|
||||||
|
"Des UEs ne sont pas rattachées à des compétences"
|
||||||
|
)
|
||||||
|
nom = ue.niveau_competence.competence.titre
|
||||||
|
self.acronymes_ues_to_competences[ue.acronyme] = nom
|
||||||
|
self.competences_sorted = sorted(
|
||||||
|
list(set(self.acronymes_ues_to_competences.values()))
|
||||||
|
)
|
||||||
|
"""Les compétences triées par nom"""
|
||||||
|
|
||||||
# Les tags personnalisés et auto:
|
# Les tags personnalisés et auto:
|
||||||
tags_dict = self._get_tags_dict()
|
tags_dict = self._get_tags_dict()
|
||||||
self._check_tags(tags_dict)
|
self._check_tags(tags_dict)
|
||||||
|
|
||||||
# Les coefficients pour le calcul de la moyenne générale
|
# Les coefficients pour le calcul de la moyenne générale, donnés par
|
||||||
self.matrice_coeffs_moy_gen = self.ues_inscr_parcours_df * [
|
# acronymes d'UE
|
||||||
ue.ects for ue in ues_standards # if ue.type != UE_SPORT <= déjà supprimé
|
self.matrice_coeffs_moy_gen = self._get_matrice_coeffs(
|
||||||
]
|
self.ues_inscr_parcours_df, self.ues_standards
|
||||||
|
)
|
||||||
|
"""DataFrame indiquant les coeffs des UEs par ordre alphabétique d'acronyme"""
|
||||||
|
|
||||||
# Les capitalisations (mask etuids x acronyme_ue valant True si capitalisée, False sinon)
|
# Les capitalisations (mask etuids x acronyme_ue valant True si capitalisée, False sinon)
|
||||||
self.capitalisations = self._get_capitalisations(ues_standards)
|
self.capitalisations = self._get_capitalisations(self.ues_standards)
|
||||||
|
"""DataFrame indiquant les UEs capitalisables d'un étudiant (etudids x )"""
|
||||||
|
|
||||||
# Calcul des moyennes & les classements de chaque étudiant à chaque tag
|
# Calcul des moyennes & les classements de chaque étudiant à chaque tag
|
||||||
self.moyennes_tags = {}
|
self.moyennes_tags = {}
|
||||||
|
"""Les moyennes par tags (personnalisés ou 'but')"""
|
||||||
for tag in tags_dict["personnalises"]:
|
for tag in tags_dict["personnalises"]:
|
||||||
# pe_affichage.pe_print(f" -> Traitement du tag {tag}")
|
# pe_affichage.pe_print(f" -> Traitement du tag {tag}")
|
||||||
infos_tag = tags_dict["personnalises"][tag]
|
infos_tag = tags_dict["personnalises"][tag]
|
||||||
@ -123,49 +131,76 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Ajoute les moyennes par UEs + la moyenne générale (but)
|
# Ajoute les moyennes par UEs + la moyenne générale (but)
|
||||||
df_ues = pd.DataFrame(
|
moy_gen = self.compute_moy_gen()
|
||||||
{ue.id: self.etud_moy_ue[ue.id] for ue in ues_standards},
|
|
||||||
index=self.etudids,
|
|
||||||
)
|
|
||||||
# Transforme les UEs en acronyme
|
|
||||||
colonnes = df_ues.columns
|
|
||||||
acronymes = [self.ues_to_acronymes[col] for col in colonnes]
|
|
||||||
df_ues.columns = acronymes
|
|
||||||
|
|
||||||
self.moyennes_tags["but"] = MoyennesTag(
|
self.moyennes_tags["but"] = MoyennesTag(
|
||||||
"but", df_ues, self.matrice_coeffs_moy_gen # , moy_gen_but
|
"but", moy_gen, self.matrice_coeffs_moy_gen # , moy_gen_but
|
||||||
)
|
)
|
||||||
|
|
||||||
self.tags_sorted = self.get_all_tags()
|
self.tags_sorted = self.get_all_tags()
|
||||||
"""Tags (personnalisés+compétences) par ordre alphabétique"""
|
"""Tags (personnalisés+compétences) par ordre alphabétique"""
|
||||||
|
|
||||||
def get_repr(self, verbose=False):
|
def get_repr(self, verbose=False) -> str:
|
||||||
"""Nom affiché pour le semestre taggué"""
|
"""Nom affiché pour le semestre taggué, de la forme (par ex.):
|
||||||
if verbose:
|
|
||||||
return f"{self.formsemestre} (#{self.formsemestre.formsemestre_id})"
|
* S1#69 si verbose est False
|
||||||
|
* S1 FI 2023 si verbose est True
|
||||||
|
"""
|
||||||
|
if not verbose:
|
||||||
|
return f"{self.formsemestre}#{self.formsemestre.formsemestre_id}"
|
||||||
else:
|
else:
|
||||||
return pe_etudiant.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
return pe_etudiant.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
||||||
|
|
||||||
def _get_capitalisations(self, ues_hors_sport) -> pd.DataFrame:
|
def _get_matrice_coeffs(
|
||||||
"""Renvoie un dataFrame résumant les UEs capitalisables par les
|
self, ues_inscr_parcours_df: pd.DataFrame, ues_standards: list[UniteEns]
|
||||||
étudiants, d'après les décisions de jury
|
) -> pd.DataFrame:
|
||||||
|
"""Renvoie un dataFrame donnant les coefficients à appliquer aux UEs
|
||||||
|
dans le calcul de la moyenne générale (toutes UEs confondues).
|
||||||
|
Prend en compte l'inscription des étudiants aux UEs en fonction de leur parcours
|
||||||
|
(cf. ues_inscr_parcours_df).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ues_hors_sport: Liste des UEs autres que le sport
|
ues_inscr_parcours_df: Les inscriptions des étudiants aux UEs
|
||||||
|
ues_standards: Les UEs standards à prendre en compte
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Un dataFrame etudids x acronymes_UEs avec les coeffs des UEs
|
||||||
"""
|
"""
|
||||||
capitalisations = pd.DataFrame(False, index=self.etudids_sorted, columns=self.acronymes_sorted)
|
matrice_coeffs_moy_gen = ues_inscr_parcours_df * [
|
||||||
|
ue.ects for ue in ues_standards # if ue.type != UE_SPORT <= déjà supprimé
|
||||||
|
]
|
||||||
|
matrice_coeffs_moy_gen.columns = [
|
||||||
|
self.ues_to_acronymes[ue.id] for ue in ues_standards
|
||||||
|
]
|
||||||
|
# Tri par etudids (dim 0) et par acronymes (dim 1)
|
||||||
|
matrice_coeffs_moy_gen = matrice_coeffs_moy_gen.sort_index()
|
||||||
|
matrice_coeffs_moy_gen = matrice_coeffs_moy_gen.sort_index(axis=1)
|
||||||
|
return matrice_coeffs_moy_gen
|
||||||
|
|
||||||
|
def _get_capitalisations(self, ues_standards) -> pd.DataFrame:
|
||||||
|
"""Renvoie un dataFrame résumant les UEs capitalisables par les
|
||||||
|
étudiants, d'après les décisions de jury (sous réserve qu'elles existent).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ues_standards: Liste des UEs standards (notamment autres que le sport)
|
||||||
|
Returns:
|
||||||
|
Un dataFrame etudids x acronymes_UEs dont les valeurs sont ``True`` si l'UE
|
||||||
|
est capitalisable, ``False`` sinon
|
||||||
|
"""
|
||||||
|
capitalisations = pd.DataFrame(
|
||||||
|
False, index=self.etudids_sorted, columns=self.acronymes_sorted
|
||||||
|
)
|
||||||
self.get_formsemestre_validations() # charge les validations
|
self.get_formsemestre_validations() # charge les validations
|
||||||
res_jury = self.validations
|
res_jury = self.validations
|
||||||
if res_jury:
|
if res_jury:
|
||||||
for etud in self.etuds:
|
for etud in self.etuds:
|
||||||
etudid = etud.etudid
|
etudid = etud.etudid
|
||||||
decisions = res_jury.decisions_jury_ues.get(etudid, {})
|
decisions = res_jury.decisions_jury_ues.get(etudid, {})
|
||||||
for ue in ues_hors_sport:
|
for ue in ues_standards:
|
||||||
if ue.id in decisions and decisions[ue.id]["code"] == sco_codes.ADM:
|
if ue.id in decisions and decisions[ue.id]["code"] == sco_codes.ADM:
|
||||||
capitalisations.loc[etudid, ue.acronyme] = True
|
capitalisations.loc[etudid, ue.acronyme] = True
|
||||||
# pe_affichage.pe_print(
|
# Tri par etudis et par accronyme d'UE
|
||||||
# f" ⚠ Capitalisation de {ue.acronyme} pour {etud.etat_civil}"
|
capitalisations = capitalisations.sort_index()
|
||||||
# )
|
capitalisations = capitalisations.sort_index(axis=1)
|
||||||
return capitalisations
|
return capitalisations
|
||||||
|
|
||||||
def compute_moy_ues_tag(self, info_tag: dict[int, dict]) -> pd.DataFrame:
|
def compute_moy_ues_tag(self, info_tag: dict[int, dict]) -> pd.DataFrame:
|
||||||
@ -208,14 +243,38 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag):
|
|||||||
block=self.formsemestre.block_moyennes,
|
block=self.formsemestre.block_moyennes,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Ne conserve que les UEs standards
|
||||||
|
colonnes = [ue.id for ue in self.ues_standards]
|
||||||
|
moyennes_ues_tag = moyennes_ues_tag[colonnes]
|
||||||
|
|
||||||
# Transforme les UEs en acronyme
|
# Transforme les UEs en acronyme
|
||||||
colonnes = moyennes_ues_tag.columns
|
acronymes = [self.ues_to_acronymes[ue.id] for ue in self.ues_standards]
|
||||||
ue_to_acro = {ue.id: ue.acronyme for ue in self.ues}
|
|
||||||
acronymes = [ue_to_acro[col] for col in colonnes]
|
|
||||||
moyennes_ues_tag.columns = acronymes
|
moyennes_ues_tag.columns = acronymes
|
||||||
|
|
||||||
|
# Tri par etudids et par ordre alphabétique d'acronyme
|
||||||
|
moyennes_ues_tag = moyennes_ues_tag.sort_index()
|
||||||
|
moyennes_ues_tag = moyennes_ues_tag.sort_index(axis=1)
|
||||||
|
|
||||||
return moyennes_ues_tag
|
return moyennes_ues_tag
|
||||||
|
|
||||||
|
def compute_moy_gen(self):
|
||||||
|
"""Récupère les moyennes des UEs pour le calcul de la moyenne générale,
|
||||||
|
en associant à chaque UE.id son acronyme (toutes UEs confondues)
|
||||||
|
"""
|
||||||
|
df_ues = pd.DataFrame(
|
||||||
|
{ue.id: self.etud_moy_ue[ue.id] for ue in self.ues_standards},
|
||||||
|
index=self.etudids,
|
||||||
|
)
|
||||||
|
# Transforme les UEs en acronyme
|
||||||
|
colonnes = df_ues.columns
|
||||||
|
acronymes = [self.ues_to_acronymes[col] for col in colonnes]
|
||||||
|
df_ues.columns = acronymes
|
||||||
|
|
||||||
|
# Tri par ordre aphabétique de colonnes
|
||||||
|
df_ues.sort_index(axis=1)
|
||||||
|
|
||||||
|
return df_ues
|
||||||
|
|
||||||
def _get_tags_dict(self):
|
def _get_tags_dict(self):
|
||||||
"""Renvoie les tags personnalisés (déduits des modules du semestre)
|
"""Renvoie les tags personnalisés (déduits des modules du semestre)
|
||||||
et les tags automatiques ('but'), et toutes leurs informations,
|
et les tags automatiques ('but'), et toutes leurs informations,
|
||||||
|
@ -54,20 +54,24 @@ class SxTag(TableTag):
|
|||||||
ressembuttags: dict[int, pe_ressemtag.ResSemBUTTag],
|
ressembuttags: dict[int, pe_ressemtag.ResSemBUTTag],
|
||||||
):
|
):
|
||||||
"""Calcule les moyennes/classements par tag d'un semestre de type 'Sx'
|
"""Calcule les moyennes/classements par tag d'un semestre de type 'Sx'
|
||||||
(par ex. 'S1', 'S2', ...) avec une orientation par UE :
|
(par ex. 'S1', 'S2', ...) représentés par acronyme d'UE.
|
||||||
|
|
||||||
* pour les étudiants non redoublants, ce sont les moyennes/classements
|
Il représente :
|
||||||
|
|
||||||
|
* pour les étudiants *non redoublants* : moyennes/classements
|
||||||
du semestre suivi
|
du semestre suivi
|
||||||
* pour les étudiants redoublants, c'est une fusion des moyennes/classements
|
* pour les étudiants *redoublants* : une fusion des moyennes/classements
|
||||||
dans les (2) 'Sx' qu'il a suivi
|
dans les (2) 'Sx' qu'il a suivi, en exploitant les informations de capitalisation :
|
||||||
|
meilleure moyenne entre l'UE capitalisée et l'UE refaite (la notion de meilleure
|
||||||
|
s'appliquant à la moyenne d'UE)
|
||||||
|
|
||||||
Un SxTag peut donc regrouper plusieurs semestres.
|
Un SxTag (regroupant potentiellement plusieurs semestres) est identifié
|
||||||
|
par un tuple ``(Sx, fid)`` où :
|
||||||
|
|
||||||
Un SxTag est identifié par un tuple (x, fid) où x est le numéro (semestre_id)
|
* ``x`` est le rang (semestre_id) du semestre
|
||||||
du semestre et fid le formsemestre_id du semestre final (le plus récent) du
|
* ``fid`` le formsemestre_id du semestre final (le plus récent) du regroupement.
|
||||||
regrouprement.
|
|
||||||
|
|
||||||
Les **tags**, les **UE** et les inscriptions aux UEs (pour les etudiants)
|
Les **tags**, les **UE** et les inscriptions aux UEs (pour les étudiants)
|
||||||
considérés sont uniquement ceux du semestre final.
|
considérés sont uniquement ceux du semestre final.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -85,6 +89,7 @@ class SxTag(TableTag):
|
|||||||
|
|
||||||
self.rcf = rcf
|
self.rcf = rcf
|
||||||
"""Le RCF sur lequel il s'appuie"""
|
"""Le RCF sur lequel il s'appuie"""
|
||||||
|
assert rcf.rcs_id == sxtag_id, "Problème de correspondance SxTag/RCF"
|
||||||
|
|
||||||
# Les resultats des semestres taggués à prendre en compte dans le RCF
|
# Les resultats des semestres taggués à prendre en compte dans le RCF
|
||||||
self.ressembuttags = {fid: ressembuttags[fid] for fid in rcf.semestres_aggreges}
|
self.ressembuttags = {fid: ressembuttags[fid] for fid in rcf.semestres_aggreges}
|
||||||
@ -95,10 +100,9 @@ class SxTag(TableTag):
|
|||||||
self.ressembuttag_final = ressembuttags[self.fid_final]
|
self.ressembuttag_final = ressembuttags[self.fid_final]
|
||||||
"""Le ResSemBUTTag final"""
|
"""Le ResSemBUTTag final"""
|
||||||
|
|
||||||
self.etuds = ressembuttags[self.fid_final].etuds
|
# Ajoute les etudids et les états civils
|
||||||
"""Les étudiants du ReSemBUTTag final"""
|
self.etuds = self.ressembuttag_final.etuds
|
||||||
|
"""Les étudiants (extraits du ReSemBUTTag final)"""
|
||||||
# Ajout les etudids et les états civils
|
|
||||||
self.add_etuds(self.etuds)
|
self.add_etuds(self.etuds)
|
||||||
self.etudids_sorted = sorted(self.etudids)
|
self.etudids_sorted = sorted(self.etudids)
|
||||||
"""Les etudids triés"""
|
"""Les etudids triés"""
|
||||||
@ -108,88 +112,93 @@ class SxTag(TableTag):
|
|||||||
|
|
||||||
# Les tags
|
# Les tags
|
||||||
self.tags_sorted = self.ressembuttag_final.tags_sorted
|
self.tags_sorted = self.ressembuttag_final.tags_sorted
|
||||||
"""Tags (extraits uniquement du semestre final)"""
|
"""Tags (extraits du ReSemBUTTag final)"""
|
||||||
pe_affichage.pe_print(f"* Tags : {', '.join(self.tags_sorted)}")
|
pe_affichage.pe_print(f"* Tags : {', '.join(self.tags_sorted)}")
|
||||||
|
|
||||||
# Les UE
|
# Les UE données par leur acronyme
|
||||||
moy_sem_final = self.ressembuttag_final.moyennes_tags["but"]
|
self.acronymes_sorted = self.ressembuttag_final.acronymes_sorted
|
||||||
self.ues = list(moy_sem_final.matrice_notes.columns)
|
"""Les acronymes des UEs (extraits du ResSemBUTTag final)"""
|
||||||
|
|
||||||
# L'association UE-compétences extraites du dernier semestre
|
# L'association UE-compétences extraites du dernier semestre
|
||||||
self.competences = self.ressembuttag_final.competences
|
self.acronymes_ues_to_competences = (
|
||||||
|
self.ressembuttag_final.acronymes_ues_to_competences
|
||||||
|
)
|
||||||
|
"""L'association acronyme d'UEs -> compétence"""
|
||||||
|
self.competences_sorted = sorted(self.acronymes_ues_to_competences.values())
|
||||||
|
"""Les compétences triées par nom"""
|
||||||
|
|
||||||
# Les acronymes des UE
|
# Les coeffs pour la moyenne générale (traduisant également l'inscription
|
||||||
self.acronymes_ues_sorted = sorted(self.ues)
|
# des étudiants aux UEs) (etudids_sorted x acronymes_ues_sorted)
|
||||||
|
self.matrice_coeffs_moy_gen = self.ressembuttag_final.matrice_coeffs_moy_gen
|
||||||
# Les inscriptions des étudiants aux UEs
|
|
||||||
# => ne conserve que les UEs du semestre final (pour les redoublants)
|
|
||||||
self.ues_inscr_parcours_df = self.ressembuttag_final.ues_inscr_parcours_df
|
|
||||||
self.ues_inscr_parcours_df.sort_index()
|
|
||||||
|
|
||||||
# Les coeffs pour la moyenne générale
|
|
||||||
self.matrice_coeffs_moy_gen = self.ressembuttag_final.moyennes_tags[
|
|
||||||
"but"
|
|
||||||
].matrice_coeffs_moy_gen
|
|
||||||
self.matrice_coeffs_moy_gen.sort_index() # Trie les coeff par etudids
|
|
||||||
|
|
||||||
# Les moyennes par tag
|
|
||||||
self.moyennes_tags: dict[str, pd.DataFrame] = {}
|
|
||||||
"""Les notes aux UEs dans différents tags"""
|
|
||||||
|
|
||||||
# Masque des inscriptions et des capitalisations
|
# Masque des inscriptions et des capitalisations
|
||||||
self.masque_df, masque_cube = compute_masques_ues_cube(
|
self.masque_df = None
|
||||||
|
"""Le DataFrame traduisant les capitalisations des différents semestres"""
|
||||||
|
self.masque_df, masque_cube = compute_masques_capitalisation_cube(
|
||||||
self.etudids_sorted,
|
self.etudids_sorted,
|
||||||
self.acronymes_ues_sorted,
|
self.acronymes_sorted,
|
||||||
self.ressembuttags,
|
self.ressembuttags,
|
||||||
self.fid_final,
|
self.fid_final,
|
||||||
)
|
)
|
||||||
self._aff_capitalisations()
|
self._aff_capitalisations()
|
||||||
|
|
||||||
|
# Les moyennes par tag
|
||||||
|
self.moyennes_tags: dict[str, pd.DataFrame] = {}
|
||||||
|
"""Moyennes aux UEs (identifiées par leur acronyme) des différents tags"""
|
||||||
for tag in self.tags_sorted:
|
for tag in self.tags_sorted:
|
||||||
# Y-a-t-il des notes ?
|
# Y-a-t-il des notes ?
|
||||||
if not self.has_notes(tag):
|
if not self.has_notes(tag):
|
||||||
pe_affichage.pe_print(f"> MoyTag 🏷{tag} actuellement sans ◯ notes")
|
pe_affichage.pe_print(f"> MoyTag 🏷{tag} actuellement sans ◯ notes")
|
||||||
matrice_moys_ues = pd.DataFrame(np.nan, index=self.etudids_sorted, columns=self.acronymes_ues_sorted)
|
matrice_moys_ues = pd.DataFrame(
|
||||||
|
np.nan, index=self.etudids_sorted, columns=self.acronymes_sorted
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# Cube de note etudids x UEs
|
# Cube de note etudids x UEs
|
||||||
notes_df, notes_cube = compute_notes_ues_cube(
|
notes_df, notes_cube = compute_notes_ues_cube(
|
||||||
tag,
|
tag,
|
||||||
self.etudids_sorted,
|
self.etudids_sorted,
|
||||||
self.acronymes_ues_sorted,
|
self.acronymes_sorted,
|
||||||
self.ressembuttags,
|
self.ressembuttags,
|
||||||
)
|
)
|
||||||
|
|
||||||
# self.ues_inscr_parcours = ~np.isnan(self.matrice_coeffs.to_numpy())
|
# Masque des inscriptions aux UEs (extraits de la matrice de coefficients)
|
||||||
# inscr_mask = self.ues_inscr_parcours
|
inscr_mask: np.array = ~np.isnan(self.matrice_coeffs_moy_gen.to_numpy())
|
||||||
|
|
||||||
# Calcule des moyennes sous forme d'un dataframe
|
# Matrice des moyennes
|
||||||
inscr_mask = ~np.isnan(self.ues_inscr_parcours_df.to_numpy())
|
|
||||||
matrice_moys_ues: pd.DataFrame = compute_notes_ues(
|
matrice_moys_ues: pd.DataFrame = compute_notes_ues(
|
||||||
notes_cube,
|
notes_cube,
|
||||||
masque_cube,
|
masque_cube,
|
||||||
self.etudids_sorted,
|
self.etudids_sorted,
|
||||||
self.acronymes_ues_sorted,
|
self.acronymes_sorted,
|
||||||
inscr_mask,
|
inscr_mask,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Les profils d'ects (pour debug)
|
# Affichage de debug
|
||||||
profils_ects = []
|
self.__aff_profil_coeff_ects(tag)
|
||||||
for i in self.matrice_coeffs_moy_gen.index:
|
|
||||||
val = tuple(self.matrice_coeffs_moy_gen.loc[i].fillna("x"))
|
|
||||||
if tuple(val) not in profils_ects:
|
|
||||||
profils_ects.append(tuple(val))
|
|
||||||
pe_affichage.pe_print(
|
|
||||||
f"> MoyTag 🏷{tag} avec "
|
|
||||||
+ f"ues={self.acronymes_ues_sorted} "
|
|
||||||
+ f"ects={profils_ects}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Les moyennes au tag
|
# Mémorise les infos pour la moyennes au tag
|
||||||
self.moyennes_tags[tag] = MoyennesTag(
|
self.moyennes_tags[tag] = MoyennesTag(
|
||||||
tag, matrice_moys_ues, self.matrice_coeffs_moy_gen
|
tag, matrice_moys_ues, self.matrice_coeffs_moy_gen
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __aff_profil_coeff_ects(self, tag):
|
||||||
|
"""Extrait de la matrice des coeffs, les différents types d'inscription
|
||||||
|
et de coefficients (appelés profil) des étudiants et les affiche
|
||||||
|
(pour debug)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Les profils d'ects (pour debug)
|
||||||
|
profils_ects = []
|
||||||
|
for i in self.matrice_coeffs_moy_gen.index:
|
||||||
|
val = tuple(self.matrice_coeffs_moy_gen.loc[i].fillna("x"))
|
||||||
|
if tuple(val) not in profils_ects:
|
||||||
|
profils_ects.append(tuple(val))
|
||||||
|
|
||||||
|
# L'affichage
|
||||||
|
ues = ", ".join(self.acronymes_sorted)
|
||||||
|
pe_affichage.pe_print(
|
||||||
|
f"> MoyTag 🏷{tag} avec " + f"ues={ues} " + f"inscr/ects={profils_ects}"
|
||||||
|
)
|
||||||
|
|
||||||
def has_notes(self, tag):
|
def has_notes(self, tag):
|
||||||
"""Détermine si le SxTag, pour un tag donné, est en cours d'évaluation.
|
"""Détermine si le SxTag, pour un tag donné, est en cours d'évaluation.
|
||||||
@ -229,7 +238,7 @@ class SxTag(TableTag):
|
|||||||
cap = []
|
cap = []
|
||||||
for frmsem_id in self.ressembuttags:
|
for frmsem_id in self.ressembuttags:
|
||||||
if frmsem_id != self.fid_final:
|
if frmsem_id != self.fid_final:
|
||||||
for accr in self.acronymes_ues_sorted:
|
for accr in self.acronymes_sorted:
|
||||||
if self.masque_df[frmsem_id].loc[etud.etudid, accr] > 0.0:
|
if self.masque_df[frmsem_id].loc[etud.etudid, accr] > 0.0:
|
||||||
cap += [accr]
|
cap += [accr]
|
||||||
if cap:
|
if cap:
|
||||||
@ -239,7 +248,7 @@ class SxTag(TableTag):
|
|||||||
|
|
||||||
|
|
||||||
def compute_notes_ues_cube(
|
def compute_notes_ues_cube(
|
||||||
tag, etudids_sorted, acronymes_ues_sorted, ressembuttags
|
tag, etudids_sorted, acronymes_sorted, ressembuttags
|
||||||
) -> (pd.DataFrame, np.array):
|
) -> (pd.DataFrame, np.array):
|
||||||
"""Construit le cube de notes des UEs (etudid x accronyme_ue x semestre_aggregé)
|
"""Construit le cube de notes des UEs (etudid x accronyme_ue x semestre_aggregé)
|
||||||
nécessaire au calcul des moyennes du tag pour le RCS Sx.
|
nécessaire au calcul des moyennes du tag pour le RCS Sx.
|
||||||
@ -247,7 +256,7 @@ def compute_notes_ues_cube(
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
etudids_sorted: La liste des etudids triés par ordre croissant (dim 0)
|
etudids_sorted: La liste des etudids triés par ordre croissant (dim 0)
|
||||||
acronymes_ues_sorted: La liste des acronymes de UEs triés par acronyme croissant (dim 1)
|
acronymes_sorted: La liste des acronymes de UEs triés par acronyme croissant (dim 1)
|
||||||
ressembuttags: Le dictionnaire des résultats de semestres BUT (tous tags confondus)
|
ressembuttags: Le dictionnaire des résultats de semestres BUT (tous tags confondus)
|
||||||
"""
|
"""
|
||||||
# Index du cube (etudids -> dim 0, ues -> dim 1, semestres -> dim2)
|
# Index du cube (etudids -> dim 0, ues -> dim 1, semestres -> dim2)
|
||||||
@ -259,7 +268,7 @@ def compute_notes_ues_cube(
|
|||||||
|
|
||||||
for frmsem_id in semestres_id:
|
for frmsem_id in semestres_id:
|
||||||
# Partant d'un dataframe vierge
|
# Partant d'un dataframe vierge
|
||||||
df = pd.DataFrame(np.nan, index=etudids_sorted, columns=acronymes_ues_sorted)
|
df = pd.DataFrame(np.nan, index=etudids_sorted, columns=acronymes_sorted)
|
||||||
|
|
||||||
# Charge les notes du semestre tag
|
# Charge les notes du semestre tag
|
||||||
sem_tag = ressembuttags[frmsem_id]
|
sem_tag = ressembuttags[frmsem_id]
|
||||||
@ -289,23 +298,27 @@ def compute_notes_ues_cube(
|
|||||||
return dfs, etudids_x_ues_x_semestres
|
return dfs, etudids_x_ues_x_semestres
|
||||||
|
|
||||||
|
|
||||||
def compute_masques_ues_cube(
|
def compute_masques_capitalisation_cube(
|
||||||
etudids_sorted: list[int],
|
etudids_sorted: list[int],
|
||||||
acronymes_ues_sorted: list[str],
|
acronymes_sorted: list[str],
|
||||||
ressembuttags: dict[int, pe_ressemtag.ResSemBUTTag],
|
ressembuttags: dict[int, pe_ressemtag.ResSemBUTTag],
|
||||||
formsemestre_id_final: int,
|
formsemestre_id_final: int,
|
||||||
) -> (pd.DataFrame, np.array):
|
) -> (pd.DataFrame, np.array):
|
||||||
"""Construit le cube traduisant le masque des UEs à prendre en compte dans le calcul
|
"""Construit le cube traduisant les masques des UEs à prendre en compte dans le calcul
|
||||||
des moyennes, en utilisant le df capitalisations de chaque ResSemBUTTag
|
des moyennes, en utilisant le dataFrame de capitalisations de chaque ResSemBUTTag
|
||||||
|
|
||||||
Ce masque contient : 1 si la note doit être prise en compte ; 0 sinon
|
Ces masques contiennent : 1 si la note doit être prise en compte, 0 sinon
|
||||||
|
|
||||||
|
Le masque des UEs à prendre en compte correspondant au semestre final (identifié par
|
||||||
|
son formsemestre_id_final) est systématiquement à 1 (puisque les résultats
|
||||||
|
de ce semestre doivent systématiquement
|
||||||
|
être pris en compte notamment pour les étudiants non redoublant).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
etudids_sorted: La liste des etudids triés par ordre croissant (dim 0)
|
etudids_sorted: La liste des etudids triés par ordre croissant (dim 0)
|
||||||
acronymes_ues_sorted: La liste des acronymes de UEs triés par acronyme croissant (dim 1)
|
acronymes_sorted: La liste des acronymes de UEs triés par acronyme croissant (dim 1)
|
||||||
# ues_inscr_parcours_df: Le dataFrame des inscriptions au UE en fonction du parcours
|
|
||||||
ressembuttags: Le dictionnaire des résultats de semestres BUT (tous tags confondus)
|
ressembuttags: Le dictionnaire des résultats de semestres BUT (tous tags confondus)
|
||||||
formsemestre_id_final: L'identifiant du formsemestre_id_final (dont il faut forcément prendre en compte les coeffs)
|
formsemestre_id_final: L'identifiant du formsemestre_id_final
|
||||||
"""
|
"""
|
||||||
# Index du cube (etudids -> dim 0, ues -> dim 1, semestres -> dim2)
|
# Index du cube (etudids -> dim 0, ues -> dim 1, semestres -> dim2)
|
||||||
# etudids_sorted = etudids_sorted
|
# etudids_sorted = etudids_sorted
|
||||||
@ -317,15 +330,16 @@ def compute_masques_ues_cube(
|
|||||||
for frmsem_id in semestres_id:
|
for frmsem_id in semestres_id:
|
||||||
# Partant d'un dataframe contenant des 1.0
|
# Partant d'un dataframe contenant des 1.0
|
||||||
if frmsem_id == formsemestre_id_final:
|
if frmsem_id == formsemestre_id_final:
|
||||||
df = pd.DataFrame(1.0, index=etudids_sorted, columns=acronymes_ues_sorted)
|
df = pd.DataFrame(1.0, index=etudids_sorted, columns=acronymes_sorted)
|
||||||
else: # semestres redoublés
|
else: # semestres redoublés
|
||||||
df = pd.DataFrame(0.0, index=etudids_sorted, columns=acronymes_ues_sorted)
|
df = pd.DataFrame(0.0, index=etudids_sorted, columns=acronymes_sorted)
|
||||||
|
|
||||||
# Traitement des capitalisations
|
# Traitement des capitalisations : remplace les infos de capitalisations par les coeff 1 ou 0
|
||||||
capitalisations = ressembuttags[frmsem_id].capitalisations
|
capitalisations = ressembuttags[frmsem_id].capitalisations
|
||||||
capitalisations = capitalisations.replace(True, 1.0).replace(False, 0.0)
|
capitalisations = capitalisations.replace(True, 1.0).replace(False, 0.0)
|
||||||
|
|
||||||
# Met à 0 les coeffs des UEs non capitalisées : 1.0*False => 0.0
|
# Met à 0 les coeffs des UEs non capitalisées pour les étudiants
|
||||||
|
# inscrits dans les 2 semestres: 1.0*False => 0.0
|
||||||
etudids_communs, acronymes_communs = pe_comp.find_index_and_columns_communs(
|
etudids_communs, acronymes_communs = pe_comp.find_index_and_columns_communs(
|
||||||
df, capitalisations
|
df, capitalisations
|
||||||
)
|
)
|
||||||
@ -347,7 +361,7 @@ def compute_notes_ues(
|
|||||||
set_cube: np.array,
|
set_cube: np.array,
|
||||||
masque_cube: np.array,
|
masque_cube: np.array,
|
||||||
etudids_sorted: list,
|
etudids_sorted: list,
|
||||||
acronymes_ues_sorted: list,
|
acronymes_sorted: list,
|
||||||
inscr_mask: np.array,
|
inscr_mask: np.array,
|
||||||
):
|
):
|
||||||
"""Calcule la moyenne par UEs à un tag donné en prenant la note maximum (UE
|
"""Calcule la moyenne par UEs à un tag donné en prenant la note maximum (UE
|
||||||
@ -359,7 +373,7 @@ def compute_notes_ues(
|
|||||||
masque_cube: masque indiquant si la note doit être prise en compte ndarray
|
masque_cube: masque indiquant si la note doit être prise en compte ndarray
|
||||||
(semestre_ids x etudids x UEs), des 1.0 ou des 0.0
|
(semestre_ids x etudids x UEs), des 1.0 ou des 0.0
|
||||||
etudids_sorted: liste des étudiants (dim. 0 du cube) trié par etudid
|
etudids_sorted: liste des étudiants (dim. 0 du cube) trié par etudid
|
||||||
acronymes_ues_sorted: liste des acronymes des ues (dim. 1 du cube) trié par acronyme
|
acronymes_sorted: liste des acronymes des ues (dim. 1 du cube) trié par acronyme
|
||||||
inscr_mask: masque etudids x UE traduisant les inscriptions des
|
inscr_mask: masque etudids x UE traduisant les inscriptions des
|
||||||
étudiants aux UE (du semestre terminal)
|
étudiants aux UE (du semestre terminal)
|
||||||
Returns:
|
Returns:
|
||||||
@ -369,7 +383,7 @@ def compute_notes_ues(
|
|||||||
nb_etuds, nb_ues, nb_semestres = set_cube.shape
|
nb_etuds, nb_ues, nb_semestres = set_cube.shape
|
||||||
nb_etuds_mask, nb_ues_mask = inscr_mask.shape
|
nb_etuds_mask, nb_ues_mask = inscr_mask.shape
|
||||||
assert nb_etuds == len(etudids_sorted)
|
assert nb_etuds == len(etudids_sorted)
|
||||||
assert nb_ues == len(acronymes_ues_sorted)
|
assert nb_ues == len(acronymes_sorted)
|
||||||
assert nb_etuds == nb_etuds_mask
|
assert nb_etuds == nb_etuds_mask
|
||||||
assert nb_ues == nb_ues_mask
|
assert nb_ues == nb_ues_mask
|
||||||
|
|
||||||
@ -397,7 +411,7 @@ def compute_notes_ues(
|
|||||||
etud_moy_tag_df = pd.DataFrame(
|
etud_moy_tag_df = pd.DataFrame(
|
||||||
etud_moy,
|
etud_moy,
|
||||||
index=etudids_sorted, # les etudids
|
index=etudids_sorted, # les etudids
|
||||||
columns=acronymes_ues_sorted, # les tags
|
columns=acronymes_sorted, # les acronymes d'UEs
|
||||||
)
|
)
|
||||||
|
|
||||||
etud_moy_tag_df.fillna(np.nan)
|
etud_moy_tag_df.fillna(np.nan)
|
||||||
|
@ -105,7 +105,7 @@ def associe_ues_et_parcours(formation: Formation, formation_infos: dict):
|
|||||||
|
|
||||||
# Niveaux compétences:
|
# Niveaux compétences:
|
||||||
if ue_infos.get("competence"):
|
if ue_infos.get("competence"):
|
||||||
competence = referentiel_competence.competences.filter_by(
|
competence = referentiel_competence.acronymes_ues_to_competences.filter_by(
|
||||||
titre=ue_infos["competence"]
|
titre=ue_infos["competence"]
|
||||||
).first()
|
).first()
|
||||||
assert competence is not None # La compétence de titre indiqué doit exister
|
assert competence is not None # La compétence de titre indiqué doit exister
|
||||||
|
Loading…
Reference in New Issue
Block a user