# 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**: ```python 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étence - `total_points_possible`: Somme des max_points de ces éléments - `total_points_obtained`: 0 (non pertinent dans cette perspective) #### 2. Endpoint modifié (`backend/api/routes/classes.py`) **Chargement des relations**: ```python assessments_query = ( select(Assessment) .options( selectinload(Assessment.exercises).selectinload(Exercise.grading_elements) ) .where(...) ) ``` **Utilisation du nouveau service**: ```python # 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**: ```vue
{{ domain.name }} {{ domain.total_points_obtained }}/{{ domain.total_points_possible }}

{{ domain.evaluation_count }} évaluations

{{ domain.name }} {{ domain.total_points_possible }} points

{{ domain.evaluation_count }} élément(s) de notation

``` **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**: ```javascript 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**: ```vue
``` 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`**: ```python 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**: ```python # 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**: ```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) 1. **`backend/domain/services/class_statistics_service.py`** - Ajout: `calculate_domain_competence_from_elements()` - Logique: Parcours des GradingElements - Retour: DomainStats et CompetenceStats 2. **`backend/api/routes/classes.py`** - Modification: Chargement des assessments avec relations - Modification: Appel de la nouvelle méthode de calcul ### Frontend (1 fichier) 3. **`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 1. Sélectionner un trimestre 2. Scroller jusqu'aux sections "Évaluations par domaine/compétence" 3. 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