1
0
forked from ScoDoc/ScoDoc

Fin traitement coeffs

This commit is contained in:
Cléo Baras 2024-02-26 12:03:19 +01:00
parent 57d616da1a
commit a50bbe9223
7 changed files with 74 additions and 53 deletions

View File

@ -84,7 +84,7 @@ class InterClassTag(pe_tabletags.TableTag):
self.type = type_interclassement self.type = type_interclassement
pe_affichage.pe_print( pe_affichage.pe_print(
f"--> Interclassement par 🗂️{type_interclassement} pour le RCS ⏯️{nom_rcs}" f"*** Interclassement par 🗂️{type_interclassement} pour le RCS ⏯️{nom_rcs}"
) )
# Les informations sur les étudiants diplômés # Les informations sur les étudiants diplômés
@ -119,13 +119,20 @@ class InterClassTag(pe_tabletags.TableTag):
# Les données sur les tags # Les données sur les tags
self.tags_sorted = self._do_taglist() self.tags_sorted = self._do_taglist()
"""Liste des tags (triés par ordre alphabétique)""" """Liste des tags (triés par ordre alphabétique)"""
aff_tag = ["👜" + tag for tag in self.tags_sorted] aff = pe_affichage.aff_tag(self.tags_sorted)
pe_affichage.pe_print(f"--> Tags : {', '.join(aff_tag)}") pe_affichage.pe_print(f"--> Tags : {aff}")
# Les données sur les UEs (si SxTag) ou compétences (si RCSTag) # Les données sur les UEs (si SxTag) ou compétences (si RCSTag)
self.champs_sorted = self._do_ues_ou_competences_list() self.champs_sorted = self._do_ues_ou_competences_list()
"""Les champs (UEs ou compétences) de l'interclassement""" """Les champs (UEs ou compétences) de l'interclassement"""
self._aff_comp_ou_ues_debug() if self.type == pe_moytag.CODE_MOY_UE:
pe_affichage.pe_print(
f"--> UEs : {pe_affichage.aff_UEs(self.champs_sorted)}"
)
else:
pe_affichage.pe_print(
f"--> Compétences : {pe_affichage.aff_competences(self.champs_sorted)}"
)
# Construit la matrice de notes # Construit la matrice de notes
etudids_sorted = sorted(list(self.diplomes_ids)) etudids_sorted = sorted(list(self.diplomes_ids))
@ -136,15 +143,14 @@ class InterClassTag(pe_tabletags.TableTag):
# Synthétise les moyennes/classements par tag # Synthétise les moyennes/classements par tag
self.moyennes_tags: dict[str, pe_moytag.MoyennesTag] = {} self.moyennes_tags: dict[str, pe_moytag.MoyennesTag] = {}
for tag in self.tags_sorted: for tag in self.tags_sorted:
pe_affichage.pe_print(f"--> Moyenne 👜{tag} : ")
notes = self.compute_notes_matrice(tag, etudids_sorted, self.champs_sorted) notes = self.compute_notes_matrice(tag, etudids_sorted, self.champs_sorted)
coeffs = self.compute_coeffs_matrice( coeffs = self.compute_coeffs_matrice(
tag, etudids_sorted, self.champs_sorted tag, etudids_sorted, self.champs_sorted
) )
self.__aff_profil_coeffs(coeffs) aff = pe_affichage.aff_profil_coeffs(coeffs, with_index=True)
pe_affichage.pe_print(f"--> Moyenne 👜{tag} avec coeffs: {aff} ")
self.moyennes_tags[tag] = pe_moytag.MoyennesTag( self.moyennes_tags[tag] = pe_moytag.MoyennesTag(
tag, tag,
@ -248,7 +254,7 @@ class InterClassTag(pe_tabletags.TableTag):
for rcstag in self.rcstags.values(): for rcstag in self.rcstags.values():
if tag in rcstag.moyennes_tags: if tag in rcstag.moyennes_tags:
# Charge les coeffs au tag d'un RCStag # Charge les coeffs au tag d'un RCStag
coeffs: pd.DataFrame = rcstag.moyennes_tags[tag].matrice_notes coeffs: pd.DataFrame = rcstag.moyennes_tags[tag].matrice_coeffs_moy_gen
# Etudiants/Champs communs entre le RCSTag et les données interclassées # Etudiants/Champs communs entre le RCSTag et les données interclassées
( (
@ -279,21 +285,6 @@ class InterClassTag(pe_tabletags.TableTag):
dict_champs.extend(champs) dict_champs.extend(champs)
return sorted(set(dict_champs)) return sorted(set(dict_champs))
def _aff_comp_ou_ues_debug(self):
"""Affichage pour debug"""
aff_comp = []
for comp in self.champs_sorted:
liste = []
if self.type == pe_moytag.CODE_MOY_UE:
liste += ["📍" + comp]
else:
liste += ["💡" + comp]
if self.type == pe_moytag.CODE_MOY_UE:
pe_affichage.pe_print(f"--> UEs : {', '.join(aff_comp)}")
else:
pe_affichage.pe_print(f"--> Compétences : {', '.join(aff_comp)}")
def has_tags(self): def has_tags(self):
"""Indique si l'interclassement a des tags (cas d'un """Indique si l'interclassement a des tags (cas d'un
interclassement sur un S5 qui n'a pas eu lieu) interclassement sur un S5 qui n'a pas eu lieu)

View File

@ -99,7 +99,9 @@ class Moyenne:
def get_df_synthese(self): def get_df_synthese(self):
"""Renvoie le df de synthese limité aux colonnes de synthese""" """Renvoie le df de synthese limité aux colonnes de synthese"""
return self.df[self.COLONNES_SYNTHESE] df = self.df[self.COLONNES_SYNTHESE].copy()
df["rang"] = df["rang"].replace("nan", "")
return df
def to_dict(self) -> dict: def to_dict(self) -> dict:
"""Renvoie un dictionnaire de synthèse des moyennes/classements/statistiques générale (but)""" """Renvoie un dictionnaire de synthèse des moyennes/classements/statistiques générale (but)"""

View File

@ -173,7 +173,10 @@ class RCSemXTag(pe_tabletags.TableTag):
self.etudids_sorted, self.etudids_sorted,
self.competences_sorted, self.competences_sorted,
) )
pe_affichage.aff_profil_coeffs(matrice_coeffs_moy_gen) aff = pe_affichage.aff_profil_coeffs(
matrice_coeffs_moy_gen, with_index=True
)
pe_affichage.pe_print(f" > Moyenne calculée avec pour coeffs : {aff}")
# Mémorise les moyennes et les coeff associés # Mémorise les moyennes et les coeff associés
self.moyennes_tags[tag] = pe_moytag.MoyennesTag( self.moyennes_tags[tag] = pe_moytag.MoyennesTag(
@ -344,23 +347,19 @@ class RCSemXTag(pe_tabletags.TableTag):
inscription_df = pd.DataFrame( inscription_df = pd.DataFrame(
0, index=etudids_sorted, columns=competences_sorted 0, index=etudids_sorted, columns=competences_sorted
) )
# Les étudiants dont les résultats au sxtag ont été calculés
etudids_sxtag = sxtag.etudids_sorted
# Les étudiants communs
etudids_communs = sorted(set(etudids_sorted) & set(etudids_sxtag))
# Acte l'inscription
inscription_df.loc[etudids_communs, :] = 1
# Stocke les dfs # Stocke les dfs
inscriptions_dfs[sxtag_id] = inscription_df inscriptions_dfs[sxtag_id] = inscription_df
for etudid in etudids_sorted:
for sem in self.rcsemx.aggregat:
if etudid in self.semXs_suivis:
semx_suivi = self.semXs_suivis[etudid][sem]
if semx_suivi:
semx_suivi_id = semx_suivi.rcs_id
if semx_suivi_id not in self.sxtags_connus:
pe_affichage.pe_print(
f"Un SxTag est manquant : {semx_suivi_id}"
)
if semx_suivi_id in inscriptions_dfs:
# Si le sxtag est l'un des siens
inscriptions_dfs[semx_suivi_id].loc[etudid, :] = 1
"""Réunit les inscriptions sous forme d'un cube etudids x competences x semestres""" """Réunit les inscriptions sous forme d'un cube etudids x competences x semestres"""
sxtag_x_etudids_x_comps = [inscriptions_dfs[sxtag_id] for sxtag_id in sxstags] sxtag_x_etudids_x_comps = [inscriptions_dfs[sxtag_id] for sxtag_id in sxstags]
inscriptions_etudids_x_comps_x_sxtag = np.stack( inscriptions_etudids_x_comps_x_sxtag = np.stack(
@ -434,14 +433,13 @@ def compute_coeffs_competences(
# Applique le masque des inscriptions aux coeffs et aux notes # Applique le masque des inscriptions aux coeffs et aux notes
coeffs_significatifs = coeff_cube * inscriptions coeffs_significatifs = coeff_cube * inscriptions
set_cube_significatif = set_cube * inscriptions
# Quelles entrées du cube contiennent des notes ?
mask = ~np.isnan(set_cube_significatif)
# 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
coeffs_cube_no_nan = np.nan_to_num(coeffs_significatifs, nan=0.0) coeffs_cube_no_nan = np.nan_to_num(coeffs_significatifs, nan=0.0)
# Quelles entrées du cube contiennent des notes ?
mask = ~np.isnan(set_cube)
# Retire les coefficients associés à des données sans notes # Retire les coefficients associés à des données sans notes
coeffs_cube_no_nan = coeffs_cube_no_nan * mask coeffs_cube_no_nan = coeffs_cube_no_nan * mask
@ -453,7 +451,7 @@ def compute_coeffs_competences(
coeff_tag, index=etudids_sorted, columns=competences_sorted coeff_tag, index=etudids_sorted, columns=competences_sorted
) )
# Remet à Nan les coeffs à 0 # Remet à Nan les coeffs à 0
coeffs_df.fillna(np.nan) coeffs_df = coeffs_df.fillna(np.nan)
return coeffs_df return coeffs_df

View File

@ -8,7 +8,7 @@
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved. # Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU Generfal Public License as published by
# the Free Software Foundation; either version 2 of the License, or # the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #

View File

@ -189,7 +189,10 @@ class SxTag(pe_tabletags.TableTag):
) )
# Affichage de debug # Affichage de debug
self.__aff_profil_coeff_ects(tag) aff = pe_affichage.aff_profil_coeffs(
self.matrice_coeffs_moy_gen, with_index=True
)
pe_affichage.pe_print(f" > MoyTag 👜{tag} : {aff}")
# Mémorise les infos pour la moyennes au tag # Mémorise les infos pour la moyennes au tag
self.moyennes_tags[tag] = pe_moytag.MoyennesTag( self.moyennes_tags[tag] = pe_moytag.MoyennesTag(
@ -471,6 +474,6 @@ def compute_notes_ues(
columns=acronymes_sorted, # les acronymes d'UEs columns=acronymes_sorted, # les acronymes d'UEs
) )
etud_moy_tag_df.fillna(np.nan) etud_moy_tag_df = etud_moy_tag_df.fillna(np.nan)
return etud_moy_tag_df return etud_moy_tag_df

View File

@ -9,7 +9,7 @@
from flask import g from flask import g
from app import log from app import log
PE_DEBUG = True PE_DEBUG = False
# On stocke les logs PE dans g.scodoc_pe_log # On stocke les logs PE dans g.scodoc_pe_log
@ -76,6 +76,31 @@ def aff_profil_coeffs(matrice_coeffs_moy_gen, with_index=False):
profils_aff = "\n" + "\n".join(elmts) profils_aff = "\n" + "\n".join(elmts)
else: else:
profils_aff = "\n".join(profils) profils_aff = "\n".join(profils)
pe_print( return profils_aff
f" > Moyenne calculée avec pour coeffs (de compétences) : {profils_aff}"
)
def aff_UEs(champs):
"""Affiche les UEs"""
champs_tries = sorted(champs)
aff_comp = []
for comp in champs_tries:
aff_comp += ["📍" + comp]
return ", ".join(aff_comp)
def aff_competences(champs):
"""Affiche les compétences"""
champs_tries = sorted(champs)
aff_comp = []
for comp in champs_tries:
aff_comp += ["💡" + comp]
return ", ".join(aff_comp)
def aff_tag(tags):
"""Affiche les tags"""
tags_tries = sorted(tags)
aff_tag = ["👜" + tag for tag in tags_tries]
return ", ".join(aff_tag)

View File

@ -451,6 +451,7 @@ class JuryPE(object):
nom_onglet = onglet nom_onglet = onglet
onglets += [nom_onglet] onglets += [nom_onglet]
# écriture dans l'onglet: # écriture dans l'onglet:
df_final = df_final.replace("nan", "")
df_final.to_excel(writer, nom_onglet, index=True, header=True) df_final.to_excel(writer, nom_onglet, index=True, header=True)
pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}") pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}")
output.seek(0) output.seek(0)
@ -563,6 +564,7 @@ class JuryPE(object):
tags_cibles=[tag], tags_cibles=[tag],
cohorte="Promo", cohorte="Promo",
) )
if not df_promo.empty: if not df_promo.empty:
aff_aggregat += [aggregat] aff_aggregat += [aggregat]
df = df.join(df_promo) df = df.join(df_promo)
@ -634,14 +636,14 @@ class JuryPE(object):
) )
if colonne in df.columns: if colonne in df.columns:
valeur = df.loc[etudid, colonne] valeur = df.loc[etudid, colonne]
if valeur != "nan": if valeur and str(valeur) != "nan":
moyennes[tag][aggregat][comp]["rang_groupe"] = valeur moyennes[tag][aggregat][comp]["rang_groupe"] = valeur
colonne = pe_moytag.get_colonne_df( colonne = pe_moytag.get_colonne_df(
aggregat, tag, comp, "Promo", "rang" aggregat, tag, comp, "Promo", "rang"
) )
if colonne in df.columns: if colonne in df.columns:
valeur = df.loc[etudid, colonne] valeur = df.loc[etudid, colonne]
if valeur != "nan": if valeur and str(valeur) != "nan":
moyennes[tag][aggregat][comp]["rang_promo"] = valeur moyennes[tag][aggregat][comp]["rang_promo"] = valeur
html = template.render( html = template.render(