Aller au contenu

TP Python – Validation et contrôle de données

BTS SIO SISR 1re année – Mathématiques pour l'informatique – S15

Note

Comment ce TP fonctionne. Chaque exercice a un éditeur Python intégré à la page (il s'exécute dans ton navigateur, rien à installer). Avant de lancer, écris sur ta feuille ce que tu anticipes (« J'anticipe »). Puis lance et compare. Le bouton Valider exécute des tests : un test réussi ne dispense pas de comprendre pourquoi.

Exercice A – Valider des formats

Complète est_octet(s), ipv4_valide(s) et mac_valide(s). N'utilise pas d'expression régulière : parcours les chaînes avec des boucles et des tests.

J'anticipe. Que renvoie ipv4_valide("192.168.10.77.1") ? Quelle règle est violée ?

###
assert estpy-undoctet("0") is True and estpy-undoctet("255") is True and estpy-undoctet("77") is Truebksl-nlassert estpy-undoctet("256") is False and estpy-undoctet("-1") is False and estpy-undoctet("") is Falsebksl-nlassert estpy-undoctet("012") is False and estpy-undoctet("1a") is False and estpy-undoctet("00") is Falsebksl-nlassert ipv4py-undvalide("192.168.10.77") is True and ipv4py-undvalide("0.0.0.0") is Truebksl-nlassert ipv4py-undvalide("192.168.10") is False and ipv4py-undvalide("192.168.10.77.1") is Falsebksl-nlassert ipv4py-undvalide("192.168.300.1") is False and ipv4py-undvalide("192.168.01.1") is Falsebksl-nlassert ipv4py-undvalide("192.168..1") is False and ipv4py-undvalide("a.b.c.d") is Falsebksl-nlassert macpy-undvalide("00:1A:2b:3C:4d:5E") is Truebksl-nlassert macpy-undvalide("00:1A:2b:3C:4d") is False and macpy-undvalide("00:1A:2b:3C:4d:5G") is Falsebksl-nlassert macpy-undvalide("001A:2b:3C:4d:5E:6F") is False and macpy-undvalide("0:1A:2b:3C:4d:5E") is Falsebksl-nlbksl-nl ∞/∞

def estpy-undoctet(s):bksl-nl """Vrai si s (chaîne) écrit un entier de 0 à 255 en décimal, sans zéro inutile au début."""bksl-nl if s == "" or not s.isdigit():bksl-nl return Falsebksl-nl # À compléter : refuser un zéro initial (sauf "0" seul), puis tester 0 <= int(s) <= 255bksl-nl return Falsebksl-nlbksl-nldef ipv4py-undvalide(s):bksl-nl """Vrai si s est une adresse IPv4 écrite en notation décimale pointée."""bksl-nl morceaux = s.split(".")bksl-nl # À compléter : exactement 4 morceaux, tous valides selon estpy-undoctetbksl-nl return Falsebksl-nlbksl-nldef macpy-undvalide(s):bksl-nl """Vrai si s a la forme AA:BB:CC:DD:EE:FF (6 groupes de 2 chiffres hexadécimaux)."""bksl-nl hexa = "0123456789abcdefABCDEF"bksl-nl groupes = s.split(":")bksl-nl # À compléter : 6 groupes, chacun de 2 caractères pris dans hexabksl-nl return Falsebksl-nlbksl-nl



Exercice B – Bit de parité

Complète bit_parite(bits), ajoute_parite(bits) (qui renvoie une nouvelle liste) et mot_valide(mot).

Je comprends. Pourquoi mot_valide peut-il s'écrire avec bit_parite ? Que valent bit_parite([]) et mot_valide([]) ?

###
assert bitpy-undparite([1, 0, 1, 1, 0, 0, 1]) == 0 and bitpy-undparite([1, 0, 1, 1, 0, 0, 0]) == 1bksl-nlassert bitpy-undparite([]) == 0 and bitpy-undparite([1]) == 1 and bitpy-undparite([0, 0, 0]) == 0bksl-nlassert ajoutepy-undparite([1, 0, 1, 1, 0, 0, 0]) == [1, 0, 1, 1, 0, 0, 0, 1]bksl-nlassert ajoutepy-undparite([1, 1]) == [1, 1, 0]bksl-nlm = [1, 0, 1]bksl-nlassert ajoutepy-undparite(m) == [1, 0, 1, 0] and m == [1, 0, 1]bksl-nlassert motpy-undvalide([1, 0, 1, 1, 0, 0, 1, 0]) is True and motpy-undvalide([1, 0, 1, 1, 0, 0, 1, 1]) is Falsebksl-nlassert motpy-undvalide([1, 0, 1, 1, 0, 0, 0, 1]) is Truebksl-nlassert motpy-undvalide([1, 0, 1, 1, 1, 0, 0, 1]) is Falsebksl-nlassert motpy-undvalide([1, 0, 0, 1, 0, 0, 1, 1]) is Truebksl-nlassert motpy-undvalide([]) is Truebksl-nlbksl-nl ∞/∞

def bitpy-undparite(bits):bksl-nl """Bit à ajouter pour que le nombre total de 1 soit pair (parité paire)."""bksl-nl # À compléter : compter les 1 ; renvoyer 0 si leur nombre est pair, 1 sinonbksl-nl return 0bksl-nlbksl-nldef ajoutepy-undparite(bits):bksl-nl """Renvoie une nouvelle liste : bits suivis du bit de parité."""bksl-nl return list(bits) # À compléter : ajouter le bit de paritébksl-nlbksl-nldef motpy-undvalide(mot):bksl-nl """Vrai si le nombre de 1 de mot (bit de parité compris) est pair."""bksl-nl # À compléterbksl-nl return Falsebksl-nlbksl-nl



