Les fonctions
L'un des concepts les plus importants en programmation est celui de fonction. Les fonctions permettent en effet de décomposer un programme complexe en une série de sous-programmes plus simples, lesquels peuvent à leur tour être décomposés en fragments plus petits, et ainsi de suite.
Méthode : Spécification
Spécifier une fonction, c'est
choisir un identificateur pour la nommer ;
préciser le nombre et le type de ses paramètres, et les nommer ;
indiquer les conditions d'utilisation (CU) que doivent vérifier les paramètres lors d'un appel à la fonction ;
indiquer le type de la valeur qu'elle renvoie ;
indiquer quelle est la relation entre la valeur renvoyée et les paramètres qui lui sont passés.
Exemple : La fonction supérieur du module carte
La fonction du module Cartes
qui permet de comparer les hauteurs des cartes situées au sommet de deux tas est nommée superieur
, elle prend deux paramètres de type Cartes.numero_tas
, et renvoie une valeur de type bool
. Elle possède aussi une contrainte d'utilisation qui exige qu'aucun des deux tas passés en paramètre ne soit vide.
On peut écrire les spécifications :
superieur : numero_tas, numero_tas → bool
n ,p→vrai si la carte au sommet du tas n est de plus haute valeur que celle au sommet de p
→faux sinon
CU : les tas n et p ne doivent pas être vides.
Méthode : Déclaration de fonction en Python
def nomDeLaFonction(liste de paramètres):
... bloc d'instructions
...
return ...
Il est à noter l'importance de l'indentation en Python.
L'instruction return
définit ce que doit être la valeur « renvoyée » par la fonction.
>>> def f(v):
... return 3*v+1
...
>>> f(5)
16
Exemple de fonction retournant un nombre multiplié par 3 auquel on ajoute 1
Définition : La notion de prédicat
Une fonction ayant comme une valeur retournée de type booléen est appelée prédicat.
Soit à écrire le prédicat rouge
dont la spécification est
rouge : numero_tas →bool
n →vrai si la carte au sommet du tas n est rouge
→faux sinon
CU : le tas n\ne doit pas être vide.
def rouge(n):
>>> sommet_coeur(n) or sommet_carreau(n)
Comme on peut le constater, en Python il n'est pas nécessaire au programmeur de préciser le type des paramètres et celui de la valeur renvoyée, contrairement au cas de langages comme C, Ada ou Pascal.
C'est le langage qui calcule ces types.
Exemple : Fonction sans paramètre
Il est possible de définir des fonctions sans paramètre.
La fonction sans paramètre constante égale à 1
un : unit → int
Ø→1
et tout appel à cette fonction produit l'entier 1.
>>> def un():
... return 1
...
>>> un()
1
Définition : Fonction à un paramètre
Nous pouvons transmettre une information à la fonction. Cette information que nous voulons transmettre à la fonction au moment même où nous l'appelons s'appelle un argument.
Dans l'exemple, nous allons compter les cartes d'un tas de cartes et donc utiliser une fonction qui va nous retourner le nombre de cartes du tas.
Définition : Fonction à plusieurs paramètres
Comme la fonction superieur
, une fonction peut avoir plus d'un paramètre. Ces paramètres peuvent être de types identiques ou non. Un appel à une fonction à plusieurs paramètres doit se faire avec le bon nombre et le bon type des paramètres.
La fonction puissance
qui à partir de deux entiers a
et n
renvoie l'entier an
puissance1 : int * int →int
{a,n} →a^n
>>> def puissance1(a,n):
... p=1
... for i in range (1,n+1):
... p=p*a
... return p
...
>>> puissance1(2,10)
1024
>>>
Un appel à une fonction à plusieurs paramètres doit se faire avec le bon nombre et le bon type des paramètres.
>>> puissance1(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: puissance1() missing 1 required positional argument: 'n'
l'interprète signale une erreur dans l'appel à la fonction puissance1
parce qu'un seul entier a été passé en paramètre au lieu des deux attendus,
Complément : Les modules
Il existe un grand nombre de modules pré-programmés qui sont fournis d'office avec Python. Vous pouvez en trouver d'autres chez divers fournisseurs. Souvent on essaie de regrouper dans un même module des ensembles de fonctions apparentées, que l'on appelle des bibliothèques.
Par exemple, le module Carte
s
fournit les fonctions suivantes: i
nit_tas
, deplacer_sommet, couleur_sommet, sommet_trefle,sommet_carreau, sommet_coeur, sommet_pique, superieur, tas_vide, tas_non_vide
.
La construction import permet d'importer un module et de fournir accès à son contenu. L'importation d'un module peut se faire de deux manière. La première solution est de désigner le module que l'on souhaite utiliser, son contenu est alors utilisable de manière «scopée», c'est-à-dire en préfixant le nom de la fonctionnalité du nom du module.
>>> import Cartes
>>> Cartes.init_tas(1, 'C')
La seconde solution repose sur la construction from import où l'on identifie la ou les fonctionnalités que l'on souhaite importer d'un module. Dans le cas d'un import de plusieurs fonctionnalités, les noms sont séparés par des virgules. L'utilisation se fait alors sans préfixer par le nom de module («non scopé»).
>>> from Cartes import init_tas
>>> init_tas(1, 'C')
Enfin, il est possible d'importer, avec cette seconde approche, tous les éléments d'un module en utilisant la notation *
. Attention, avec cette dernière forme car il y a pollution du namespace (espace de noms) global: deux imports consécutifs peuvent charger deux définitions d'une même fonction. La seconde masquera la première.
>>> from Cartes import *
>>> deplacer_sommet(1, 2)
Exemple :
from Cartes import *
Permet de charger le module carte nécessaire dans tout ce cours.
Méthode : Intérêt des fonctions
reflet de l'analyse du problème
modularité
lisibilité des programmes
factorisation du code
Complément : Suivre une trace de programme
Dans vos fonctions, il peut être utile de comprendre l'évolution des valeurs de variables. Il faut pour cela utiliser le mode débuggueur.