forked from ScoDoc/ScoDoc
Modernisation code: remplace DictDefault
This commit is contained in:
parent
40978f30ee
commit
fc786db83e
@ -28,6 +28,7 @@
|
|||||||
"""Génération des bulletins de notes
|
"""Génération des bulletins de notes
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
import email
|
import email
|
||||||
import time
|
import time
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -143,7 +144,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
|
|||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
if not nt.get_etud_etat(etudid):
|
if not nt.get_etud_etat(etudid):
|
||||||
raise ScoValueError("Étudiant non inscrit à ce semestre")
|
raise ScoValueError("Étudiant non inscrit à ce semestre")
|
||||||
I = scu.DictDefault(defaultvalue="")
|
I = collections.defaultdict(str)
|
||||||
I["etudid"] = etudid
|
I["etudid"] = etudid
|
||||||
I["formsemestre_id"] = formsemestre_id
|
I["formsemestre_id"] = formsemestre_id
|
||||||
I["sem"] = formsemestre.get_infos_dict()
|
I["sem"] = formsemestre.get_infos_dict()
|
||||||
@ -260,7 +261,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
|
|||||||
# n'affiche pas le rang sur le bulletin s'il y a des
|
# n'affiche pas le rang sur le bulletin s'il y a des
|
||||||
# notes en attente dans ce semestre
|
# notes en attente dans ce semestre
|
||||||
rang = scu.RANG_ATTENTE_STR
|
rang = scu.RANG_ATTENTE_STR
|
||||||
rang_gr = scu.DictDefault(defaultvalue=scu.RANG_ATTENTE_STR)
|
rang_gr = collections.defaultdict(lambda: scu.RANG_ATTENTE_STR)
|
||||||
inscriptions_counts = nt.get_inscriptions_counts()
|
inscriptions_counts = nt.get_inscriptions_counts()
|
||||||
I["rang"] = rang
|
I["rang"] = rang
|
||||||
I["rang_gr"] = rang_gr
|
I["rang_gr"] = rang_gr
|
||||||
@ -710,50 +711,15 @@ def etud_descr_situation_semestre(
|
|||||||
decisions_ue : noms (acronymes) des UE validées, séparées par des virgules.
|
decisions_ue : noms (acronymes) des UE validées, séparées par des virgules.
|
||||||
descr_decisions_ue : ' UE acquises: UE1, UE2', ou vide si pas de dec. ou si pas show_uevalid
|
descr_decisions_ue : ' UE acquises: UE1, UE2', ou vide si pas de dec. ou si pas show_uevalid
|
||||||
descr_mention : 'Mention Bien', ou vide si pas de mention ou si pas show_mention
|
descr_mention : 'Mention Bien', ou vide si pas de mention ou si pas show_mention
|
||||||
|
descr_parcours : le nom (libelle) du parcours dans lequel est inscrit l'étudiant en BUT (vide ailleurs)
|
||||||
"""
|
"""
|
||||||
# Fonction utilisée par tous les bulletins (APC ou classiques)
|
# Fonction utilisée par tous les bulletins (APC ou classiques)
|
||||||
cnx = ndb.GetDBConnexion()
|
infos = collections.defaultdict(str)
|
||||||
infos = scu.DictDefault(defaultvalue="")
|
|
||||||
|
|
||||||
# --- Situation et décisions jury
|
# --- Situation et décisions jury
|
||||||
# démission/inscription ?
|
|
||||||
events = sco_etud.scolar_events_list(
|
date_inscr, date_dem, date_def = _dates_insc_dem_def(etudid, formsemestre_id)
|
||||||
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
|
|
||||||
)
|
|
||||||
date_inscr = None
|
|
||||||
date_dem = None
|
|
||||||
date_def = None
|
|
||||||
for event in events:
|
|
||||||
event_type = event["event_type"]
|
|
||||||
if event_type == "INSCRIPTION":
|
|
||||||
if date_inscr:
|
|
||||||
# plusieurs inscriptions ???
|
|
||||||
# date_inscr += ', ' + event['event_date'] + ' (!)'
|
|
||||||
# il y a eu une erreur qui a laissé un event 'inscription'
|
|
||||||
# on l'efface:
|
|
||||||
log(
|
|
||||||
f"etud_descr_situation_semestre: removing duplicate INSCRIPTION event for etudid={etudid} !"
|
|
||||||
)
|
|
||||||
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
|
||||||
else:
|
|
||||||
date_inscr = event["event_date"]
|
|
||||||
elif event_type == "DEMISSION":
|
|
||||||
# assert date_dem == None, 'plusieurs démissions !'
|
|
||||||
if date_dem: # cela ne peut pas arriver sauf bug (signale a Evry 2013?)
|
|
||||||
log(
|
|
||||||
f"etud_descr_situation_semestre: removing duplicate DEMISSION event for etudid={etudid} !"
|
|
||||||
)
|
|
||||||
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
|
||||||
else:
|
|
||||||
date_dem = event["event_date"]
|
|
||||||
elif event_type == "DEFAILLANCE":
|
|
||||||
if date_def:
|
|
||||||
log(
|
|
||||||
f"etud_descr_situation_semestre: removing duplicate DEFAILLANCE event for etudid={etudid} !"
|
|
||||||
)
|
|
||||||
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
|
||||||
else:
|
|
||||||
date_def = event["event_date"]
|
|
||||||
if show_date_inscr:
|
if show_date_inscr:
|
||||||
if not date_inscr:
|
if not date_inscr:
|
||||||
infos["date_inscription"] = ""
|
infos["date_inscription"] = ""
|
||||||
@ -851,6 +817,49 @@ def etud_descr_situation_semestre(
|
|||||||
return infos, dpv
|
return infos, dpv
|
||||||
|
|
||||||
|
|
||||||
|
def _dates_insc_dem_def(etudid, formsemestre_id) -> tuple:
|
||||||
|
"Cherche les dates d'inscription, démission et défaillance de l'étudiant"
|
||||||
|
cnx = ndb.GetDBConnexion()
|
||||||
|
events = sco_etud.scolar_events_list(
|
||||||
|
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
|
||||||
|
)
|
||||||
|
date_inscr = None
|
||||||
|
date_dem = None
|
||||||
|
date_def = None
|
||||||
|
for event in events:
|
||||||
|
event_type = event["event_type"]
|
||||||
|
if event_type == "INSCRIPTION":
|
||||||
|
if date_inscr:
|
||||||
|
# plusieurs inscriptions ???
|
||||||
|
# date_inscr += ', ' + event['event_date'] + ' (!)'
|
||||||
|
# il y a eu une erreur qui a laissé un event 'inscription'
|
||||||
|
# on l'efface:
|
||||||
|
log(
|
||||||
|
f"etud_descr_situation_semestre: removing duplicate INSCRIPTION event for etudid={etudid} !"
|
||||||
|
)
|
||||||
|
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
||||||
|
else:
|
||||||
|
date_inscr = event["event_date"]
|
||||||
|
elif event_type == "DEMISSION":
|
||||||
|
# assert date_dem == None, 'plusieurs démissions !'
|
||||||
|
if date_dem: # cela ne peut pas arriver sauf bug (signale a Evry 2013?)
|
||||||
|
log(
|
||||||
|
f"etud_descr_situation_semestre: removing duplicate DEMISSION event for etudid={etudid} !"
|
||||||
|
)
|
||||||
|
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
||||||
|
else:
|
||||||
|
date_dem = event["event_date"]
|
||||||
|
elif event_type == "DEFAILLANCE":
|
||||||
|
if date_def:
|
||||||
|
log(
|
||||||
|
f"etud_descr_situation_semestre: removing duplicate DEFAILLANCE event for etudid={etudid} !"
|
||||||
|
)
|
||||||
|
sco_etud.scolar_events_delete(cnx, event["event_id"])
|
||||||
|
else:
|
||||||
|
date_def = event["event_date"]
|
||||||
|
return date_inscr, date_dem, date_def
|
||||||
|
|
||||||
|
|
||||||
def _format_situation_fields(
|
def _format_situation_fields(
|
||||||
infos, field_names: list[str], extra_values: list[str]
|
infos, field_names: list[str], extra_values: list[str]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
"""Evaluations
|
"""Evaluations
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
import datetime
|
import datetime
|
||||||
import operator
|
import operator
|
||||||
import time
|
import time
|
||||||
@ -171,8 +172,8 @@ def do_evaluation_etat(evaluation_id, partition_id=None, select_first_partition=
|
|||||||
|
|
||||||
# On considere une note "manquante" lorsqu'elle n'existe pas
|
# On considere une note "manquante" lorsqu'elle n'existe pas
|
||||||
# ou qu'elle est en attente (ATT)
|
# ou qu'elle est en attente (ATT)
|
||||||
GrNbMissing = scu.DictDefault() # group_id : nb notes manquantes
|
GrNbMissing = collections.defaultdict(int) # group_id : nb notes manquantes
|
||||||
GrNotes = scu.DictDefault(defaultvalue=[]) # group_id: liste notes valides
|
GrNotes = collections.defaultdict(list) # group_id: liste notes valides
|
||||||
TotalNbMissing = 0
|
TotalNbMissing = 0
|
||||||
TotalNbAtt = 0
|
TotalNbAtt = 0
|
||||||
groups = {} # group_id : group
|
groups = {} # group_id : group
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
"""Opérations d'inscriptions aux semestres et modules
|
"""Opérations d'inscriptions aux semestres et modules
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
@ -543,10 +544,8 @@ def formsemestre_inscription_option(etudid, formsemestre_id):
|
|||||||
mods = sco_moduleimpl.moduleimpl_withmodule_list(formsemestre_id=formsemestre_id)
|
mods = sco_moduleimpl.moduleimpl_withmodule_list(formsemestre_id=formsemestre_id)
|
||||||
inscr = sco_moduleimpl.do_moduleimpl_inscription_list(etudid=etudid)
|
inscr = sco_moduleimpl.do_moduleimpl_inscription_list(etudid=etudid)
|
||||||
# Formulaire
|
# Formulaire
|
||||||
modimpls_by_ue_ids = scu.DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_id ]
|
modimpls_by_ue_ids = collections.defaultdict(list) # ue_id : [ moduleimpl_id ]
|
||||||
modimpls_by_ue_names = scu.DictDefault(
|
modimpls_by_ue_names = collections.defaultdict(list) # ue_id : [ moduleimpl_name ]
|
||||||
defaultvalue=[]
|
|
||||||
) # ue_id : [ moduleimpl_name ]
|
|
||||||
ues = []
|
ues = []
|
||||||
ue_ids = set()
|
ue_ids = set()
|
||||||
initvalues = {}
|
initvalues = {}
|
||||||
|
@ -33,8 +33,8 @@ Elle n'est pas utilisée pour les parcours, ni pour rien d'autre
|
|||||||
(c'est donc un attribut "cosmétique").
|
(c'est donc un attribut "cosmétique").
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
import app.scodoc.sco_utils as scu
|
|
||||||
from app import log
|
from app import log
|
||||||
|
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ def group_sems_by_modalite(sems):
|
|||||||
"""Given the list of fromsemestre, group them by modalite,
|
"""Given the list of fromsemestre, group them by modalite,
|
||||||
sorted in each one by semestre id and date
|
sorted in each one by semestre id and date
|
||||||
"""
|
"""
|
||||||
sems_by_mod = scu.DictDefault(defaultvalue=[])
|
sems_by_mod = collections.defaultdict(list)
|
||||||
modalites = list_formsemestres_modalites(sems)
|
modalites = list_formsemestres_modalites(sems)
|
||||||
for modalite in modalites:
|
for modalite in modalites:
|
||||||
for sem in sems:
|
for sem in sems:
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
"""Opérations d'inscriptions aux modules (interface pour gérer options ou parcours)
|
"""Opérations d'inscriptions aux modules (interface pour gérer options ou parcours)
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
@ -676,7 +677,7 @@ def get_etuds_with_capitalized_ue(formsemestre_id: int) -> list[dict]:
|
|||||||
"""For each UE, computes list of students capitalizing the UE.
|
"""For each UE, computes list of students capitalizing the UE.
|
||||||
returns { ue_id : [ { infos } ] }
|
returns { ue_id : [ { infos } ] }
|
||||||
"""
|
"""
|
||||||
ues_cap_info = scu.DictDefault(defaultvalue=[])
|
ues_cap_info = collections.defaultdict(list)
|
||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
"""Feuille excel pour préparation des jurys classiques (non BUT)
|
"""Feuille excel pour préparation des jurys classiques (non BUT)
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from openpyxl.styles.numbers import FORMAT_NUMBER_00
|
from openpyxl.styles.numbers import FORMAT_NUMBER_00
|
||||||
@ -64,10 +65,10 @@ def feuille_preparation_jury(formsemestre_id):
|
|||||||
"partition_id"
|
"partition_id"
|
||||||
]
|
]
|
||||||
|
|
||||||
prev_moy_ue = scu.DictDefault(defaultvalue={}) # ue_code_s : { etudid : moy ue }
|
prev_moy_ue = collections.defaultdict(dict) # ue_code_s : { etudid : moy ue }
|
||||||
prev_ue_acro = {} # ue_code_s : acronyme (à afficher)
|
prev_ue_acro = {} # ue_code_s : acronyme (à afficher)
|
||||||
prev_moy = {} # moyennes gen sem prec
|
prev_moy = {} # moyennes gen sem prec
|
||||||
moy_ue = scu.DictDefault(defaultvalue={}) # ue_acro : moyennes { etudid : moy ue }
|
moy_ue = collections.defaultdict(dict) # ue_acro : moyennes { etudid : moy ue }
|
||||||
ue_acro = {} # ue_code_s : acronyme (à afficher)
|
ue_acro = {} # ue_code_s : acronyme (à afficher)
|
||||||
moy = {} # moyennes gen
|
moy = {} # moyennes gen
|
||||||
moy_inter = {} # moyenne gen. sur les 2 derniers semestres
|
moy_inter = {} # moyenne gen. sur les 2 derniers semestres
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
Formulaires paramétrage PV et génération des tables
|
Formulaires paramétrage PV et génération des tables
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
import time
|
import time
|
||||||
from reportlab.platypus import Paragraph
|
from reportlab.platypus import Paragraph
|
||||||
from reportlab.lib import styles
|
from reportlab.lib import styles
|
||||||
@ -283,7 +283,7 @@ def formsemestre_pvjury(formsemestre_id, format="html", publish=True):
|
|||||||
H.append(tab.html())
|
H.append(tab.html())
|
||||||
|
|
||||||
# Count number of cases for each decision
|
# Count number of cases for each decision
|
||||||
counts = scu.DictDefault()
|
counts = collections.defaultdict(int)
|
||||||
for row in rows:
|
for row in rows:
|
||||||
counts[row["decision"]] += 1
|
counts[row["decision"]] += 1
|
||||||
# add codes for previous (for explanation, without count)
|
# add codes for previous (for explanation, without count)
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
- statistiques decisions
|
- statistiques decisions
|
||||||
- suivi cohortes
|
- suivi cohortes
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
import re
|
import re
|
||||||
@ -178,7 +179,8 @@ def _results_by_category(
|
|||||||
if etud[category] in Count:
|
if etud[category] in Count:
|
||||||
Count[etud[category]][etud[result]] += 1
|
Count[etud[category]][etud[result]] += 1
|
||||||
else:
|
else:
|
||||||
Count[etud[category]] = scu.DictDefault(kv_dict={etud[result]: 1})
|
Count[etud[category]] = collections.defaultdict(int, {etud[result]: 1})
|
||||||
|
|
||||||
# conversion en liste de dict
|
# conversion en liste de dict
|
||||||
C = [Count[cat] for cat in categories]
|
C = [Count[cat] for cat in categories]
|
||||||
# Totaux par lignes et colonnes
|
# Totaux par lignes et colonnes
|
||||||
@ -551,7 +553,7 @@ def table_suivi_cohorte(
|
|||||||
indices_sems.sort()
|
indices_sems.sort()
|
||||||
for p in P:
|
for p in P:
|
||||||
p.nb_etuds = 0 # nombre total d'etudiants dans la periode
|
p.nb_etuds = 0 # nombre total d'etudiants dans la periode
|
||||||
p.sems_by_id = scu.DictDefault(defaultvalue=[])
|
p.sems_by_id = collections.defaultdict(list)
|
||||||
for s in p.sems:
|
for s in p.sems:
|
||||||
p.sems_by_id[s["semestre_id"]].append(s)
|
p.sems_by_id[s["semestre_id"]].append(s)
|
||||||
p.nb_etuds += len(s["members"])
|
p.nb_etuds += len(s["members"])
|
||||||
@ -1162,7 +1164,7 @@ def table_suivi_cursus(formsemestre_id, only_primo=False, grouped_parcours=True)
|
|||||||
civilites,
|
civilites,
|
||||||
statuts,
|
statuts,
|
||||||
) = tsp_etud_list(formsemestre_id, only_primo=only_primo)
|
) = tsp_etud_list(formsemestre_id, only_primo=only_primo)
|
||||||
codes_etuds = scu.DictDefault(defaultvalue=[])
|
codes_etuds = collections.defaultdict(list)
|
||||||
for etud in etuds:
|
for etud in etuds:
|
||||||
etud["code_cursus"], etud["decisions_jury"] = get_code_cursus_etud(etud)
|
etud["code_cursus"], etud["decisions_jury"] = get_code_cursus_etud(etud)
|
||||||
codes_etuds[etud["code_cursus"]].append(etud)
|
codes_etuds[etud["code_cursus"]].append(etud)
|
||||||
@ -1350,17 +1352,16 @@ def graph_cursus(
|
|||||||
civilites,
|
civilites,
|
||||||
statuts,
|
statuts,
|
||||||
)
|
)
|
||||||
edges = scu.DictDefault(
|
edges = collections.defaultdict(set)
|
||||||
defaultvalue=set()
|
# {("SEM"formsemestre_id_origin, "SEM"formsemestre_id_dest) : etud_set}
|
||||||
) # {("SEM"formsemestre_id_origin, "SEM"formsemestre_id_dest) : etud_set}
|
|
||||||
|
|
||||||
def sem_node_name(sem, prefix="SEM"):
|
def sem_node_name(sem, prefix="SEM"):
|
||||||
"pydot node name for this integer id"
|
"pydot node name for this integer id"
|
||||||
return prefix + str(sem["formsemestre_id"])
|
return prefix + str(sem["formsemestre_id"])
|
||||||
|
|
||||||
sems = {}
|
sems = {}
|
||||||
effectifs = scu.DictDefault(defaultvalue=set()) # formsemestre_id : etud_set
|
effectifs = collections.defaultdict(set) # formsemestre_id : etud_set
|
||||||
decisions = scu.DictDefault(defaultvalue={}) # formsemestre_id : { code : nb_etud }
|
decisions = collections.defaultdict(dict) # formsemestre_id : { code : nb_etud }
|
||||||
isolated_nodes = [] # [ node_name_de_formsemestre_id, ... ]
|
isolated_nodes = [] # [ node_name_de_formsemestre_id, ... ]
|
||||||
connected_nodes = set() # { node_name_de_formsemestre_id }
|
connected_nodes = set() # { node_name_de_formsemestre_id }
|
||||||
diploma_nodes = []
|
diploma_nodes = []
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"""
|
"""
|
||||||
import base64
|
import base64
|
||||||
import bisect
|
import bisect
|
||||||
import copy
|
import collections
|
||||||
import datetime
|
import datetime
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import io
|
import io
|
||||||
@ -270,32 +270,11 @@ def get_mention(moy):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class DictDefault(dict): # obsolete, use collections.defaultdict
|
def group_by_key(d: dict, key) -> dict:
|
||||||
"""A dictionnary with default value for all keys
|
grouped = collections.defaultdict(lambda: [])
|
||||||
Each time a non existent key is requested, it is added to the dict.
|
|
||||||
(used in python 2.4, can't use new __missing__ method)
|
|
||||||
"""
|
|
||||||
|
|
||||||
defaultvalue = 0
|
|
||||||
|
|
||||||
def __init__(self, defaultvalue=0, kv_dict={}):
|
|
||||||
dict.__init__(self)
|
|
||||||
self.defaultvalue = defaultvalue
|
|
||||||
self.update(kv_dict)
|
|
||||||
|
|
||||||
def __getitem__(self, k):
|
|
||||||
if k in self:
|
|
||||||
return self.get(k)
|
|
||||||
value = copy.copy(self.defaultvalue)
|
|
||||||
self[k] = value
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def group_by_key(d, key):
|
|
||||||
gr = DictDefault(defaultvalue=[])
|
|
||||||
for e in d:
|
for e in d:
|
||||||
gr[e[key]].append(e)
|
grouped[e[key]].append(e)
|
||||||
return gr
|
return grouped
|
||||||
|
|
||||||
|
|
||||||
# ----- Global lock for critical sections (except notes_tables caches)
|
# ----- Global lock for critical sections (except notes_tables caches)
|
||||||
|
Loading…
Reference in New Issue
Block a user