Exercice C – Parité à deux dimensions

Complète lignes_incorrectes(g), colonnes_incorrectes(g) et corrige(g). La grille contient déjà ses bits de parité (dernière ligne et dernière colonne).

Je comprends. Que doit faire corrige si deux lignes sont fausses ? Pourquoi ne peut-on pas corriger dans ce cas ?

###
ok = [[1, 0, 1, 0], [0, 1, 1, 0], [1, 1, 0, 0], [0, 0, 0, 0]]bksl-nlassert lignespy-undincorrectes(ok) == [] and colonnespy-undincorrectes(ok) == []bksl-nlko = [[1, 0, 1, 0], [0, 1, 0, 0], [1, 1, 0, 0], [0, 0, 0, 0]]bksl-nlassert lignespy-undincorrectes(ko) == [1] and colonnespy-undincorrectes(ko) == [2]bksl-nlassert corrige(ko) == okbksl-nlassert corrige(ok) == okbksl-nlko2 = [[1, 0, 1, 0], [0, 1, 1, 0], [1, 1, 0, 0], [0, 0, 0, 1]]bksl-nlassert lignespy-undincorrectes(ko2) == [3] and colonnespy-undincorrectes(ko2) == [3]bksl-nlassert corrige(ko2) == okbksl-nlko3 = [[1, 0, 1, 1], [0, 1, 1, 0], [1, 1, 0, 0], [0, 0, 0, 0]]bksl-nlassert corrige(ko3) == okbksl-nlassert ko[1][2] == 0bksl-nlbksl-nl ∞/∞

def lignespy-undincorrectes(g):bksl-nl """Indices des lignes de g dont le nombre de 1 est impair."""bksl-nl res = []bksl-nl for i in range(len(g)):bksl-nl # À compléter : si sum(g[i]) est impair, ajouter i à resbksl-nl passbksl-nl return resbksl-nlbksl-nldef colonnespy-undincorrectes(g):bksl-nl """Indices des colonnes de g dont le nombre de 1 est impair."""bksl-nl res = []bksl-nl for j in range(len(g[0])):bksl-nl total = 0bksl-nl # À compléter : additionner g[i][j] pour toutes les lignes ibksl-nl if total % 2 == 1:bksl-nl res.append(j)bksl-nl return resbksl-nlbksl-nldef corrige(g):bksl-nl """Renvoie une copie de g où l'unique bit erroné (s'il y en a un) est rétabli."""bksl-nl copie = [ligne[:] for ligne in g]bksl-nl lignes = lignespy-undincorrectes(g)bksl-nl colonnes = colonnespy-undincorrectes(g)bksl-nl # À compléter : si une seule ligne i et une seule colonne j sont incorrectes,bksl-nl # inverser copie[i][j] (0 devient 1, 1 devient 0)bksl-nl return copiebksl-nlbksl-nl



Exercice D – Sommes de contrôle

Complète somme_controle(octets), trame_valide(octets, c) et xor_controle(octets).

J'anticipe. Pour [10, 20, 30], quelle est la somme de contrôle ? Vérifie avec le cours.

###
assert sommepy-undcontrole([10, 20, 30]) == 196 and sommepy-undcontrole([255, 1]) == 0bksl-nlassert sommepy-undcontrole([]) == 0 and sommepy-undcontrole([200, 100]) == 212bksl-nlassert tramepy-undvalide([10, 20, 30], 196) is True and tramepy-undvalide([10, 20, 31], 196) is Falsebksl-nlassert tramepy-undvalide([200, 100], 212) is True and tramepy-undvalide([], 0) is Truebksl-nlassert all(tramepy-undvalide([a, b], sommepy-undcontrole([a, b])) for a in range(0, 256, 17) for b in range(0, 256, 13))bksl-nlassert xorpy-undcontrole([]) == 0 and xorpy-undcontrole([5]) == 5 and xorpy-undcontrole([5, 5]) == 0bksl-nlassert xorpy-undcontrole([0b1100, 0b1010]) == 0b0110 and xorpy-undcontrole([1, 2, 4]) == 7bksl-nlassert xorpy-undcontrole([0xC0, 0xA8, 0x0A, 0x4D]) == 0x2Fbksl-nlbksl-nl ∞/∞

def sommepy-undcontrole(octets):bksl-nl """Octet c (0 à 255) tel que la somme des octets, plus c, soit un multiple de 256."""bksl-nl # À compléter : utiliser sum et le reste de la division par 256bksl-nl return 0bksl-nlbksl-nldef tramepy-undvalide(octets, c):bksl-nl """Vrai si la somme des octets, plus c, est un multiple de 256."""bksl-nl # À compléterbksl-nl return Falsebksl-nlbksl-nldef xorpy-undcontrole(octets):bksl-nl """OU exclusif (^) de tous les octets ; 0 pour une liste vide."""bksl-nl r = 0bksl-nl for o in octets:bksl-nl # À compléter : combiner r et o avec ^bksl-nl passbksl-nl return rbksl-nlbksl-nl



Pour aller plus loin

Dans la console, écris une fonction ajoute_erreur(octets, i) qui inverse un bit d'un octet (opérateur ^ avec une puissance de 2) et vérifie qu'une somme de contrôle détecte toute erreur sur un seul bit.