From 04a8177d12694db423ef4da32d89aa4d4c03d614 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 26 Aug 2024 14:46:28 +0200 Subject: [PATCH] =?UTF-8?q?Editeur=20de=20partitions:=20liens=20vers=20out?= =?UTF-8?q?il=20de=20r=C3=A9partition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scodoc/sco_groups.py | 108 ++++++++---------- app/static/css/partition_editor.css | 20 +++- .../formsemestre/groups_auto_repartition.j2 | 30 +++++ app/templates/scolar/partition_editor.j2 | 37 +++++- .../scolar/students_groups_auto_assignment.j2 | 13 +++ app/views/scolar.py | 13 +-- sco_version.py | 2 +- 7 files changed, 150 insertions(+), 73 deletions(-) create mode 100644 app/templates/formsemestre/groups_auto_repartition.j2 diff --git a/app/scodoc/sco_groups.py b/app/scodoc/sco_groups.py index c585223d..ae9d7e1c 100644 --- a/app/scodoc/sco_groups.py +++ b/app/scodoc/sco_groups.py @@ -1332,17 +1332,6 @@ def groups_auto_repartition(partition: Partition): ), ] - H = [ - f"""

Répartition des groupes de {partition.partition_name}

-

Semestre {formsemestre.titre_annee()}

-

Les groupes existants seront effacés et remplacés par - ceux créés ici. La répartition aléatoire tente d'uniformiser le niveau - des groupes (en utilisant la dernière moyenne générale disponible pour - chaque étudiant) et de maximiser la mixité de chaque groupe. -

- """, - ] - tf = TrivialFormulator( request.base_url, scu.get_request_args(), @@ -1354,58 +1343,59 @@ def groups_auto_repartition(partition: Partition): ) if tf[0] == 0: return render_template( - "sco_page.j2", - title="Répartition des groupes", - content="\n".join(H) + "\n" + tf[1], + "formsemestre/groups_auto_repartition.j2", + title="Répartition dans des groupes", + form_html=tf[1], + partition=partition, sco=ScoData(formsemestre=formsemestre), ) - elif tf[0] == -1: + if tf[0] == -1: return flask.redirect(dest_url) - else: - # form submission - log(f"groups_auto_repartition({partition})") - group_names = tf[2]["groupNames"] - group_names = sorted({x.strip() for x in group_names.split(",")}) - # Détruit les groupes existant de cette partition - for group in partition.groups: - db.session.delete(group) - db.session.commit() - # Crée les nouveaux groupes - groups = [] - for group_name in group_names: - if group_name.strip(): - groups.append(partition.create_group(group_name)) - # - nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) - identdict = nt.identdict - # build: { civilite : liste etudids trie par niveau croissant } - civilites = {x["civilite"] for x in identdict.values()} - listes = {} + + # form submission + log(f"groups_auto_repartition({partition})") + group_names = tf[2]["groupNames"] + group_names = sorted({x.strip() for x in group_names.split(",")}) + # Détruit les groupes existant de cette partition + for group in partition.groups: + db.session.delete(group) + db.session.commit() + # Crée les nouveaux groupes + groups = [] + for group_name in group_names: + if group_name.strip(): + groups.append(partition.create_group(group_name)) + # + nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) + identdict = nt.identdict + # build: { civilite : liste etudids trie par niveau croissant } + civilites = {x["civilite"] for x in identdict.values()} + listes = {} + for civilite in civilites: + listes[civilite] = [ + (_get_prev_moy(x["etudid"], formsemestre.id), x["etudid"]) + for x in identdict.values() + if x["civilite"] == civilite + ] + listes[civilite].sort() + log("listes[%s] = %s" % (civilite, listes[civilite])) + # affect aux groupes: + n = len(identdict) + igroup = 0 + nbgroups = len(groups) + while n > 0: + log(f"n={n}") for civilite in civilites: - listes[civilite] = [ - (_get_prev_moy(x["etudid"], formsemestre.id), x["etudid"]) - for x in identdict.values() - if x["civilite"] == civilite - ] - listes[civilite].sort() - log("listes[%s] = %s" % (civilite, listes[civilite])) - # affect aux groupes: - n = len(identdict) - igroup = 0 - nbgroups = len(groups) - while n > 0: - log(f"n={n}") - for civilite in civilites: - log(f"civilite={civilite}") - if len(listes[civilite]): - n -= 1 - etudid = listes[civilite].pop()[1] - group = groups[igroup] - igroup = (igroup + 1) % nbgroups - log(f"in {etudid} in group {group.id}") - change_etud_group_in_partition(etudid, group) - log(f"{etudid} in group {group.id}") - return flask.redirect(dest_url) + log(f"civilite={civilite}") + if len(listes[civilite]): + n -= 1 + etudid = listes[civilite].pop()[1] + group = groups[igroup] + igroup = (igroup + 1) % nbgroups + log(f"in {etudid} in group {group.id}") + change_etud_group_in_partition(etudid, group) + log(f"{etudid} in group {group.id}") + return flask.redirect(dest_url) def _get_prev_moy(etudid: int, formsemestre_id: int) -> float | str: diff --git a/app/static/css/partition_editor.css b/app/static/css/partition_editor.css index 00bbb248..90e895be 100644 --- a/app/static/css/partition_editor.css +++ b/app/static/css/partition_editor.css @@ -309,7 +309,7 @@ body.editionActivated .filtres>div>div>div>div { display: none; } -#zonePartitions span.editing a { +#zonePartitions span.editing a { text-decoration: none; } @@ -400,7 +400,7 @@ body.editionActivated .filtres .nonEditable .move { /*****************************/ /* Zone Etudiants */ /*****************************/ -#zoneChoix summary{ +#zoneChoix summary { margin: 0 0 16px; cursor: pointer; } @@ -450,6 +450,7 @@ body.editionActivated .filtres .nonEditable .move { margin-bottom: 4px; width: fit-content; } + #zoneChoix .autoAffectation .progress { position: absolute; top: 100%; @@ -524,7 +525,8 @@ body.editionActivated .filtres .nonEditable .move { } #zoneChoix .etudiants .partition>div, -#zoneChoix .etudiants .partition span { +#zoneChoix .etudiants .partition span, +div.partition-name { display: block; padding: 4px 8px; border: 1px solid #aaa; @@ -541,12 +543,22 @@ body.editionActivated .filtres .nonEditable .move { color: #fff; } -#zoneChoix .etudiants .partition>:nth-child(1) { +#zoneChoix .etudiants .partition>:nth-child(1), +div.partition-name { background: #09c; border-color: #09c; color: #fff; } +div.partition-name { + display: inline-block; + width: fit-content; +} + +div.partition-name a { + color: #fff !important; +} + section:not(#zonePartitions) .hide { display: none !important; } diff --git a/app/templates/formsemestre/groups_auto_repartition.j2 b/app/templates/formsemestre/groups_auto_repartition.j2 new file mode 100644 index 00000000..34a799b9 --- /dev/null +++ b/app/templates/formsemestre/groups_auto_repartition.j2 @@ -0,0 +1,30 @@ +{# Formulaire répartition auto dans les groupes #} + +{% extends "sco_page.j2" %} + +{% block app_content %} + +

