IPT_TP_manipulation_nombres_PCSI MANIPULER LES NOMBRES AVEC PYTHON Le but de ce TP est d'utiliser Python pour effectuer des calculs sur les nombres entiers et flottants. On a besoin pour cela de charger des modules. Modules Un module est un regroupement de fonctions portant sur un même thème. Par exemple, • le module math regroupe des fonctions mathématiques • le module random regroupe des fonctions permettant de générer des données aléatoires • le module matplotlib regroupe des commandes pour les tracés de courbes • le module numpy regroupe des commandes pour créer et manipuler des vecteurs • le module scipy regroupe des fonctions dédiées au calcul scientifique (résolution d'équations, calcul matriciel, ... ) • le module sympy regroupe des commandes pour faire du calcul symbolique • le module fractions permet de manipuler des fractions de façon exacte. • ... Certains modules sont déjà préchargés dans la console Python de Spyder. C'est le cas de numpy, scipy, matplotlib. Importation d'un module On insère au début du script Python une commande du type "import nom_module" avec différentes syntaxes d'importation possibles : >>> import math Les commandes du module math sont toutes chargées mais doivent être préfixées par "math" . exemple : math.cos(math.pi/4) >>> from math import * Les commandes sont également toutes chargées mais n'ont pas besoin d'être préfixées pour être comprises par l'interpréteur. exemple : cos(pi/4). Par contre, si un autre module possède une fonction nommée cos (numpy par exemple), il peut y avoir des conflits. C'est la fonction du dernier module chargé qui prévaut. >>> from math import floor On n'importe que la fonction dont on a besoin, en l'occurrence ici « floor » (partie entière). On utilise cette possibilité pour certains modules très volumineux (comme scipy). On importe seulement ce dont on a besoin. print(dir(math)) : affiche toutes les fonctions du module math (la même syntaxe prévaut pour d'autre type d'objets) dir(int), dir(str), etc ... ) Aide sur une fonction : help(math.ceil) - page 1 - IPT_TP_manipulation_nombres_PCSI Le module Math Opération de base • + , − , / division flottante (le résultat est un flottant en Python 3), ** puissances (ou bien pow(x,y) = xy) • a//b division entière (quotient dans la division euclidienne de a par b) a%b (reste dans la division euclidienne de a par b) Constantes • math.pi, math.e (ou pi, e, ... selon le mode d'importation). Fonctions de base : • cos, sin, tan, acos, asin, atan : fonctions trigonométriques de base et leurs réciproques • cosh, sinh, tanh, asinh, acosh : fonctions trigonométriques hyperboliques de base et leurs réciproques • sqrt (racine carrée) • exp, log, log10, math.log(x, base) Appel d’une fonction : math.cos(x) (ou simplement cos(x) selon le mode d'importation). • math.factorial pour les factorielles • floor (partie entière : plus grand entier ≤ x), ceil (plus petit entier ≥ x), round pour arrondir‹ attention, résultats flottants même si x est entier ! Un résultat flottant peut-être reconverti en entier par int(x) (renvoie le plus proche entier en direction de 0). La fonction trunc a le même effet. • modf(x) = (partie fractionnaire, partie entière) frexp(x) = (mantisse, exposant) : x = mantisse*2exposant avec mantisse dans ]− 1,1[ • radians(x) convertit de degrés en radians • cmp(x,y) = 1 si x > y, 0 si x = y et – 1 si x < y Rappel de cours Un flottant en double précision est codé sur 8 octets, 1 bit pour le signe, 11 bits pour l’exposant (compris entre − 1022 et 1023) et 52 bits pour la mantisse (la mantisse est comprise entre 1 inclus et 2 exclu et les 52 bits décrivent les décimales) La précision en entiers longs est illimitée. Pour faire des calculs sur les nombres flottants avec une haute précision, on peut utiliser le module décimal qui est livré avec la distribution. - page 2 - IPT_TP_manipulation_nombres_PCSI Le module decimal Calculs en haute précision sur les flottants. Importation : from decimal import * getcontext() donne les paramètres en cours. En particulier, getcontext().prec = nombre de chiffres significatifs (28 chiffres significatifs par défaut) La commande decimal.getcontext().prec retourne 28. Les règles d'arrondi et la précision n'interviennent toutefois que dans les calculs arithmétiques. Decimal('0.1') renvoie Decimal('0.1') (valeur exacte) tandis que Decimal(0.1) renvoie 0.1000000000000000055511151231257827021181583404541015625 decimal.Decimal('0.1') + decimal.Decimal('0.5') retourne Decimal('0.6') decimal.Decimal(0.1) + decimal.Decimal(0.5) retourne (avec 28 chiffres significatifs) Decimal('0.6000000000000000055511151231') decimal.Decimal(0.6) retourne Decimal('0.59999999999999997779553950749686919152736663818359375') Ces résultats légèrement différents s'expliquent par le fait que 0.1 et 0.6 ne sont pas représentables de façon exacte en machine (développement binaire illimité). On peut gérer différentes formes d'arrondi, utile notamment dans les calculs monétaires. Le module fraction Il permet d'effectuer des calculs exacts sur les fractions. Importation : import fractions fractions.Fraction(2,3) représente la fraction 2/3 ‹ fractions.Fraction(0.1) ne retourne pas fractions.Fraction(11,10); par contre fractions.Fraction('0.1') retourne Fraction(1,10). fractions.gcd(a,b) calcule le pgcd des entiers a et b Nombres complexes : Les nombres complexes s'écrivent sous la forme a + bj (sans * devant j). ‹ si b = 1, il faut écrire a + 1j et non pas 1 + j. z.imag et z.real donnent les parties imaginaires et réelles du complexe z. abs(z) donne le module. Le module cmath fournit des fonctions de la variable complexe. Par exemple : cmath.phase(z) donne l’argument principal, polar(z) rend le couple (module, argument principal). - page 3 - IPT_TP_manipulation_nombres_PCSI Variables Dans Python, on crée une variable et on l’affecte en même temps : >>> ma_variable = valeur On peut faire des affectations simultanées : >>> var1, var2 = valeur1, valeur2 On peut réinitialiser une variable : >>> var = None # aucune valeur (et donc aucun type) n’est affectée à la variable. Tout calcul où x apparaît déclenchera une erreur. >>> del var # a le même effet On peut tester le type d’une variable ou demander quel est son type. Par exemple, >>> isinstance(var, int) va tester si var est un entier. Réponse bouléenne. >>> type(var) retourne le type de la variable. >>> id(var) donne (sous forme décimale) l’adresse en mémoire où la variable est stockée. Types courants • int, long (entiers longs), float, complex (nombres complexes) • str (chaînes), bool (bouléen), unicode • tuple (suites d'objets), list (listes), dict (dictionnaires), file (fichiers) • NoneType, function (fonctions), module, ... Conversions • bin(entier) (resp. hex(entier)) retourne l'écriture binaire (resp. hexadécimale) de l'entier. • int(‘nombre binaire’,2) retourne l'écriture en base 10 du nombre binaire. int(‘nombre hexadécimal’,16) retourne l'écriture en base 10 du nombre hexadécimal. int('entier', base) retourne l'entier en base 10 int(flottant) donne l'entier le plus proche (en direction de 0) du nombre flottant. int(chaîne) donne l'entier correspondant si la chaîne de caractères est interprétable comme un entier. • float(entier) donne l'écriture flottante du nombre entier. • float.hex(flottant) donne la représentation hexadécimale du flottant. - page 4 - IPT_TP_manipulation_nombres_PCSI Entrées-Sorties La plupart du temps, le jeu de données nécessaire à des calculs sera introduit par transmission des paramètres lors de l'appel d'une fonction. On peut cependant interagir avec un utilisateur directement au clavier, les calculs étant en pause tant que ce dernier n'a pas validé la donnée demandée. Il y a une différence dans la syntaxe selon qu'on utilise Python2 ou Python3. On privilégie désormais Python3. Entrées L'utilisateur rentre au clavier une donnée conforme à ce qui est demandé dans le texte qui s'affiche à l'écran. ‹ Le résultat est toujours une chaîne de caractères. Il faut convertir la donnée obtenue si on veut faire du calcul numérique. Exemple : >>> x = input("entrer un entier : ") # x est une chaîne de caractères >>> x1 = int(x) # x1 est un entier >>> y1 = x1**2 # Si l'on fait le calcul directement sur x au lieu de le faire sur x1, cela provoque une erreur. Remarque En Python2, la syntaxe est variable = input(texte ) : la variable prend le type de ce qui est rentré par l‘utilisateur. L'équivalent du input de Python3 est variable = raw_input(texte ) : la variable est forcément une chaîne de caractères. Sorties Pour une sortie vers l'écran, la commande est >>> print(objets à afficher séparés par des virgules) Les objets peuvent être de type différent. Exemple, >>> x, y = 1.2 , 3.4 >>> print("la valeur de x est : ", x, "la valeur de y est : ", y, "la norme du vecteur ('x,y) est : ", sqrt(x**2 + y**2)) Pour insérer un saut de ligne : print('\n'); pour insérer une tabulation : print('\t'). On peut vouloir insérer des valeurs numériques (ou autres) dans une chaîne de caractères. Syntaxe : print("chaîne où les valeurs à insérer sont remplacées par des accolades {}").format(suite des éléments à inclure) A l'intérieur des accolades, on précise le type de la variable à substituer (‹ ne pas oublier " : " dans la syntaxe) : :d pour un entier relatif :s pour une chaîne de caractères :e pour un nombre réel au format exponentiel :f pour un nombre réel au format décimal :n.pf pour un formatage des flottants avec n chiffres dont p décimales :g pour un nombre au format décimal ou exponentiel selon la taille du nombre, Exemple - page 5 - IPT_TP_manipulation_nombres_PCSI >>> figure, n = 'rectangle', 3 >>> x, y = 4.26, 7.51 >>> print('Le {:s} n°{:d} a pour largeur {:f} cm et pour longueur {:f} cm'.format(figure, n, min(x,y), max(x,y)) + '\n' + 'Sa surface est : {:3.2f} cm² '.format(x*y)) >>> x, y = 2,3 >>> print(‘x + y est égal à {:d} et x/y est égal à {:f}’.format(x + y , x/y)) Le rectangle n°3 a pour largeur 4.260000 cm et pour longueur 7.510000 cm Sa surface est : 31.99 cm² Noter dans le premier exemple, l'opérateur + pour mettre bout à bout plusieurs chaînes de caractères; noter aussi le'\n' pour sauter une ligne et réaliser ainsi l'affichage sur deux lignes. Enfin, les données à insérer sont listées à l'intérieur de format() dans l'ordre où elles apparaissent dans la chaîne. La syntaxe marche aussi en dehors d'un print; par exemple : >>> '{:.2f}'.format(sqrt(2)) , '{:e}'.format(2**52) en python3 ('1.41', '4.503600e+15') # ‹ le résultat est une chaîne de caractères On peut aussi sauvegarder directement sur le disque dur, par exemple un graphique sous forme d'image, un fichier texte Remarque En python2, print ne nécessite pas de parenthèses. On remplace dans les chaînes {} par % - page 6 -