# -*- pole: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Emmanuel Viennet emmanuel.viennet@viennet.net # ############################################################################## ############################################################################## # Module "Avis de poursuite d'étude" # conçu et développé par Cléo Baras (IUT de Grenoble) ############################################################################## """ Created on Thu Sep 8 09:36:33 2016 @author: barasc """ import pandas as pd from app.models import Identite from app.pe.moys import pe_moytag TAGS_RESERVES = ["but"] CHAMPS_ADMINISTRATIFS = ["Civilité", "Nom", "Prénom"] class TableTag(object): def __init__(self): """Classe centralisant différentes méthodes communes aux SemestreTag, TrajectoireTag, AggregatInterclassTag """ # Les étudiants # self.etuds: list[Identite] = None # A venir """Les étudiants""" # self.etudids: list[int] = {} """Les etudids""" def add_etuds(self, etuds: list[Identite]): """Mémorise les informations sur les étudiants Args: etuds: la liste des identités de l'étudiant """ # self.etuds = etuds self.etudids = list({etud.etudid for etud in etuds}) def get_all_significant_tags(self): """Liste des tags de la table, triée par ordre alphabétique, extraite des clés du dictionnaire ``moyennes_tags``, en ne considérant que les moyennes ayant des notes. Returns: Liste de tags triés par ordre alphabétique """ tags = [] tag: str = "" moytag: pe_moytag.MoyennesTag = None for tag, moytag in self.moyennes_tags.items(): if moytag.has_notes(): tags.append(tag) return sorted(tags) def to_df( self, administratif=True, aggregat=None, tags_cibles=None, cohorte=None, options={"min_max_moy": True}, ) -> pd.DataFrame: """Renvoie un dataframe listant toutes les données des moyennes/classements/nb_inscrits/min/max/moy des étudiants aux différents tags. tags_cibles limitent le dataframe aux tags indiqués type_colonnes indiquent si les colonnes doivent être passées en multiindex Args: administratif: Indique si les données administratives sont incluses aggregat: l'aggrégat représenté tags_cibles: la liste des tags ciblés cohorte: la cohorte représentée Returns: Le dataframe complet de synthèse """ # Les tags visés tags_tries = self.get_all_significant_tags() if not tags_cibles: tags_cibles = tags_tries tags_cibles = sorted(tags_cibles) # Les tags visés avec des notes # Les étudiants visés if administratif: df = df_administratif(self.etuds, aggregat=aggregat, cohorte=cohorte) else: df = pd.DataFrame(index=self.etudids) if not self.is_significatif(): return df # Ajout des données par tags for tag in tags_cibles: if tag in self.moyennes_tags: moy_tag_df = self.moyennes_tags[tag].to_df( aggregat=aggregat, cohorte=cohorte, options=options ) df = df.join(moy_tag_df) # Tri par nom, prénom if administratif: colonnes_tries = [ _get_champ_administratif(champ, aggregat=aggregat, cohorte=cohorte) for champ in CHAMPS_ADMINISTRATIFS[1:] ] # Nom + Prénom df = df.sort_values(by=colonnes_tries) return df def has_etuds(self): """Indique si un tabletag contient des étudiants""" return len(self.etuds) > 0 def is_significatif(self): """Indique si une tabletag a des données""" # A des étudiants if not self.etuds: return False # A des tags avec des notes tags_tries = self.get_all_significant_tags() if not tags_tries: return False return True def _get_champ_administratif(champ, aggregat=None, cohorte=None): """Pour un champ donné, renvoie l'index (ou le multindex) à intégrer au dataframe""" liste = [] if aggregat != None: liste += [aggregat] liste += ["Administratif", "Identité"] if cohorte != None: liste += [champ] liste += [champ] return "|".join(liste) def df_administratif( etuds: list[Identite], aggregat=None, cohorte=None ) -> pd.DataFrame: """Renvoie un dataframe donnant les données administratives des étudiants du TableTag Args: etuds: Identité des étudiants générant les données administratives """ identites = {etud.etudid: etud for etud in etuds} donnees = {} etud: Identite = None for etudid, etud in identites.items(): data = { CHAMPS_ADMINISTRATIFS[0]: etud.civilite_str, CHAMPS_ADMINISTRATIFS[1]: etud.nom, CHAMPS_ADMINISTRATIFS[2]: etud.prenom_str, } donnees[etudid] = { _get_champ_administratif(champ, aggregat, cohorte): data[champ] for champ in CHAMPS_ADMINISTRATIFS } colonnes = [ _get_champ_administratif(champ, aggregat, cohorte) for champ in CHAMPS_ADMINISTRATIFS ] df = pd.DataFrame.from_dict(donnees, orient="index", columns=colonnes) df = df.sort_values(by=colonnes[1:]) return df