mathématiques et programmation fonctionnellelivrecinq.org/math/ja2013/livretpython.pdf ·...

26
Mathématiques et programmation fonctionnelle Pascal CHAUVIN [email protected] Groupe « Environnements Interactifs et Enseignement des Mathématiques » IREM des Pays de la Loire Journées académiques de l’IREM des Pays de la Loire 17 & 18 avril 2013 Table des matières 1 L’ordinateur : un super-calculateur! 2 2 Un jeu d’enfants... pour voir 3 2.1 La distributivité avec Python ........................................ 3 2.2 La distributivité avec C ........................................... 4 2.3 La distributivité avec Objective Caml ................................... 5 2.4 La distributivité avec Python : le retour ! ................................. 6 3 Nombres décimaux et représentation binaire 7 4 Un type pour représenter les nombres rationnels : « rationnel.py » 8 5 Un type pour les rationnels : quelques exemples 9 5.1 Convergence d’une série ........................................... 9 5.2 Algorithme de Babylone (méthode de H d’Alexandrie) ...................... 11 6 Les listes en Python 12 6.1 Le type « list » de Python3 ........................................ 12 6.2 Fractions continues : le retour ! ....................................... 13 7 La programmation fonctionnelle 14 7.1 Fonctions pures ................................................ 14 7.2 Curryfication .................................................. 14 7.3 Fonction comme argument d’une autre fonction ............................. 15 8 La programmation récursive 17 8.1 Retour sur les boucles ............................................ 17 8.2 Spirale « carrée » ............................................... 18 8.3 Pentagones .................................................. 19 A Le module « outils.py » 20 B Le module « rationnel.py » 24 C Fractions continues : le calcul des réduites 26 1

Upload: others

Post on 01-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

Mathématiques et programmation fonctionnelle

Pascal [email protected]

Groupe « Environnements Interactifs et Enseignement des Mathématiques »IREM des Pays de la Loire

Journées académiques de l’IREM des Pays de la Loire

17 & 18 avril 2013

Table des matières1 L’ordinateur : un super-calculateur ! 2

2 Un jeu d’enfants... pour voir 32.1 La distributivité avec Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 La distributivité avec C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3 La distributivité avec Objective Caml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.4 La distributivité avec Python : le retour ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3 Nombres décimaux et représentation binaire 7

4 Un type pour représenter les nombres rationnels : « rationnel.py » 8

5 Un type pour les rationnels : quelques exemples 95.1 Convergence d’une série . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95.2 Algorithme de Babylone (méthode de Héron d’Alexandrie) . . . . . . . . . . . . . . . . . . . . . . 11

6 Les listes en Python 126.1 Le type « list » de Python3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126.2 Fractions continues : le retour ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

7 La programmation fonctionnelle 147.1 Fonctions pures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147.2 Curryfication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147.3 Fonction comme argument d’une autre fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

8 La programmation récursive 178.1 Retour sur les boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178.2 Spirale « carrée » . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188.3 Pentagones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

A Le module « outils.py » 20

B Le module « rationnel.py » 24

C Fractions continues : le calcul des réduites 26

1

Page 2: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

1 L’ordinateur : un super-calculateur !

$ python3Python 3.2.3 (default , Feb 20 2013, 14:44:27)[GCC 4.7.2] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> print (2**200)1606938044258990275541962092341162602522202993782792835301376>>>$

2

Page 3: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

2 Un jeu d’enfants... pour voir2.1 La distributivité avec Python

Programme 1 – distributivite.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 a = 1.15 b = 5.36 k = 2.278 p r i n t ( k*(a + b) )9 p r i n t ( k*a + k*b )

10 p r i n t ( (k*(a + b)) - (k*a + k*b) )

$ ./ distributivite.py14.08000000000000214.081.7763568394002505e-15$

3

Page 4: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

2.2 La distributivité avec C

Programme 2 – distributivite.c1 #i n c l u d e <stdio.h>23 i n t main( i n t argc , c h a r *argv []) {4 doub l e a = 1.1;5 doub l e b = 5.3;6 doub l e k = 2.2;78 printf("%f\n", k*(a + b) );9 printf("%f\n", k*a + k*b );

10 printf("%f\n", (k*(a + b)) - (k*a + k*b) );11 r e t u r n 0;12 }

