Informatique CPGE 1 re année Clemenceau TP 3 : Fonctions et π-treries Tous les programmes dont ce TP fait référence sont sauvegardés dans le répertoire suivant : Ressources pedagogiques\ informatique \ Eleves \MPSI2\TP2 Objectifs structures de contrôle, fonctions. 1 Utilisation du debugger En appelant la fontion f1 avec 2 en argument, on appelle la fonction f2 avec 2 + 1 = 3 en argument. Pour afficher (a,b, x), Python lit les valeurs de a et de b dans l espace de noms local de la fonction f2 et la valeur de l argument de f2, elle aussi mémorisée dans l espace de noms local de la fonction f2. Ensuite, pour afficher (a,b) dans la fonction f1, Python lit la valeur de a dans l espace de noms local de la fonction f1, mais ne trouve pas de valeur pour b, ni dans l espace de noms local de f1, ni dans l espace global du programme. Il indique ce dysfonctionnement en affichant l erreur suivante : NameError : global name b is not defined. Pour debugger ce programme, il suffit d indiquer une valeur pour b, soit dans la fonction f1 avant de demander l affichage de (a,b), soit dans le programme principal avant l appel de f1(2). Remarque 1. Python cherche la valeur d une variable d abord dans l espace de noms local où cette variable est appelée, puis dans les espaces de noms encapsulants. 2 Approximation de π import math as m def u_n(n) : renvoie le nieme terme de la suite Un un = 0 un += 1 / ( ( k + 1) ** 2) return (un) def pi1 (n) : renvoie une estimation de pi a partir de Un return (m. sqrt (6 * u_n(n ) ) ) def v_n (n) : renvoie le nieme terme de la suite Vn vn = 0 vn += 1 / ( ( k + 1) ** 6) return ( vn ) def pi2 (n) : renvoie une estimation de pi a partir de Vn return (pow(945 * v_n (n), 1 / 6 ) ) def w_n(n) : renvoie l e nieme terme de l a s u i te Wn wn = 0 wn += (( 1) ** k ) / (2 * k + 1) return (wn) def pi3 (n) : renvoie une estimation de pi a partir de Wn return (4 * w_n(n ) )
def f a c t (n) : renvoie f a c t o r i e l l e (n) res = 1 for i in range ( 1, n + 1) : res *= i return ( res ) def r_n (n) : renvoie le nieme terme de la suite Rn rn = 0 rn += ( f a c t (4 * k ) * (1103 + 26390 * k ) ) / ( ( f a c t ( k ) ** 4) * 396 ** (4 * k ) ) return ( rn ) def pi4 (n) : renvoie une estimation de pi a partir de Rn return (1 / ( (m. sqrt ( 8 ) / 9801) * r_n (n ) ) ) def decimales_ ( val ) : renvoie l e nombre de decimales identiques a la valeur de pi fournie par l e module math n, i = 0, 2 # n est le compteur de decimales. # i demarre a 2 car l e s deux premiers caracteres sont 3 et. correct = True while correct and i < min( len ( str ( val ) ), len ( str (m. pi ) ) ) : # Si toutes l e s decimales correspondent, i l faut arreter la boucle quand on a # termine de scruter l e s c h i f f r e s du nombre comportant le moins de decimales n += 1 i f str ( val ) [ i ]!= str (m. pi ) [ i ] : correct = False n = 1 i += 1 return (n) # retourne l e nombre de decimales c o r r e c t e s apres la virgule def affichage ( fonction, valeurs ) : affiche la valeur d une fonction d approximation de pi pour une l i s t e de valeurs # On a donc i c i une fonction de fonction for val in valeurs : approx = fonction ( val ) print ( str ( fonction ). s p l i t ( ) [ 1 ], (, float ( val ), ) =, approx, \ soit, decimales_ ( approx ), decimales. ) # s t r ( fonction ). s p l i t ( ) [ 1 ] permet d i s o l e r l e nom de la fonction # a partir de sa declaration dans la console # >>> pi1 ( par exemple ) renvoie <function pi1 at 0x02C8AD68> # ce renvoi est converti en chaine de caracteres ( s t r ), puis est # decompose en l i s t e de mots ( methode s p l i t ( ) ) # i l faut alors prendre le deuxieme mot, s o i t a l index 1 ## Etude des s u i t e s Un, Vn, Wn et Rn ###################################### valeurs_1 = [10 ** i for i in range ( 1, 7 ) ] valeurs_2 = range ( 6 ) fonctions_pi = [ [ pi1, Un, valeurs_1 ], [ pi2, Vn, valeurs_1 ], \ [ pi3, Wn, valeurs_1 ], [ pi4, Rn, valeurs_2 ] ] # On rentre i c i une l i s t e de l i s t e s contenant la fonction, l e nom # de la suite qui lui correspond, et l e s valeurs a evaluer for f c t in fonctions_pi : print ( Pour l a s u i te, f c t [ 1 ] ) affichage ( f c t [ 0 ], f c t [ 2 ] ) 1. Approximations de π à l aide de la suite u n : Approximation de π 3.0574815067075627 3.1321704261963457 3.1406390095181815 Nombre de décimales 0 1 2 Approximation de π 3.1414971734948915 3.1415831044219478 3.141591698661464 Nombre de décimales 3 4 5
2. Approximations de π à l aide de la suite v n : Approximation de π 3.1415921466013486 3.141592653580239 3.1415926535897887 Nombre de décimales 6 11 13 Approximation de π 3.1415926535897887 3.1415926535897887 3.1415926535897887 Nombre de décimales 13 13 13 3. Approximations de π à l aide de la suite w n : Approximation de π 3.232315809405594 3.1514934010709914 3.1425916543395442 Nombre de décimales 0 1 2 Approximation de π 3.1416926435905346 3.1416026534897203 3.1415936535887745 Nombre de décimales 3 3 5 4. Approximations de π à l aide de la suite r n : n = 0 n = 1 n = 2 Approximation de π 3.1415927300133055 3.1415926535897936 3.141592653589793 Nombre de décimales 6 15 15 n = 3 n = 4 n = 5 Approximation de π 3.141592653589793 3.141592653589793 3.141592653589793 Nombre de décimales 15 15 15 def pi2bis (n) : renvoie pi a partir de Un en effectuant les operations dans l ordre inverse un = 0 un += 1 / ( ( ( n k ) + 1) ** 6) return (pow(945 * un, 1 / 6 ) ) valeurs_3 = [10, 1000, int (1e5 ), 10 ** 7] # 1e5 est un flottant, i l faut donc le convertir en entier, ou plutot u t i l i s e r # 10 ** 5 fonctions_comp = [ [ pi2, Vn normal, valeurs_3 ], \ [ pi2bis, Vn inverse, valeurs_3 ] ] for f c t in fonctions_comp : print ( Pour l a s u i te, f c t [ 1 ] ) affichage ( f c t [ 0 ], f c t [ 2 ] ) Ordre n = 10 n = 1000 n = 10 5 n = 10 7 u n Normal 3.0574815067075627 3.1406390095181815 3.1415831044219478 3.1415925580959123 Inverse 3.0574815067075627 3.1406390095181798 3.1415831044219322 3.1415925580968405 π Normal 0 2 4 6 Inverse 0 2 4 6 En fait, la suite u n ne permet pas de mettre en évidence le phénomène. La suite v n est plus intéressante. On a pu voir précédemment qu elle donnait une estimation de π qui ne varie plus à partir d une certaine valeur de n. Voici le même tableau que précédemment, mais avec la fonction pi2().
Ordre n = 10 n = 1000 n = 10 5 n = 10 7 v n Normal 3.1415921466013486 3.1415926535897887 3.1415926535897887 3.1415926535897887 Inverse 3.141592146601349 3.141592653589793 3.141592653589793 3.141592653589793 π Normal 6 13 13 13 Inverse 6 15 15 15 Les différences observées viennent des erreurs d arrondis. Quand on calcule la somme avec les dénominateurs dans l ordre décroissant, on va pouvoir prendre en compte les valeurs les plus petites auxquelles on va ajouter les valeurs les plus grandes. Le résultat sera malgré tout influencé par ces petites valeurs. Alors que si on calcule la somme dans le sens des dénominateurs croissants, une fois que la somme est exprimée avec 16 décimales, les petites valeurs suivantes ne seront pas prises en compte. Voilà pourquoi la valeur de l estimation de π par la fonction pi2(n) reste constante à partir d une certaine valeur de n. 3 Calculs d aires et de volumes # Import du module math import math as m # Perimetre du c e r c l e def perim_cercle ( r ) : renvoie le perimetre du cercle de rayon r return (m. pi * 2 * r ) # Aire du disque def surf_disque ( r ) : renvoie l a i r e du cercle de rayon r return (m. pi * pow( r, 2 ) ) # Volume du cylindre de revolution def vol_cyl_rev ( r, h) : renvoie le volume du cylindre de revolution de rayon r et de hauteur h return ( surf_disque ( r ) * h) # Aire du cylindre de revolution def surf_cyl_rev ( r, h) : renvoie l aire du cylindre de revolution de rayon r et de hauteur h return (2 * math. pi * r * h + 2 * math. pi * r ** 2) # Volume d une boule def vol_sphere ( r ) : renvoie l e volume d une boule de rayon r return (2 * vol_cyl_rev ( r, 2 * r ) / 3) # Surface d une boule def surf_sphere ( r ) : renvoie l a surface d une boule de rayon r return (2 * surf_cyl_rev ( r, 2 * r ) / 3)
4 Fonctions sur les chaînes de caractère from poemepi import poeme print (poeme) # On ne cherche que la mantisse, on va donc modifier le premier vers poeme[0]= " j aime a f a i r e apprendre un nombre u t i l e aux sages! " def pi ( ) : pi= 3. for vers in poeme : liste_mots = vers. s p l i t ( ) # On decompose le vers en l i s t e de mots for i in range ( len ( liste_mots ) ) : mots = liste_mots [ i ] i f mots. isalpha ( ) : # s i le mot est compose de caractere alphanumerique dec = len ( mots ) # On remplace l e s mots de 10 l e t t r e par l information 0 else : dec = 0 for l e t t r e in mots : i f l e t t r e. isalpha ( ) : dec += 1 e l i f dec!= 0 : dec = 0 i f dec!= 0 : return ( pi ) # Evidemment, pour simplifier, on pouvait entrer le poeme en supprimant la # ponctuation, mais c e s t moins agreable a l i r e... 5 Suite de Conway La suite de John Horton Conway (Angleterre, né en 1937) est une suite dite audioactive qu il a publiée en 1986. Elle est également connue sous le nom anglais de Look and Say («regarder et dire»). Dans cette suite, un terme se détermine en annonçant les chiffres formant le terme précédent. # Suite de Conway def terme_suivant ( terme ) : renvoie l e terme qui s u i t l e terme indique en argument dans l a s u i te de Conway r e s u l t a t = dernier = terme [ 0 ] nombre = 1 for courant in terme [ 1 : ] : i f courant == dernier : nombre += 1 else : r e s u l t a t += str (nombre) + dernier dernier = courant nombre = 1 return ( resultat + str (nombre) + dernier ) terme = 1 for i in range (20) : print ( i, terme ) terme = terme_suivant ( terme )