2024-02-27 14:39:14 +01:00
|
|
|
# -*- pole: python -*-
|
2024-02-21 20:02:38 +01:00
|
|
|
# -*- 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():
|
2024-02-27 14:39:14 +01:00
|
|
|
if moytag.has_notes(None):
|
2024-02-21 20:02:38 +01:00
|
|
|
tags.append(tag)
|
|
|
|
return sorted(tags)
|
|
|
|
|
|
|
|
def to_df(
|
2024-02-27 14:39:14 +01:00
|
|
|
self,
|
|
|
|
pole,
|
|
|
|
administratif=True,
|
|
|
|
aggregat=None,
|
|
|
|
tags_cibles=None,
|
|
|
|
cohorte=None,
|
2024-02-21 20:02:38 +01:00
|
|
|
) -> 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
|
2024-02-27 14:39:14 +01:00
|
|
|
pole: Les modules à prendre en compte dans la moyenne (None=tous, Ressources ou SAEs)
|
2024-02-21 20:02:38 +01:00
|
|
|
Returns:
|
|
|
|
Le dataframe complet de synthèse
|
|
|
|
"""
|
|
|
|
if not self.is_significatif():
|
|
|
|
return None
|
|
|
|
|
|
|
|
# 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:
|
2024-02-27 14:39:14 +01:00
|
|
|
df = df_administratif(self.etuds, aggregat=aggregat, cohorte=cohorte)
|
2024-02-21 20:02:38 +01:00
|
|
|
else:
|
|
|
|
df = pd.DataFrame(index=self.etudids)
|
|
|
|
|
|
|
|
# Ajout des données par tags
|
|
|
|
for tag in tags_cibles:
|
2024-02-24 09:31:47 +01:00
|
|
|
if tag in self.moyennes_tags:
|
2024-02-27 14:39:14 +01:00
|
|
|
moy_tag_df = self.moyennes_tags[tag].to_df(
|
|
|
|
pole, aggregat=aggregat, cohorte=cohorte
|
|
|
|
)
|
2024-02-24 09:31:47 +01:00
|
|
|
df = df.join(moy_tag_df)
|
2024-02-21 20:02:38 +01:00
|
|
|
|
|
|
|
# Tri par nom, prénom
|
|
|
|
if administratif:
|
|
|
|
colonnes_tries = [
|
2024-02-27 14:39:14 +01:00
|
|
|
_get_champ_administratif(champ, aggregat=aggregat, cohorte=cohorte)
|
2024-02-21 20:02:38 +01:00
|
|
|
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 = []
|
2024-02-24 09:31:47 +01:00
|
|
|
if aggregat != None:
|
2024-02-21 20:02:38 +01:00
|
|
|
liste += [aggregat]
|
2024-02-27 14:39:14 +01:00
|
|
|
liste += [""] # le pole (None, RESSOURCES, SAEs)
|
2024-02-21 20:02:38 +01:00
|
|
|
liste += ["Administratif", "Identité"]
|
2024-02-24 09:31:47 +01:00
|
|
|
if cohorte != None:
|
2024-02-21 20:02:38 +01:00
|
|
|
liste += [champ]
|
|
|
|
liste += [champ]
|
2024-02-24 09:31:47 +01:00
|
|
|
return "|".join(liste)
|
2024-02-21 20:02:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
]
|
2024-02-24 09:31:47 +01:00
|
|
|
|
2024-02-21 20:02:38 +01:00
|
|
|
df = pd.DataFrame.from_dict(donnees, orient="index", columns=colonnes)
|
|
|
|
df = df.sort_values(by=colonnes[1:])
|
|
|
|
return df
|