# 📏 Configuration des Échelles - Notytex ## Vue d'ensemble Notytex utilise un système de notation hybride qui distingue trois types de valeurs d'évaluation : 1. **Notes** : Valeurs numériques décimales (ex: 2.5/4, 18/20, 15.5/20) 2. **Scores** : Échelle fixe de 0 à 3 pour l'évaluation par compétences 3. **Valeurs spéciales** : Valeurs configurables comme "." (non évalué), "d" (dispensé), etc. ## Architecture Technique ### Modèle de Données ```python # Modèle CompetenceScaleValue class CompetenceScaleValue(db.Model): value: str # "0", "1", "2", "3", ".", "d", etc. label: str # "Non acquis", "En cours d'acquisition", etc. color: str # "#dc2626", "#059669", etc. included_in_total: bool # True/False pour inclusion dans calculs ``` ### Configuration Centralisée La configuration est gérée par `app_config.py` avec stockage en SQLite : ```python # Configuration des dégradés de couleurs pour les notes 'grading.notes_gradient.min_color': '#dc2626' # Rouge pour note 0 'grading.notes_gradient.max_color': '#059669' # Vert pour note max 'grading.notes_gradient.enabled': True ``` ## Types de Notation ### 1. Notes (Numerical Grading) **Caractéristiques :** - Valeurs numériques décimales : 2.5, 18, 15.5, etc. - Barème variable selon l'exercice : /4, /20, /10, etc. - Calcul automatique des pourcentages et moyennes - **Nouveau** : Système de dégradé de couleurs automatique **Dégradé de Couleurs (2025) :** - Configuration via interface `/config/scale` - Couleur minimum pour note 0 (par défaut : rouge #dc2626) - Couleur maximum pour note maximale (par défaut : vert #059669) - Interpolation HSL pour des transitions naturelles (évite le gris) - Calcul automatique des couleurs intermédiaires selon ratio note/maximum ```javascript // Exemple de calcul de couleur function calculateNoteColor(note, maxPoints, minColor, maxColor) { const factor = note / maxPoints; return interpolateColorHSL(minColor, maxColor, factor); } ``` **Interface Utilisateur :** - Sélecteurs de couleurs min/max sur une ligne - Barre de dégradé visuelle avec interpolation HSL - Exemples de notes positionnés sur le dégradé (5/20, 10/20, 15/20) - Sauvegarde intégrée au formulaire principal ### 2. Scores (Competence Grading) **Caractéristiques :** - Échelle fixe et non configurable : **0, 1, 2, 3** - Signification par défaut : - **0** : Non acquis (rouge #dc2626) - **1** : En cours d'acquisition (orange #ea580c) - **2** : Acquis (vert #059669) - **3** : Expert (bleu #2563eb) - Chaque niveau peut être personnalisé (libellé, couleur, inclusion) **Configuration :** - Labels modifiables via interface - Couleurs personnalisables avec sélecteurs - Option d'inclusion/exclusion du calcul global - Valeurs 0-3 dans la section "Échelle numérique" ### 3. Valeurs Spéciales **Valeurs Prédéfinies :** - **"."** : Non évalué (par défaut gris #6b7280) - Compte comme 0 dans les notes mais inclus dans le total possible - Généralement incluse pour maintenir la cohérence des calculs - **"d"** : Dispensé (configurable) - Exclu des calculs par défaut **Valeurs Personnalisées :** - Ajout via interface : "NA", "ABS", "X", etc. - Configuration complète : valeur, libellé, couleur, inclusion - Suppression possible (sauf valeurs de base) ## Interface de Configuration ### Page `/config/scale` - "Échelle de réussite" **Structure :** 1. **Dégradé de couleurs pour les notes** - Sélecteur couleur minimum (gauche) - Barre de dégradé visuelle (centre, pleine largeur) - Sélecteur couleur maximum (droite) - Exemples positionnés sur le dégradé 2. **Échelle numérique (0 à 3)** - Configuration des 4 niveaux fixes - Libellé, couleur et inclusion pour chaque niveau - Interface en grille responsive 3. **Valeurs spéciales** - Liste des valeurs non-numériques - Ajout/modification/suppression - Protection de la valeur "." (non supprimable) **Sauvegarde Unifiée :** - Bouton unique : "Enregistrer les paramètres" - Sauvegarde simultanée : échelle + dégradé + valeurs spéciales - Messages de succès différenciés selon les modifications ## Utilisation dans le Code ### Application dans la Page de Notation Le dégradé HSL est **automatiquement appliqué dans la page de notation** (`/assessments//grading`) pour tous les éléments de type `"notes"`. #### Transmission de la Configuration ```python # routes/grading.py - Route assessment_grading() notes_gradient = { 'min_color': config_manager.get('grading.notes_gradient.min_color', '#dc2626'), 'max_color': config_manager.get('grading.notes_gradient.max_color', '#059669'), 'enabled': config_manager.get('grading.notes_gradient.enabled', False) } return render_template('assessment_grading.html', notes_gradient=notes_gradient, # ← Nouvelle transmission # ... autres paramètres ) ``` #### Calcul Dynamique des Couleurs ```javascript // Fonction globale pour calculer la couleur d'une note window.getNotesGradientColor = function(note, maxPoints) { if (!GRADING_CONFIG.notes_gradient.enabled) return '#6b7280'; const factor = Math.min(1, Math.max(0, note / maxPoints)); return interpolateColorHSL( GRADING_CONFIG.notes_gradient.min_color, GRADING_CONFIG.notes_gradient.max_color, factor ); }; ``` #### Application Automatique ```javascript // ColorManager.applyColorToInput() - Logique de colorisation if (type === 'notes') { // Valeurs spéciales (., d, etc.) → couleurs échelle if (GRADING_CONFIG.scale_values[value] && isNaN(value)) { // Couleur spéciale avec style italique } // Notes numériques (2, 2.0, 15.5, etc.) → dégradé HSL const numValue = parseFloat(value); if (!isNaN(numValue)) { const noteColor = window.getNotesGradientColor(numValue, maxPoints); input.style.color = '#374151'; // Texte gris doux input.style.backgroundColor = hexToRgba(noteColor, 0.25); // Fond coloré input.style.borderColor = hexToRgba(noteColor, 0.5); // Bordure accentuée } } ``` ### Accès aux Valeurs d'Échelle ```python # Repository pattern pour l'accès aux données competence_scale = config_manager.get_competence_scale_values() # Structure retournée { '0': {'label': 'Non acquis', 'color': '#dc2626', 'included_in_total': True}, '1': {'label': 'En cours', 'color': '#ea580c', 'included_in_total': True}, '2': {'label': 'Acquis', 'color': '#059669', 'included_in_total': True}, '3': {'label': 'Expert', 'color': '#2563eb', 'included_in_total': True}, '.': {'label': 'Non évalué', 'color': '#6b7280', 'included_in_total': True} } ``` ## Interpolation des Couleurs ### Problématique RGB vs HSL **RGB (Ancien système) :** - Interpolation linéaire entre composantes R, G, B - Problème : transitions via des couleurs "sales" (gris/marron) - Exemple : Rouge → Vert passe par un gris terne **HSL (Nouveau système) :** - Interpolation dans l'espace teinte-saturation-luminosité - Transitions naturelles via le cercle chromatique - Gestion du "chemin le plus court" pour les teintes - Résultat : dégradés vibrants et naturels ### Implementation JavaScript ```javascript function interpolateColorHSL(color1, color2, factor) { const rgb1 = hexToRgb(color1); const rgb2 = hexToRgb(color2); const hsl1 = rgbToHsl(rgb1.r, rgb1.g, rgb1.b); const hsl2 = rgbToHsl(rgb2.r, rgb2.g, rgb2.b); // Gérer transition teinte (chemin le plus court) let deltaH = hsl2.h - hsl1.h; if (deltaH > 180) hsl2.h -= 360; else if (deltaH < -180) hsl2.h += 360; // Interpolation HSL const h = hsl1.h + (hsl2.h - hsl1.h) * factor; const s = hsl1.s + (hsl2.s - hsl1.s) * factor; const l = hsl1.l + (hsl2.l - hsl1.l) * factor; const rgb = hslToRgb(h, s, l); return rgbToHex(rgb.r, rgb.g, rgb.b); } ``` ## Routes et Endpoints ### Configuration des Échelles ```python # Routes principales GET /config/scale # Interface de configuration POST /config/scale/update # Sauvegarde unifiée (échelle + dégradé) POST /config/scale/add # Ajouter valeur spéciale POST /config/scale/delete/ # Supprimer valeur spéciale POST /config/scale/reset # Réinitialisation par défaut # Route dépréciée (fusionnée dans update_scale) POST /config/scale/notes-gradient # Ancienne sauvegarde séparée ``` ### Validation des Données ```python # Validation couleurs hexadécimales if not re.match(r'^#[0-9a-fA-F]{6}$', color): flash('Format de couleur invalide', 'error') # Protection valeurs de base base_values = ['0', '1', '2', '3', '.'] if value in base_values: flash('Valeur de base non supprimable', 'error') ``` ## Evolution et Améliorations ### Phase Actuelle (2025) ✅ **Réalisé :** - Système de dégradé HSL pour les notes - Interface unifiée de configuration - Sauvegarde intégrée échelle + dégradé - Exemples visuels positionnés sur le dégradé - Validation et protection des données ### Évolutions Possibles 🔮 **Futures améliorations :** - Export/import de configurations d'échelles - Présets de couleurs (thèmes prédéfinis) - Aperçu temps réel sur vraies données - Historique des modifications - Configuration par classe/matière - API REST pour configuration programmatique ## Cas d'Usage Typiques ### Enseignant Mathématiques ``` Échelle 0-3 : Non acquis → En cours → Acquis → Expert Dégradé notes : Rouge foncé → Vert clair (sur /20) Valeurs spéciales : "." pour absents, "d" pour dispensés sport ``` ### Enseignant Langues ``` Échelle 0-3 : A découvrir → En apprentissage → Maîtrisé → Excellence Dégradé notes : Orange → Bleu (évaluations /10) Valeurs spéciales : "NA" pour non applicable, "O" pour oral seulement ``` ## Indicateurs Visuels d'Erreur ### Validation des Saisies Le système détecte automatiquement les **valeurs interdites** et applique un indicateur visuel très visible : ```javascript // Valeurs interdites → Indicateur rouge vif if (!isValid) { input.style.color = '#ffffff'; // Texte blanc input.style.backgroundColor = '#dc2626'; // Fond rouge vif input.style.borderColor = '#dc2626'; // Bordure rouge input.style.borderWidth = '2px'; // Bordure épaisse input.style.boxShadow = '0 0 0 3px rgba(220, 38, 38, 0.3)'; // Ombre rouge input.style.fontWeight = 'bold'; // Texte en gras } ``` ### Exemples d'Erreurs Détectées **Pour les scores (type="score")** : - Valeurs autres que 0, 1, 2, 3 ou valeurs spéciales configurées - Exemples : `"5"`, `"1.5"`, `"abc"`, `"-1"` **Pour les notes (type="notes")** : - Valeurs négatives : `"-5"` - Valeurs supérieures au maximum : `"25"` (si max=20) - Format invalide : `"abc"`, `"2.5.3"`, `"10,5,2"` ### Reset Automatique Dès qu'une valeur valide est saisie, tous les styles d'erreur sont automatiquement effacés et remplacés par la colorisation normale. ## Impact UX ### Bénéfices Utilisateur - **Cohérence visuelle** : Couleurs automatiques selon performance - **Feedback immédiat** : Erreurs visibles instantanément + dégradé temps réel - **Distinction claire** : Notes vs Scores vs Valeurs spéciales - **Simplicité** : Configuration centralisée, application automatique - **Flexibilité** : Adaptation aux pratiques pédagogiques ### Performance - **Client** : Calculs JavaScript optimisés avec interpolation HSL native - **Serveur** : Configuration mise en cache, transmission optimisée - **Base** : Index sur valeurs d'échelle - **Rendu** : Colorisation temps réel sans rechargement --- **Documentation maintenue à jour - Version 2025** *Dernière modification : 9 août 2025 - Ajout dégradé HSL et indicateurs d'erreur*