11 KiB
Perspective Enseignant - Domaines et Compétences
Date: 3 décembre 2025
Type: Changement de perspective - Ce qui a été évalué vs Résultats des élèves
🎯 Objectif du Changement
Passer d'une perspective centrée sur les résultats des élèves à une perspective centrée sur ce qui a été évalué par l'enseignant.
Avant (Perspective Élèves)
Domaine Algèbre:
- 75 évaluations (25 élèves × 3 questions)
- 187.5 / 250 points
→ Difficile à interpréter : mélange le nombre d'élèves et les évaluations
Après (Perspective Enseignant)
Domaine Algèbre:
- 3 éléments de notation
- 10 points maximum
→ Clair et actionnable : l'enseignant voit ce qu'il a créé
📊 Cas d'Usage Concrets
Scénario 1: Vérifier l'équilibre d'un trimestre
Données affichées:
Domaines:
- Algèbre : 8 éléments, 25 points
- Géométrie : 3 éléments, 12 points ← Sous-représenté
- Probabilités : 2 éléments, 8 points ← Sous-représenté
- Calcul : 6 éléments, 18 points
Action enseignant: Créer plus d'évaluations sur Géométrie et Probabilités pour le prochain contrôle.
Scénario 2: Analyser une évaluation
Données affichées:
Compétences:
- Calculer : 5 éléments, 15 points
- Raisonner : 3 éléments, 12 points
- Communiquer : 1 élément, 5 points ← Sous-représenté
Action enseignant: Ajouter des questions de communication dans la prochaine évaluation.
Scénario 3: Comparer les trimestres
| Domaine | T1 | T2 | T3 |
|---|---|---|---|
| Algèbre | 8 éléments, 25pts | 6 éléments, 18pts | 10 éléments, 30pts |
| Géométrie | 3 éléments, 12pts | 7 éléments, 20pts | 5 éléments, 15pts |
Insight: L'enseignant voit qu'il a moins travaillé la géométrie au T3, peut ajuster pour l'année suivante.
🔧 Modifications Techniques
Backend
1. Nouveau Service (backend/domain/services/class_statistics_service.py)
Méthode ajoutée: calculate_domain_competence_from_elements()
Logique:
for assessment in assessments:
for exercise in assessment.exercises:
for element in exercise.grading_elements:
# Compter par domaine
if element.domain_id:
domain_count[element.domain_id] += 1
domain_points[element.domain_id] += element.max_points
# Compter par compétence (via skill)
if element.skill:
competence = find_competence_by_name(element.skill)
if competence:
competence_count[competence.id] += 1
competence_points[competence.id] += element.max_points
Retourne:
evaluation_count: Nombre de GradingElements utilisant ce domaine/compétencetotal_points_possible: Somme des max_points de ces élémentstotal_points_obtained: 0 (non pertinent dans cette perspective)
2. Endpoint modifié (backend/api/routes/classes.py)
Chargement des relations:
assessments_query = (
select(Assessment)
.options(
selectinload(Assessment.exercises).selectinload(Exercise.grading_elements)
)
.where(...)
)
Utilisation du nouveau service:
# AVANT
domains_stats, competences_stats = stats_service.aggregate_domain_competence_stats(
student_averages=student_averages,
domains=domains,
competences=competences,
)
# APRÈS
domains_stats, competences_stats = stats_service.calculate_domain_competence_from_elements(
assessments=assessments, # Avec exercises et grading_elements chargés
domains=domains,
competences=competences,
)
Frontend
1. Affichage modifié (frontend/src/views/ClassDashboardView.vue)
Template:
<!-- AVANT -->
<div>
<span>{{ domain.name }}</span>
<span>{{ domain.total_points_obtained }}/{{ domain.total_points_possible }}</span>
<p>{{ domain.evaluation_count }} évaluations</p>
</div>
<!-- APRÈS -->
<div>
<span>{{ domain.name }}</span>
<span>{{ domain.total_points_possible }} points</span>
<p>{{ domain.evaluation_count }} élément(s) de notation</p>
</div>
Titres modifiés:
- "Statistiques par domaine" → "Évaluations par domaine"
- "Statistiques par compétence" → "Évaluations par compétence"
Sous-titre ajouté:
- "Perspective enseignant : ce qui a été évalué"
2. Barre de progression relative
Nouvelle logique:
function getRelativeWidth(item, allItems) {
const maxPoints = Math.max(...allItems.map(d => d.total_points_possible || 0))
if (maxPoints === 0) return 0
return ((item.total_points_possible || 0) / maxPoints) * 100
}
Utilisation:
<div class="progress-bar">
<div :style="{ width: `${getRelativeWidth(domain, stats.domains_stats)}%` }"></div>
</div>
La barre montre la proportion relative par rapport au domaine le plus évalué, pas un pourcentage absolu.
📈 Comparaison Avant/Après
Exemple avec une classe de 25 élèves, 2 contrôles
Contrôle 1 (Trimestre 1):
- Q1: Algèbre, 5 points
- Q2: Algèbre, 3 points
- Q3: Géométrie, 4 points
Contrôle 2 (Trimestre 1):
- Q1: Algèbre, 2 points
- Q2: Probabilités, 5 points
Avant (Perspective Élèves)
Domaine Algèbre:
evaluation_count: 75 (3 questions × 25 élèves)total_points_obtained: 187.5 (moyenne hypothétique)total_points_possible: 250 ((5+3+2) × 25)
Affichage: "75 évaluations - 187.5/250" → Illisible pour l'enseignant
Après (Perspective Enseignant)
Domaine Algèbre:
evaluation_count: 3 (nombre de questions posées)total_points_possible: 10 (5+3+2)
Affichage: "3 éléments de notation - 10 points" → Très lisible et actionnable
🎓 Avantages Pédagogiques
1. Clarté
- Indépendant du nombre d'élèves: 3 éléments restent 3 éléments
- Unité cohérente: Points = barème défini par l'enseignant
2. Planification
- Voir rapidement quels domaines ont été peu évalués
- Équilibrer les évaluations entre domaines
- Comparer les trimestres facilement
3. Réflexivité
- Analyse de pratique: "Ai-je trop évalué l'algèbre ?"
- Diversification: "Dois-je ajouter plus de géométrie ?"
- Cohérence: "Mon programme est-il équilibré ?"
4. Communication
- Conseil de classe: "J'ai évalué 8 fois l'algèbre ce trimestre"
- Parents: "Voici la répartition de mes évaluations"
- Équipe pédagogique: "Comparons nos pratiques d'évaluation"
🔍 Détails d'Implémentation
Gestion des Compétences
Mapping via element.skill:
if element.skill:
matching_competence = next(
(c for c in competences if c.name == element.skill),
None
)
Logique:
- Les compétences sont stockées dans
GradingElement.skill(champ texte libre) - Le matching se fait par nom de compétence
- Si aucune correspondance: la compétence n'est pas comptée
Amélioration future: Ajouter competence_id dans GradingElement pour éviter le matching par nom.
Performance
Requête optimisée:
# Un seul trip à la base de données
assessments = session.execute(
select(Assessment)
.options(selectinload(Assessment.exercises).selectinload(Exercise.grading_elements))
.where(...)
).scalars().all()
Complexité: O(n) où n = nombre total de GradingElements du trimestre
Charge typique:
- 5 évaluations × 15 éléments/évaluation = 75 éléments à parcourir
- Temps: < 10ms
Données Retournées
Structure JSON:
{
"domains_stats": [
{
"id": 1,
"name": "Algèbre",
"color": "#3B82F6",
"evaluation_count": 3,
"total_points_obtained": 0.0,
"total_points_possible": 10.0
}
],
"competences_stats": [
{
"id": 1,
"name": "Calculer",
"color": "#10B981",
"evaluation_count": 5,
"total_points_obtained": 0.0,
"total_points_possible": 15.0
}
]
}
Note: total_points_obtained est à 0 car non pertinent dans cette perspective.
📁 Fichiers Modifiés
Backend (2 fichiers)
-
backend/domain/services/class_statistics_service.py- Ajout:
calculate_domain_competence_from_elements() - Logique: Parcours des GradingElements
- Retour: DomainStats et CompetenceStats
- Ajout:
-
backend/api/routes/classes.py- Modification: Chargement des assessments avec relations
- Modification: Appel de la nouvelle méthode de calcul
Frontend (1 fichier)
frontend/src/views/ClassDashboardView.vue- Modification: Titres ("Évaluations par..." au lieu de "Statistiques par...")
- Modification: Affichage (points seuls au lieu de obtained/possible)
- Modification: Texte ("élément(s) de notation" au lieu de "évaluations")
- Ajout: Fonction
getRelativeWidth()pour barre proportionnelle - Ajout: Sous-titre explicatif "Perspective enseignant : ce qui a été évalué"
✅ Tests Suggérés
1. Vérifier le comptage
- Créer 3 évaluations avec 2, 3, 4 éléments respectivement
- Vérifier:
evaluation_count = 9
2. Vérifier les points
- Élément 1: 5 points
- Élément 2: 3 points
- Élément 3: 2 points
- Vérifier:
total_points_possible = 10
3. Vérifier le filtrage par domaine
- 3 éléments Algèbre, 2 éléments Géométrie
- Vérifier: Algèbre montre 3, Géométrie montre 2
4. Vérifier les compétences
- Créer des éléments avec
skill = "Calculer" - Vérifier: Compétence "Calculer" affiche le bon nombre
5. Vérifier l'absence de données
- Domaine sans éléments:
evaluation_count = 0, total_points_possible = 0 - Affichage: "0 élément(s) de notation - 0 points"
🚀 Utilisation
Accéder au Dashboard
http://localhost:5173/classes/{id}
Vérifier l'affichage
- Sélectionner un trimestre
- Scroller jusqu'aux sections "Évaluations par domaine/compétence"
- Vérifier:
- ✅ Titre: "Évaluations par domaine/compétence"
- ✅ Sous-titre: "Perspective enseignant : ce qui a été évalué"
- ✅ Affichage: "X points" (pas de fraction)
- ✅ Texte: "X élément(s) de notation"
- ✅ Barre proportionnelle au domaine le plus évalué
🎯 Conclusion
Cette modification transforme le dashboard d'une vue résultats (complexe, orientée élèves) en une vue enseignant (simple, orientée pratique pédagogique).
Impact pédagogique:
- ✅ Meilleure visibilité sur la répartition des évaluations
- ✅ Aide à l'équilibrage du programme
- ✅ Facilite la réflexion sur les pratiques d'évaluation
- ✅ Indépendant du nombre d'élèves (plus cohérent)
Impact technique:
- ✅ Code plus simple (pas de double comptage élèves × éléments)
- ✅ Requêtes optimisées avec selectinload
- ✅ Données plus claires et exploitables