Hors programme. Unicode permet d'écrire « é » de deux façons : le…
Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 2 — Flottants, booléens et textes · Unicode dans le détail
Énoncé
Hors programme. Unicode permet d'écrire « é » de deux façons : le caractère précomposé U+00E9, ou la lettre e suivie de l'accent combinant U+0301. Construire les deux en Python, comparer leurs longueurs et leur égalité, puis les réconcilier avec unicodedata.normalize.
Corrigé
import unicodedata
a = "\u00e9" # e accent aigu precompose : 1 caractere
b = "e\u0301" # e + accent combinant : 2 caracteres
>>> len(a), len(b)
(1, 2)
>>> a == b
False
>>> a.encode("utf-8"), b.encode("utf-8")
(b'\xc3\xa9', b'e\xcc\x81')
>>> unicodedata.normalize("NFC", b) == a
True
>>> unicodedata.normalize("NFD", a) == b
True
Le fait déroutant. Les deux chaînes s'affichent identiquement — un terminal ne permet pas de les distinguer — et pourtant elles diffèrent : longueurs et , octets différents, égalité fausse. Un mot de passe, un nom de fichier ou une clé de dictionnaire peuvent ainsi ne pas correspondre alors que l'utilisateur jure avoir tapé la même chose.
La réponse d'Unicode : la normalisation. NFC compose au maximum (e + accent devient U+00E9), NFD décompose au maximum. Comparer deux textes venus de l'extérieur suppose de les avoir normalisés d'abord — c'est ce que font les systèmes de fichiers, chacun à sa façon, ce qui explique bien des surprises entre macOS (plutôt NFD) et Linux ou Windows (plutôt NFC).
La leçon générale du chapitre : un caractère n'est pas une lettre. C'est un point de code — et une même lettre peut correspondre à plusieurs suites de points de code. La question « combien de caractères dans ce mot ? » n'a même pas de réponse unique.
Contrôle : après normalize("NFC", b), longueur et égalité vraie.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.