feat: intégrer la configuration des compétences dans la gestion des assessments

- 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 <noreply@anthropic.com>
This commit is contained in:
2025-08-05 06:13:28 +02:00
parent b08cc2aba4
commit 6de8dc066f
3 changed files with 61 additions and 10 deletions

View File

@@ -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