Le langage C exige une étape de compilation :

$ gcc distributivite.c$

$ ./a.out14.08000014.0800000.000000$

4

Page 5: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

2.3 La distributivité avec Objective Caml

Programme 3 – distributivite.ml1 #!/usr/bin/env ocaml23 l e t calcul =4 l e t a = 1.1 i n5 l e t b = 5.3 i n6 l e t k = 2.2 i n7 print_float ( k *. (a +. b) );8 print_string "\n";9

10 print_float ( k *. a +. k *. b );11 print_string "\n";1213 print_float ( (k *. (a +. b)) -. (k *. a +. k *. b) );14 print_string "\n"15 ;;1617 calcul ;;

$ ./ distributivite.ml14.0814.081.7763568394e-15$

5

Page 6: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

2.4 La distributivité avec Python : le retour !

Programme 4 – distributivite2.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom decimal impo r t *56 a = Decimal("1.1")7 b = Decimal("5.3")8 k = Decimal("2.2")9

10 p r i n t ( k*(a + b) )1112 p r i n t ( k*a + k*b )1314 p r i n t ( (k*(a + b)) - (k*a + k*b) )

$ ./ distributivite2.py14.0814.080.00$

6

Page 7: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

3 Nombres décimaux et représentation binaireUn nombre décimal x en système décimal :

x = ap ap−1 . . . a2 a1 a0 ,a−1 a−2 a−3 . . . a−q 10

C’est-à-dire :

x =

(p∑

i=0

ai × 10i

)+

(q∑

i=0

a−i × 10−i

)

En système binaire :

x =

p′∑i=0

bi × 2i

+

q′∑i=0

b−i × 2−i

Le nombre « 1,1 » ne s’écrit pas bien en système binaire 1 !

1,110

= 1,000110011 . . .2

Le module « outils.py » présenté plus loin permet quelques conversions :

$ python3>>> from outils import *>>> approx (11, 10, 16, 10)’1 ,1000000000000000 ’>>> approx (11, 10, 16, 2)’1 ,0001100110011001 ’>>> approx (11, 10, 16, 3)’1 ,0022002200220022 ’>>>$

1. Le module « rationnel.py » présenté plus loin offre des outils pour la conversion entre bases de numération.

7

Page 8: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

4 Un type pour représenter les nombres rationnels : « rationnel.py »Le programme ci-dessous exploite deux modules « rationnel.py » et « outils.py », dont le code source

complet est donné en annexe.

Programme 5 – calculsQ.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom rationnel impo r t *56 a = rationnel (1, 2)7 p r i n t (a)89 b = rationnel(-2, -6)

10 p r i n t (b)1112 c = a / rationnel (3)13 p r i n t (c)1415 p r i n t (a + b + c)1617 t = a * rationnel(-1, 7)18 p r i n t (t)1920 u = (t / b) ** 521 p r i n t (u)22 p r i n t (u.approximation ())23 p r i n t (u.approximation (30))24 p r i n t (u.fraction_continue ())

$ ./ calculsQ.py(1) /(2)(1) /(3)(1) /(6)(1)(-243) /(537824)-0 ,0004518206699589-0 ,000451820669958945677396322960[-1, 1, 2212, 3, 1, 2, 1, 4, 1, 2]$

8

Page 9: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

5 Un type pour les rationnels : quelques exemples5.1 Convergence d’une série

Python permet de réaliser aisément la figure suivante, un peu à la manière du langage LOGO. Elle illustre

graphiquement la convergence de la série+∞∑i=1

(14

)i, à l’aide du module natif « turtle » de Python :

Programme 6 – dessin.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom turtle impo r t *56 d e f triangle(cote , code_couleur):7 i f code_couleur == 0: color("green")8 i f code_couleur == 1: color("white")9 i f code_couleur == 2: color("maroon")

10 begin_fill ()11 f o r i i n range (3):12 forward(cote)13 left (120)14 end_fill ()15 color("black")16 f o r i i n range (3):17 forward(cote)18 left (120)1920 d e f figure(n, cote):21 i f n > 0:22 triangle(cote , 0)23 triangle(cote/2, 1)24 forward(cote /2)25 triangle(cote/2, 2)26 backward(cote /2)27 left (60)28 forward(cote /2)29 right (60)30 figure(n - 1, cote /2)3132 figure(6, 512)

