Vous pouvez me contacter via Facebook pour questions & suggestions :
Page Facebook relative à mon site
La notion de fonction est omniprésente en Python.
Dans ce chapitre vous verrez que Python vous propose un nombre impressionnant de fonctions prédéfinies (prêtes à l'emploi).
Il existe les fonctions natives du module de base mais aussi les fonctions des modules à importer.
les méthodes sont des fonctions spécifiques à une classe d'objets.
Vous avez déjà utilisé de nombreuses fonctions natives de Python : print(), len(), type(), list(), etc.
Ci-desssous tableau de toutes les fonctions natives (ou génériques "built-in functions" en anglais) :
Ces fonctions sont toujours disponibles car définies dans le module de base de Python.
Il n'est pas nécessaire de procéder à une importation.
Ci-dessous une série de commandes pour vous familiariser avec certaines de ces fonctions.
>>> maliste =[7,3,5,1,9]
>>> max(maliste)
9
>>> min(maliste)
1
>>> sum(maliste)
25
>>> int(15.5)
15
>>> eval("15.5")
15.5
>>> pow(10,5)
100000
>>> round(17.89,1)
17.9
>>> abs(-10)
10
>>> machaine ="bonjour"
>>> max(machaine)
'u'
>>> min(machaine)
'b'
Ces fonctions sont dites aussi génériques car elles peuvent s'appliquer à différents types de données (à la différence
des méthodes de classe qui sont spécifiques à un type d'objet).
Ainsi je vous montre que les fonctions min() & max() peuvent avoir pour argument une liste ou une chaine.
La fonction round(nombre décimal,n) arrondit à l'entier le plus proche OU au nombre de décimales si un deuxième argument
est précisé.
La fonction pow(x,n ) élève x à la puissance n
eval(chaine numérique) : convertit une chaine en flottant à condition bien sûr que cette chaine ait un
format numérique (suite de chiffres avec éventuellement un point décimal).
Ne confondez pas les fonctions natives avec les mots clés.
La liste des mots clés peut être affichée dans la console :
>>> help("keywords")
Here is a list of the Python keywords. Enter any keyword to get more help.
False break for not
None class from or
True continue global pass
__peg_parser__ def if raise
and del import return
as elif in try
assert else is while
async except lambda with
await finally nonlocal yield
Vous n'avez pas le droit d'utiliser un mot clé pour définir un identifiant (nom de variable simple, de fonction, de liste, ...).
>>> in = [5,4,3,2] ... SyntaxError: invalid syntax >>> del = (5,4,3) ... SyntaxError: invalid syntax
On ne peut pas nommer une liste, un tuple avec des mots clés tels "in" ou "del".
del est un mot clé qui joue le rôle d'une fonction.
>>> liste =list(range(2,10)) >>> liste [2, 3, 4, 5, 6, 7, 8, 9] >>> del(liste[0]) >>> liste [3, 4, 5, 6, 7, 8, 9] >>> del(liste) >>> liste ... NameError: name 'liste' is not defined
J'ai supprimé le premier élément de la liste puis toute la liste avec le mot clé del donc la demande d'affichage de cette liste retourne un message d'erreur.
Parmi les 72 fonctions natives certaines sont très utiles en mathématiques.
Par exemple, ne prenez pas la peine de créer une fonction pour traiter la division entière ; elle existe déjà !
>>> ord('a')
97
>>> chr(97)
'a'
>>> bin(64)
'0b1000000'
>>> oct(64)
'0o100'
>>> hex(64)
'0x40'
>>> hex(192)
'0xc0'
>>> divmod(10,3)
(3, 1) # quotient et reste de la division de 10 par 3
>>> y =float("10000.55")
>>> y
10000.55
Attention pour les fonctions bin(), oct(), hex() les deux premièrs caractères de la réponse précisent la base : "0b" ou "0o" ou "0x".
Une méthode est une fonction spécifique à un type d'objet.
Pour chaque classe il existe un certain nombre de méthodes.
Par exemple pour trier une liste, vous pouvez utiliser la fonction générique sorted() OU la méthode de liste sort().
Commandes dans la console :
>>> maliste =[5,4,3,2,1] >>> liste_triee = sorted(maliste) >>>liste_triee [1, 2, 3, 4, 5] >>> maliste [5, 4, 3, 2, 1] >>> maliste.sort() >>> maliste [1, 2, 3, 4, 5] >>>
Dans le cas de la fonction générique sorted(), l'ordre d'origine est sauvegardé.
Dans le cas de la méthode sort(), l'ordre d'origine est perdu.
Chaque classe propose de nombreuses méthodes.
Pour connaitre les méthodes applicables à un objet en fonction de son type, il suffit de taper la commande dir(nomClasse)
>>> dir(tuple) ... 'count', 'index' >>> dir (set) ... 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update' >>>
Les tuples sont des séries non mutables donc les méthodes ne sont qu'au nombe de 2 alors que pour les ensembles (ou "set"), la liste des méthodes disponibles est impressionnante.
Il ne faut pas confondre vitesse et précipitation. Avant de vous lancer dans la création d'une fonction personnelle complexe, vous devez vous documenter sur les fonctions proposées par Python.
En plus des fonctions natives (celles dans le module de base), Python proposent des fonctions dans différents modules. Pour disposer de ces fonctions il faut donc importer le module en question.
Je veux calculer la racine carré de 25. Je sais qu'il existe une fonction de Python qui fait ce travail : sqrt().
>>> sqrt(25) ... NameError: name 'sqrt' is not defined
l'interpréteur me dit que la fonction sqrt() n'est pas définie ...
En effet cette fonction existe bien mais elle fait partie du module math, module qui n'a pas été importé donc elle n'est pas
encore disponible.
>>> import math >>> math.sqrt(25) 5.0 >>> math.ceil(18.9) 19 >>> math.floor(18.9) 18 >>>
Pour disposer de toutes les fonctions du module math il suffit de taper la commande import math
qui importe la totalité du module : toutes les fonctions.
Ensuite pour appeler une fonction du module il faut la préfixer avec le nom du module.
>>> dir(math) 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp'] >>>
Il suffit de taper dir(math) pour obtenir la liste des fonctions proposées par ce module.
Vous devinez qu'il y a des fonctions de trigonométrie. J'aurais l'occasion d'y revenir ...
Il y a aussi une fonction nommée "factorial" et une autre nommée "gcd"
Il existe un autre module qu'il faut souvent utiliser : random.
En anglais “random” signifie “le hasard”. Ce module propose des fonctions pour générer un réel, un entier de façon aléatoire, etc.
Donc si vous voulez programmer des jeux simulant le hasard, ce module est incontournable.
>>> import random as rand >>> alea = rand.random() >>> alea 0.6545422177112703 >>> car_retenu = rand.choice(['a','b','c', 'd']) >>> car_retenu 'c' >>> entier = rand.randint(5,25) >>> entier 8 >>>
En important le module random je lui donne un alias : "rand".
Ainsi pour appeler la fonction random de ce module il suffit de taper rand.random
et non pas random.random().
Les bibliothèques (librairies) sont des extensions du langage Python.
Une bibliothèque comprend un ou plusieurs modules. Chaque module propose des fonctions.
À la différence des modules standards, les bibliothèques doivent être chargées (avec l'utilitaire PIP, par exemple).
Un seul exemple : pour tracer des courbes représentatives de fonctions, il faut disposer des fonctions du module
pyplot. Ce module fait partie de la librairie matplolib. Il faudra au préalable télécharger sur votre PC cette
extension.
Comment installer une extension ?
Avant de vous lancer dans la création d'une fonction reposant sur un algorithme complexe, recherchez sur la "toile" pour savoir si elle n'existe pas en tant que fonction générique ou dans un module voire dans une bibliothèque.
Supposons que vous deviez calculer le plus grand commun diviseur de plusieurs nombres.
Il suffit de saisir dans un moteur de recherche la requête : python + plus grand commun diviseur
Le site "koor.fr" vous indique que la fonction se nomme "gcd" et est dans le module "math".
Il est précisé aussi que cette fonction est récente : depuis Python 3.5
J'aurais pu utiliser aussi la "réponse flash" du moteur de recherche Qwant.
>>> import math >>> math.gcd(14,35) 7 >>> math.gcd(60,50,40,30) 10
Il s'agit d'une fonction qui admet un nombre variable de paramètres (voir chapitre 12).
La fonction native la plus utilisée est la fonction print(). Il convient de maitriser son usage.
La fonction print() peut être argumentée avec plusieurs expressions (variables, chaines, numériques) séparées par une virgule. Par défaut chaque expression est séparée de la précédente avec un espace.
Vous pouvez modifier le type de séparateur voir le supprimer avec le mot clé sep
>>> nom ='Marchand' >>> prenom ='leon' >>> age = 22 >>> print(nom, prenom, age, " ans") Marchand leon 22 ans >>> print(nom,prenom,age,' ans', sep ='-') Marchand-leon-22- ans >>> print(nom,prenom,age,'ans', sep ='') Marchandleon22ans >>>
>>> maliste = list(range(1,11,2)) >>> for ele in maliste : ... print(ele) ... 1 3 5 7 9 >>> for ele in maliste : ... print(ele,end ="-") ... 1-3-5-7-9->>>
Par défaut il y a un saut de ligne après une instruction print() sauf si on emploie comme argument le mot clé end = ' '. Il faut préciser le type de séparateur entre les quotes.
Les f-strings existent depuis la version 3.6 de Python. C'est un gros progrès en matière d'affichage de plusieurs expressions avec la même instruction print().
>>> nom ="Dubuis"
>>> age = 22
>>> print(nom + " est âge de " + age + " ans")
...
TypeError: can only concatenate str (not "int") to str
>>> print(nom, "est âgé de :" , age, " ans")
Dubuis est âgé de : 22 ans
>>> print(f"{nom} est âgé de {age} ans")
Dubuis est âgé de 22 ans
L'instruction print(nom + " est âge de " + age + " ans") est incorrecte !
En effet la variable age n'est pas de type str donc la concaténation est ici impossible.
L'instruction print(nom, "est âgé de :" , age, " ans") est correcte mais lourde dans sa syntaxe.
print(f"{nom} est âgé de {age} ans") : chaine formatée !
Une chaine formatée est délimitée par des guillemets doubles et est précédée de "f".
Dans une chaine formatée on peut insérer des variables à condition qu'elles soient entre accolades.
C'est la notation "moustache".
Vous verrez que l'on peut même insérer des formules (entre accolades) et du balisage HTML ...
J'ai employé de multiples fois le terme "fonction". J'ai évoqué les fonctions natives ainsi que les fonctions
de modules (modules installés ou modules de bibliothèques).
J'ai aussi signalé que les méthodes étaient des formes particulières de fonctions.
Mais je n'ai pas encore défini le terme "fonction" ...
Une fonction est une portion de code nommée, qui accomplit une tâche spécifique. Les fonctions reçoivent généralement des données en entrée(arguments) et retournent généralement en sortie les résultats d'un traitement.
Au propos des fonctions on emploie les termes paramètres et arguments
Les paramètres sont définis lors de la création de la fonction et servent de variables locales à l'intérieur de la fonction.
Les arguments sont les valeurs réelles passées à la fonction lors de son appel et doivent correspondre aux paramètres
définis (ainsi deux arguments à saisir si deux paramètres obligatoires).
>>> divmod(11,3) (3, 2) >>> q,r = divmod(11,3) >>> q 3 >>> r 2 >>>
La fonction générique divmod (division entière) exige deux arguments lors de son appel et retourne deux valeurs. Elle a donc été définie avec deux paramètres obligatoires.
Si vous n'avez pas trouvé votre bonheur (parmi les fonctions génériques, les fonctions des modules, les méthodes de classe, les fonctions dans les extensions) vous devez alors créer vos propres fonctions. Avez-vous bien cherché ???
Concrétement il faudra définir cette fonction puis l'appeler N fois.
Pour définir une fonction personnelle il faut créer un bloc d'instructions commençant par le mot clé def.
>>> def date_courante():
... import time
... print("date du jour : " + time.strftime("%A %d %B %Y"))
...
>>> date_courante() #appel de la fonction
date du jour : Wednesday 03 January 2024
>>>
Notez la syntaxe de la première ligne du bloc : def nomFonction(). Les parenthèses sont obligatoires.
La fonction "date_courante" n'exige aucun argument lors de son appel et se contente d'afficher la date du jour. Elle ne retourne aucune valeur.
Pour appeler cette fonction il suffit d'écrire : date_courante() avec aucun argument entre les parenthèses. Mais la paire de parenthèses est obligatoire pour bien préciser que vous appelez une fonction.
Ci-dessous je définis une fonction qui permet d'afficher une table de multiplication.
La fonction se contente d'afficher les données sous forme d'un tableau mais ne retourne pas de valeur.
>>> def table(nombre,ligne):
... for i in range(1,ligne+1):
... print(f" {i} * {nombre} = {i * nombre}")
...
>>> table(9,10)
1 * 9 = 9
2 * 9 = 18
3 * 9 = 27
4 * 9 = 36
5 * 9 = 45
6 * 9 = 54
7 * 9 = 63
8 * 9 = 72
9 * 9 = 81
10 * 9 = 90
Notez la syntaxe de la première ligne du bloc : def nomFonction(param1, param2)
Appel de la fonction : j'ai tapé table(9,10). Ce qui signifie que je demande l'affichage de la table par 9 et
les dix premières lignes.
Notez que dans une chaine formatée on peut manipuler des formules basées sur plusieurs variables telles {i * nombre}.
>>> def instant_present(): ... import time ... return time.localtime() ... >>> cejour = instant_present() #appel de la fonctionn >>> print(cejour) time.struct_time(tm_year=2024, tm_mon=12, tm_mday=29, tm_hour=9, tm_min=34, tm_sec=23, tm_wday=6, tm_yday=364, tm_isdst=0)
Notez le mot clé "return" qui signifie que la fonction retourne une (ou plusieurs) valeurs.
La valeur retournée est ici récupérée dans la variable "cejour".
Cette fonction perso est construite à partir de la fonction time.localtime() (fonction localtime du module time). Voir le chapitre 9 pour davantage d'explications.
J'entends par "normale" une fonction qui exige un ou plusieurs arguments lors de son appel et retourne une valeur.
Cette fonction exige un argument lors de son appel et retourne valeur.
Création d'une fonction perso. basée sur l'équation : f(x) = x2 + 10 puis appel trois fois de cette fonction.
>>> def parabole(x): ... y = pow(x,2)+10 ... return y ... >>> parabole(-10) 110 >>> parabole(0) 10 >>> parabole(10) 110
Pour construire ma fonction perso je fais appel à la fonction native pow().
Une fonction peut retourner un tuple de valeurs.
>>> def cercle(r): ... aire = r * r * 3.14 ... circonference = r*2 * 3.14 ... return aire,circonference ... >>> a,c = cercle(10) >>> a 314.0 >>> c 62.8 >>>
La fonction nommmée "cercle" reçoit le rayon en argument et retourne la surface et la circonférence du cercle.
Appel de la fonction : a,c = cercle(10). L'aire du cercle de 10 de rayon est récupérée dans la variable "a" et
la circonférence dans la variable "b".
En général une variable déclarée dans une fonction n'est manipulée qu'au sein de cette fonction et une variable déclarée en dehors de toute fonction n'est manipulée que dans le programme principal.
Je veux afficher pi en dehors de la fonction. Or il s'agit d'une variable déclarée dans la fonction ...
def cercle(r):
pi =3.14
aire = r * r * pi
circon = r * 2 * pi
return aire, circon
# appel de ma fonction perso
a,c = cercle(10)
print (a)
print (c)
print (pi)
314.0 62.800000000000004 ... NameError: name 'pi' is not defined
La dernière instruction plante !
Une variable déclarée dans une fonction est une variable locale.
Une variable locale est créée lors de l'appel de la fonction mais détruite ensuite.
La solution ci-dessous :
def cercle(r):
global pi
pi =3.14
aire = r * r * pi
circon = r * 2 * pi
return aire, circon
# appel fonction
a,c = cercle(10)
print ("aire : ", a)
print ("circonference : ", c)
print ("valeur de pi : ", pi)
Règle : lorsqu'une variable est définie à l'intérieur d'une fonction, elle est considérée comme locale, sauf si elle est explicitement déclarée comme globale.
Le rendu dans le shell :
aire : 314.0 circonference : 62.800000000000004 valeur de pi : 3.14
Les fonctions en Python étant un vaste sujet, je consacre une deuxième chapitre sur ce sujet. Je reviens sur les fonctions au chapitre 12.