Repository navigation
Description
Sans parent : defaut adjacent decouvert pendant #24246 (meme famille -- chaine non normalisee -- mais perimetre distinct : la regle 5, pas la regle 3).
Constat
La regle 5 de GradeBookApp/gradebook.py (rejet des evaluations doubles, l.262-267) prend l'adresse brute comme cle :
evaluator_id = eval_record.email # gradebook.py:263
if evaluator_id in seen_evaluators:
...
seen_evaluators.add(evaluation.email) # gradebook.py:273seen_evaluators est un set Python ordinaire : comparaison sensible a la casse, et aucune normalisation des espaces.
Mesure (2026-11-02, po-2024)
Deux evaluations de la meme personne, adresses ecrites differemment :
a = "Jean.Dupont@example.org"
b = " jean.dupont@example.org "1re eval acceptee : True
2e eval acceptee : True # le doublon passe
Consequence : deux evaluations identiques du meme evaluateur comptent deux fois dans la moyenne du groupe, alors que la regle 5 existe precisement pour l'empecher.
Divergence avec le miroir C#
GradeBookApp/ProjectModel.cs fait la meme detection en insensible a la casse :
var seenEvaluatorsForGroup = new HashSet<string>(StringComparer.OrdinalIgnoreCase); // l.126
var evaluatorEmail = eval.Email ?? $"{eval.Nom}{eval.Prénom}"; // l.130Deux ecarts entre les deux implementations :
| Point | C# (ProjectModel.cs) |
Python (gradebook.py) |
|---|---|---|
| Casse de l'adresse | insensible (OrdinalIgnoreCase) |
sensible |
| Espaces autour de l'adresse | non normalises | non normalises (meme ecart, des deux cotes) |
| Cle de repli si adresse absente | Nom + Prenom (l.130) |
aucune (l'adresse seule) |
Le troisieme point n'est pas mesure comme un defaut : pandas.read_csv rend le singleton np.nan, et l'identite d'objet fait que les lignes sans adresse sont bien vues comme doublons (verifie). Il est cite parce qu'un futur chargement produisant des float('nan') distincts casserait silencieusement la detection.
Correctif propose
Normaliser la cle des deux cotes de la comparaison, sans changer la semantique de rejet :
evaluator_id = str(eval_record.email or "").strip().lower()(str(...) pour absorber les valeurs non-chaine ; or "" pour le None.)
A verifier avant merge : que .strip().lower() suffit sur les exports reels (colonne Adresse e-mail du formulaire), et que le meme .Trim() est ajoute cote C# pour supprimer le second ecart.
Pourquoi en issue separee
#24246 traite la regle 3 et le rapprochement par noms ; toucher la regle 5 dans la meme PR changerait le decompte des doublons sur les carnets de notes deja calcules, sans rapport avec le defaut corrige. Un sujet par PR.
Criteres d'acceptation
- Deux evaluations dont l'adresse ne differe que par la casse ou les espaces de bord sont comptees comme un doublon (test unitaire dans
GradeBookApp/). - Deux evaluations d'adresses reellement differentes restent acceptees (controle negatif).
- La decision sur le troisieme ecart (cle de repli
Nom + Prenomcote Python, comme l.130 du C#) est ecrite dans la PR : alignee ou explicitement refusee.
Activity
jsboige commentedon Nov 2, 2026
[CLAIMED] lane myia-po-2024:CoursIA -- normaliser la cle de doublon de la regle 5 (strip + lower) et aligner le repli sur le miroir C# -- paths: GradeBookApp/gradebook.py, GradeBookApp/test_project_name.py
jsboige commentedon Nov 2, 2026
[DELIVERED] lane myia-po-2024:CoursIA -- PR #24281 — clé de la règle 5 normalisée (casse + espaces de bord) et repli sur Nom + Prénom quand l'adresse manque ; miroir C# aligné (
.Trim()+IsNullOrWhiteSpace) — paths: GradeBookApp/gradebook.py, GradeBookApp/ProjectModel.cs, GradeBookApp/test_evaluator_key.pyLes trois critères d'acceptation sont couverts :
filter_evaluationsconserve une seule des deux évaluationsJean.Dupont@…etjean.dupont@…(tests de bout en bout, pas seulement unitaires).jean.dupont@vsjean.dupont2@.Nom + PrénomcommeProjectModel.cs:130, avec la raison mesurée : sans lui, toutes les lignes sans adresse partagent une clé unique et une seule évaluation est retenue par groupe. Le C# gagne au passage la couverture de l'adresse vide (""), qui collapsait aussi.Mesures : 36 tests verts côté Python (dont 21 nouveaux),
dotnet build0 erreur. Contrôle négatif sur legradebook.pyd'origin/main: 8 échecs comportementaux, les cas qui portent le défaut.Écart résiduel signalé dans la PR et non corrigé : une ligne avec adresse et une ligne du même évaluateur sans adresse restent deux clés distinctes — comportement identique au C#, et le corriger changerait la sémantique de la règle 5.
La clôture revient au coordinateur (
Closes #24276dans le body de la PR).Fix(gradebook,#24276): cle de doublon de la regle 5 normalisee des de…