En Python, l’indentation du code-source est fondamentale : la profondeur détermine le début et la find’un bloc d’instructions.

9

Page 10: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

On peut aussi mener la recherche naïve de la limite de la série, avec le programme suivant :

Programme 7 – serie.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom rationnel impo r t *56 #7 # quelques "constantes"8 #9 ZERO = rationnel ()

10 UN_QUART = rationnel (1, 4)1112 d e f somme_part(n):13 i f n > 0:14 r e t u r n UN_QUART ** n + somme_part(n-1)15 e l s e :16 r e t u r n ZERO1718 sigma = somme_part (5)19 p r i n t (sigma)20 p r i n t (sigma.approximation ())2122 sigma = somme_part (6)23 p r i n t (sigma)24 p r i n t (sigma.approximation ())

$ ./ serie.py(341) /(1024)0 ,3330078125000000(1365) /(4096)0 ,3332519531250000$

10

Page 11: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

5.2 Algorithme de Babylone (méthode de Héron d’Alexandrie)

Programme 8 – babylone.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom rationnel impo r t *56 #7 # quelques "constantes"8 #9 UN = rationnel (1)

10 DEUX = rationnel (2)1112 d e f Babylone(a, x, n):13 i f n > 0:14 t = Babylone(a, x, n-1)15 r e t u r n (t + (a/t))/DEUX16 e l s e :17 r e t u r n UN1819 a = rationnel (5)20 r = Babylone(a, UN , 8)2122 p r i n t ("Une␣approximation␣de␣la␣racine␣carree␣de", a, "est:")23 p r i n t (r)24 p r i n t (r.approximation (40))25 p r i n t (r.fraction_continue ())

$ ./ babylone.pyUne approximation de la racine carree de (5) est:(316837008400094222150776738483768236006420971486980607)

/(141693817714056513234709965875411919657707794958199867)2 ,2360679774997896964091736687312762354406[2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,

4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,4, 4, 4, 4, 4, 4, 3]

$

On peut démontrer rapidement à la main la périodicité du développement en fraction continue de√5 :

√5 = 2 +

1

4 +1

4 +1

...

Soit en notation abrégée de la période :√5 =

[2 , 4

]

11

Page 12: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

6 Les listes en Python6.1 Le type « list » de Python3

$ python3Python 3.2.3 (default , Feb 20 2013, 14:44:27)[GCC 4.7.2] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> a = ["chevre", "loup", "chou"]>>> a[’chevre ’, ’loup ’, ’chou ’]>>> del a[1]>>> a[’chevre ’, ’chou ’]>>> len(a)2>>> a.append("loup")>>> a[’chevre ’, ’chou ’, ’loup ’]>>> x = a.pop()>>> x’loup ’>>> a[’chevre ’, ’chou ’]>>> a.insert(0, x)>>> a[’loup ’, ’chevre ’, ’chou ’]>>> a.reverse ()>>> a[’chou ’, ’chevre ’, ’loup ’]>>>$

