PTSI2 – 2016/2017 – Info Lycée La Martinière-Monplaisir – Lyon
Ch 4. Fonctions.
1 Introduction, premiers exemples
Nous avons déjà rencontré, en Python, diverses fonctions pré-programmées, comme cos,sqrt dans la
bibliothèque math, mais aussi len,int,print... Nous pouvons aussi créer nos propres fonctions.
Les fonctions sont très importantes pour plusieurs raisons :
Il peut arriver qu’une même séquence d’instructions doive être utilisée plusieurs fois dans notre
programme. On souhaite ne pas avoir à la récrire systématiquement.
Devant un problème complexe, le plus efficace est souvent de le décomposer en plusieurs sous-
problèmes plus simples que l’on traite séparément à l’aide d’un algorithme chacun. Autrement
dit, on crée plusieurs fonctions auxiliaires et une fonction principale qui se sert de ces autres
fonctions pour répondre au problème.
Exemple : Au chapitre précédent, nous avons écrit un algorithme pour calculer la factorielle d’un
nombre donné. Si on veut calculer 100
32 sans utiliser de fonction, sachant que 100
32 =100!
32!(100 32)!,
on est obligé d’écrire :
n = 100
k = 32
# calcul de 100!
p1 = 1
for i in range(2 , n + 1):
p1 = p1 * i
# calcul de 32!
p2 = 1
for i in range(2 , k + 1):
p2 = p2 * i
# calcul de (100-32)!
p3 = 1
for i in range(2 , n - k + 1):
p3 = p3 * i
print(p1 / (p2 * p3))
C’est long !
1
Il est plus efficace de créer une fonction qui calcule n!pour un argument ndonné. On écrira donc, dans
un fichier factorielle.py :
def facto(n):
p=1
for i in range(2 , n + 1):
p = p * i # Attention à bien indenter !
return(p)
# Remarque : la fonction marche parfaitement pour n = 0 et n = 1
Ici, la dernière ligne de la fonction est return(resultat), car on veut que la fonction renvoie un
résultat (on dit aussi "retourner" un résultat).
Pour le calcul de 100
32 , on écrit dans notre fichier :
print( facto(100) / ( facto(32) * facto(100 - 32) ) )
Exercice : La fonction facto étant définie comme ci-dessus, définir une fonction binomial qui prend
deux arguments, net k, et qui retourne n
k.
Amélioration :
2
2 Caractéristiques générales d’une fonction
Voici la syntaxe générale d’une fonction en Python :
def nom_de_la_fonction(arguments):
bloc d’instructions
Bien noter l’indentation du bloc d’instructions.
2.a Arguments : un seul, plusieurs, aucun...
Première ligne pour un argument :
def fonction(arg):
Pour plusieurs arguments, on les sépare par des virgules. Par exemple :
def fonction(arg1, arg2, arg3, arg4, arg5):
On peut très bien n’avoir aucun argument ; dans ce cas on écrit :
def fonction():
Cela peut paraître étrange au premier abord, mais il y a de nombreuses situations où une fonction sans
argument est adaptée. Par exemple, s’il l’on veut simuler un lancer de deux dés, à l’aide de la fonction
randint de la bibliothèque random :randint(a,b) renvoie un entier aléatoire entre aet bcompris.
import random as r
def des():
return( r.randint(1,6) , r.randint(1,6) ) # Plusieurs résultats renvoyés
Pour simuler 10 lancers, on complète le programme :
for i in range(10):
print(des())
# pour un joli affichage : print(’Lancer no’ + str(i+1) + ’ : ’ + str(des()) )
2.b Utilisation d’une fonction comportant un return
La plupart des fonctions que nous écrirons se termineront par un return : elles permettent de "ren-
voyer" quelque chose.
Remarque :return interrompt automatiquement le flux d’exécution : on "sort" de la fonction. Par
exemple, dans le programme suivant, la ligne n=n-2est inutile car elle ne sera jamais exécutée :
def f(n):
n=n+1
return(n)
n=n-2
3
Reprenons l’exemple de la factorielle :
def facto(n):
p=1
for i in range(2 , n + 1):
p=p*i
return(p)
Si on exécute seulement ces lignes, l’interpréteur ne répond rien. Le compilateur se contente de vérifier
que la syntaxe est bonne. Il faut faire un appel à la fonction pour la tester ou l’utiliser.
Tests :
Par exemple si on veut voir la valeur de 10! dans l’interpréteur (le "shell"), on a deux méthodes :
écrire, après l’exécution, dans le shell :
Python shell
>>> facto(10)
3628800
écrire, avant l’exécution, dans le fichier (le "script") (après la définition de la fonction) :
print(facto(10))
Cette deuxième méthode est à privilégier. Il suffira de mettre cette ligne en commentaire si on
ne veut plus voir le test. On peut copier-coller le résultat dans le fichier, en commentaire :
# Résultat : 3628800
Utilisations :
Si on écrit seulement l’instruction facto(10) ou print(facto(10)) quelque part dans notre fichier,
le calcul est effectué, le résultat éventuellement affiché, mais ce résultat n’est stocké nulle part et il est
immédiatement "perdu". Il faut soit intégrer directement facto(10) dans un autre calcul, soit stocker
la valeur de 10! en faisant une affectation :
print( facto(10) % 2 == 0 ) # affichage du booléen disant si 10! est pair ou non
N = facto(10!) # affectation d’une variable N pour utiliser la valeur 10! plus tard
print( N % 2 == 0 ) # utilisation de la variable
Nous avons vu avec la fonction des que l’on peut mettre dans le return plusieurs objets séparés par
des virgules 1. Voici un autre exemple : la fonction fqui à xassocie (x+ 1, x2):
def f(x):
return( -x + 1 , x**2 )
1. On verra bientôt que cela revient à renvoyer ce qu’on appelle un tuple.
4
Pour récupérer les deux résultats, une méthode possible et très efficace est la suivante :
Python shell
>>> u, v = f(15)
>>> u
-14
>>> v
225
Autre solution : faire une seule affectation t = f(15) ; les deux quantités sont alors t[0] et t[1].
Une fonction peut aussi ne rien renvoyer du tout... Précisons cela :
2.c Effets de bord
Les fonctions que nous avons créées jusqu’à présent étaient sans effet de bord, c’est-à-dire qu’elles
renvoient un résultat utilisable (en l’affectant par exemple à une variable).
Voici une autre version de la fonction facto, en remplaçant le return par print 2:
def factobis(n):
p=1
for i in range(2 , n + 1):
p=p*i
print(p) # à la place du return
L’inconvénient est qu’on ne peut pas utiliser le résultat ! Testons :
Python shell
>>> facto(5)
120
>>> a = facto(5)
>>> a
120
>>> type(a)
<class ’int’>
>>> 2 * a
240
Python shell
>>> factobis(5)
120 # Pas de différence pour l’instant...
>>> b = factobis(5)
120 # Bizarre : pas le même comportement que facto...
>>> b # ça ne répond rien !!
>>> type(b)
<class ’NoneType’>
>>> 2 * b
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
2*b
TypeError: unsupported operand type(s) for *: ’int’ and ’NoneType’
2. S’il n’y a pas de return, la fonction renvoie quand même quelque chose : une valeur spéciale appelée None
5
1 / 11 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !