From 94ee3dbbff3fe725759e6c039f5b0247c144ac32 Mon Sep 17 00:00:00 2001 From: Geoffrey Frogeye Date: Fri, 28 Nov 2014 00:22:50 +0100 Subject: [PATCH] Ajout TP 9 --- S1/TP 9/nombre.py | 358 +++++++++++++++++++++++++++++++++++++++++++++ S1/TP 9/shadock.py | 291 ++++++++++++++++++++++++++++++++++++ 2 files changed, 649 insertions(+) create mode 100644 S1/TP 9/nombre.py create mode 100644 S1/TP 9/shadock.py diff --git a/S1/TP 9/nombre.py b/S1/TP 9/nombre.py new file mode 100644 index 0000000..1c8fae1 --- /dev/null +++ b/S1/TP 9/nombre.py @@ -0,0 +1,358 @@ +# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015 +# TP n°9 donné le 21/11/2014 - Exercices sur la représentation des nombres +# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/seq6_binaire.html#exercices + +import doctest + +# Exercice Écritures + +# Écrire en binaire le nombre n=2014. + +# En calculant : + +# 2014 = 2 × 1007 + 0 +# 1007 = 2 × 503 + 1 +# 503 = 2 × 251 + 1 +# 251 = 2 × 125 + 1 +# 125 = 2 × 62 + 1 +# 62 = 2 × 31 + 0 +# 31 = 2 × 15 + 1 +# 15 = 2 × 7 + 1 +# 7 = 2 × 3 + 1 +# 3 = 2 × 1 + 1 +# 1 = 2 × 0 + 1 +# 0b11111011110 + +# Avec Python + +# >>> bin(n) +# '0b11111011110' + + +# Déterminez les écritures octale et hexadécimale de ce nombre de deux façons +# différentes. + +# En calculant + +# 2014 = 8 × 251 + 6 +# 251 = 8 × 31 + 3 +# 31 = 8 × 3 + 7 +# 3 = 8 × 0 + 3 +# 0o3736 + +# Avec Python + +# >>> oct(2014) +# '0o3736' + +# En calculant + +# 2014 = 16 × 125 + 14 # E +# 125 = 16 × 7 + 13 # D +# 7 = 16 × 0 + 7 +# 0x7de + +# Avec Python + +# >>> hex(2014) +# '0x7de' + + +# Exercice Pair ou impair ? + +# Comment reconnaître qu’un nombre entier est pair ou impair lorsqu’on dispose +# de son écriture binaire ? + +# Le dernier chiffre binaire détermine si un nombre est pair ou non (les +# puissance de deux supérieures à 0 étant forcément paires, leur somme ne peut +# donner qu'un nombre pair) +# Le prélicat suivant permet de déterminer si un nombre est pair + +def bin_est_pair(b): + """ + Indique si le nombre binaire est pair + bin → bool + + >>> bin_est_pair('0b11111011110') + True + >>> bin_est_pair('0b10101011') + False + """ + + return b[-1] == '0' + + +# Exercice + +# Quel est le plus grand nombre entier qu’on peut écrire en binaire avec +# 8 bits ? + +# Comparez ces nombres avec 2^t pour t=8,32,64. + +# 0b11111111 = 1 × 2^0 + 1 × 2^1 + 1 × 2^2 + 1 × 2^3 + 1 × 2^4 + 1 × 2^5 + 1 × +# 2^6 + 1 × 2^7 = 2^8-1 = 255 + +# 32 bits ? + +# 0b11111111111111111111111111111111 +# = 1 × 2^0 + 1 × 2^1 + 1 × 2^2 + 1 × 2^3 + 1 × 2^4 + 1 × 2^5 + 1 × 2^6 + 1 × +# 2^7 + 1 × 2^8 + 1 × 2^9 + 1 × 2^10 + 1 × 2^11 + 1 × 2^12 + 1 × 2^13 + 1 × 2^14 +# + 1 × 2^15 + 1 × 2^16 + 1 × 2^17 + 1 × 2^18 + 1 × 2^19 + 1 × 2^20 + 1 × 2^21 + +# 1 × 2^22 + 1 × 2^23 + 1 × 2^24 + 1 × 2^25 + 1 × 2^26 + 1 × 2^27 + 1 × 2^28 + 1 +# × 2^29 + 1 × 2^30 + 1 × 2^31 +# = 2^16-1 = 4 294 967 295 + +# 64 bits ? + +# 0b1111111111111111111111111111111111111111111111111111111111111111 +# = 1 × 2^0 + 1 × 2^1 + 1 × 2^2 + 1 × 2^3 + 1 × 2^4 + 1 × 2^5 + 1 × 2^6 + 1 × +# 2^7 + 1 × 2^8 + 1 × 2^9 + 1 × 2^10 + 1 × 2^11 + 1 × 2^12 + 1 × 2^13 + 1 × 2^14 +# + 1 × 2^15 + 1 × 2^16 + 1 × 2^17 + 1 × 2^18 + 1 × 2^19 + 1 × 2^20 + 1 × 2^21 + +# 1 × 2^22 + 1 × 2^23 + 1 × 2^24 + 1 × 2^25 + 1 × 2^26 + 1 × 2^27 + 1 × 2^28 + 1 +# × 2^29 + 1 × 2^30 + 1 × 2^31 + 1 × 2^32 + 1 × 2^33 + 1 × 2^34 + 1 × 2^35 + 1 × +# 2^36 + 1 × 2^37 + 1 × 2^38 + 1 × 2^39 + 1 × 2^40 + 1 × 2^41 + 1 × 2^42 + 1 × +# 2^43 + 1 × 2^44 + 1 × 2^45 + 1 × 2^46 + 1 × 2^47 + 1 × 2^48 + 1 × 2^49 + 1 × +# 2^50 + 1 × 2^51 + 1 × 2^52 + 1 × 2^53 + 1 × 2^54 + 1 × 2^55 + 1 × 2^56 + 1 × +# 2^57 + 1 × 2^58 + 1 × 2^59 + 1 × 2^60 + 1 × 2^61 + 1 × 2^62 + 1 × 2^63 +# = 2^64-1 = 18 446 744 073 709 551 615 + + +# Exercice fonction ``mon_bin`` + +# En suivant l’algorithme de conversion vu dans le cours, programmez une +# fonction que vous nommerez mon_bin qui agit exactement de la même façon que la +# fonction bin de Python. Concevez d’abord votre fonction pour des nombres +# positifs + +def mon_bin(d): + """ + Équivalent de la fonction native bin() définie sur les entiers positifs + int → bin + CU : int strictement positif + + >>> mon_bin(2014) + '0b11111011110' + >>> mon_bin(42) + '0b101010' + """ + + assert(d > 0), "d doit être strictement positif" + D = d + r = '' + while D >= 1: + r = str(D % 2) + r + D = D // 2 + return '0b' + r + + +# Observez les réponses fournies par votre fonction pour plusieurs nombres +# positifs, puis pour 0. Est-ce que tout est correct ? + +# >>> mon_bin(2014) +# '0b11111011110' +# >>> mon_bin(42) +# '0b101010' +# >>> mon_bin(0) +# '0b' +# >>> mon_bin(-42) +# '0b' + +# Chaque nombre ≤ 0 donné renverra '0b'. Cela est dû au fait qu'on vérifie que +# D ≥ 1. On devrait utiliser sa valeur absolue, soit vérifier que |D| ≥ 1. +# Cependant, on remarque que l'instruction D // 2 arrondit à l'entier inférieur, +# la fonction restera bloqué avec un D valant -1. On préfèrera prendre la valeur +# absolue de d au départ et rajouter un - au résultat, plutôt que de vérifier +# si l'arrondi doit être fait à l'entier supérieur ou inférieur à l'intérieur +# de la boucle, ce qui prendrait trop de temps. + +# Étendez le domaine d’application de votre fonction au cas de 0 et des nombres +# négatifs. + +def mon_bin2(d): + """ + Équivalent de la fonction native bin() + int → bin + + >>> mon_bin2(2014) + '0b11111011110' + >>> mon_bin2(42) + '0b101010' + >>> mon_bin2(0) + '0b0' + >>> mon_bin2(-42) + '-0b101010' + """ + + D = abs(d) + if d != 0: + r = '' + while D >= 1: + r = str(D % 2) + r + D = D // 2 + else: + r = '0' + return ('-' if d < 0 else '') + '0b' + r + + +# Exercice fonction ``bin_inv`` + +# En utilsant l’algorithme vu en cours, réalisez une fonction que vous nommerez +# bin_inv qui fait le travail inverse de la fonction bin, c’est-à-dire qui +# calcule l’entier correspondant à une chaîne de caractères décrivant cet entier +# en binaire. + +def bin_inv(b): + """ + Réalise le travail inverse de la fonction native bin() + bin → int + + >>> bin_inv ('0b101111') + 47 + >>> bin_inv ('-0b101111') + -47 + """ + + B = b.replace('0b', '') + if b[0] == '-': + B = B.replace('-', '') + d = 0 + if len(B) > 0: + for i in range(-1, -len(B) - 1, -1): + d += int(B[i]) * 2 ** (-i - 1) + return -d if b[0] == '-' else d + + +# Exercice fonction ``mon_hex`` + +# Que faut-il changer à l’algorithme de l’écriture binaire d’un nombre pour +# calculer la représentation hexadécimale d’un nombre entier naturel non nul ? + +# Il faut remplacer les divisions par deux par des divisions par 16, et +# remplacer les nombres au dessus de 10 par des lettres. On utilisera une +# autre fonction pour cela, elle pourra très probablement resservir + +# Réalisez une fonction que vous nommerez mon_hex équivalente à la fonction hex. +# Commencez pour les nombres positifs, puis envisagez le cas des nombres +# négatifs. + +def mon_hex_unique(d): + """ + Équivalent de la fonction native hex() pour un seul caractère héxadécimal + int → hex + CU : 0 ≤ d < 16 + + >>> mon_hex_unique(11) + 'b' + >>> mon_hex_unique(8) + '8' + """ + + assert(type(d) is int and d >= 0 and d < 16), "" + return chr(97 + d - 10) if d >= 10 else str(d) + + +def mon_hex(d): + """ + Équivalent de la fonction native hex() + int → hex + + >>> mon_hex(47) + '0x2f' + >>> mon_hex(-47) + '-0x2f' + """ + + D = abs(d) + if d != 0: + r = '' + while D >= 1: + r = mon_hex_unique(D % 16) + r + D = D // 16 + else: + r = '0' + return ('-' if d < 0 else '') + '0x' + r + +# Exercice fonction ``hex_inv`` + +# Réalisez la fonction hex_inv inverse de la fonction hex, c’est–à–dire la +# fonction qui, à partir d’une chaîne de donnant l’écriture hexadécimale d’un +# entier, calcule cet entier. Vous devez obtenir par exemple: + + +def hex_inv_unique(h): + """ + Réalise le travail inverse de la fonction native hex() pour un seul + caractère héxadécimal + hex → int + + >>> hex_inv_unique('b') + 11 + >>> hex_inv_unique('8') + 8 + """ + + return ord(h) - 97 + 10 if ord(h) >= 97 else int(h) + + +def hex_inv(h): + """ + Réalise le travail inverse de la fonction native hex() + hex → int + + >>> hex_inv ('0x2f') + 47 + >>> hex_inv ('-0x2f') + -47 + """ + H = h.replace('0x', '') + if h[0] == '-': + H = H.replace('-', '') + d = 0 + if len(H) > 0: + for i in range(-1, -len(H) - 1, -1): + d += hex_inv_unique(H[i]) * 16 ** (-i - 1) + return -d if h[0] == '-' else d + + +# Exercice fonction ``bin_en_hex`` + +# Sans utiliser les fonctions hex et/ou bin (ni même mon_bin et/ou mon_hex), +# programmez une fonction nommée bin_en_hex qui convertit une chaîne de +# caractères représentant un nombre entier écrit en binaire en la chaîne +# hexadécimale représentant le même entier. + +# Notez bien dans cet exemple que la valeur passée en argument à la fonction +# bin_en_hex est une chaîne de caractères. + +def bin_en_hex(b): + """ + Convertit un binaire en hexadécimal + bin → hex + + >>> bin_en_hex('0b101111') + '0x2f' + >>> bin_en_hex('-0b101111') + '-0x2f' + """ + B = b.replace('0b', '') + if b[0] == '-': + B = B.replace('-', '') + if len(B) > 0: + r = '' + for i in range(-1, -len(B) - 1, -4): + p = 0 + # On coupe le binaire en partie de 4 chiffres + for j in range(4): + rang = i - j + if -rang <= len(B): + p += int(B[rang]) * 2 ** (j) + else: + p += 0 + r = mon_hex_unique(p) + r + else: + r = '0' + return ('-' if b[0] == '-' else '') + '0x' + r + + +def tester(): + doctest.testmod(verbose=True) diff --git a/S1/TP 9/shadock.py b/S1/TP 9/shadock.py new file mode 100644 index 0000000..e4aa471 --- /dev/null +++ b/S1/TP 9/shadock.py @@ -0,0 +1,291 @@ +# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015 +# TP n°9 donné le 21/11/2014 - L’alphabet shadok +# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/tp_numeration_shadok.html + +import doctest + + +# À l’aide de la fonction chr, définissez quatre constantes GA, BU, ZO et +# MEU ayant pour valeur les quatre chiffres shadoks. + +GA = chr(0x004F) +BU = chr(0x2212) +ZO = chr(0x2A3C) +MEU = chr(0x25FF) + + +# Définissez une variable ALPHABET_SHADOK dont la valeur est la liste des +# quatre chiffres shadoks dans l’ordre O, −, ⨼ et ◿. + +ALPHABET_SHADOK = [GA, BU, ZO, MEU] + + +# Réalisez une fonction entier_en_shadok qui renvoie l’écriture shadok de +# l’entier passé en paramètre. Contentez-vous d’une fonction qui convient +# pour les entiers positifs ou nuls. + + +def entier_en_shadok(d): + """ + Renvoie l’écriture shadok de l’entier positif passé en paramètre. + CU : d positif ou nul + int → str + + >>> entier_en_shadok(0) + 'O' + >>> entier_en_shadok(1) + '−' + >>> entier_en_shadok(2) + '⨼' + >>> entier_en_shadok(3) + '◿' + >>> entier_en_shadok(13) + '◿−' + """ + assert(type(d) is int and d >= 0), "d doit être un entier positif ou nul" + + if d == 0: + return GA + else: + D = d + r = '' + while D >= 1: + r = ALPHABET_SHADOK[D % 4] + r + D = D // 4 + return r + + +# Quelle est l’écriture shadok de 2014 ? + +# −◿◿−◿⨼ + + +# Réalisez la fonction nommée shadok_en_entier réciproque de la précédente +# qui renvoie le nombre correspondant à une écriture shadok. + + +def shadok_en_entier_unique(s): + """ + Renvoie le nombre correspondant à un symbole shadok + str → int + + >>> shadok_en_entier(GA) + 0 + >>> shadok_en_entier(BU) + 1 + >>> shadok_en_entier(ZO) + 2 + >>> shadok_en_entier(MEU) + 3 + """ + if s == GA: + return 0 + elif s == BU: + return 1 + elif s == ZO: + return 2 + elif s == MEU: + return 3 + else: + assert(False), "Pas un symbole shadok" + + +def shadok_en_entier(s): + """ + Renvoie le nombre correspondant à une écriture shadok + str → int + + >>> shadok_en_entier(GA) + 0 + >>> shadok_en_entier(BU) + 1 + >>> shadok_en_entier(ZO) + 2 + >>> shadok_en_entier(MEU) + 3 + >>> shadok_en_entier(MEU+BU) + 13 + """ + S = s + d = 0 + if len(S) > 0: + for i in range(-1, -len(S) - 1, -1): + d += shadok_en_entier_unique(S[i]) * 4 ** (-i - 1) + return d + + +# Répondez à la question posée à la fin de la vidéo : quel est l’entier +# correspondant au nombre écrit − ⨼ O ◿ ? + +# >>> shadok_en_entier('−⨼O◿') +# 99 + +# J'ai malheureusement peur qu'il ne soit trop tard pour le professeur Shadoko + + +# Messages Shadok + +# Expliquez pourquoi tout nombre entier représentable sur un octet peut +# être écrit en shadok avec quatre chiffres shadoks. + +# Il y a 2^8=256 possibilités de nombres entier pouvant se représenter sur un +# octet. Il y a aussi 4^4=256 possibilités d'ensembles de 4 chiffres en base 4 +# (ou de chiffres shadoks). On peut donc trouver un équivalent entre les deux + + +# Réalisez une fonction nommée octet_en_shadok qui renvoie l’écriture +# shadok avec exactement quatre chiffres d’un entier représentable sur un +# octet. + +def octet_en_shadok(o): + """ + Renvoie l’écriture shadok avec exactement quatre chiffres d’un entier + représentable sur un octet + int → str + + >>> octet_en_shadok (0) + 'OOOO' + >>> octet_en_shadok (255) + '◿◿◿◿' + >>> octet_en_shadok (65) + '−OO−' + """ + assert(type(o) is int and o < 256), 'o doit être représentable sur un seul \ +octet' + s = entier_en_shadok(o) + while len(s) < 4: + s = GA + s + return s + + +# Quel est la chaîne de caractères shadoks qui code le caractère e ? + +# >>> octet_en_shadok(ord('e')) +# '−⨼−−' + + +# Réalisez une fonction code_car_en_shadok qui code un caractère ASCII en +# shadok. + + +def code_car_en_shadok(c): + """ + Code un caractère ASCII en shadok + str → str + CU : c un unique caractère + + >>> code_car_en_shadok('A') + '−OO−' + >>> code_car_en_shadok('e') + '−⨼−−' + """ + assert(type(c) is str and len(c) == 1), "c doit être un unique caractère" + + return octet_en_shadok(ord(c)) + +# Réalisez une fonction code_en_shadok qui code en shadok la chaîne de +# caractères ASCII passée en paramètre. + + +def code_en_shadok(s): + """ + Code une chaîne de caractères ASCII en shadok + str → str + CU : c str + + >>> code_en_shadok ('Timoleon') + '−−−O−⨼⨼−−⨼◿−−⨼◿◿−⨼◿O−⨼−−−⨼◿◿−⨼◿⨼' + """ + assert(type(s) is str), "s doit être un str" + + r = '' + for i in s: + r += code_car_en_shadok(i) + return r + + +# Quel est le caractère ASCII codé par la chaîne ‘O⨼⨼⨼’ ? + +# >>> shadok_en_entier('O⨼⨼⨼') +# 42 + +# Et le caractère ASCII associé à la Grande Question sur la vie, l'univers et +# le reste est ... + +# >>> chr(42) +# '*' + +# * étant le caractère joker sous les systèmes de type Unix qui correspond à +# tous les élément d'une liste. Ce qui possède un sens en soi. + +# Plus sérieusement, la réponse est * + + +# Est-il possible que la chaîne ‘⨼◿◿−’ corresponde à un caractère ASCII ? + +# >>> shadok_en_entier('⨼◿◿−') +# 189 + +# Or 189 est supérieur à 127, qui est le dernier caractère dans la table ASCII. + +# >>> bin(189) +# '0b10111101' + +# Cependant, on obtient un nombre pair de chiffres 0 et de chiffres 1, pour +# l'ASCII standard, possédant un bit de contrôle, ce caractère est valide + +# Cependant, Python 3 utilisant par défaut l'UTF-8, notammennt la fonction chr() +# on obtiendra le caractère UTF-8 correspondant à l'octet 0b10111101. + +# >>> chr(shadok_en_entier('⨼◿◿−')) +# '½' + + +# Réalisez une fonction decode_car_du_shadok qui décode une chaîne de +# quatre caractères shadoks en un caractère ASCII. (Réfléchissez bien sur +# les contraintes d’utilisation) + +def decode_car_du_shadok(s): + """ + Décode une chaîne de quatre caractères shadoks en un caractère ASCII + str → str + CU : s str composé de 4 caractères parmi GA, BU, ZO ou MEU correspondant à + un caractère ASCII existant (le bit de contrôle étant égal à 0) + + >>> decode_car_du_shadok('−OO−') + 'A' + >>> decode_car_du_shadok('O⨼⨼⨼') + '*' + """ + assert(type(s) is str and len(s) == 4), "s doit être un str composé de 4 \ +caractères" + d = shadok_en_entier(s) + assert(d < 128), "s doit correspondre à un caractères ASCII existant" + return chr(d) + + +# Réalisez une fonction decode_du_shadok qui décode une chaîne shadok. + +def decode_du_shadok(s): + """ + Décode une suite d'ensembles de quatre caractères shadoks en caractère ASCII + str → str + CU : s str composé d'ensembles de 4 caractères parmi GA, BU, ZO ou MEU + correspondant à un caractère ASCII existant (le bit de contrôle étant égal à + 0) + + >>> decode_du_shadok('−−−O−⨼⨼−−⨼◿−−⨼◿◿−⨼◿O−⨼−−−⨼◿◿−⨼◿⨼') + 'Timoleon' + """ + assert(type(s) is str and len(s)%4 == 0), "s doit être un str composé \ +d'ensembles de 4 caractères" + + r = '' + for i in range(0, len(s), 4): + r += decode_car_du_shadok(s[i:i+4]) + return r + +# Décodez le message ‘−O−◿−OO−−OO⨼−−−−−−⨼⨼−O◿◿−O◿−−O−−−−−−’. + +def tester(): + doctest.testmod(verbose=True)