Informatique générale pour l’ingénieur Chapitre VI : Compléments sur les fonctions I. Rappels A. Mais Euh … A quoi ça sert une fonction ? Lorsque vous commencerez à développer de véritables projets, vous serez confrontés à des problèmes souvent complexes, et les lignes de programme vont commencer à s’accumuler... L’approche efficace d’un problème complexe consiste souvent à le décomposer en plusieurs sousproblèmes plus simples qui seront étudiés séparément . Il arrivera également souvent qu’une même séquence d’instructions doive être utilisée à plusieurs reprises dans un programme, et on souhaitera bien évidemment ne pas avoir à la réécrire systématiquement. Les fonctions sont des structures qui ont été imaginées par les concepteurs des langages de haut niveau afin de résoudre ces difficultés. Définir une fonction, c’est regrouper dans un sous programme ( c’est à dire un bout de code indépendant du reste) les instructions destinées à accomplir une tache donnée qui se répète souvent. Le langage a des fonctions préprogrammées (directement ou à travers l’importation de bibliothèques) si elles ne conviennent pas à la tâche souhaitée c’est à nous de définir la fonction. B. Définition et vocabulaire def nomDeLaFonction(liste de paramètres): • La ligne contenant l’ instruction def se termine obligatoirement par un double point, lequel introduit un bloc d’instructions que vous ne devez pas oublier d’indenter. ... bloc d'instructions ... • La liste de paramètres spécifie quelles • Une fonction s’utilise pratiquement comme une informations (et dans quel ordre) il faudra fournir instruction quelconque. Dans le corps d ’un en guise d’arguments lorsque l’on voudra utiliser parenthèses peuvent programme, un appel de fonction est constitué du cette fonction (les parfaitement rester vides si la fonction ne nécessite nom de la fonction suivi de parenthèses pas d’arguments). Voici un exemple de fonction sans paramètres def table(): Que fait cette fonction ? for i in range(1,11): n=1 Critique du while ? while n <11 : print('{0:<3}'.format(n * i), end =' ') Nouvelle option de la méthode format ? n = n +1 print() 1 C. Valeur de sortie d’une fonction 1. print ou return ? Une erreur, hélas encore trop fréquente (mais cela va s’arranger !) , est de confondre print et return alors que les rôles de ces deux instructions sont totalement différents. def carrep(x): def carre (x): print (x*x) return x*x Un appel de la fonction carrep provoque l’affichage de x*x alors qu’un appel de la fonction carre renvoie au programme principal à l’endroit où la fonction a été appelée la valeur de x*x . De plus ,quand une fonction (comme carrep ) ne retourne pas explicitement une valeur au programme principal, Python attribue par défaut la valeur None à la valeur de sortie. Pour fixer les idées, voyons un exemple en essayant de faire calculer 3*x*x+2 en réutilisant les fonctions précédentes. Comparez les résultats de x=3 x=3 y=3*carre(x)+2 y=3*carrep(x)+2 print (y) print (y) 29 ( ouf c’est ce qu’on voulait !) 9 Traceback (most recent call last): File "C:\Documents and Settings\user\Bureau\chap5.py", line 28, in <module> y=3*carrep(x)+2 TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' Bref : Pas de print dans une fonction sauf si ce n’est qu’une fonction d’affichage Remarque : fonction ou procédures Pour les puristes, les fonctions comme carrep ne sont pas tout à fait des fonctions au sens strict, mais plus exactement des procédures . En théorie informatique, une « vraie » fonction (au sens strict) doit en effet renvoyer une valeur lorsqu’elle se termine autrement dit une « vraie » fonction doit pouvoir être utilisée s’utiliser à la droite du signe égale dans des affectations telles que y = sin(a). Python ne fait pas cette distinction, d’autres langages la font …… 2. Valeurs de sortie multiples Rappelez vous de notre fonction somdiff def somdif(a,b): """somdif retourne la somme et la différence des nombres passés en arguments""" return a+b,a-b 2 Ici on a une valeur de sortie multiple ( les deux valeurs étant séparées par une virgule dans l’instruction return) . Le programme principal devra donc recueillir la sortie multiple dans un tuple , une liste ou à l’aide d’une affectation parallèle. Exemple t=somdif(a,b) ou s,d=somdiff(a,b) II. Un peu plus sur les fonctions Dans ce paragraphe, on va donner quelques petits plus sur les fonctions et introduire quelques nouvelles instructions. A. Documentation et valeurs défauts On peut préciser des valeurs par défaut pour les paramètres formels. def zeta(p,N=1000): """Renvoie une évaluation de la fonction zéta(p)avec N itérations""" return sum([1/i**p for i in range(1,N+1)]) Commentaires B. Fonction anonyme : instruction lambda Python permet de définir rapidement des petites fonctions sans passer par def. Lorsque le code d’une fonction tient en une ligne et est le résultat d’une expression, il est ainsi possible de condenser son écriture à l’aide du mot-clé lambda . Ces fonctions peuvent être utilisées n’importe où (où une fonction est attendue). La syntaxe de l’instruction lambda est la suivante nom_fonction = lambda param_1, ..., param_n : expression Exemple : norm = lambda x,y : (x*x+y*y)**(1/2) (lire norm fonction qui à x,y associe ….) print(norm(1,1)) Remarque : fonction ou pas fonction ? Avec des trucs de genre ou dans des programmes longs, on peut se perdre et ne plus savoir si un identificateur est une fonction c’est a dire si tel identificateur est appelable comme une fonction. On peut alors avoir recours à l’instruction callable qui retourne le booléen True si l’identificateur qu’on lui passe en paramètre est une fonction. 3 L’instruction lambda est particulièrement utile quand on veut faire des opérations sur des fonctions. Exemple d’application : la composition de fonctions. def compo(f,g): return lambda x: f(g(x)) coscarr=compo(carre,cos) # c'est ce qu'en math on note fog ; prononcez f rond g Compo est une fonction qui reçoit en arguments deux autres fonctions et qui retourne comme valeur de sortie une fonction !! ( pas une valeur numérique) print(3*coscarr(pi/4)) Remarque : Il est important de comprendre qu’une fonction est une valeur comme un autre, c’est à dire qu’elle peut être passée en argument, renvoyée comme résultat ou encore stockée dans une variable. C. Variable locales variable globales En Python on distingue deux sortes de variables : les globales et les locales. ■ Une variable globale a une signification dans tout le programme . Sa portée s’étend à tout le programme ■ Alors que définie dans une fonction, une variable n’a qu’une signification à l’intérieur du bloc d’instructions de la fonction. C’est une variable locale . Voici un exemple def mafonc(): Traceback (most recent call last): y=8 File "C:\Documents and Settings\user\Bureau\chap5.py", line 62, in <module> return y print(y) print(y) NameError: name 'y' is not defined Si on veut qu’une variable utilisée dans la fonction soit une variable globale, il faut la déclarer comme telle par l’instruction global voici un exemple a,b=1,8 (2, 'lulu', 4) def demo(): 28 global a Traceback (most recent call last): a=a+1 File "C:\Documents and Settings\fuxa\Bureau\vendr\chap5.py", line 73, in <module> c=2*a b='lulu' # essayer en commentant cette ligne print(c) return (a,b,c) NameError: name 'c' is not defined print(demo()) print(a,b) print(c) Une variable est locale (c dans l’exemple ) sauf si elle est utilisée dans la fonction sans être affectée (b est affectée donc est locale, comparez ‘lulu’ et 8 ) ou si elle est déclarée par global (a) . De façon générale, une bonne pratique consiste à n’utiliser des variables globales que pour les constantes du problème et à leur donner des noms explicites. Le recours à l’instruction global est déconseillé. 4 D. Ajout de fonction par transformation de chaine de caractère 1. Instruction eval Elle évalue toute chaîne de caractères contenant une expression écrite avec la syntaxe du langage Python. Cette expression peut utiliser toute variable ou toute fonction accessible au moment où est appelée la fonction eval. from math import pi,sin x=3 y=4 print (eval ("x*x+y*sin(pi)+y**2+2*x*y")) z=eval(input("Entrez une valeur :")) print ("j'ajoute un cela donne donc",z+1) 2. Instruction exec Un peu dans le même ordre d’idée, l’instruction exec permet d’exécuter une instruction représentée par une chaine de caractère. Voyons un exemple from math import * x=eval(input('x=? :')) fonction=input('f(x)=?') code =("""def f(x): return {}""".format(fonction)) exec (code) print('{:.6f}'.format(f(x))) 5