import numpy
print(numpy.arange(5))
[0 1 2 3 4]
Les fonctions permettent de généraliser des instructions. Il s’agit ainsi d’un outil privilégié pour automatiser des tâches répétitives ou réduire la complexité d’une chaîne de traitement. Elles sont donc à utiliser sans modération. Ce chapitre présente quelques rappels sur le sujet.
Lino Galiana
July 9, 2020
Python
, comme R
, sont des langages
construits sur le principe de briques.
Ces briques sont ce qu’on appelle des packages.
Au contraire de Stata
mais comme pour R
,
il
faut toujours préciser les packages que vous utilisez au début du code,
sinon Python
ne reconnait pas les fonctions appelées.
On charge un module grâce à la commande import
.
Pour chaque code que vous exécutez,
il faut charger les modules en introduction.
Une fois qu’on a chargé le module, on peut faire appel aux commandes qui en dépendent en les appelant après avoir tapé le nom du module. Si vous ne précisez pas le nom du module avant celui de la fonction, il ne la trouvera pas forcément.
Voici un exemple avec le module numpy
qui est très courant et permet de faire des
calculs matriciels sous Python
.
On peut aussi donner un pseudonyme au module pour éviter de taper un nom trop long à chaque fois qu’on utilise une fonction.
Classiquement le nom raccourci de numpy
est np
,
celui de pandas
est pd
.
Si on ne veut pas être obligé de donner
le nom du module avant d’appeler
la fonction,
il y a toujours la possibilité de n’importer qu’une fonction du module.
Dans le cas de l’exemple, Python
sait que la fonction arrange
est celle de numpy
.
Mais attention : si deux fonctions de modules différents ont le même nom, c’est toujours la dernière importée qui gagne.
On voit souvent from _module_ import *
.
C’est-à-dire qu’on importe toutes
les fonctions du module
mais on n’a pas besoin de spécifier le nom du module avant les méthodes.
La méthode from _module_ import *
n’est pas recommandée car elle rend le code moins intelligible.
En effet, d’où vient la fonction floor
? De maths
ou de numpy
?
Elle risque
aussi de créer des conflits de fonction, qui malgré un nom commun peuvent ne
pas attendre les mêmes arguments ou objets.
Les tests permettent d’exécuter telle ou telle instruction selon la valeur d’une condition.
Pour faire un test avec un bloc d’instructions, il faut toujours :
:
if
et else
Comme dans les autres langages, on teste une condition. Si elle est vérifiée, alors une instruction suit et sinon, une autre instruction est exécutée.
Il est conseillé de toujours indiquer une contrepartie afin d’éviter les surprises.
if
, elif
et else
Avec if
et elif
,
dès qu’on rencontre une condition qui est réalisée,
on n’en cherche pas d’autres potentiellement vérifiées.
Plusieurs if
à la suite peuvent quant à eux être vérifiés.
Suivant ce que vous souhaitez faire, les opérateurs ne sont pas substituables.
Notez la différence entre ces deux bouts de code :
#code 1
x = 5
if x != 10 :
print("x ne vaut pas 10")
elif x >= 5 :
print("x est égal ou supérieur à 5")
x ne vaut pas 10
Dans le cas de elif, on s’arrête à la première condition vérifiée et dans le cas suivant, on continue à chaque condition vérifiée
Il existe deux types de boucles : les boucles for
et les boucles while
La boucle for
parcourt un ensemble, tandis que la boucle while
continue tant qu’une condition est vraie.
for
On va faire une boucle sur les éléments d’une liste
Avec les listes, il existe aussi un moyen très élégant de condenser son code pour éviter de faire apparaitre des boucles sans arrêt. Comme les boucles doivent etre indentées, le code peut rapidement devenir illisible.
Grace aux list comprehension, vous pouvez en une ligne faire ce qu’une boucle vous permettait de faire en 3 lignes.
Par exemple, imaginez que vous vouliez faire la liste de toutes les lettres contenues dans un mot, avec un boucle vous devrez d’abord créer une liste vide, puis ajouter à cette liste toutes les lettres en question avec un .append()
['E', 'N', 'S', 'A', 'E']
avec une list comprehension, on condense la syntaxe de la manière suivante :
Avec une list comprehension
est équivalent à
Mettez sous forme de list comprehension le bout de code suivant
Le bloc d’instruction d’une boucle while est exécuté tant que la condition est vérifiée.
Le piège de ces boucles : la boucle while
infinie ! Il faut toujours vérifier que votre boucle s’arrêtera un jour, il faut qu’à un moment ou à un autre, il y ait un élément qui s’incrémente ou qui soit modifié.
x = 10
y = 8
# tant que y est plus petit que 10, je continue de lui ajouter 1
while y <= x :
print("y n'est pas encore plus grand que x")
y += 1 # l'incrément
else :
print("y est plus grand que x et vaut",y)
y n'est pas encore plus grand que x
y n'est pas encore plus grand que x
y n'est pas encore plus grand que x
y est plus grand que x et vaut 11
Dans les boucles for ou while on peut avoir besoin d’ignorer ou de ne pas effectuer certaines itérations. 2 instructions utiles :
Les fonctions permettent de faire la même chose sans avoir à recopier le code plusieurs fois dans le même programme. Dès que vous le pouvez, faites des fonctions : le copier-coller est trop dangereux.
# 1er exemple de fonction
def ma_fonction_increment(parametre) :
"""Cette fonction ajoute 1 au paramètre qu'on lui donne"""
x = parametre + 1
return x
# pour documenter la fonction, on écrit son aide
help(ma_fonction_increment)
Help on function ma_fonction_increment in module __main__:
ma_fonction_increment(parametre)
Cette fonction ajoute 1 au paramètre qu'on lui donne
On peut également :
def ma_fonction(p,q = 2) :
y1 = p + q
y2 = y1%3 #reste de la division euclidienne
return y1,y2
x = ma_fonction(11)
# ici, on n'a pas de 2nd paramètre
#, par défaut, x = ma_fonction(10,2)
print("x=", x)
z = ma_fonction(10,-1)
print("z =",z)
x= (13, 1)
z = (9, 0)
Une fonction peut également s’appeler elle même : c’est ce qu’on appelle une fonction récursive.
Dans cet exemple, somme_recursion()
est une fonction que nous avons définie de sorte à ce qu’elle s’appelle elle-même (récursif).
On utilise l’argument k, qui décroit (-1) chaque fois qu’on fait appel à la fonction.
La récursion s’arrête quand k est nul. Dans cet exemple, on va donc appeler 6 fois la fonction récursive.
def somme_recursion(k):
if(k > 0):
result = k + somme_recursion(k - 1)
print(k,result)
else:
result = 0
return result
somme_recursion(6)
1 1
2 3
3 6
4 10
5 15
6 21
21
Les fonctions sont très utiles et nous vous invitons à les utiliser dès que vous le pouvez car elles permettent d’avoir un code clair et structuré, plutôt que des bouts de code éparpillés.
Python peut rencontrer des erreurs en exécutant votre programme.
Ces erreurs peuvent être interceptées très facilement et c’est même, dans certains cas, indispensable. Par exemple, si vous voulez faire une boucle mais que vous savez que l’instruction ne marchera pas toujours : au lieu de lister les cas où une opération n’est pas possible, on peut indiquer directement quelle erreur doit être ignorée.
Cependant, il ne faut pas tout intercepter non plus : si Python envoie une erreur, c’est qu’il y a une raison. Si vous ignorez une erreur, vous risquez d’avoir des résultats très étranges dans votre programme.
# éviter une division par 0, c'est une bonne idée :
def inverse(x) :
'''Cette fonction renvoie l inverse de l argument'''
y = 1/x
return y
div = inverse(0)
ZeroDivisionError: division by zero
L’erreur est écrite noir sur blanc : ZeroDivisionError
Dans l’idéal on aimerait éviter que notre code bloque sur ce problème. On pourrait passer par un test if et vérifier que x est différent de 0. Mais on se rend vite compte que dans certains cas, on ne peut lister tous les tests en fonction de valeurs.
Alors on va lui précisier ce qu’il doit faire en fonction de l’erreur retournée.
Syntaxe
Try :
instruction
except TypeErreur :
autre instruction
def inverse(x) :
try :
y = 1/x
except ZeroDivisionError :
y = None
return y
print(inverse(10))
print(inverse(0))
0.1
None
Il est recommandé de toujours préciser le type d’erreur qu’on rencontre. Si on met uniquement “except” sans préciser le type, on peut passer à côté d’erreurs pour lesquelles la solution n’est pas universelle.
Ecrivez un programme qui peut trouver tous les nombres divisibles par 7 et non multiples de 5 entre 6523 et 8463 (inclus)
Ecrivez un programme qui prend une phrase en entrée et qui calcule le nombre de voyelles en Majuscules et de consonnes en minuscules :
@book{galiana2023,
author = {Galiana, Lino},
title = {Python Pour La Data Science},
date = {2023},
url = {https://pythonds.linogaliana.fr/},
doi = {10.5281/zenodo.8229676},
langid = {en}
}