From 8a1569ac54b5b3434b1acfac5b0393c1055089e3 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Thu, 19 May 2022 10:51:43 +0200
Subject: [PATCH 01/16] API: nom des permissions
---
app/scodoc/sco_permissions.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/scodoc/sco_permissions.py b/app/scodoc/sco_permissions.py
index ccf46e8e8..fd04e5105 100644
--- a/app/scodoc/sco_permissions.py
+++ b/app/scodoc/sco_permissions.py
@@ -50,10 +50,10 @@ _SCO_PERMISSIONS = (
(1 << 27, "RelationsEntreprisesCorrespondants", "Voir les correspondants"),
# 27 à 39 ... réservé pour "entreprises"
# Api scodoc9
- (1 << 40, "APIView", "Voir"),
- (1 << 41, "APIEtudChangeGroups", "Modifier les groupes"),
- (1 << 42, "APIEditAllNotes", "Modifier toutes les notes"),
- (1 << 43, "APIAbsChange", "Saisir des absences"),
+ (1 << 40, "APIView", "API: Lecture"),
+ (1 << 41, "APIEtudChangeGroups", "API: Modifier les groupes"),
+ (1 << 42, "APIEditAllNotes", "API: Modifier toutes les notes"),
+ (1 << 43, "APIAbsChange", "API: Saisir des absences"),
)
From 994959960cc3e3eeaf954416d64cbcc9c5031594 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Mon, 23 May 2022 10:59:43 +0200
Subject: [PATCH 02/16] Recap: rangs dans les groupes
---
app/comp/res_common.py | 22 ++++++++++++++++++++--
app/scodoc/sco_groups.py | 4 +---
app/static/js/table_recap.js | 18 ++++++++++++++----
sco_version.py | 2 +-
4 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/app/comp/res_common.py b/app/comp/res_common.py
index 5170875d7..654a1ae36 100644
--- a/app/comp/res_common.py
+++ b/app/comp/res_common.py
@@ -70,6 +70,7 @@ class ResultatsSemestre(ResultatsCache):
self.etud_moy_gen: pd.Series = None
self.etud_moy_gen_ranks = {}
self.etud_moy_gen_ranks_int = {}
+ self.moy_gen_rangs_by_group = None # virtual
self.modimpl_inscr_df: pd.DataFrame = None
"Inscriptions: row etudid, col modimlpl_id"
self.modimpls_results: ModuleImplResults = None
@@ -824,17 +825,25 @@ class ResultatsSemestre(ResultatsCache):
self.formsemestre.id
)
first_partition = True
+ col_order = 10
for partition in partitions:
cid = f"part_{partition['partition_id']}"
+ rg_cid = cid + "_rg" # rang dans la partition
titles[cid] = partition["partition_name"]
if first_partition:
klass = "partition"
else:
klass = "partition partition_aux"
titles[f"_{cid}_class"] = klass
- titles[f"_{cid}_col_order"] = 10
+ titles[f"_{cid}_col_order"] = col_order
+ titles[f"_{rg_cid}_col_order"] = col_order + 1
+ col_order += 2
+ if partition["bul_show_rank"]:
+ titles[rg_cid] = f"Rg {partition['partition_name']}"
+ titles[f"_{rg_cid}_class"] = "partition_rangs"
partition_etud_groups = partitions_etud_groups[partition["partition_id"]]
for row in rows:
+ group = None # group (dict) de l'étudiant dans cette partition
# dans NotesTableCompat, à revoir
etud_etat = self.get_etud_etat(row["etudid"])
if etud_etat == "D":
@@ -847,8 +856,17 @@ class ResultatsSemestre(ResultatsCache):
group = partition_etud_groups.get(row["etudid"])
gr_name = group["group_name"] if group else ""
if gr_name:
- row[f"{cid}"] = gr_name
+ row[cid] = gr_name
row[f"_{cid}_class"] = klass
+ # Rangs dans groupe
+ if (
+ partition["bul_show_rank"]
+ and (group is not None)
+ and (group["id"] in self.moy_gen_rangs_by_group)
+ ):
+ rang = self.moy_gen_rangs_by_group[group["id"]][0]
+ row[rg_cid] = rang.get(row["etudid"], "")
+
first_partition = False
def _recap_add_evaluations(
diff --git a/app/scodoc/sco_groups.py b/app/scodoc/sco_groups.py
index d316640fc..79ed91cad 100644
--- a/app/scodoc/sco_groups.py
+++ b/app/scodoc/sco_groups.py
@@ -1046,9 +1046,7 @@ def partition_set_attr(partition_id, attr, value):
partition[attr] = value
partitionEditor.edit(cnx, partition)
# invalid bulletin cache
- sco_cache.invalidate_formsemestre(
- pdfonly=True, formsemestre_id=partition["formsemestre_id"]
- )
+ sco_cache.invalidate_formsemestre(formsemestre_id=partition["formsemestre_id"])
return "enregistré"
diff --git a/app/static/js/table_recap.js b/app/static/js/table_recap.js
index 36426b508..fd5068e60 100644
--- a/app/static/js/table_recap.js
+++ b/app/static/js/table_recap.js
@@ -15,13 +15,23 @@ $(function () {
},
{
name: "toggle_partitions",
- text: "Toutes les partitions",
+ text: "Montrer groupes",
action: function (e, dt, node, config) {
let visible = dt.columns(".partition_aux").visible()[0];
dt.columns(".partition_aux").visible(!visible);
- dt.buttons('toggle_partitions:name').text(visible ? "Toutes les partitions" : "Cacher les partitions");
+ dt.buttons('toggle_partitions:name').text(visible ? "Montrer groupes" : "Cacher les groupes");
}
- }];
+ },
+ {
+ name: "toggle_partitions_rangs",
+ text: "Rangs groupes",
+ action: function (e, dt, node, config) {
+ let rangs_visible = dt.columns(".partition_rangs").visible()[0];
+ dt.columns(".partition_rangs").visible(!rangs_visible);
+ dt.buttons('toggle_partitions_rangs:name').text(rangs_visible ? "Rangs groupes" : "Cacher rangs groupes");
+ }
+ },
+ ];
if (!$('table.table_recap').hasClass("jury")) {
buttons.push(
$('table.table_recap').hasClass("apc") ?
@@ -95,7 +105,7 @@ $(function () {
"columnDefs": [
{
// cache les codes, le détail de l'identité, les groupes, les colonnes admission et les vides
- targets: ["codes", "identite_detail", "partition_aux", "admission", "col_empty"],
+ targets: ["codes", "identite_detail", "partition_aux", "partition_rangs", "admission", "col_empty"],
visible: false,
},
{
diff --git a/sco_version.py b/sco_version.py
index 3222274fa..d3dd51f24 100644
--- a/sco_version.py
+++ b/sco_version.py
@@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
-SCOVERSION = "9.2.22"
+SCOVERSION = "9.2.23"
SCONAME = "ScoDoc"
From 11b1b50a42ad1b506858cf2ffa141bd5ab5380bf Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Sun, 29 May 2022 17:38:52 +0200
Subject: [PATCH 03/16] Fix: recapcomplet / xlsall
---
app/comp/res_common.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/app/comp/res_common.py b/app/comp/res_common.py
index 654a1ae36..645f067e6 100644
--- a/app/comp/res_common.py
+++ b/app/comp/res_common.py
@@ -398,7 +398,7 @@ class ResultatsSemestre(ResultatsCache):
- titles: { column_id : title }
- columns_ids: (liste des id de colonnes)
- . Si convert_values, transforme les notes en chaines ("12.34").
+ Si convert_values, transforme les notes en chaines ("12.34").
Les colonnes générées sont:
etudid
rang : rang indicatif (basé sur moy gen)
@@ -590,7 +590,9 @@ class ResultatsSemestre(ResultatsCache):
f"moy_{modimpl.module.type_abbrv()}_{modimpl.id}_{ue.id}"
)
val_fmt = val_fmt_html = fmt_note(val)
- if modimpl.module.module_type == scu.ModuleType.MALUS:
+ if convert_values and (
+ modimpl.module.module_type == scu.ModuleType.MALUS
+ ):
val_fmt_html = (
(scu.EMO_RED_TRIANGLE_DOWN + val_fmt) if val else ""
)
From 596a45a90e9b173f023d542e2e701d822117ab63 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Mon, 30 May 2022 12:13:31 +0200
Subject: [PATCH 04/16] Fix: ajout de validations d'UE externes
---
app/scodoc/sco_ue_external.py | 58 ++++++++++++++++++++------------
app/static/js/sco_ue_external.js | 17 ++++++----
2 files changed, 47 insertions(+), 28 deletions(-)
diff --git a/app/scodoc/sco_ue_external.py b/app/scodoc/sco_ue_external.py
index b90afd0dd..825982286 100644
--- a/app/scodoc/sco_ue_external.py
+++ b/app/scodoc/sco_ue_external.py
@@ -56,6 +56,7 @@ Solution proposée (nov 2014):
import flask
from flask import request
from flask_login import current_user
+from app.models.formsemestre import FormSemestre
import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu
@@ -65,7 +66,6 @@ from app.scodoc import sco_codes_parcours
from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue
-from app.scodoc import sco_evaluations
from app.scodoc import sco_evaluation_db
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
@@ -85,17 +85,21 @@ def external_ue_create(
ects=0.0,
):
"""Crée UE/matiere/module/evaluation puis saisie les notes"""
- log("external_ue_create( formsemestre_id=%s, titre=%s )" % (formsemestre_id, titre))
- sem = sco_formsemestre.get_formsemestre(formsemestre_id)
+ formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
+ log(f"creating external UE in {formsemestre}: {acronyme}")
+
# Contrôle d'accès:
if not current_user.has_permission(Permission.ScoImplement):
- if not sem["resp_can_edit"] or (current_user.id not in sem["responsables"]):
+ if (not formsemestre.resp_can_edit) or (
+ current_user.id not in [u.id for u in formsemestre.responsables]
+ ):
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
#
- formation_id = sem["formation_id"]
- log("creating external UE in %s: %s" % (formsemestre_id, acronyme))
+ formation_id = formsemestre.formation.id
- numero = sco_edit_ue.next_ue_numero(formation_id, semestre_id=sem["semestre_id"])
+ numero = sco_edit_ue.next_ue_numero(
+ formation_id, semestre_id=formsemestre.semestre_id
+ )
ue_id = sco_edit_ue.do_ue_create(
{
"formation_id": formation_id,
@@ -120,7 +124,8 @@ def external_ue_create(
"ue_id": ue_id,
"matiere_id": matiere_id,
"formation_id": formation_id,
- "semestre_id": sem["semestre_id"],
+ "semestre_id": formsemestre.semestre_id,
+ "module_type": scu.ModuleType.STANDARD,
},
)
@@ -129,17 +134,23 @@ def external_ue_create(
"module_id": module_id,
"formsemestre_id": formsemestre_id,
# affecte le 1er responsable du semestre comme resp. du module
- "responsable_id": sem["responsables"][0],
+ "responsable_id": formsemestre.responsables[0].id
+ if len(formsemestre.responsables)
+ else None,
},
)
return moduleimpl_id
-def external_ue_inscrit_et_note(moduleimpl_id, formsemestre_id, notes_etuds):
+def external_ue_inscrit_et_note(
+ moduleimpl_id: int, formsemestre_id: int, notes_etuds: dict
+):
+ """Inscrit les étudiants au moduleimpl, crée au besoin une évaluation
+ et enregistre les notes.
+ """
log(
- "external_ue_inscrit_et_note(moduleimpl_id=%s, notes_etuds=%s)"
- % (moduleimpl_id, notes_etuds)
+ f"external_ue_inscrit_et_note(moduleimpl_id={moduleimpl_id}, notes_etuds={notes_etuds})"
)
# Inscription des étudiants
sco_moduleimpl.do_moduleimpl_inscrit_etuds(
@@ -175,17 +186,17 @@ def external_ue_inscrit_et_note(moduleimpl_id, formsemestre_id, notes_etuds):
)
-def get_existing_external_ue(formation_id):
- "la liste de toutes les UE externes définies dans cette formation"
+def get_existing_external_ue(formation_id: int) -> list[dict]:
+ "Liste de toutes les UE externes définies dans cette formation"
return sco_edit_ue.ue_list(args={"formation_id": formation_id, "is_external": True})
-def get_external_moduleimpl_id(formsemestre_id, ue_id):
+def get_external_moduleimpl_id(formsemestre_id: int, ue_id: int) -> int:
"moduleimpl correspondant à l'UE externe indiquée de ce formsemestre"
r = ndb.SimpleDictFetch(
"""
SELECT mi.id AS moduleimpl_id FROM notes_moduleimpl mi, notes_modules mo
- WHERE mi.id = %(formsemestre_id)s
+ WHERE mi.formsemestre_id = %(formsemestre_id)s
AND mi.module_id = mo.id
AND mo.ue_id = %(ue_id)s
""",
@@ -194,11 +205,14 @@ def get_external_moduleimpl_id(formsemestre_id, ue_id):
if r:
return r[0]["moduleimpl_id"]
else:
- raise ScoValueError("aucun module externe ne correspond")
+ raise ScoValueError(
+ f"""Aucun module externe ne correspond
+ (formsemestre_id={formsemestre_id}, ue_id={ue_id})"""
+ )
# Web function
-def external_ue_create_form(formsemestre_id, etudid):
+def external_ue_create_form(formsemestre_id: int, etudid: int):
"""Formulaire création UE externe + inscription étudiant et saisie note
- Demande UE: peut-être existante (liste les UE externes de cette formation),
ou sinon spécifier titre, acronyme, type, ECTS
@@ -233,7 +247,9 @@ def external_ue_create_form(formsemestre_id, etudid):
html_footer = html_sco_header.sco_footer()
Fo = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0]
parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"])
- ue_types = parcours.ALLOWED_UE_TYPES
+ ue_types = [
+ typ for typ in parcours.ALLOWED_UE_TYPES if typ != sco_codes_parcours.UE_SPORT
+ ]
ue_types.sort()
ue_types_names = [sco_codes_parcours.UE_TYPE_NAME[k] for k in ue_types]
ue_types = [str(x) for x in ue_types]
@@ -255,7 +271,7 @@ def external_ue_create_form(formsemestre_id, etudid):
"input_type": "menu",
"title": "UE externe existante:",
"allowed_values": [""]
- + [ue["ue_id"] for ue in existing_external_ue],
+ + [str(ue["ue_id"]) for ue in existing_external_ue],
"labels": [default_label]
+ [
"%s (%s)" % (ue["titre"], ue["acronyme"])
@@ -337,7 +353,7 @@ def external_ue_create_form(formsemestre_id, etudid):
+ html_footer
)
if tf[2]["existing_ue"]:
- ue_id = tf[2]["existing_ue"]
+ ue_id = int(tf[2]["existing_ue"])
moduleimpl_id = get_external_moduleimpl_id(formsemestre_id, ue_id)
else:
acronyme = tf[2]["acronyme"].strip()
diff --git a/app/static/js/sco_ue_external.js b/app/static/js/sco_ue_external.js
index 24cd2157c..fb57807f4 100644
--- a/app/static/js/sco_ue_external.js
+++ b/app/static/js/sco_ue_external.js
@@ -9,19 +9,22 @@ function toggle_new_ue_form(state) {
text_color = 'rgb(0,0,0)';
}
- $("#tf_extue_titre td:eq(1) input").prop( "disabled", state );
- $("#tf_extue_titre td:eq(1) input").css('color', text_color)
+ $("#tf_extue_titre td:eq(1) input").prop("disabled", state);
+ $("#tf_extue_titre").css('color', text_color)
- $("#tf_extue_acronyme td:eq(1) input").prop( "disabled", state );
- $("#tf_extue_acronyme td:eq(1) input").css('color', text_color)
+ $("#tf_extue_acronyme td:eq(1) input").prop("disabled", state);
+ $("#tf_extue_acronyme").css('color', text_color)
- $("#tf_extue_ects td:eq(1) input").prop( "disabled", state );
- $("#tf_extue_ects td:eq(1) input").css('color', text_color)
+ $("#tf_extue_type td:eq(1) select").prop("disabled", state);
+ $("#tf_extue_type").css('color', text_color)
+
+ $("#tf_extue_ects td:eq(1) input").prop("disabled", state);
+ $("#tf_extue_ects").css('color', text_color)
}
function update_external_ue_form() {
- var state = (tf.existing_ue.value != "")
+ var state = (tf.existing_ue.value != "");
toggle_new_ue_form(state);
}
From ff0437d8448f1ab2f1aa902e564e96ce646716b2 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Tue, 31 May 2022 14:15:21 +0200
Subject: [PATCH 05/16] lint
---
app/scodoc/sco_edit_ue.py | 2 +-
sco_version.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py
index 4c0a8ef59..a0f4ff743 100644
--- a/app/scodoc/sco_edit_ue.py
+++ b/app/scodoc/sco_edit_ue.py
@@ -147,7 +147,7 @@ def can_delete_ue(ue: UniteEns) -> bool:
et n'a pas de module rattachés
"""
# "pas un seul module de cette UE n'a de modimpl...""
- return (not len(ue.modules.all())) and not any(m.modimpls.all() for m in ue.modules)
+ return (ue.modules.count() == 0) and not any(m.modimpls.all() for m in ue.modules)
def do_ue_delete(ue_id, delete_validations=False, force=False):
diff --git a/sco_version.py b/sco_version.py
index d3dd51f24..3de1255fd 100644
--- a/sco_version.py
+++ b/sco_version.py
@@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
-SCOVERSION = "9.2.23"
+SCOVERSION = "9.2.24"
SCONAME = "ScoDoc"
From f626fa3eff740fefd25132635cebaab43b3c53bd Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Wed, 1 Jun 2022 12:41:04 +0200
Subject: [PATCH 06/16] Modification bonus IUT de Rennes (n'affecte plus les
moy. d'UE hors BUT).
---
app/comp/bonus_spo.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/app/comp/bonus_spo.py b/app/comp/bonus_spo.py
index 06a7bde76..48856771d 100644
--- a/app/comp/bonus_spo.py
+++ b/app/comp/bonus_spo.py
@@ -711,7 +711,8 @@ class BonusIUTRennes1(BonusSportAdditif):
Les étudiants peuvent suivre un ou plusieurs activités optionnelles notées.
La meilleure des notes obtenue est prise en compte, si elle est supérieure à 10/20.
- Le vingtième des points au dessus de 10 est ajouté à la moyenne des UE.
+ Le vingtième des points au dessus de 10 est ajouté à la moyenne de chaque UE
+ en BUT, ou à la moyenne générale pour les autres formations.
Exemple: un étudiant ayant 16/20 bénéficiera d'un bonus de (16-10)/20 = 0,3 points
sur chaque UE.
@@ -720,10 +721,10 @@ class BonusIUTRennes1(BonusSportAdditif):
"""
name = "bonus_iut_rennes1"
- displayed_name = "IUTs de Rennes 1 (Lannion, St Malo)"
+ displayed_name = "IUTs de Rennes 1 (Lannion, Rennes, St Brieuc, St Malo)"
seuil_moy_gen = 10.0
proportion_point = 1 / 20.0
- classic_use_bonus_ues = True
+ classic_use_bonus_ues = False
# Adapté de BonusTarbes, mais s'applique aussi en classic
def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
"""calcul du bonus"""
From 10811173e66f3c13d2825b3778c0337b732db49d Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Thu, 2 Jun 2022 00:02:32 +0200
Subject: [PATCH 07/16] Suppression source bonus ScoDoc7
---
app/scodoc/bonus_sport.py | 492 --------------------------------------
app/scodoc/sco_config.py | 4 +-
2 files changed, 1 insertion(+), 495 deletions(-)
delete mode 100644 app/scodoc/bonus_sport.py
diff --git a/app/scodoc/bonus_sport.py b/app/scodoc/bonus_sport.py
deleted file mode 100644
index b49b6159b..000000000
--- a/app/scodoc/bonus_sport.py
+++ /dev/null
@@ -1,492 +0,0 @@
-# -*- mode: python -*-
-# -*- coding: utf-8 -*-
-
-##############################################################################
-#
-# Gestion scolarite IUT
-#
-# Copyright (c) 1999 - 2022 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
-#
-##############################################################################
-
-from operator import mul
-import pprint
-
-""" ANCIENS BONUS SPORT pour ScoDoc < 9.2 NON UTILISES A PARTIR DE 9.2 (voir comp/bonus_spo.py)
-
-La fonction bonus_sport reçoit:
-
- - notes_sport: la liste des notes des modules de sport et culture (une note par module
- de l'UE de type sport/culture, toujours dans remise sur 20);
- - coefs: un coef (float) pondérant chaque note (la plupart des bonus les ignorent);
- - infos: dictionnaire avec des données pouvant être utilisées pour les calculs.
- Ces données dépendent du type de formation.
- infos = {
- "moy" : la moyenne générale (float). 0. en BUT.
- "sem" : {
- "date_debut_iso" : "2010-08-01", # date de début de semestre
- }
- "moy_ues": {
- ue_id : { # ue_status
- "is_capitalized" : True|False,
- "moy" : float, # moyenne d'UE prise en compte (peut-être capitalisée)
- "sum_coefs": float, # > 0 si UE avec la moyenne calculée
- "cur_moy_ue": float, # moyenne de l'UE (sans capitalisation))
- }
- }
- }
-
-Les notes passées sont:
- - pour les formations classiques, la moyenne dans le module, calculée comme d'habitude
- (moyenne pondérée des notes d'évaluations);
- - pour le BUT: pareil, *en ignorant* les éventuels poids des évaluations. Le coefficient
- de l'évaluation est pris en compte, mais pas les poids vers les UE.
-
-Pour modifier les moyennes d'UE:
- - modifier infos["moy_ues"][ue_id][["cur_moy_ue"]
- et, seulement si l'UE n'est pas capitalisée, infos["moy_ues"][ue_id][["moy"]/
-
-La valeur retournée est:
- - formations classiques: ajoutée à la moyenne générale
- - BUT: valeur multipliée par la somme des coefs modules sport ajoutée à chaque UE.
-
-"""
-
-
-def bonus_iutv(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport, culture), règle IUT Villetaneuse
-
- Les étudiants de l'IUT peuvent suivre des enseignements optionnels
- de l'Université Paris 13 (sports, musique, deuxième langue,
- culture, etc) non rattachés à une unité d'enseignement. Les points
- au-dessus de 10 sur 20 obtenus dans chacune des matières
- optionnelles sont cumulés et 5% de ces points cumulés s'ajoutent à
- la moyenne générale du semestre déjà obtenue par l'étudiant.
- """
- bonus = sum([(x - 10) / 20.0 for x in notes_sport if x > 10])
- return bonus
-
-
-def bonus_direct(notes_sport, coefs, infos=None):
- """Un bonus direct et sans chichis: les points sont directement ajoutés à la moyenne générale.
- Les coefficients sont ignorés: tous les points de bonus sont sommés.
- (rappel: la note est ramenée sur 20 avant application).
- """
- return sum(notes_sport)
-
-
-def bonus_iut_stdenis(notes_sport, coefs, infos=None):
- """Semblable à bonus_iutv mais total limité à 0.5 points."""
- points = sum([x - 10 for x in notes_sport if x > 10]) # points au dessus de 10
- bonus = points * 0.05 # ou / 20
- return min(bonus, 0.5) # bonus limité à 1/2 point
-
-
-def bonus_colmar(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport, culture), règle IUT Colmar.
-
- Les étudiants de l'IUT peuvent suivre des enseignements optionnels
- de l'U.H.A. (sports, musique, deuxième langue, culture, etc) non
- rattachés à une unité d'enseignement. Les points au-dessus de 10
- sur 20 obtenus dans chacune des matières optionnelles sont cumulés
- dans la limite de 10 points. 5% de ces points cumulés s'ajoutent à
- la moyenne générale du semestre déjà obtenue par l'étudiant.
-
- """
- # les coefs sont ignorés
- points = sum([x - 10 for x in notes_sport if x > 10])
- points = min(10, points) # limite total à 10
- bonus = points / 20.0 # 5%
- return bonus
-
-
-def bonus_iutva(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport, culture), règle IUT Ville d'Avray
-
- Les étudiants de l'IUT peuvent suivre des enseignements optionnels
- de l'Université Paris 10 (C2I) non rattachés à une unité d'enseignement.
- Si la note est >= 10 et < 12, bonus de 0.1 point
- Si la note est >= 12 et < 16, bonus de 0.2 point
- Si la note est >= 16, bonus de 0.3 point
- Ce bonus s'ajoute à la moyenne générale du semestre déjà obtenue par
- l'étudiant.
- """
- sumc = sum(coefs) # assumes sum. coefs > 0
- note_sport = sum(map(mul, notes_sport, coefs)) / sumc # moyenne pondérée
- if note_sport >= 16.0:
- return 0.3
- if note_sport >= 12.0:
- return 0.2
- if note_sport >= 10.0:
- return 0.1
- return 0
-
-
-def bonus_iut1grenoble_2017(notes_sport, coefs, infos=None):
- """Calcul bonus sport IUT Grenoble sur la moyenne générale (version 2017)
-
- La note de sport de nos étudiants va de 0 à 5 points.
- Chaque point correspond à un % qui augmente la moyenne de chaque UE et la moyenne générale.
- Par exemple : note de sport 2/5 : la moyenne générale sera augmentée de 2%.
-
- Calcul ici du bonus sur moyenne générale
- """
- # les coefs sont ignorés
- # notes de 0 à 5
- points = sum([x for x in notes_sport])
- factor = (points / 4.0) / 100.0
- bonus = infos["moy"] * factor
-
- return bonus
-
-
-def bonus_lille(notes_sport, coefs, infos=None):
- """calcul bonus modules optionels (sport, culture), règle IUT Villeneuve d'Ascq
-
- Les étudiants de l'IUT peuvent suivre des enseignements optionnels
- de l'Université Lille 1 (sports,etc) non rattachés à une unité d'enseignement. Les points
- au-dessus de 10 sur 20 obtenus dans chacune des matières
- optionnelles sont cumulés et 4% (2% avant aout 2010) de ces points cumulés s'ajoutent à
- la moyenne générale du semestre déjà obtenue par l'étudiant.
- """
- if (
- infos["sem"]["date_debut_iso"] > "2010-08-01"
- ): # changement de regle en aout 2010.
- return sum([(x - 10) / 25.0 for x in notes_sport if x > 10])
- return sum([(x - 10) / 50.0 for x in notes_sport if x > 10])
-
-
-# Fonction Le Havre, par Dom. Soud.
-def bonus_iutlh(notes_sport, coefs, infos=None):
- """Calcul bonus sport IUT du Havre sur moyenne générale et UE
-
- La note de sport de nos étudiants va de 0 à 20 points.
- m2=m1*(1+0.005*((10-N1)+(10-N2))
- m2 : Nouvelle moyenne de l'unité d'enseignement si note de sport et/ou de langue supérieure à 10
- m1 : moyenne de l'unité d'enseignement avant bonification
- N1 : note de sport si supérieure à 10
- N2 : note de seconde langue si supérieure à 10
- Par exemple : sport 15/20 et langue 12/20 : chaque UE sera multipliée par 1+0.005*7, ainsi que la moyenne générale.
- Calcul ici de la moyenne générale et moyennes d'UE non capitalisées.
- """
- # les coefs sont ignorés
- points = sum([x - 10 for x in notes_sport if x > 10])
- points = min(10, points) # limite total à 10
- factor = 1.0 + (0.005 * points)
- # bonus nul puisque les moyennes sont directement modifiées par factor
- bonus = 0
- # Modifie la moyenne générale
- infos["moy"] = infos["moy"] * factor
- # Modifie les moyennes de toutes les UE:
- for ue_id in infos["moy_ues"]:
- ue_status = infos["moy_ues"][ue_id]
- if ue_status["sum_coefs"] > 0:
- # modifie moyenne UE ds semestre courant
- ue_status["cur_moy_ue"] = ue_status["cur_moy_ue"] * factor
- if not ue_status["is_capitalized"]:
- # si non capitalisee, modifie moyenne prise en compte
- ue_status["moy"] = ue_status["cur_moy_ue"]
-
- # open('/tmp/log','a').write( pprint.pformat(ue_status) + '\n\n' )
- return bonus
-
-
-def bonus_nantes(notes_sport, coefs, infos=None):
- """IUT de Nantes (Septembre 2018)
- Nous avons différents types de bonification
- bonfication Sport / Culture / engagement citoyen
- Nous ajoutons sur le bulletin une bonification de 0,2 pour chaque item
- la bonification totale ne doit pas excéder les 0,5 point.
- Sur le bulletin nous ne mettons pas une note sur 20 mais directement les bonifications.
-
- Dans ScoDoc: on a déclaré une UE "sport&culture" dans laquelle on aura des modules
- pour chaque activité (Sport, Associations, ...)
- avec à chaque fois une note (ScoDoc l'affichera comme une note sur 20, mais en fait ce sera la
- valeur de la bonification: entrer 0,1/20 signifiera un bonus de 0,1 point la moyenne générale)
- """
- bonus = min(0.5, sum([x for x in notes_sport])) # plafonnement à 0.5 points
- return bonus
-
-
-# Bonus sport IUT Tours
-def bonus_tours(notes_sport, coefs, infos=None):
- """Calcul bonus sport & culture IUT Tours sur moyenne generale
-
- La note de sport & culture de nos etudiants est applique sur la moyenne generale.
- """
- return min(1.0, sum(notes_sport)) # bonus maximum de 1 point
-
-
-def bonus_iutr(notes_sport, coefs, infos=None):
- """Calcul du bonus , règle de l'IUT de Roanne
- (contribuée par Raphael C., nov 2012)
-
- Le bonus est compris entre 0 et 0.35 point.
- cette procédure modifie la moyenne de chaque UE capitalisable.
-
- """
- # modifie les moyennes de toutes les UE:
- # le bonus est le minimum entre 0.35 et la somme de toutes les bonifs
- bonus = min(0.35, sum([x for x in notes_sport]))
- for ue_id in infos["moy_ues"]:
- # open('/tmp/log','a').write( str(ue_id) + infos['moy_ues'] + '\n\n' )
- ue_status = infos["moy_ues"][ue_id]
- if ue_status["sum_coefs"] > 0:
- # modifie moyenne UE dans semestre courant
- ue_status["cur_moy_ue"] = ue_status["cur_moy_ue"] + bonus
- if not ue_status["is_capitalized"]:
- ue_status["moy"] = ue_status["cur_moy_ue"]
- return bonus
-
-
-def bonus_iutam(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport), regle IUT d'Amiens.
- Les etudiants de l'IUT peuvent suivre des enseignements optionnels.
- Si la note est de 10.00 a 10.49 -> 0.50% de la moyenne
- Si la note est de 10.50 a 10.99 -> 0.75%
- Si la note est de 11.00 a 11.49 -> 1.00%
- Si la note est de 11.50 a 11.99 -> 1.25%
- Si la note est de 12.00 a 12.49 -> 1.50%
- Si la note est de 12.50 a 12.99 -> 1.75%
- Si la note est de 13.00 a 13.49 -> 2.00%
- Si la note est de 13.50 a 13.99 -> 2.25%
- Si la note est de 14.00 a 14.49 -> 2.50%
- Si la note est de 14.50 a 14.99 -> 2.75%
- Si la note est de 15.00 a 15.49 -> 3.00%
- Si la note est de 15.50 a 15.99 -> 3.25%
- Si la note est de 16.00 a 16.49 -> 3.50%
- Si la note est de 16.50 a 16.99 -> 3.75%
- Si la note est de 17.00 a 17.49 -> 4.00%
- Si la note est de 17.50 a 17.99 -> 4.25%
- Si la note est de 18.00 a 18.49 -> 4.50%
- Si la note est de 18.50 a 18.99 -> 4.75%
- Si la note est de 19.00 a 20.00 -> 5.00%
- Ce bonus s'ajoute a la moyenne generale du semestre de l'etudiant.
- """
- # une seule note
- note_sport = notes_sport[0]
- if note_sport < 10.0:
- return 0.0
- prc = min((int(2 * note_sport - 20.0) + 2) * 0.25, 5)
- bonus = infos["moy"] * prc / 100.0
- return bonus
-
-
-def bonus_saint_etienne(notes_sport, coefs, infos=None):
- """IUT de Saint-Etienne (jan 2014)
- Nous avons différents types de bonification
- bonfication Sport / Associations
- coopératives de département / Bureau Des Étudiants
- / engagement citoyen / Langues optionnelles
- Nous ajoutons sur le bulletin une bonification qui varie entre 0,1 et 0,3 ou 0,35 pour chaque item
- la bonification totale ne doit pas excéder les 0,6 point.
- Sur le bulletin nous ne mettons pas une note sur 20 mais directement les bonifications.
-
-
- Dans ScoDoc: on a déclarer une UE "sport&culture" dans laquelle on aura des modules
- pour chaque activité (Sport, Associations, ...)
- avec à chaque fois une note (ScoDoc l'affichera comme une note sur 20, mais en fait ce sera la
- valeur de la bonification: entrer 0,1/20 signifiera un bonus de 0,1 point la moyenne générale)
- """
- bonus = min(0.6, sum([x for x in notes_sport])) # plafonnement à 0.6 points
-
- return bonus
-
-
-def bonus_iutTarbes(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionnels
- (sport, Langues, action sociale, Théâtre), règle IUT Tarbes
- Les coefficients ne sont pas pris en compte,
- seule la meilleure note est prise en compte
- le 1/30ème des points au-dessus de 10 sur 20 est retenu et s'ajoute à
- la moyenne générale du semestre déjà obtenue par l'étudiant.
- """
- bonus = max([(x - 10) / 30.0 for x in notes_sport if x > 10] or [0.0])
- return bonus
-
-
-def bonus_iutSN(notes_sport, coefs, infos=None):
- """Calcul bonus sport IUT Saint-Nazaire sur moyenne générale
-
- La note de sport de nos étudiants va de 0 à 5 points.
- La note de culture idem,
- Elles sont cumulables,
- Chaque point correspond à un % qui augmente la moyenne générale.
- Par exemple : note de sport 2/5 : la moyenne générale sera augmentée de 2%.
-
- Calcul ici du bonus sur moyenne générale et moyennes d'UE non capitalisées.
- """
- # les coefs sont ignorés
- # notes de 0 à 5
- points = sum([x for x in notes_sport])
- factor = points / 100.0
- bonus = infos["moy"] * factor
- return bonus
-
-
-def bonus_iutBordeaux1(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport, culture), règle IUT Bordeaux 1, sur moyenne générale et UE
-
- Les étudiants de l'IUT peuvent suivre des enseignements optionnels
- de l'Université Bordeaux 1 (sport, théâtre) non rattachés à une unité d'enseignement.
- En cas de double activité, c'est la meilleure des 2 notes qui compte.
- Chaque point au-dessus de 10 sur 20 obtenus dans cet enseignement correspond à un %
- qui augmente la moyenne de chaque UE et la moyenne générale.
- Formule : le % = points>moyenne / 2
- Par exemple : sport 13/20 : chaque UE sera multipliée par 1+0,015, ainsi que la moyenne générale.
-
- Calcul ici du bonus sur moyenne générale et moyennes d'UE non capitalisées.
- """
- # open('/tmp/log','a').write( '\n---------------\n' + pprint.pformat(infos) + '\n' )
- # les coefs sont ignorés
- # on récupère la note maximum et les points au-dessus de la moyenne
- sport = max(notes_sport)
- points = max(0, sport - 10)
- # on calcule le bonus
- factor = (points / 2.0) / 100.0
- bonus = infos["moy"] * factor
- # Modifie les moyennes de toutes les UE:
- for ue_id in infos["moy_ues"]:
- ue_status = infos["moy_ues"][ue_id]
- if ue_status["sum_coefs"] > 0:
- # modifie moyenne UE ds semestre courant
- ue_status["cur_moy_ue"] = ue_status["cur_moy_ue"] * (1.0 + factor)
- if not ue_status["is_capitalized"]:
- # si non capitalisee, modifie moyenne prise en compte
- ue_status["moy"] = ue_status["cur_moy_ue"]
-
- # open('/tmp/log','a').write( pprint.pformat(ue_status) + '\n\n' )
- return bonus
-
-
-def bonus_iuto(notes_sport, coefs, infos=None): # OBSOLETE => EN ATTENTE (27/01/2022)
- """Calcul bonus modules optionels (sport, culture), règle IUT Orleans
- * Avant aout 2013
- Un bonus de 2,5% de la note de sport est accordé à chaque UE sauf
- les UE de Projet et Stages
- * Après aout 2013
- Un bonus de 2,5% de la note de sport est accordé à la moyenne générale
- """
- sumc = sum(coefs) # assumes sum. coefs > 0
- note_sport = sum(map(mul, notes_sport, coefs)) / sumc # moyenne pondérée
- bonus = note_sport * 2.5 / 100
- if (
- infos["sem"]["date_debut_iso"] > "2013-08-01"
- ): # changement de regle en aout 2013.
- return bonus
- coefs = 0.0
- coefs_total = 0.0
- for ue_id in infos["moy_ues"]:
- ue_status = infos["moy_ues"][ue_id]
- coefs_total = coefs_total + ue_status["sum_coefs"]
- # Extremement spécifique (et n'est plus utilisé)
- if ue_status["ue"]["ue_code"] not in {
- "ORA14",
- "ORA24",
- "ORA34",
- "ORA44",
- "ORB34",
- "ORB44",
- "ORD42",
- "ORE14",
- "ORE25",
- "ORN44",
- "ORO44",
- "ORP44",
- "ORV34",
- "ORV42",
- "ORV43",
- }:
- if ue_status["sum_coefs"] > 0:
- coefs = coefs + ue_status["sum_coefs"]
- # modifie moyenne UE ds semestre courant
- ue_status["cur_moy_ue"] = ue_status["cur_moy_ue"] + bonus
- if not ue_status["is_capitalized"]:
- # si non capitalisee, modifie moyenne prise en compte
- ue_status["moy"] = ue_status["cur_moy_ue"]
- return bonus * coefs / coefs_total
-
-
-def bonus_iutbethune(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport), règle IUT Bethune
-
- Les points au dessus de la moyenne de 10 apportent un bonus pour le semestre.
- Ce bonus est égal au nombre de points divisé par 200 et multiplié par la
- moyenne générale du semestre de l'étudiant.
- """
- # les coefs sont ignorés
- points = sum([x - 10 for x in notes_sport if x > 10])
- points = min(10, points) # limite total à 10
- bonus = int(infos["moy"] * points / 2) / 100.0 # moyenne-semestre x points x 0,5%
- return bonus
-
-
-def bonus_iutbeziers(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport, culture), regle IUT BEZIERS
-
- Les étudiants de l'IUT peuvent suivre des enseignements optionnels
- sport , etc) non rattaches à une unité d'enseignement. Les points
- au-dessus de 10 sur 20 obtenus dans chacune des matières
- optionnelles sont cumulés et 3% de ces points cumulés s'ajoutent à
- la moyenne générale du semestre déjà obtenue par l'étudiant.
- """
- sumc = sum(coefs) # assumes sum. coefs > 0
- # note_sport = sum(map(mul, notes_sport, coefs)) / sumc # moyenne pondérée
- bonus = sum([(x - 10) * 0.03 for x in notes_sport if x > 10])
- # le total du bonus ne doit pas dépasser 0.3 - Fred, 28/01/2020
-
- if bonus > 0.3:
- bonus = 0.3
- return bonus
-
-
-def bonus_iutlemans(notes_sport, coefs, infos=None):
- "fake: formule inutilisée en ScoDoc 9.2 mais doiut être présente"
- return 0.0
-
-
-def bonus_iutlr(notes_sport, coefs, infos=None):
- """Calcul bonus modules optionels (sport, culture), règle IUT La Rochelle
- Si la note de sport est comprise entre 0 et 10 : pas d'ajout de point
- Si la note de sport est comprise entre 10.1 et 20 : ajout de 1% de cette note sur la moyenne générale du semestre
- """
- # les coefs sont ignorés
- # une seule note
- note_sport = notes_sport[0]
- if note_sport <= 10:
- return 0
- bonus = note_sport * 0.01 # 1%
- return bonus
-
-
-def bonus_demo(notes_sport, coefs, infos=None):
- """Fausse fonction "bonus" pour afficher les informations disponibles
- et aider les développeurs.
- Les informations sont placées dans le fichier /tmp/scodoc_bonus.log
- qui est ECRASE à chaque appel.
- *** Ne pas utiliser en production !!! ***
- """
- with open("/tmp/scodoc_bonus.log", "w") as f: # mettre 'a' pour ajouter en fin
- f.write("\n---------------\n" + pprint.pformat(infos) + "\n")
- # Statut de chaque UE
- # for ue_id in infos['moy_ues']:
- # ue_status = infos['moy_ues'][ue_id]
- # #open('/tmp/log','a').write( pprint.pformat(ue_status) + '\n\n' )
-
- return 0.0
diff --git a/app/scodoc/sco_config.py b/app/scodoc/sco_config.py
index 95b9dcc98..b338f9a7d 100644
--- a/app/scodoc/sco_config.py
+++ b/app/scodoc/sco_config.py
@@ -1,13 +1,11 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
-"""Configuration de ScoDoc (version ScoDOc 9)
+"""Configuration de ScoDoc (version ScoDoc 9)
NE PAS MODIFIER localement ce fichier !
mais éditer /opt/scodoc-data/config/scodoc_local.py
"""
-from app.scodoc import bonus_sport
-
class AttrDict(dict):
def __init__(self, *args, **kwargs):
From 3240d625b0c8836ce35bf4a63758103e41de8097 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Thu, 2 Jun 2022 11:36:47 +0200
Subject: [PATCH 08/16] Bonus St Nazaire
---
app/comp/bonus_spo.py | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/app/comp/bonus_spo.py b/app/comp/bonus_spo.py
index 48856771d..0cc5257fb 100644
--- a/app/comp/bonus_spo.py
+++ b/app/comp/bonus_spo.py
@@ -266,6 +266,8 @@ class BonusSportMultiplicatif(BonusSport):
amplitude = 0.005 # multiplie les points au dessus du seuil
# En classique, les bonus multiplicatifs agissent par défaut sur les UE:
classic_use_bonus_ues = True
+ # Facteur multiplicatif max: (bonus = moy_ue*factor)
+ factor_max = 1000.0 # infini
# C'est un bonus "multiplicatif": on l'exprime en additif,
# sur chaque moyenne d'UE m_0
@@ -285,6 +287,8 @@ class BonusSportMultiplicatif(BonusSport):
notes = np.nan_to_num(notes, copy=False)
factor = (notes - self.seuil_moy_gen) * self.amplitude # 5% si note=20
factor[factor <= 0] = 0.0 # note < seuil_moy_gen, pas de bonus
+ # note < seuil_moy_gen, pas de bonus: pas de facteur négatif, ni
+ factor.clip(0.0, self.factor_max, out=factor)
# Ne s'applique qu'aux moyennes d'UE
if len(factor.shape) == 1: # classic
@@ -967,7 +971,7 @@ class BonusNantes(BonusSportAdditif):
class BonusPoitiers(BonusSportAdditif):
"""Calcul bonus optionnels (sport, culture), règle IUT de Poitiers.
- Les deux notes d'option supérieure à 10, bonifies les moyennes de chaque UE.
+ Les deux notes d'option supérieure à 10, bonifient les moyennes de chaque UE.
bonus = (option1 - 10)*5% + (option2 - 10)*5%
"""
@@ -993,7 +997,7 @@ class BonusRoanne(BonusSportAdditif):
class BonusStBrieuc(BonusSportAdditif):
- """IUT de Saint Brieuc
+ """IUT de Saint-Brieuc
Ne s'applique qu'aux semestres pairs (S2, S4, S6), et bonifie les moyennes d'UE:
@@ -1045,7 +1049,7 @@ class BonusStDenis(BonusSportAdditif):
class BonusStMalo(BonusStBrieuc):
# identique à St Brieux, sauf la doc
- """IUT de Saint Malo
+ """IUT de Saint-Malo
Ne s'applique qu'aux semestres pairs (S2, S4, S6), et bonifie les moyennes d'UE:
@@ -1056,6 +1060,33 @@ class BonusStMalo(BonusStBrieuc):
displayed_name = "IUT de Saint-Malo"
+class BonusStNazaire(BonusSportMultiplicatif):
+ """IUT de Saint-Nazaire
+
+ Trois bonifications sont possibles : sport, culture et engagement citoyen
+ (qui seront déclarées comme des modules séparés de l'UE bonus).
+
+ - Chaque bonus est compris entre 0 et 20 points -> 4pt = 1%
+ (note 4/20: 1%, 8/20: 2%, 12/20: 3%, 16/20: 4%, 20/20: 5%)
+
+ - Le total des 3 bonus ne peut excéder 10%
+ - La somme des bonus s'applique à la moyenne de chaque UE
+
+ Exemple: une moyenne d'UE de 10/20 avec un total des bonus de 6% donne
+ une moyenne de 10,6.
+ Les bonifications s'appliquent aussi au classement général du semestre
+ et de l'année.
+
+ """
+
+ name = "bonus_iutSN"
+ displayed_name = "IUT de Saint-Nazaire"
+ classic_use_bonus_ues = True # s'applique aux UEs en DUT et LP
+ seuil_moy_gen = 0.0 # tous les points comptent
+ amplitude = 0.01 / 4 # 4pt => 1%
+ factor_max = 0.1 # 10% max
+
+
class BonusTarbes(BonusSportAdditif):
"""Calcul bonus optionnels (sport, culture), règle IUT de Tarbes.
From be92c86baf6bb61cb0ea7e7465b0528bb094f330 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Thu, 2 Jun 2022 11:37:13 +0200
Subject: [PATCH 09/16] cosmetic
---
app/scodoc/sco_evaluations.py | 14 ++++++++------
app/scodoc/sco_moduleimpl_status.py | 6 +++++-
app/scodoc/sco_saisie_notes.py | 4 +++-
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/app/scodoc/sco_evaluations.py b/app/scodoc/sco_evaluations.py
index 6152e8810..09bf21024 100644
--- a/app/scodoc/sco_evaluations.py
+++ b/app/scodoc/sco_evaluations.py
@@ -606,12 +606,10 @@ def formsemestre_evaluations_delai_correction(formsemestre_id, format="html"):
# -------------- VIEWS
-def evaluation_describe(evaluation_id="", edit_in_place=True):
+def evaluation_describe(evaluation_id="", edit_in_place=True, link_saisie=True):
"""HTML description of evaluation, for page headers
edit_in_place: allow in-place editing when permitted (not implemented)
"""
- from app.scodoc import sco_saisie_notes
-
E = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})[0]
moduleimpl_id = E["moduleimpl_id"]
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
@@ -646,7 +644,7 @@ def evaluation_describe(evaluation_id="", edit_in_place=True):
if Mod["module_type"] == ModuleType.MALUS:
etit += ' (points de malus)'
H = [
- 'Evaluation%sModule : %s
'
+ 'Évaluation%sModule : %s
'
% (etit, mod_descr)
]
if Mod["module_type"] == ModuleType.MALUS:
@@ -689,12 +687,16 @@ def evaluation_describe(evaluation_id="", edit_in_place=True):
modifier l'évaluation
-
+ """
+ )
+ if link_saisie:
+ H.append(
+ f"""
saisie des notes
"""
- )
+ )
H.append("
")
return '' + "\n".join(H) + "
"
diff --git a/app/scodoc/sco_moduleimpl_status.py b/app/scodoc/sco_moduleimpl_status.py
index d6def3697..b9e6a3ee0 100644
--- a/app/scodoc/sco_moduleimpl_status.py
+++ b/app/scodoc/sco_moduleimpl_status.py
@@ -277,7 +277,11 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
if modimpl.module.is_apc():
H.append(_ue_coefs_html(modimpl.module.ue_coefs_list()))
else:
- H.append(f"Coef. dans le semestre: {modimpl.module.coefficient}")
+ H.append(
+ f"""Coef. dans le semestre: {
+ "non défini" if modimpl.module.coefficient is None else modimpl.module.coefficient
+ }"""
+ )
H.append(""" | """)
# 3ieme ligne: Formation
H.append(
diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py
index 733ef1730..e75977359 100644
--- a/app/scodoc/sco_saisie_notes.py
+++ b/app/scodoc/sco_saisie_notes.py
@@ -943,7 +943,9 @@ def saisie_notes(evaluation_id, group_ids=[]):
cssstyles=sco_groups_view.CSSSTYLES,
init_qtip=True,
),
- sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
+ sco_evaluations.evaluation_describe(
+ evaluation_id=evaluation_id, link_saisie=False
+ ),
'Saisie des notes',
]
H.append("""
""")
From 1dc6dd3d6dd45afd4ee6602c6a95878a7af43b7a Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Thu, 2 Jun 2022 11:53:53 +0200
Subject: [PATCH 10/16] Regroupe bonus IUT de Renens 1
---
app/comp/bonus_spo.py | 52 +++++++++++++------------------------------
1 file changed, 16 insertions(+), 36 deletions(-)
diff --git a/app/comp/bonus_spo.py b/app/comp/bonus_spo.py
index 0cc5257fb..7cbac1c79 100644
--- a/app/comp/bonus_spo.py
+++ b/app/comp/bonus_spo.py
@@ -709,10 +709,11 @@ class BonusGrenobleIUT1(BonusSportMultiplicatif):
class BonusIUTRennes1(BonusSportAdditif):
"""Calcul bonus optionnels (sport, langue vivante, engagement étudiant),
- règle IUT de l'Université de Rennes 1 (Lannion, St Malo).
+ règle IUT de l'Université de Rennes 1 (Lannion, Rennes, St Brieuc, St Malo).
- - Les étudiants peuvent suivre un ou plusieurs activités optionnelles notées.
+
- Les étudiants peuvent suivre un ou plusieurs activités optionnelles notées
+ dans les semestres pairs.
La meilleure des notes obtenue est prise en compte, si elle est supérieure à 10/20.
- Le vingtième des points au dessus de 10 est ajouté à la moyenne de chaque UE
@@ -753,6 +754,19 @@ class BonusIUTRennes1(BonusSportAdditif):
self.bonus_additif(bonus_moy_arr)
+# juste pour compatibilité (nom bonus en base):
+class BonusStBrieuc(BonusIUTRennes1):
+ name = "bonus_iut_stbrieuc"
+ displayed_name = "IUTs de Rennes 1/St-Brieuc"
+ __doc__ = BonusIUTRennes1.__doc__
+
+
+class BonusStMalo(BonusIUTRennes1):
+ name = "bonus_iut_stmalo"
+ displayed_name = "IUTs de Rennes 1/St-Malo"
+ __doc__ = BonusIUTRennes1.__doc__
+
+
class BonusLaRochelle(BonusSportAdditif):
"""Calcul bonus modules optionnels (sport, culture), règle IUT de La Rochelle.
@@ -996,27 +1010,6 @@ class BonusRoanne(BonusSportAdditif):
proportion_point = 1
-class BonusStBrieuc(BonusSportAdditif):
- """IUT de Saint-Brieuc
-
- Ne s'applique qu'aux semestres pairs (S2, S4, S6), et bonifie les moyennes d'UE:
-
- """
-
- # Utilisé aussi par St Malo, voir plus bas
- name = "bonus_iut_stbrieuc"
- displayed_name = "IUT de Saint-Brieuc"
- proportion_point = 1 / 20.0
- classic_use_bonus_ues = False
-
- def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
- """calcul du bonus"""
- if self.formsemestre.semestre_id % 2 == 0:
- super().compute_bonus(sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan)
-
-
class BonusStEtienne(BonusSportAdditif):
"""IUT de Saint-Etienne.
@@ -1047,19 +1040,6 @@ class BonusStDenis(BonusSportAdditif):
bonus_max = 0.5
-class BonusStMalo(BonusStBrieuc):
- # identique à St Brieux, sauf la doc
- """IUT de Saint-Malo
-
- Ne s'applique qu'aux semestres pairs (S2, S4, S6), et bonifie les moyennes d'UE:
-
- """
- name = "bonus_iut_stmalo"
- displayed_name = "IUT de Saint-Malo"
-
-
class BonusStNazaire(BonusSportMultiplicatif):
"""IUT de Saint-Nazaire
From c890e21ed0b75d3cb8e85d739e1b6b317f8c466b Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Wed, 8 Jun 2022 14:49:31 +0200
Subject: [PATCH 11/16] =?UTF-8?q?Modif=20bonus=20Tarbes,=20qui=20a=20la=20?=
=?UTF-8?q?m=C3=AAme=20logique=20que=20celui=20de=20Rennes=201?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/comp/bonus_spo.py | 30 ++++--------------------------
1 file changed, 4 insertions(+), 26 deletions(-)
diff --git a/app/comp/bonus_spo.py b/app/comp/bonus_spo.py
index 7cbac1c79..cd2db6316 100644
--- a/app/comp/bonus_spo.py
+++ b/app/comp/bonus_spo.py
@@ -730,7 +730,7 @@ class BonusIUTRennes1(BonusSportAdditif):
seuil_moy_gen = 10.0
proportion_point = 1 / 20.0
classic_use_bonus_ues = False
- # Adapté de BonusTarbes, mais s'applique aussi en classic
+ # S'applique aussi en classic, sur la moy. gen.
def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
"""calcul du bonus"""
# Prend la note de chaque modimpl, sans considération d'UE
@@ -1067,14 +1067,15 @@ class BonusStNazaire(BonusSportMultiplicatif):
factor_max = 0.1 # 10% max
-class BonusTarbes(BonusSportAdditif):
+class BonusTarbes(BonusIUTRennes1):
"""Calcul bonus optionnels (sport, culture), règle IUT de Tarbes.
- Les étudiants opeuvent suivre un ou plusieurs activités optionnelles notées.
La meilleure des notes obtenue est prise en compte, si elle est supérieure à 10/20.
- - Le trentième des points au dessus de 10 est ajouté à la moyenne des UE.
+
- Le trentième des points au dessus de 10 est ajouté à la moyenne des UE en BUT,
+ ou à la moyenne générale en DUT et LP.
- Exemple: un étudiant ayant 16/20 bénéficiera d'un bonus de (16-10)/30 = 0,2 points
sur chaque UE.
@@ -1088,29 +1089,6 @@ class BonusTarbes(BonusSportAdditif):
proportion_point = 1 / 30.0
classic_use_bonus_ues = True
- def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
- """calcul du bonus"""
- # Prend la note de chaque modimpl, sans considération d'UE
- if len(sem_modimpl_moys_inscrits.shape) > 2: # apc
- sem_modimpl_moys_inscrits = sem_modimpl_moys_inscrits[:, :, 0]
- # ici sem_modimpl_moys_inscrits est nb_etuds x nb_mods_bonus, en APC et en classic
- note_bonus_max = np.max(sem_modimpl_moys_inscrits, axis=1) # 1d, nb_etuds
- ues = self.formsemestre.query_ues(with_sport=False).all()
- ues_idx = [ue.id for ue in ues]
-
- if self.formsemestre.formation.is_apc(): # --- BUT
- bonus_moy_arr = np.where(
- note_bonus_max > self.seuil_moy_gen,
- (note_bonus_max - self.seuil_moy_gen) * self.proportion_point,
- 0.0,
- )
- self.bonus_ues = pd.DataFrame(
- np.stack([bonus_moy_arr] * len(ues)).T,
- index=self.etuds_idx,
- columns=ues_idx,
- dtype=float,
- )
-
class BonusTours(BonusDirect):
"""Calcul bonus sport & culture IUT Tours.
From bde51dc6391dccca6f8342a2e36b32a07aa249ff Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Wed, 8 Jun 2022 17:42:52 +0200
Subject: [PATCH 12/16] Fix: check suppression formation/ue
---
app/models/ues.py | 9 +++++++++
app/scodoc/sco_edit_formation.py | 5 +++--
app/scodoc/sco_edit_ue.py | 16 ++++------------
3 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/app/models/ues.py b/app/models/ues.py
index 518bd7219..48d81a14f 100644
--- a/app/models/ues.py
+++ b/app/models/ues.py
@@ -75,6 +75,15 @@ class UniteEns(db.Model):
return sco_edit_ue.ue_is_locked(self.id)
+ def can_be_deleted(self) -> bool:
+ """True si l'UE n'est pas utilisée dans des formsemestre
+ et n'a pas de module rattachés
+ """
+ # "pas un seul module de cette UE n'a de modimpl...""
+ return (self.modules.count() == 0) or not any(
+ m.modimpls.all() for m in self.modules
+ )
+
def guess_semestre_idx(self) -> None:
"""Lorsqu'on prend une ancienne formation non APC,
les UE n'ont pas d'indication de semestre.
diff --git a/app/scodoc/sco_edit_formation.py b/app/scodoc/sco_edit_formation.py
index aabfaddce..606fc7421 100644
--- a/app/scodoc/sco_edit_formation.py
+++ b/app/scodoc/sco_edit_formation.py
@@ -66,8 +66,9 @@ def formation_delete(formation_id=None, dialog_confirmed=False):
sems = sco_formsemestre.do_formsemestre_list({"formation_id": formation_id})
if sems:
H.append(
- """
Impossible de supprimer cette formation, car les sessions suivantes l'utilisent:
-"""
+ """Impossible de supprimer cette formation,
+ car les sessions suivantes l'utilisent:
+ """
)
for sem in sems:
H.append(
diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py
index a0f4ff743..28cc1e083 100644
--- a/app/scodoc/sco_edit_ue.py
+++ b/app/scodoc/sco_edit_ue.py
@@ -142,14 +142,6 @@ def do_ue_create(args):
return ue_id
-def can_delete_ue(ue: UniteEns) -> bool:
- """True si l'UE n'est pas utilisée dans des formsemestre
- et n'a pas de module rattachés
- """
- # "pas un seul module de cette UE n'a de modimpl...""
- return (ue.modules.count() == 0) and not any(m.modimpls.all() for m in ue.modules)
-
-
def do_ue_delete(ue_id, delete_validations=False, force=False):
"delete UE and attached matieres (but not modules)"
from app.scodoc import sco_formations
@@ -158,9 +150,9 @@ def do_ue_delete(ue_id, delete_validations=False, force=False):
ue = UniteEns.query.get_or_404(ue_id)
formation_id = ue.formation_id
semestre_idx = ue.semestre_idx
- if not can_delete_ue(ue):
+ if not ue.can_be_deleted():
raise ScoNonEmptyFormationObject(
- "UE",
+ f"UE (id={ue.id}, dud)",
msg=ue.titre,
dest_url=url_for(
"notes.ue_table",
@@ -540,9 +532,9 @@ def ue_delete(ue_id=None, delete_validations=False, dialog_confirmed=False):
semestre_idx=ue.semestre_idx,
),
)
- if not can_delete_ue(ue):
+ if not ue.can_be_deleted():
raise ScoNonEmptyFormationObject(
- "UE",
+ f"UE",
msg=ue.titre,
dest_url=url_for(
"notes.ue_table",
From 1676fba5ab53d8ac6b4f8dd26d36f1e3031539e0 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Wed, 8 Jun 2022 17:56:27 +0200
Subject: [PATCH 13/16] moduleimpl_is_conforme: bug cache (?) => refresh et
exception
---
app/comp/moy_mod.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/app/comp/moy_mod.py b/app/comp/moy_mod.py
index f5efbeb25..8f8bd1a89 100644
--- a/app/comp/moy_mod.py
+++ b/app/comp/moy_mod.py
@@ -41,7 +41,8 @@ from app import db
from app.models import ModuleImpl, Evaluation, EvaluationUEPoids
from app.scodoc import sco_utils as scu
from app.scodoc.sco_codes_parcours import UE_SPORT
-
+from app.scodoc import sco_cache
+from app.scodoc.sco_exceptions import ScoBugCatcher
from app.scodoc.sco_utils import ModuleType
@@ -423,7 +424,9 @@ def moduleimpl_is_conforme(
if nb_ues == 0:
return False # situation absurde (pas d'UE)
if len(modules_coefficients) != nb_ues:
- raise ValueError("moduleimpl_is_conforme: nb ue incoherent")
+ # il arrive (#bug) que le cache ne soit pas à jour...
+ sco_cache.invalidate_formsemestre()
+ raise ScoBugCatcher("moduleimpl_is_conforme: nb ue incoherent")
module_evals_poids = evals_poids.transpose().sum(axis=1).to_numpy() != 0
check = all(
(modules_coefficients[moduleimpl.module_id].to_numpy() != 0)
From 3f15ff099dcd2560532746523bfa09c907aae263 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Wed, 8 Jun 2022 21:16:09 +0200
Subject: [PATCH 14/16] =?UTF-8?q?R=C3=A9-=C3=A9criture=20fonction=20ajout?=
=?UTF-8?q?=20modules=20de=20malus=20=C3=A0=20toutes=20les=20UE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/scodoc/sco_edit_module.py | 104 ++++++++++++++++++----------------
1 file changed, 54 insertions(+), 50 deletions(-)
diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py
index 68166788e..f99bb8a18 100644
--- a/app/scodoc/sco_edit_module.py
+++ b/app/scodoc/sco_edit_module.py
@@ -33,7 +33,7 @@ from flask import url_for, render_template
from flask import g, request
from flask_login import current_user
-from app import log
+from app import db, log
from app import models
from app.models import APO_CODE_STR_LEN
from app.models import Formation, Matiere, Module, UniteEns
@@ -421,7 +421,7 @@ def module_delete(module_id=None):
H = [
html_sco_header.sco_header(page_title="Suppression d'un module"),
- f"""Suppression du module {module.titre} ({module.code})""",
+ f"""Suppression du module {module.titre or "sans titre"} ({module.code})""",
]
dest_url = url_for(
@@ -848,21 +848,13 @@ def module_count_moduleimpls(module_id):
def formation_add_malus_modules(formation_id, titre=None, redirect=True):
"""Création d'un module de "malus" dans chaque UE d'une formation"""
- from app.scodoc import sco_edit_ue
- ues = sco_edit_ue.ue_list(args={"formation_id": formation_id})
+ formation = Formation.query.get_or_404(formation_id)
- for ue in ues:
- # Un seul module de malus par UE:
- nb_mod_malus = len(
- [
- mod
- for mod in module_list(args={"ue_id": ue["ue_id"]})
- if mod["module_type"] == scu.ModuleType.MALUS
- ]
- )
- if nb_mod_malus == 0:
- ue_add_malus_module(ue["ue_id"], titre=titre)
+ for ue in formation.ues:
+ ue_add_malus_module(ue, titre=titre)
+
+ formation.invalidate_cached_sems()
if redirect:
return flask.redirect(
@@ -872,46 +864,58 @@ def formation_add_malus_modules(formation_id, titre=None, redirect=True):
)
-def ue_add_malus_module(ue_id, titre=None, code=None):
- """Add a malus module in this ue"""
- from app.scodoc import sco_edit_ue
+def ue_add_malus_module(ue: UniteEns, titre=None, code=None) -> int:
+ """Add a malus module in this ue.
+ If already exists, do nothing.
+ Returns id of malus module.
+ """
+ modules_malus = [m for m in ue.modules if m.module_type == scu.ModuleType.MALUS]
+ if len(modules_malus) > 0:
+ return modules_malus[0].id # déjà existant
- ue = sco_edit_ue.ue_list(args={"ue_id": ue_id})[0]
-
- if titre is None:
- titre = ""
- if code is None:
- code = "MALUS%d" % ue["numero"]
+ titre = titre or ""
+ code = code or f"MALUS{ue.numero}"
# Tout module doit avoir un semestre_id (indice 1, 2, ...)
- semestre_ids = sco_edit_ue.ue_list_semestre_ids(ue)
- if semestre_ids:
- semestre_id = semestre_ids[0]
+ if ue.semestre_idx is None:
+ semestre_ids = sorted(list(set([m.semestre_id for m in ue.modules])))
+ if len(semestre_ids) > 0:
+ semestre_id = semestre_ids[0]
+ else:
+ # c'est ennuyeux: dans ce cas, on pourrait demander à indiquer explicitement
+ # le semestre ? ou affecter le malus au semestre 1 ???
+ raise ScoValueError(
+ "Impossible d'ajouter un malus s'il n'y a pas d'autres modules"
+ )
else:
- # c'est ennuyeux: dans ce cas, on pourrait demander à indiquer explicitement
- # le semestre ? ou affecter le malus au semestre 1 ???
- raise ScoValueError(
- "Impossible d'ajouter un malus s'il n'y a pas d'autres modules"
- )
+ semestre_id = ue.semestre_idx
# Matiere pour placer le module malus
- Matlist = sco_edit_matiere.matiere_list(args={"ue_id": ue_id})
- numero = max([mat["numero"] for mat in Matlist]) + 10
- matiere_id = sco_edit_matiere.do_matiere_create(
- {"ue_id": ue_id, "titre": "Malus", "numero": numero}
- )
+ titre_matiere_malus = "Malus"
- module_id = do_module_create(
- {
- "titre": titre,
- "code": code,
- "coefficient": 0.0, # unused
- "ue_id": ue_id,
- "matiere_id": matiere_id,
- "formation_id": ue["formation_id"],
- "semestre_id": semestre_id,
- "module_type": scu.ModuleType.MALUS,
- },
- )
+ matieres_malus = [mat for mat in ue.matieres if mat.titre == titre_matiere_malus]
+ if len(matieres_malus) > 0:
+ # matière Malus déjà existante, l'utilise
+ matiere = matieres_malus[0]
+ else:
+ if ue.matieres.count() > 0:
+ numero = max([mat.numero for mat in ue.matieres]) + 10
+ else:
+ numero = 0
+ matiere = Matiere(ue_id=ue.id, titre=titre_matiere_malus, numero=numero)
+ db.session.add(matiere)
- return module_id
+ module = Module(
+ titre=titre,
+ code=code,
+ coefficient=0.0,
+ ue=ue,
+ matiere=matiere,
+ formation=ue.formation,
+ semestre_id=semestre_id,
+ module_type=scu.ModuleType.MALUS,
+ )
+ db.session.add(module)
+ db.session.commit()
+
+ return module.id
From b140e891f13e77a3e2521786a3ee6656fbbacc98 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Wed, 8 Jun 2022 22:18:39 +0200
Subject: [PATCH 15/16] Bonus La Rochelle (nouvelle version)
---
app/comp/bonus_spo.py | 47 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 44 insertions(+), 3 deletions(-)
diff --git a/app/comp/bonus_spo.py b/app/comp/bonus_spo.py
index cd2db6316..6cf0767f0 100644
--- a/app/comp/bonus_spo.py
+++ b/app/comp/bonus_spo.py
@@ -771,18 +771,59 @@ class BonusLaRochelle(BonusSportAdditif):
"""Calcul bonus modules optionnels (sport, culture), règle IUT de La Rochelle.
- - Si la note de sport est comprise entre 0 et 10 : pas d'ajout de point.
- - Si la note de sport est comprise entre 10 et 20 : ajout de 1% de cette
- note sur la moyenne générale du semestre (ou sur les UE en BUT).
+ - Si la note de sport est comprise entre 0 et 10 : pas d’ajout de point.
+ - Si la note de sport est comprise entre 10 et 20 :
+
+ - Pour le BUT, application pour chaque UE du semestre :
+
+ - pour une note entre 18 et 20 => + 0,10 points
+ - pour une note entre 16 et 17,99 => + 0,08 points
+ - pour une note entre 14 et 15,99 => + 0,06 points
+ - pour une note entre 12 et 13,99 => + 0,04 points
+ - pour une note entre 10 et 11,99 => + 0,02 points
+
+
+ - Pour les DUT/LP :
+ ajout de 1% de la note sur la moyenne générale du semestre
+
+
+
"""
name = "bonus_iutlr"
displayed_name = "IUT de La Rochelle"
+
seuil_moy_gen = 10.0 # si bonus > 10,
seuil_comptage = 0.0 # tous les points sont comptés
proportion_point = 0.01 # 1%
+ def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
+ """calcul du bonus"""
+ # La date du semestre ?
+ if self.formsemestre.formation.is_apc():
+ if 0 in sem_modimpl_moys_inscrits.shape:
+ # pas d'étudiants ou pas d'UE ou pas de module...
+ return
+ # Calcule moyenne pondérée des notes de sport:
+ with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN)
+ bonus_moy_arr = np.sum(
+ sem_modimpl_moys_inscrits * modimpl_coefs_etuds_no_nan, axis=1
+ ) / np.sum(modimpl_coefs_etuds_no_nan, axis=1)
+ np.nan_to_num(bonus_moy_arr, nan=0.0, copy=False)
+ bonus_moy_arr[bonus_moy_arr < 10.0] = 0.0
+ bonus_moy_arr[bonus_moy_arr >= 18.0] = 0.10
+ bonus_moy_arr[bonus_moy_arr >= 16.0] = 0.08
+ bonus_moy_arr[bonus_moy_arr >= 14.0] = 0.06
+ bonus_moy_arr[bonus_moy_arr >= 12.0] = 0.04
+ bonus_moy_arr[bonus_moy_arr >= 10.0] = 0.02
+ self.bonus_additif(bonus_moy_arr)
+ else:
+ # DUT et LP:
+ return super().compute_bonus(
+ sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan
+ )
+
class BonusLeHavre(BonusSportAdditif):
"""Bonus sport IUT du Havre sur les moyennes d'UE
From 21a2c1b7e764a03aa47d8e7f95cc286d2a771ef5 Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Wed, 8 Jun 2022 22:41:53 +0200
Subject: [PATCH 16/16] removed useless function
---
app/scodoc/sco_edit_ue.py | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py
index 28cc1e083..33ffc69cf 100644
--- a/app/scodoc/sco_edit_ue.py
+++ b/app/scodoc/sco_edit_ue.py
@@ -1346,16 +1346,6 @@ def ue_is_locked(ue_id):
return len(r) > 0
-def ue_list_semestre_ids(ue: dict):
- """Liste triée des numeros de semestres des modules dans cette UE
- Il est recommandable que tous les modules d'une UE aient le même indice de semestre.
- Mais cela n'a pas toujours été le cas dans les programmes pédagogiques officiels,
- aussi ScoDoc laisse le choix.
- """
- modules = sco_edit_module.module_list(args={"ue_id": ue["ue_id"]})
- return sorted(list(set([mod["semestre_id"] for mod in modules])))
-
-
UE_PALETTE = [
"#B80004", # rouge
"#F97B3D", # Orange Crayola
|