$ python3Python 3.2.3 (default , Feb 20 2013, 14:44:27)[GCC 4.7.2] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> a = [ n*(n+1)/2 for n in range (10) ]>>> a[0.0, 1.0, 3.0, 6.0, 10.0, 15.0, 21.0, 28.0, 36.0, 45.0]>>> a = [ n*(n+1) //2 for n in range (10) ]>>> a[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]>>> b = range(3, 20, 4)>>> print(list(b))[3, 7, 11, 15, 19]>>>$

12

Page 13: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

6.2 Fractions continues : le retour !

Programme 9 – reduite.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom rationnel impo r t *56 d e f reduite(quotients , r):7 i f len(quotients) > 0:8 r e t u r n rationnel(quotients [0]) + rationnel (1) / reduite(quotients [1:], r)9 e l s e :

10 r e t u r n r1112 d e f calcul_reduite(quotients):13 r e t u r n reduite(quotients , rationnel ())1415 d e f tests_unitaires ():16 r = rationnel (4291 , 1329)17 p r i n t (r)18 a = r.fraction_continue ()19 p r i n t (a)20 p r i n t (calcul_reduite(a))2122 i f __name__ == "__main__":23 tests_unitaires ()

$ ./ reduite.py(4291) /(1329)[3, 4, 2, 1, 2, 4, 2, 1, 2](4291) /(1329)$

On consultera en annexe une méthode de calcul faisant appel aux suites définies par récurrence. La méthodevalable pour les nombres rationnels s’étend aux irrationnels quadratiques.

Le module rationnel.py offre déjà dans forme minimale actuelle un bon champ d’investigation en classe,avec une construction déjà accessible aux élèves.

13

Page 14: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

7 La programmation fonctionnelleProgrammation fonctionnelle

On exprime la solution d’un problème en termes d’appels de fonctions. La notion de récursivité (et partant,de fonction) est prépondérante dans ce modèle de programmation.

Programmation impérativeOn procède par modifications successives des états de la machine. Dans ce style de programmation,l’assignation de valeur (affectation) joue un rôle central. L’aspect séquentiel est très important à considérer.

Une précision terminologique, importante pour la classeOn distingue deux sens au mot « fonction », en Mathématiques et en programmation :– en Mathématiques : (...)– en programmation : une fonction est un sous-programme ou routine (c’est-à-dire un programme dans le

programme) que le programme (ou toute routine du programme) pourra invoquer à loisir.Une fonction peut comporter des paramètres, et modifier (selon les règles du langage) son environnementexterne.Un appel de fonction rend un résultat ; une procédure est une fonction ne délivrant aucun résultat, plusexactement le résultat « vide ».

En programmation fonctionnelle, les fonctions sont des types de données, au même titre que les entiers,flottants, chaînes de caractères, types composés ou objets... Une fonction peut par exemple servir de paramètreà une autre fonction.

7.1 Fonctions puresEn programmation, une fonction est dite « fonction pure » lorsque :– elle a pour seul effet de rendre un résultat, i.-e. elle ne modifie pas son environnement (son contexte

d’exécution) ;– entre différentes invocations, la fonction rend le même résultat pour les mêmes arguments.

7.2 Curryfication

Programme 10 – curry.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 d e f ajoute(x):5 r e t u r n lambda y: x + y67 p r i n t ( ajoute (3) (4) )

Programme 11 – curry.ml1 #!/usr/bin/env ocaml23 let ajoute x =4 function y -> x + y;;56 print_int (( ajoute 3) 4);;7 print_string "\n";;

14

Page 15: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

7.3 Fonction comme argument d’une autre fonction

Programme 12 – trinome.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom rationnel impo r t *56 #7 # p(x) = 3*x^2 + 3*x + 2/38 #9 d e f p(x):

10 a = rationnel (3)11 b = rationnel (2, 3)12 r e t u r n a * x ** 2 + a * x + b1314 PI = rationnel (22, 7)1516 u = p(PI)17 p r i n t (u)18 p r i n t (u.approximation (20))1920 d e f image(f, x):21 r e t u r n f(x)2223 v = image(p, PI)24 p r i n t (v)25 p r i n t (v.approximation ())

15

Page 16: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

Deux modèles de calcul de30∑i=1

i :

Programme 13 – somme1.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 somme = 056 f o r i i n range (30 + 1):7 somme = somme + i89 p r i n t (somme)

Programme 14 – somme2.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 d e f somme(n):5 i f n > 0:6 r e t u r n n + somme(n-1)7 e l s e :8 r e t u r n 09

10 p r i n t (somme (30))

Note : le programme somme2.py peut être amélioré par une version « récursive terminale ».

16

Page 17: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

8 La programmation récursive8.1 Retour sur les boucles

Programme 15 – boucle1.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 d e f boucle(n):5 i f n > 0:6 p r i n t (n)7 boucle(n - 1)89 boucle (10)

Programme 16 – boucle2.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 d e f boucle(n):5 i f n > 0:6 boucle(n - 1)7 p r i n t (n)89 boucle (10)

Programme 17 – boucle3.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 d e f boucle(a, n):5 i f n >= a:6 boucle(a, n - 1)7 p r i n t (n)89 boucle(3, 15)

À titre d’exercice, on pourra s’entraîner à concevoir récursivement le dessin suivant :

17

Page 18: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

8.2 Spirale « carrée »On fixe un entier naturel p strictement positif et on recherche la plus longue spirale à côtés entiers, de

longueur inférieure à p, que l’on peut construire sur le modèle ci-dessous :

(on conviendra d’un nombre donné de pixels pour une unité de longueur)

Le programme de dessin de la spirale et la détermination de la longueur de son plus côté donnent lieu àdeux programmes qui illustrent parfaitement la récursivité.

18

Page 19: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

8.3 PentagonesLe programme suivant est un exemple de programmation impérative. La traduction en programmation récur-

sive constitue un excellent exercice.

Programme 18 – penta1.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom math impo r t *5 f rom turtle impo r t *67 d e f pentagone(cote):8 f o r n i n range (5):9 forward(cote)

10 left (72)1112 d e f spirale(nombre_triangles , cote):13 coeff = 0.114 a = cote15 d = coeff * a16 f o r i i n range(nombre_triangles):17 pentagone(a)18 d = coeff * a19 forward(d)20 a_prime = sqrt((a-d)**2 + d**2 -2*(a-d)*d*(1-sqrt (5))/4)21 angle = (180/ pi) * acos( (a_prime **2 + a**2 - 2*a*d)/(2* a_prime *(a-d)) )22 left(angle)23 a = a_prime2425 d e f dessin ():26 up()27 goto (-190,-210)28 down()29 spirale (50, 370)30 up()3132 i f __name__ == "__main__":33 speed("fastest")34 dessin ()3536 p r i n t "Appuyez␣sur␣la␣touche␣de␣VALIDATION␣pour␣terminer."37 touche = str(raw_input ())

19

Page 20: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

A Le module « outils.py »

Programme 19 – outils.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 impo r t sys5 sys.setrecursionlimit (10000)67 #8 # (a, b) dans N x N*9 #

10 d e f reste(a, b):11 i f a < b:12 r e t u r n a13 e l s e :14 r e t u r n reste(a - b, b)1516 #17 # (a, b) dans N x N*18 #19 d e f quotient_entier(a, b):20 i f a < b:21 r e t u r n 022 e l s e :23 r e t u r n 1 + quotient_entier(a - b, b)2425 #26 # (a, b) dans N x N27 #28 d e f pgcd(a, b):29 i f b == 0:30 r e t u r n a31 e l s e :32 r e t u r n pgcd(b, reste(a, b))3334 #35 # (a, b) dans N x N*36 #37 d e f fraction_cont_pos(q, a, b):38 q.append(quotient_entier(a, b))39 i f reste(a, b) > 0:40 r e t u r n fraction_cont_pos(q, b, reste(a, b))41 e l s e :42 r e t u r n q4344 #45 # (a, b) dans Z x N*46 #47 d e f fraction_cont_b_pos(a, b):48 q = []49 i f a < 0:50 q.append(-quotient_entier(-a + b, b))51 e l s e :52 q.append(quotient_entier(a, b))53 r e t u r n q + fraction_cont_pos ([], a - b * q[0], b)[1:]5455 #

20

Page 21: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

56 # (a, b) dans Z x Z*57 #58 d e f fraction_cont(a, b):59 i f b < 0:60 r e t u r n fraction_cont_b_pos(-a, -b)61 e l s e :62 r e t u r n fraction_cont_b_pos(a, b)6364 d e f partie_ent(chiffres , x, base):65 i f x > 0:66 partie_ent(chiffres , quotient_entier(x, base), base)67 chiffres.append(str(reste(x, base)))6869 d e f partie_frac(chiffres , n, a, b, base):70 i f n > 0:71 chiffres.append(str(quotient_entier(a * base , b)))72 partie_frac(chiffres , n - 1, reste(a * base , b), b, base)7374 d e f approx_pos(chiffres , p, q, nombre_chiffres , base):75 t = quotient_entier(p, q)76 i f t == 0:77 chiffres.append("0")78 e l s e :79 partie_ent(chiffres , t, base)80 i f reste(p, q) > 0:81 chiffres.append(",")82 partie_frac(chiffres , nombre_chiffres , reste(p, q), q, base)83 r e t u r n chiffres8485 d e f approx_q_pos(p, q, nombre_chiffres , base):86 chiffres = []87 i f p < 0:88 chiffres.append("-")89 approx_pos(chiffres , -p, q, nombre_chiffres , base)90 e l s e :91 approx_pos(chiffres , p, q, nombre_chiffres , base)92 r e t u r n "".join(chiffres)9394 d e f approx(p, q, nombre_chiffres , base):95 i f q < 0:96 r e t u r n approx_q_pos(-p, -q, nombre_chiffres , base)97 e l s e :98 r e t u r n approx_q_pos(p, q, nombre_chiffres , base)99

100 d e f approximation(p, q, nombre_chiffres =16, base =10):101 #102 # on impose la base <= 10 (pour les digits)103 #104 i f base > 10:105 base = 10106 r e t u r n approx(p, q, nombre_chiffres , base)107108 #109 # tests unitaires110 #111 d e f tests_unitaires ():112 #113 # quelques "constantes" utiles pour les tests114 #

21

Page 22: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

115 BASE_DEUX = 2116 BASE_DIX = 10117 CHIFFRES_DROITE_VIRGULE = 16118119 #120 # approximation du rationnel -4565/21121 #122 p r i n t (approx (-4565, 21, CHIFFRES_DROITE_VIRGULE , BASE_DIX))123124 #125 # approximation du rationnel ( -4565) /(-21)126 #127 p r i n t (approx (4565, -21, CHIFFRES_DROITE_VIRGULE , BASE_DIX))128129 #130 # expression du rationnel 4565/21 comme fraction continue131 #132 p r i n t (fraction_cont (4565 , 21))133134 #135 # expression du rationnel -4565/21 comme fraction continue136 #137 p r i n t (fraction_cont (-4565, 21))138139 #140 # expression du rationnel 2/3 comme fraction continue141 #142 p r i n t (fraction_cont (2, 3))143144 #145 # expression du rationnel -2/3 comme fraction continue146 #147 p r i n t (fraction_cont (2, -3))148149 #150 # approximation du rationnel 11/10151 #152 p r i n t (approx (11, 10, CHIFFRES_DROITE_VIRGULE , BASE_DIX))153154 #155 # approximation du rationnel 11/10 en base 2156 #157 p r i n t (approx (11, 10, CHIFFRES_DROITE_VIRGULE , BASE_DEUX))158159 p r i n t (approx (100, 20, CHIFFRES_DROITE_VIRGULE , BASE_DIX))160 p r i n t (approx (21, 4565, CHIFFRES_DROITE_VIRGULE , BASE_DIX))161 p r i n t (approximation (179, 260, 25))162163 i f __name__ == "__main__":164 tests_unitaires ()

Note : pour des raisons purement techniques, et éviter d’alourdir le code source sans offrir le moindre intérêtmathématique, le choix à été fait de limiter les conversions aux bases inférieures ou égales à 10.

22

Page 23: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

Après l’étude sur le calcul du reste, du quotient... on peut s’affranchir des fonctions reste et quotient_entierdéfinies « à la main », en utilisant celles fournies par le langage. Par exemple :

Programme 20 – outils2.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 impo r t sys5 sys.setrecursionlimit (10000)67 #8 # (a, b) dans N x N*9 #

10 d e f reste(a, b):11 r e t u r n (a % b)1213 #14 # (a, b) dans N x N*15 #16 d e f quotient_entier(a, b):17 r e t u r n (a // b)1819 #20 # (a, b) dans N x N21 #22 d e f pgcd(a, b):23 i f a == 0 and b == 0:24 r e t u r n 125 e l s e :26 w h i l e b > 0:27 r = reste(a, b); a = b; b = r28 r e t u r n a2930 #31 # ... la suite du fichier est identique.32 #

La fonction pgcd a également écrite de façon impérative, avec en plus un test initial, de sorte que :

PGCD (0, 0) = 1 .

23

Page 24: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

B Le module « rationnel.py »

Programme 21 – rationnel.py1 #!/usr/bin/env python32 # -*- coding: utf -8 -*-34 f rom outils impo r t *56 c l a s s rationnel(object):78 d e f __init__(self , num =0, denom =1):9 i f denom == 0:

10 #11 # signaler une erreur ici12 #13 num = 014 denom = 11516 i f denom < 0:17 p = -num18 q = -denom19 e l s e :20 p = num21 q = denom2223 d = pgcd(abs(p), q)2425 self.__num = p // d26 self.__denom = q // d2728 d e f __str__(self):29 i f self.__denom == 1:30 r e t u r n ("("+str(self.__num)+")")3132 r e t u r n ("("+str(self.__num)+")/("+str(self.__denom)+")")3334 d e f __add__(self , autre):35 num = self.__num * autre.__denom + self.__denom * autre.__num36 denom = self.__denom * autre.__denom37 r e t u r n rationnel(num , denom)3839 d e f __neg__(self):40 r e t u r n rationnel(-(self.__num), self.__denom)4142 d e f __sub__(self , autre):43 num = self.__num * autre.__denom - self.__denom * autre.__num44 denom = self.__denom * autre.__denom45 r e t u r n rationnel(num , denom)4647 d e f __mul__(self , autre):48 num = self.__num * autre.__num49 denom = self.__denom * autre.__denom50 r e t u r n rationnel(num , denom)5152 d e f __truediv__(self , autre):53 i f autre.__num == 0:54 #55 # signaler une erreur ici

24

Page 25: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

56 #57 r e t u r n rationnel ()58 num = self.__num * autre.__denom59 denom = self.__denom * autre.__num60 r e t u r n rationnel(num , denom)6162 d e f __pow__(self , exposant):63 i f self.__num == 0 and exposant == 0:64 #65 # signaler une erreur ici66 #67 r e t u r n rationnel ()6869 i f exposant < 0:70 r e t u r n rationnel(self.__denom ** (-exposant), self.__num ** (-exposant))71 e l s e :72 r e t u r n rationnel(self.__num ** exposant , self.__denom ** exposant)7374 d e f approximation(self , chiffres_apres_virgule =16):75 r e t u r n approximation(self.__num , self.__denom , chiffres_apres_virgule)7677 d e f fraction_continue(self):78 r e t u r n fraction_cont(self.__num , self.__denom)7980 d e f tests_unitaires ():81 a = rationnel (28, -561)82 p r i n t (a)83 p r i n t (a.approximation ())84 p r i n t (a.fraction_continue ())8586 b = rationnel (3)87 p r i n t (b)8889 t = a + b90 p r i n t (t)9192 t = a - b93 p r i n t (t)9495 t = a * b96 p r i n t (t)9798 t = a / b99 p r i n t (t)

100 p r i n t (t.approximation (100))101102 t = a ** 3103 p r i n t (t)104 p r i n t (t.approximation (100))105106 i f __name__ == "__main__":107 tests_unitaires ()

25

Page 26: Mathématiques et programmation fonctionnellelivrecinq.org/math/JA2013/livretpython.pdf · 2016-02-27 · Programmation fonctionnelle On exprime la solution d’un problème en termes

C Fractions continues : le calcul des réduitesL’intérêt historique des fractions continues réside dans l’approximation des nombres réels par des rationnels.

On suppose établie une écriture d’un nombre réel x sous la forme des quotients partiels (entiers) (ai)i∈N :

x = [a0 , a1 , a2 , a3 , . . . , an , . . . ]

Cette écriture est finie quand x est rationnel, périodique si x est un nombre irrationnel quadratique, infiniepour les nombres transcendants.

On peut procéder au calcul des réduites successives par l’« algorithme des fractions continues » ci-dessous.

On pose :

∀n ∈ N,

{pn+1 = anpn + pn−1

qn+1 = anqn + qn−1

avec les conventions : p−1 = 0 , p0 = 1 et q−1 = 1 , q0 = 0 .

La suite des réduites successives(pnqn

)n∈N

converge vers x, avec : limn→+∞

qn = +∞.

D’un point de vue purement mathématique, on peut agrémenter les deux suites (pn)n∈N et (pn)n∈N d’unetroisième suite des quotients incomplets (an)n∈N, définie par :

∀n ∈ N, an =

⌊−qn−1x− pn−1

qnx− pn

avec la réserve qnx− pn 6= 0 (ce qui est le cas lorsque x est irrationnel).

La suite (an)n∈N nécessite dans le calcul de chaque terme l’emploi du réel x avant d’évaluer la partieentière du quotient, ce qui pose la question du choix convenable d’une valeur approchée de x pour le calculeffectif restreint au type « rationnel ».

Exemple de calcul des premiers quotients incomplets pour√11 :

i −1 0 1 2 3 4 . . .

pi 0 1 3 10

qi 1 0 1 3

ai • 3 3 6

26