From f6051f930fe9aeb7f80b502de67c9eb60472ca2d Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Fri, 26 Jan 2024 10:18:46 +0100 Subject: [PATCH 1/3] PE: generation du zip --- app/pe/pe_jury.py | 177 +++++++++++++++++++++++----------------------- 1 file changed, 89 insertions(+), 88 deletions(-) diff --git a/app/pe/pe_jury.py b/app/pe/pe_jury.py index 790b10f8..38fdf6d5 100644 --- a/app/pe/pe_jury.py +++ b/app/pe/pe_jury.py @@ -100,126 +100,127 @@ class JuryPE(object): meme_programme: si True, impose un même programme pour tous les étudiants participant au jury, si False, permet des programmes differents """ - "L'année du diplome" self.diplome = diplome + "L'année du diplome" - "La formation associée au diplome" self.formation_id = formation_id + "La formation associée au diplome" - "Un zip où ranger les fichiers générés" self.nom_export_zip = f"Jury_PE_{self.diplome}" + "Nom du zip où ranger les fichiers générés" + self.zipdata = io.BytesIO() - self.zipfile = ZipFile(self.zipdata, "w") + with ZipFile(self.zipdata, "w") as zipfile: + # Chargement des étudiants à prendre en compte dans le jury + pe_comp.pe_print( + f"""*** Recherche et chargement des étudiants diplômés en { + self.diplome} pour la formation {self.formation_id}""" + ) + self.etudiants = EtudiantsJuryPE( + self.diplome + ) # Les infos sur les étudiants + self.etudiants.find_etudiants(self.formation_id) + self.diplomes_ids = self.etudiants.diplomes_ids - """Chargement des étudiants à prendre en compte dans le jury""" - pe_comp.pe_print( - f"""*** Recherche et chargement des étudiants diplômés en { - self.diplome} pour la formation {self.formation_id}""" - ) - self.etudiants = EtudiantsJuryPE(self.diplome) # Les infos sur les étudiants - self.etudiants.find_etudiants(self.formation_id) - self.diplomes_ids = self.etudiants.diplomes_ids + # Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE + pe_comp.pe_print("*** Génère les semestres taggués") + self.semestres_taggues = compute_semestres_tag(self.etudiants) - """Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE""" - pe_comp.pe_print("*** Génère les semestres taggués") - self.semestres_taggues = compute_semestres_tag(self.etudiants) + if pe_comp.PE_DEBUG: + # Intègre le bilan des semestres taggués au zip final + for formsemestretag in self.semestres_taggues.values(): + filename = formsemestretag.nom.replace(" ", "_") + ".csv" + pe_comp.pe_print(f" - Export csv de {filename} ") + self.add_file_to_zip( + zipfile, + filename, + formsemestretag.str_tagtable(), + path="details_semestres", + ) - if pe_comp.PE_DEBUG: - """Intègre le bilan des semestres taggués au zip final""" - for fid in self.semestres_taggues: - formsemestretag = self.semestres_taggues[fid] - filename = formsemestretag.nom.replace(" ", "_") + ".csv" - pe_comp.pe_print(f" - Export csv de {filename} ") - self.add_file_to_zip( - filename, formsemestretag.str_tagtable(), path="details_semestres" - ) + # Génère les trajectoires (combinaison de semestres suivis + # par un étudiant pour atteindre le semestre final d'un aggrégat) + pe_comp.pe_print( + "*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants" + ) + self.trajectoires = TrajectoiresJuryPE(self.diplome) + self.trajectoires.cree_trajectoires(self.etudiants) - """Génère les trajectoires (combinaison de semestres suivis - par un étudiant pour atteindre le semestre final d'un aggrégat) - """ - pe_comp.pe_print( - "*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants" - ) - self.trajectoires = TrajectoiresJuryPE(self.diplome) - self.trajectoires.cree_trajectoires(self.etudiants) + # Génère les moyennes par tags des trajectoires + pe_comp.pe_print( + "*** Calcule les moyennes par tag des trajectoires possibles" + ) + self.trajectoires_tagguees = compute_trajectoires_tag( + self.trajectoires, self.etudiants, self.semestres_taggues + ) - """Génère les moyennes par tags des trajectoires""" - pe_comp.pe_print("*** Calcule les moyennes par tag des trajectoires possibles") - self.trajectoires_tagguees = compute_trajectoires_tag( - self.trajectoires, self.etudiants, self.semestres_taggues - ) + if pe_comp.PE_DEBUG: + # Intègre le bilan des trajectoires tagguées au zip final + for trajectoire_tagguee in self.trajectoires_tagguees.values(): + filename = trajectoire_tagguee.get_repr().replace(" ", "_") + ".csv" + pe_comp.pe_print(f" - Export csv de {filename} ") + self.add_file_to_zip( + zipfile, + filename, + trajectoire_tagguee.str_tagtable(), + path="details_semestres", + ) - if pe_comp.PE_DEBUG: - """Intègre le bilan des trajectoires tagguées au zip final""" - for trajectoire_id in self.trajectoires_tagguees: - trajectoire_tagguee = self.trajectoires_tagguees[trajectoire_id] - filename = trajectoire_tagguee.get_repr().replace(" ", "_") + ".csv" - pe_comp.pe_print(f" - Export csv de {filename} ") - self.add_file_to_zip( - filename, - trajectoire_tagguee.str_tagtable(), - path="details_semestres", - ) + # Génère les interclassements (par promo et) par (nom d') aggrégat + pe_comp.pe_print("*** Génère les interclassements par aggrégat") + self.interclassements_taggues = compute_interclassements( + self.etudiants, self.trajectoires, self.trajectoires_tagguees + ) - """Génère les interclassements (par promo et) par (nom d') aggrégat""" - pe_comp.pe_print("*** Génère les interclassements par aggrégat") - self.interclassements_taggues = compute_interclassements( - self.etudiants, self.trajectoires, self.trajectoires_tagguees - ) + if pe_comp.PE_DEBUG: + # Intègre le bilan des aggrégats (par promo) au zip final + for interclass_tag in self.interclassements_taggues.values(): + filename = interclass_tag.get_repr().replace(" ", "_") + ".csv" + pe_comp.pe_print(f" - Export csv de {filename} ") + self.add_file_to_zip( + zipfile, + filename, + interclass_tag.str_tagtable(), + path="details_semestres", + ) - if pe_comp.PE_DEBUG: - """Intègre le bilan des aggrégats (par promo) au zip final""" - for nom_aggregat in self.interclassements_taggues: - interclass_tag = self.interclassements_taggues[nom_aggregat] - filename = interclass_tag.get_repr().replace(" ", "_") + ".csv" - pe_comp.pe_print(f" - Export csv de {filename} ") - self.add_file_to_zip( - filename, - interclass_tag.str_tagtable(), - path="details_semestres", - ) + # Synthèse des éléments du jury PE + self.synthese = self.synthetise_juryPE() - """Synthèse des éléments du jury PE""" - self.synthese = self.synthetise_juryPE() + # Export des données => mode 1 seule feuille -> supprimé + pe_comp.pe_print("*** Export du jury de synthese") + output = io.BytesIO() - # Export des données => mode 1 seule feuille -> supprimé - pe_comp.pe_print("*** Export du jury de synthese") - filename = "synthese_jury_" + str(self.diplome) + ".xlsx" - with pd.ExcelWriter(filename, engine="openpyxl") as writer: - for onglet in self.synthese: - df = self.synthese[onglet] - df.to_excel( - writer, onglet, index=True, header=True - ) # écriture dans l'onglet - # worksheet = writer.sheets[onglet] # l'on + with pd.ExcelWriter(output, engine="openpyxl") as writer: + for onglet, df in self.synthese.items(): + # écriture dans l'onglet: + df.to_excel(writer, onglet, index=True, header=True) + output.seek(0) - self.add_file_to_zip( - filename, - open(filename, "rb").read(), - ) + self.add_file_to_zip( + zipfile, f"synthese_jury_{self.diplome}.xlsx", output.read() + ) # Fin !!!! Tada :) - def add_file_to_zip(self, filename: str, data, path=""): - """Add a file to our zip + def add_file_to_zip(self, zipfile: ZipFile, filename: str, data, path=""): + """Add a file to given zip All files under NOM_EXPORT_ZIP/ path may specify a subdirectory Args: + zipfile: ZipFile filename: Le nom du fichier à intégrer au zip data: Les données du fichier path: Un dossier dans l'arborescence du zip """ path_in_zip = os.path.join(path, filename) # self.nom_export_zip, - self.zipfile.writestr(path_in_zip, data) + zipfile.writestr(path_in_zip, data) - def get_zipped_data(self): + def get_zipped_data(self) -> io.BytesIO | None: """returns file-like data with a zip of all generated (CSV) files. - Reset file cursor at the beginning ! + Warning: reset stream to the begining. """ - if self.zipfile: - self.zipfile.close() - self.zipfile = None self.zipdata.seek(0) return self.zipdata From 4681294cb8c09ab6b255f47ad3d00c3a9c46f5c7 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Fri, 26 Jan 2024 10:28:10 +0100 Subject: [PATCH 2/3] evaluation_listenotes: remet colonne groupes en excel --- app/scodoc/sco_liste_notes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/scodoc/sco_liste_notes.py b/app/scodoc/sco_liste_notes.py index 62ed203f..44058474 100644 --- a/app/scodoc/sco_liste_notes.py +++ b/app/scodoc/sco_liste_notes.py @@ -284,8 +284,8 @@ def _make_table_notes( columns_ids = ["etudid", "nom", "prenom"] else: columns_ids = ["nomprenom"] - if not hide_groups and fmt not in {"xls", "xml", "json"}: - # n'indique pas les groupes en xls, json car notation "humaine" ici + if not hide_groups and fmt not in {"xml", "json"}: + # n'indique pas les groupes en xml et json car notation "humaine" ici columns_ids.append("group") titles = { From 4985182b9afde21aa2b15d2dca99774c02af2f95 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Fri, 26 Jan 2024 11:38:38 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Fix:=20recherche=20tag=20num=C3=A9riques?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scodoc/sco_tag_module.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/scodoc/sco_tag_module.py b/app/scodoc/sco_tag_module.py index 05103761..7ab9d04a 100644 --- a/app/scodoc/sco_tag_module.py +++ b/app/scodoc/sco_tag_module.py @@ -212,8 +212,10 @@ class ModuleTag(ScoTag): # API -def module_tag_search(term): +# TODO placer dans la vraie API et ne plus utiliser sco_publish +def module_tag_search(term: str | int): """List all used tag names (for auto-completion)""" + term = "" if term is None else str(term) # restrict charset to avoid injections if not scu.ALPHANUM_EXP.match(term): data = []