Tri incorrect des noms avec accents #24

Closed
opened 2020-09-28 12:07:46 +02:00 by viennet · 4 comments
Owner

Quand le nom de famille d'un étudiant comporte un accent, l'ordre alphabétique de la liste des noms d'étudiants est modifiée.

Cette inversion peut être gênante à l'occasion des saisies de notes.

Trac#197

Quand le nom de famille d'un étudiant comporte un accent, l'ordre alphabétique de la liste des noms d'étudiants est modifiée. Cette inversion peut être gênante à l'occasion des saisies de notes. Trac#197
viennet added the
bug
label 2020-09-28 12:07:46 +02:00

Je n'ai pas encore eu le temps de voir où se trouve le tri des membres d'un groupe mais voici déjà une fonction qui permettrait de résoudre le problème.

Lorsque j'aurai accès à ma machine virtuelle (probablement le 23 août) Je testerai le fonctionnement de la fonction avec l'Environnement de scodoc.

import unicodedata


def remplacement_accents(chaine: str) -> str:
    """!
    @brief Fonction qui permet de transformer les caractères accentués en caractères simples.

    Paramètres :
        @param chaine : str => Une chaine de caractères avec des accents
    Retour de la fonction :
        @return str => Une chaine de caractères sans accents

    """
    nouvelle_chaine: str = ""

    # Utilisation de unicodedata.normalize pour séparer les caractères accentués en 2 caractères (lettre + accent)
    for caract in unicodedata.normalize("NFD", chaine):
        # Un accent est catégorisé par la chaine de caractère "Mn"
        if unicodedata.category(caract) != "Mn":
            nouvelle_chaine += caract

    return nouvelle_chaine

if __name__ == "__main__":

    noms = ["Déca", "Déea", "Dàea", "Daea", "Ditaud", "Deca"]

    # Tests de fonctionnement
    assert remplacement_accents("Léonard") == "Leonard"
    assert sorted(noms, key=remplacement_accents) == [
        "Dàea",
        "Daea",
        "Déca",
        "Deca",
        "Déea",
        "Ditaud",
    ]
Je n'ai pas encore eu le temps de voir où se trouve le tri des membres d'un groupe mais voici déjà une fonction qui permettrait de résoudre le problème. Lorsque j'aurai accès à ma machine virtuelle (probablement le 23 août) Je testerai le fonctionnement de la fonction avec l'Environnement de scodoc. ```py import unicodedata def remplacement_accents(chaine: str) -> str: """! @brief Fonction qui permet de transformer les caractères accentués en caractères simples. Paramètres : @param chaine : str => Une chaine de caractères avec des accents Retour de la fonction : @return str => Une chaine de caractères sans accents """ nouvelle_chaine: str = "" # Utilisation de unicodedata.normalize pour séparer les caractères accentués en 2 caractères (lettre + accent) for caract in unicodedata.normalize("NFD", chaine): # Un accent est catégorisé par la chaine de caractère "Mn" if unicodedata.category(caract) != "Mn": nouvelle_chaine += caract return nouvelle_chaine if __name__ == "__main__": noms = ["Déca", "Déea", "Dàea", "Daea", "Ditaud", "Deca"] # Tests de fonctionnement assert remplacement_accents("Léonard") == "Leonard" assert sorted(noms, key=remplacement_accents) == [ "Dàea", "Daea", "Déca", "Deca", "Déea", "Ditaud", ] ```
Author
Owner

Je n'ai pas encore eu le temps de voir où se trouve le tri des membres d'un groupe mais voici déjà une fonction qui permettrait de résoudre le problème.

merci !
Dans sco_utils.py, on a suppress_accents()qui fait:

return (
            unicodedata.normalize("NFD", s)
            .encode("ascii", "ignore")
            .decode(SCO_ENCODING)
        )

Par ailleurs, le modèle Identite (dans app/models/etudiants.py) définit une propriété pour le tri:

@cached_property
    def sort_key(self) -> tuple:
        "clé pour tris par ordre alphabétique"
        return (
            scu.sanitize_string(
                self.nom_usuel or self.nom or "", remove_spaces=False
            ).lower(),
            scu.sanitize_string(self.prenom or "", remove_spaces=False).lower(),
        )

(et ce sanitize_string appelle suppress_accents).

Cependant, les anciennes fonctions de ScoDoc n'utilisent pas encore toutes les modèles SQLAlchemy, d'où entre autres ce bug.

=> la bonne solution regarder le code de génération de la table en cause et sans doute le ré-écrire en utilisant les modèles modernes.

(et vérifier que la table en HTML est bien une datatables avec la clé de tri).

> Je n'ai pas encore eu le temps de voir où se trouve le tri des membres d'un groupe mais voici déjà une fonction qui permettrait de résoudre le problème. merci ! Dans `sco_utils.py`, on a `suppress_accents()`qui fait: ```py return ( unicodedata.normalize("NFD", s) .encode("ascii", "ignore") .decode(SCO_ENCODING) ) ``` Par ailleurs, le modèle `Identite` (dans `app/models/etudiants.py`) définit une propriété pour le tri: ```py @cached_property def sort_key(self) -> tuple: "clé pour tris par ordre alphabétique" return ( scu.sanitize_string( self.nom_usuel or self.nom or "", remove_spaces=False ).lower(), scu.sanitize_string(self.prenom or "", remove_spaces=False).lower(), ) ``` (et ce `sanitize_string` appelle `suppress_accents`). Cependant, les anciennes fonctions de ScoDoc n'utilisent pas encore toutes les modèles SQLAlchemy, d'où entre autres ce bug. => la bonne solution regarder le code de génération de la table en cause et sans doute le ré-écrire en utilisant les modèles modernes. (et vérifier que la table en HTML est bien une `datatables` avec la clé de tri).
Author
Owner

Note: dans les anciens codes, les objets étudiants sont des dictionnaires (et non des instance de la classe Identite).
J'ai donc ajouté une fonction sco_etud.etud_sort_keyqui fait exactement le même travail que Identite.sort_key(mais sur un dict).
Et modifié les appels pour les tris initiaux et dynamique des tables groupes et notes d'évalaution (il y a peut être d'autres listes à corriger ? pas vu).

Pour les tris côté client (JS), c'est DataTables qui fait le travail, grâce à l'attribut data-sort (ou data-order, les deux sont synonymes).

Fixed by d828be6be7

Note: dans les anciens codes, les objets étudiants sont des dictionnaires (et non des instance de la classe Identite). J'ai donc ajouté une fonction `sco_etud.etud_sort_key`qui fait exactement le même travail que `Identite.sort_key`(mais sur un dict). Et modifié les appels pour les tris initiaux et dynamique des tables groupes et notes d'évalaution (il y a peut être d'autres listes à corriger ? pas vu). Pour les tris côté client (JS), c'est DataTables qui fait le travail, grâce à l'attribut `data-sort` (ou `data-order`, les deux sont synonymes). Fixed by d828be6be79d328c51937c670ac0f64e83526b0a
Author
Owner

Corrigé aussi sur form saisie notes.

Corrigé aussi sur form saisie notes.
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: ScoDoc/ScoDoc#24
No description provided.