Répartition des groupes de {{partition.partition_name}}

+ +
+
Semestre {{sco.formsemestre.titre_annee()}}
+ +
+💡Les groupes existants dans cette partition seront effacés et remplacés +par ceux créés ici. La répartition aléatoire tente d'uniformiser le niveau des +groupes (en utilisant la dernière moyenne générale disponible pour chaque +étudiant) et de maximiser la mixité de chaque groupe. +
+ +{{form_html|safe}} + +
+ +
+Retour à l'éditeur de partitions +
+ +{% endblock %} diff --git a/app/templates/scolar/partition_editor.j2 b/app/templates/scolar/partition_editor.j2 index 70ad81bb..e334cffd 100644 --- a/app/templates/scolar/partition_editor.j2 +++ b/app/templates/scolar/partition_editor.j2 @@ -52,7 +52,23 @@
Outils d'affectation + `; listeGroupesAutoaffectation(); + listeGroupesRepartition(); }) .catch(error => { document.querySelector("main").innerHTML = "

Une erreur s'est produite lors de la sauvegarde des données (1).

"; @@ -730,6 +761,7 @@ // divGroupe.querySelector(".modif").click(); listeGroupesAutoaffectation(); + listeGroupesRepartition(); }) .catch(error => { document.querySelector("main").innerHTML = "

Une erreur s'est produite lors de la sauvegarde des données (4).

"; @@ -811,6 +843,7 @@ document.querySelector("main").innerHTML = "

Une erreur s'est produite lors de la sauvegarde des données (2).

"; } listeGroupesAutoaffectation(); + listeGroupesRepartition(); }) .catch(error => { document.querySelector("main").innerHTML = "

Une erreur s'est produite lors de la sauvegarde des données (3).

"; @@ -924,6 +957,7 @@ document.querySelector("main").innerHTML = "

Une erreur s'est produite lors de la sauvegarde des données (6).

"; } listeGroupesAutoaffectation(); + listeGroupesRepartition(); }) } @@ -1038,6 +1072,7 @@ document.querySelector("main").innerHTML = "

Une erreur s'est produite lors de la sauvegarde des données (6).

"; } listeGroupesAutoaffectation(); + listeGroupesRepartition(); }) .catch(error => { document.querySelector("main").innerHTML = "

Une erreur s'est produite lors de la sauvegarde des données (7).

"; diff --git a/app/templates/scolar/students_groups_auto_assignment.j2 b/app/templates/scolar/students_groups_auto_assignment.j2 index 84e5914f..a8630aaa 100644 --- a/app/templates/scolar/students_groups_auto_assignment.j2 +++ b/app/templates/scolar/students_groups_auto_assignment.j2 @@ -1,3 +1,7 @@ +{%- extends 'sco_page.j2' -%} + +{% block styles %} +{{super()}} +{% endblock %} + +{% block app_content %}
@@ -249,6 +256,11 @@
+{% endblock %} + +{% block scripts %} +{{ super() }} + +{% endblock %} \ No newline at end of file diff --git a/app/views/scolar.py b/app/views/scolar.py index 424500d2..28ead66f 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -1003,15 +1003,12 @@ def partition_editor(formsemestre_id: int, edit_partition=False): @scodoc7func def students_groups_auto_assignment(formsemestre_id: int): """Répartition auto des groupes""" - formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) - H = [ - render_template( - "scolar/students_groups_auto_assignment.j2", - formsemestre=formsemestre, - ), - ] + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) return render_template( - "sco_page.j2", title="Répartition des groupes", content="\n".join(H) + "scolar/students_groups_auto_assignment.j2", + formsemestre=formsemestre, + title="Répartition des groupes", + sco=ScoData(formsemestre=formsemestre), ) diff --git a/sco_version.py b/sco_version.py index 67bc67d6..5f1901f3 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.7.13" +SCOVERSION = "9.7.14" SCONAME = "ScoDoc"