diff --git a/app/but/bulletin_but.py b/app/but/bulletin_but.py index 009a6b1b9..5cf7d9cd0 100644 --- a/app/but/bulletin_but.py +++ b/app/but/bulletin_but.py @@ -120,8 +120,13 @@ class ResultatsSemestreBUT: "total": ue.ects, }, "competence": None, # XXX TODO lien avec référentiel - "moyenne": fmt_note(self.etud_moy_ue[ue.id].mean()), - "bonus": None, # XXX TODO + "moyenne": { + "value": fmt_note(self.etud_moy_ue[ue.id][etud.id]), + "min": fmt_note(self.etud_moy_ue[ue.id].min()), + "max": fmt_note(self.etud_moy_ue[ue.id].max()), + "moy": fmt_note(self.etud_moy_ue[ue.id].mean()), + }, + "bonus": 17.8, # None, # XXX TODO "malus": None, # XXX TODO voir ce qui est ici "capitalise": None, # "AAAA-MM-JJ" TODO "ressources": self.etud_ue_mod_results(etud, ue, self.ressources), diff --git a/app/comp/moy_ue.py b/app/comp/moy_ue.py index f609060ea..9a722f255 100644 --- a/app/comp/moy_ue.py +++ b/app/comp/moy_ue.py @@ -186,25 +186,25 @@ def compute_ue_moys( modimpl_coefs = modimpl_coefs_df.values # Duplique les inscriptions sur les UEs: modimpl_inscr_stacked = np.stack([modimpl_inscr] * nb_ues, axis=2) - # Enlève les NaN du numérateur: - # si on veut prendre en compte les module avec notes neutralisées ? - # sem_cube_no_nan = np.nan_to_num(sem_cube, nan=0.0) + # si on veut prendre en compte les modules avec notes neutralisées ? + sem_cube_no_nan = np.nan_to_num(sem_cube, nan=0.0) # Ne prend pas en compte les notes des étudiants non inscrits au module: # Annule les notes: - sem_cube_inscrits = np.where(modimpl_inscr_stacked, sem_cube, 0.0) + sem_cube_inscrits = np.where(modimpl_inscr_stacked, sem_cube_no_nan, 0.0) # Annule les coefs des modules où l'étudiant n'est pas inscrit: modimpl_coefs_etuds = np.where( modimpl_inscr_stacked, np.stack([modimpl_coefs.T] * nb_etuds), 0.0 ) - + # Annule les coefs des modules NaN + modimpl_coefs_etuds_no_nan = np.where(np.isnan(sem_cube), 0.0, modimpl_coefs_etuds) # # Version vectorisée # - etud_moy_ue = np.sum(modimpl_coefs_etuds * sem_cube_inscrits, axis=1) / np.sum( - modimpl_coefs_etuds, axis=1 - ) + etud_moy_ue = np.sum( + modimpl_coefs_etuds_no_nan * sem_cube_inscrits, axis=1 + ) / np.sum(modimpl_coefs_etuds_no_nan, axis=1) return pd.DataFrame( etud_moy_ue, index=modimpl_inscr_df.index, columns=modimpl_coefs_df.index ) diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index 72932b45e..7bf09fced 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -528,21 +528,18 @@ def module_edit(module_id=None): ("formation_id", {"input_type": "hidden"}), ("ue_id", {"input_type": "hidden"}), ("module_id", {"input_type": "hidden"}), + ( + "ue_matiere_id", + { + "input_type": "menu" if not is_apc else "hidden", + "title": "Matière", + "explanation": "un module appartient à une seule matière.", + "labels": mat_names, + "allowed_values": ue_mat_ids, + "enabled": unlocked and not is_apc, # pas d'édition des matieres en BUT + }, + ), ] - if not is_apc: - descr += [ - ( - "ue_matiere_id", - { - "input_type": "menu", - "title": "Matière", - "explanation": "un module appartient à une seule matière.", - "labels": mat_names, - "allowed_values": ue_mat_ids, - "enabled": unlocked, - }, - ), - ] if is_apc: # le semestre du module est toujours celui de son UE descr += [ diff --git a/app/scodoc/sco_liste_notes.py b/app/scodoc/sco_liste_notes.py index 3fbdf0505..a7c85ef59 100644 --- a/app/scodoc/sco_liste_notes.py +++ b/app/scodoc/sco_liste_notes.py @@ -816,7 +816,7 @@ def _add_apc_columns( etuds_moy_module = moy_mod.compute_module_moy( evals_notes, evals_poids, evaluations, evaluations_completes ) - + ue_coefs = models.ModuleImpl.query.get(moduleimpl_id).module.ue_coefs for row in rows: for ue in ues: moy_ue = etuds_moy_module[ue.id].get(row["etudid"], "?") @@ -826,4 +826,7 @@ def _add_apc_columns( col_id = f"moy_ue_{ue.id}" titles[col_id] = ue.acronyme columns_ids.append(col_id) - row_coefs[f"moy_ue_{ue.id}"] = "m" + row_coefs[f"moy_ue_{ue.id}"] = [uc for uc in ue_coefs if uc.ue_id == ue.id][ + 0 + ].coef + row_coefs[f"_moy_ue_{ue.id}_td_attrs"] = ' class="coef_mod_ue" ' diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 015f41c5f..e92e4ca2e 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -1066,6 +1066,12 @@ table.notes_evaluation td.moy_ue { color:rgb(1, 116, 96); } +td.coef_mod_ue { + font-style: normal; + font-weight: bold; + color: rgb(1, 116, 96); +} + h2.formsemestre, #gtrcontent h2 { margin-top: 2px; font-size: 130%; diff --git a/app/static/js/bulletin-but.js b/app/static/js/bulletin-but.js index b44002638..da73ea41c 100644 --- a/app/static/js/bulletin-but.js +++ b/app/static/js/bulletin-but.js @@ -1,59 +1,59 @@ /* Il manque : - - rangs - - Synthèse : moyenne UE - - Synthèse : min, max, moy classe - - Synthèse : absences - - Eval : absences + - rangs + - Synthèse : moyenne UE + - Synthèse : min, max, moy classe + - Synthèse : absences + - Eval : absences Moi : - "show_codemodules" :true, - "show_minmax": true, - "show_minmax_eval": true, - "show_minmax_mod": false, - "show_mod_rangs": false, - "show_moypromo": true, - "show_rangs": true, - "show_ue_cap_current": true, - "show_ue_cap_details": true, - "show_ue_rangs": true, - "show_uevalid": true, + "show_codemodules" :true, + "show_minmax": true, + "show_minmax_eval": true, + "show_minmax_mod": false, + "show_mod_rangs": false, + "show_moypromo": true, + "show_rangs": true, + "show_ue_cap_current": true, + "show_ue_cap_details": true, + "show_ue_rangs": true, + "show_uevalid": true, */ /*****************************/ /* Gestionnaire d'événements */ /*****************************/ document.querySelectorAll(".CTA_Liste").forEach(e => { - e.addEventListener("click", listeOnOff) + e.addEventListener("click", listeOnOff) }) function listeOnOff() { - this.parentElement.parentElement.classList.toggle("listeOff") + this.parentElement.parentElement.classList.toggle("listeOff") } /*****************************/ /* Recupération et affichage */ /*****************************/ fetch(dataSrc) - .then(r => { return r.json() }) - .then(json => showData(json)) + .then(r => { return r.json() }) + .then(json => showData(json)) function showData(data) { - showInformations(data); - showSemestre(data); - showSynthese(data); - showEvaluations(data); + showInformations(data); + showSemestre(data); + showSynthese(data); + showEvaluations(data); - setOptions(data.options); + setOptions(data.options); - document.body.classList.add("ready"); + document.body.classList.add("ready"); } /********************************/ /* Informations sur l'étudiant */ /********************************/ function showInformations(data) { - document.querySelector(".studentPic").src = data.etudiant.photo_url || "default_Student.svg"; + document.querySelector(".studentPic").src = data.etudiant.photo_url || "default_Student.svg"; - let output = ` + let output = `