From 6de8dc066f220fb461f4def08871206a07460b1d Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Tue, 5 Aug 2025 06:13:28 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20int=C3=A9grer=20la=20configuration=20de?= =?UTF-8?q?s=20comp=C3=A9tences=20dans=20la=20gestion=20des=20assessments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remplacer le champ texte libre par une liste déroulante des compétences configurées - Charger dynamiquement les compétences dans les routes d'assessments (new/edit) - Moderniser le calcul des scores pour utiliser l'échelle de compétences configurable - Adapter la logique de scoring aux valeurs personnalisées (0-3 ou autres) - Respecter le paramètre 'included_in_total' de chaque valeur de l'échelle - Maintenir la compatibilité descendante avec l'ancienne formule 🎯 Améliore l'intégration entre la configuration système et l'interface utilisateur 📊 Rend les calculs de scores plus flexibles et cohérents avec la configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- models.py | 46 ++++++++++++++++++++++---- routes/assessments.py | 16 +++++++-- templates/assessment_form_unified.html | 9 ++++- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/models.py b/models.py index 12a5fec..667c146 100644 --- a/models.py +++ b/models.py @@ -112,6 +112,10 @@ class Assessment(db.Model): Retourne un dictionnaire avec les scores par élève et par exercice.""" from collections import defaultdict import statistics + from app_config import config_manager + + # Récupérer l'échelle des compétences configurée + competence_scale = config_manager.get_competence_scale_values() students_scores = {} exercise_scores = defaultdict(lambda: defaultdict(float)) @@ -144,16 +148,44 @@ class Assessment(db.Model): exercise_max_points += element.max_points except ValueError: pass - else: # compétences - if grade.value == '.': - # '.' signifie non évalué = 0 point mais on compte le max - exercise_score += 0 - exercise_max_points += (1/3) * 3 * element.max_points # Score max de 3 + else: # compétences - utiliser la nouvelle échelle + grade_value = grade.value.strip() + + # Gérer les valeurs numériques et string + scale_key = int(grade_value) if grade_value.isdigit() else grade_value + + if scale_key in competence_scale: + scale_config = competence_scale[scale_key] + + if scale_config['included_in_total']: + # Calculer le score selon l'échelle configurée + if grade_value == '.': + # Non évalué = 0 point + exercise_score += 0 + else: + # Calculer le score proportionnel + # Trouver la valeur maximale de l'échelle + max_scale_value = max([ + int(k) if str(k).isdigit() else 0 + for k in competence_scale.keys() + if competence_scale[k]['included_in_total'] and k != '.' + ]) + + if max_scale_value > 0: + if grade_value.isdigit(): + score_ratio = int(grade_value) / max_scale_value + exercise_score += score_ratio * element.max_points + + # Compter les points maximum (sauf pour '.') + if grade_value != '.': + exercise_max_points += element.max_points + # Si not included_in_total, on ne compte ni score ni max else: + # Valeur non reconnue, utiliser l'ancienne logique par défaut try: - score_value = float(grade.value) + score_value = float(grade_value) exercise_score += (1/3) * score_value * element.max_points - exercise_max_points += (1/3) * 3 * element.max_points # Score max de 3 + exercise_max_points += element.max_points except ValueError: pass diff --git a/routes/assessments.py b/routes/assessments.py index 388b9df..595480a 100644 --- a/routes/assessments.py +++ b/routes/assessments.py @@ -160,23 +160,35 @@ def edit(id): exercise_data['grading_elements'].append(element_data) exercises_data.append(exercise_data) + # Récupérer les compétences configurées + from app_config import config_manager + competences = config_manager.get_competences_list() + return render_template('assessment_form_unified.html', form=form, title='Modifier l\'évaluation complète', assessment=assessment, exercises_json=exercises_data, - is_edit=True) + is_edit=True, + competences=competences) @bp.route('/new', methods=['GET', 'POST']) @handle_db_errors def new(): + from app_config import config_manager form = AssessmentForm() result = _handle_unified_assessment_request(form, is_edit=False) if result: return result - return render_template('assessment_form_unified.html', form=form, title='Nouvelle évaluation complète') + # Récupérer les compétences configurées + competences = config_manager.get_competences_list() + + return render_template('assessment_form_unified.html', + form=form, + title='Nouvelle évaluation complète', + competences=competences) @bp.route('//results') @handle_db_errors diff --git a/templates/assessment_form_unified.html b/templates/assessment_form_unified.html index 44422a3..ea57164 100644 --- a/templates/assessment_form_unified.html +++ b/templates/assessment_form_unified.html @@ -241,7 +241,14 @@
- +