Accueil
Fonctions (et procédures)
Objectifs du TD : apprendre à décomposer et à réutiliser le code en écrivant des fonctions
Vous avez utilisé à plusieurs reprises des fonctions comme
la fonction print ou la fonction input. Ces
fonctions sont des fonctions prédéfinies du langage. Comme en
mathématiques, une fonction a des arguments (appelés
paramètres en informatique), et effectue des calculs.
Python possède des fonctions prédéfinies dans le coeur du langage, mais aussi des fonctions qui sont définies dans des
modules spécifiques qu'il faut importer, comme la fonction randint du module random qui sert à tirer un nombre entier aléatoire.
Dans ce TD, vous allez écrire vos propres fonctions. Cela est très utile pour décomposer les problèmse et répéter plusieurs fois le même traitement à des données différentes.
EXERCICES DE COURS
1. Les fonctions
L'utilisation des fonctions dans un langage de programmation est similaire à celle des fonctions en mathématiques: il y a la définition de la fonction et l'utilisation de la fonction.
Par exemple, on peut définir une fonction affine f(a,b,x)= a*x+b et l'utiliser pour calculer
3*f(2,3,8)+1.
Définition d'une fonction
La syntaxe de la définition d'une fonction est la suivante :
def
nom_de_la_fonction(
parametre_1,...,parametre_n) :
code_de_la_fonction
return
valeur_calculée
où
- parametre_i sont les paramètres
de la fonction. Il peut éventuellement ne pas y avoir de
paramètres,
- code_de_la_fonction est un bloc d'instructions (i.e. des instructions placées avec la meme indentation),
- return est un mot du langage Python qui signifie que l'expression qui suit le return sera renvoyée lors de l'utilisation de la fonction (i.e. c'est la valeur calculée par la fonction).
L'interprèteur Python lit le programme instructions après
instructions. Quand il tombe sur le mot clé def il
stocke en mémoire la définition de la fonction jusqu'à sa dernière ligne.
Quand il trouve une instruction contenant le nom de la fonction qui a été définie, il utilise la définition de la fonction, on dit qu'il effectue un appel de fonction.
Voici par exemple la définition d'une fonction affine et plusieurs utilisations de cette fonction.
# exemple d'une fonction affine
def affine(a,b,x) :
return a*x+b
# fin de la fonction
# début du programme
# deux exemples d'appels
r = affine(3,4,8))
print(r+2*affine(1,1,1))
# boucle pour afficher tous les couples entre 1 et 10
# de la fonction affine 3x+5
print("points de la fonctions affine 3x+5")
x = 1
while x <=10 :
print(x,affine(3,5,x))
x=x+1
Explications : appel de fonction
Quand l'interprète Python exécute la ligne r=affine(3,4,8), il fait un
appel de fonction :
- il vérifie que la fonction
affine existe et il vérifie qu'on lui a fourni
le bon nombre de paramètres (3 ici),
- il substitue les paramètres de la fonction (a,b et x) avec leur
valeur d'appel (3,4 et 8). Plus précisément,
(a,b,x) sont les paramètres
formels de la fonction affine et
(3,4,8) sont les paramètres effectifs de
l'appel de la fonction.
- il exécute le code de la fonction jusqu'au return
- il renvoie le calcul (ici 3*8+4). Puisqu'on a écrit r=affine(3,4,8) le résultat du calcul est mis dans la variable r
De la même façon, la boucle while effectue 10 appels de la fonction affine avec a et b fixés à 3 et 5, et avec x qui varie de 1 à 10.
A RESPECTER
Les programmes que vous allez écrire à partir de maintenant vont être de
plus en plus complexes. Afin de ne pas introduire des erreurs de programmation,
vous devez impérativement respecter la structure suivante pour
vos fichiers .py (les points suivis de *
sont facultatifs):
- Commentaire décrivant les fonctionnalités du programme
- Import nécessaires *
- Déclaration des fonctions
- Programme principal avec :
- Définition de constantes
- Définition des variables du programme, lecture de données (via la fonction input)
- Instructions du programme principal avec appel des fonctions
- Affichage des résultats (via la fonction print)
Ne pas respecter cette structure sera sanctionné dans les évaluations.
Exercices
- Utiliser la fonction affine dans un programme de conversion entre degré Celsius et degré Fahrenheit sachant que : T(°C) = (T(°F) - 32)/1.8 et T(°F) = T(°C)×1.8 + 32 . Le programme demande la température et demande l'unité (Celsius ou Fahrenheit) et il affiche la valeur convertie. Pour vérifier vos résultats, vous pouvez aller sur http://www.le-convertisseur.com/conversion-temperature.html
- Définir les fonctions perimetre et aire qui renvoient
le perimétre et l'aire d'un cercle dont le rayon est donné en paramétre. Utilisez ces fonctions dans un programme qui demande à l'utilisateur
un rayon initial rayonInit et un nombre d'itérations.
A l'itération i, le programme
affiche le périmétre et l'aire du cercle de rayon rayonInit + 100*i.
Indications :
- la constante PI se trouve dans le module math. Pour l'utiliser, il faut importer le module au début de votre programme
import math
et ensuite écrire math.pi
.
- le carré d'un nombre x s'écrit
x**2
Rayon initial ? 124
nombre d'itérations ? 5
Rayon : 124.0 , perimétre : 779.1149780902687 , aire : 48305.12864159666
Rayon : 224.0 , perimétre : 1407.4335088082273 , aire : 157632.55298652145
Rayon : 324.0 , perimétre : 2035.7520395261859 , aire : 329791.83040324214
Rayon : 424.0 , perimétre : 2664.0705702441446 , aire : 564782.9608917587
Rayon : 524.0 , perimétre : 3292.3891009621034 , aire : 862605.944452071
Une fonction doit retourner une valeur pour tous les cas
possibles de son exécution. Sauver l'exemple suivant dans un fichier et
exécutez-le pour val=50 et val=-1. Que se passe-t-il ?
def bizare(v):
if v>=30:
print("cas 1")
return 30
else :
if v>=0:
print("cas 2")
return 0
else :
print("cas 3")
# programme principal
val = int(input("un entier "))
v = bizare(val)
print(v*3)
2. Les procédures
Les fonctions que vous avez écrites ci-dessus font un calcul et renvoient un résultat. Elles sont utiles pour structurer le code en décomposant les étapes de calcul; ceci est indispensable quand on écrit des gros programmes.
Il peut aussi être utile de structurer le code en écrivant des procédures qui font des actions mais ne renvoient pas de résultat. La différence est simplement qu'elles ne se terminent pas par return.
- Ecrire une procédure dessinePolygone qui dessine un polygone régulier. Les paramètres sont le nombre de cotés, la longueur d'un coté, le point en bas à gauche du polygone, la couleur du polygone. Utilisez cette procédure dans un programme qui affiche un carré bleu et un octogone rouge.
- Une fonction ou procédure peut appeler une autre fonction ou procédure. Par exemple,
voici un code qui définit la procédure dessineCarre :
# un carré est un polygone particulier : la procédure "dessineCarre" appelle
# la procédure "dessinePolygone"
# dessine un carré de largeur "cote", de couleur "couleur" dont le point
# en bas à gauche est en (x,y)
def dessineCarre(cote,x,y,couleur):
dessinePolygone(4,cote,x,y,couleur)
Définissez de la même façon les fonctions dessineTriangle et
dessineCercle. Tester vos procédures en dessinant
quelques carrés, cercles et triangles.
- Reprenez votre code de la table de multiplication générale
(i.e. où l'on peut dire quelle table on veut réviser et
jusqu'à quel rang) et transformez-le en une procédure. Ecrivez
un code qui fait une boucle où l'on demande à
l'utilisateur quelle table il veut réviser et jusqu'à quel
rang, puis qui demande s'il veut continuer. Exemple de trace
d'exécution :
Révision des tables de multiplication
Quelle table voulez-vous réviser ? 3
Jusqu'à quel rang ? 4
***************************
révision de la table de 3 jusqu'à 4
1 fois 3 : 3
2 fois 3 : 6
3 fois 3 : 9
4 fois 3 : 12
***************************
Encore ? (o/n) o
Quelle table voulez-vous réviser ? 2
Jusqu'à quel rang ? 5
***************************
révision de la table de 2 jusqu'à 5
1 fois 2 : 2
2 fois 2 : 4
3 fois 2 : 6
4 fois 2 : 8
5 fois 2 : 10
***************************
Encore ? (o/n) n
fin de la révision
- En utilisant la procédure dessinePolygone écrire un programme qui trace une ligne de carrés de taille croissante en allant de gauche à droite.
La taille du côté du premier carré, le facteur d'accroissement et le nombre de carés sont lus au clavier. La ligne commence au point de coordonnées (-300,0). Vous n'avez
PAS à traiter le problème de sortie de la fenêtre turtle dans
le cas où il y a trop de carrés à dessiner.
Exemple du dessin obtenu pour une longueur initiale de 50, un facteur
d'accroissement de 1.5 et 5 carrés :
Complément : variables locales et globales
Les variables qui sont utilisées dans la définition d'une fonction
sont appelées des variables locales. Par exemple, les
variables angle et longueurCote sont des
variables locales à la fonction dessinePolygone. Les
variables locales ne sont
visibles qu'à l'intérieur de la fonction, et elles masquent les
autres variables de même nom. Par exemple:
# exemple pour illustrer la notion de variable locale
def masque():
largeur = 40
return 2*largeur
#programme principal
largeur = 3
print("résultat fonction :",masque(),", variable largeur :",largeur)
Le résultat d'exécution est le suivant:
résultat fonction : 80 , variable largeur : 3
Il y a deux variables largeur dans ce code. La variable qui
est déclarée dans la fonction masque est
locale à la fonction masque c'est à dire
qu'elle n'est accessible que dans cette fonction. Quand on
exécute la fonction masque, cette variable locale
prend la valeur 40. Elle est utilisée pour calculer
la valeur renvoyée par la fonction, c'est à dire 80. Mais cela
ne modifie en rien la variable largeur qui a été
définie dans le programme principal, qui a toujours la
valeur 3.
Par opposition, les variables définies dans le programme principal sont
des variables globales du programme (comme ici la variable largeur qui a été définie dans le programme principal).
3. Valeurs par défaut des paramètres
Une des particularités du langage Python est qu'il permet
de définir très simplement les valeurs par défaut de
certains paramètres. Par exemple, voici les valeurs par
défaut de la fonction print.
Valeurs par défaut de la fonction print
La syntaxe détaillée de la fonction print est la suivante :
print(val1,val2,...,valn,sep=' ',end='\n',file=sys.stdout)
val1,val2,...,valn sont les valeurs à afficher.
sep est le séparateur; par défaut c'est un espace.
end est le caractère de fin; par défaut c'est le caractère \n qui
permet de passer à la ligne.
file indique l'endroit où il faut écrire; par défaut c'est sys.stdout
qui représente la sortie standard c'est à dire votre
écran. Nous verrons plus tard qu'on peut aussi écrire dans des
fichiers.
Le code suivant :
print("a","b",sep="",end="")
print("c","d",sep="",end="")
affiche :
abcd
puisqu'on a dit avec sep="" que les valeurs sont séparées par rien,
et avec end="" que la fin de ligne est vide c'est à dire que l'on ne passe pas à la ligne.
Le code suivant :
i=0
while i<3:
print(i,sep="",end="")
i=i+1
affiche :
012
Vous pouvez vous aussi donner des valeurs par défaut à certains
paramètres des fonctions que vous définissez. Il suffit tout
simplement de donner la valeur par défaut à l'endroit où vous
définissez le paramètre. Voici une fonction
dessineCarre qui a un paramètre par défaut qui fixe
la couleur à rouge :
from turtle import *
# dessine un carré de côté l, de couleur c
# par défaut la couleur est "red"
def carre(l,c="red"):
color(c)
angle = 90
# dessin des 4 côtés
k=0
while k<4:
left(angle)
forward(l)
k=k+1
# programme de test
# dessine un carré rouge
carre(100)
# dessine un carré bleu
carre(200,"blue")
Les paramètres par
défaut doivent être les derniers paramètres de la fonction
(i.e. on ne peut pas écrire carre(c="red",l))
Exercices
- Modifier votre fonction dessinePolygone pour que la
valeur par défaut de la couleur soit "blue" et que le point
de départ soit (0,0).
- Modifier votre fonction tableMultiplication pour que la valeur par
défaut
du rang jusqu'auquel on récite la table soit 10.