354 lines
12 KiB
Markdown
354 lines
12 KiB
Markdown
# 📏 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/<id>/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/<val> # 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* |