Conditionalité, répétition et fonctions
Contents
Conditionalité, répétition et fonctions#
Les programmes que l’on peut écrire avec seulement l’assignation de valeurs sont assez simples. Afin de pouvoir créer des programmes plus complexes, il est nécessaire de pouvoir demander au programme de faire des choses selon la valeur de certaines variables ou bien de répéter des opérations. Pour cela certains mots-clés permettant de définir ce type de comportement existent en Python.
Scopes#
On peut définir des zones du code qui ne sont exécutées que sous certaines conditions (que nous verrons plus loin). Ces zones sont appelées périmètres (“scope” en anglais) et sont définies par:
la présence d’un double-point “:” dans la ligne avant cette zone, et
une indentation de la zone du code.
L’exemple ci-dessous montre les principaux éléments définissant un scope.
<mot-clé> (<condition>):
# debut du perimetre
<opérations>
# fin du perimetre
Un point important est que les variables définies à l’intérieur d’un scope ne sont valables que dans ce scope et n’existent plus en dehors de ce scope. De la sorte, les variables définies directement dans le scope principal sont dites gloables et donc accessibles dans tous les scopes contenus dans le scope principal. Enfin, les scopes peuvent être insérés les uns dans les autres.
(content:motsclés)=
Mots-clés définissant des scopes#
Voici quelques uns des mots-clés définissant des scopes:
if/elif/else
: ces trois mots-clés permettent de définir des tests et de faire des opérations spécifiques selon les résultats de ces opérations (voir Section If/Elif/Else),for
: il permet de créer des scopes répétés un nombre de fois défini par une condition (voir Section Boucle for),while
: il permet de créer des scopes répétés tant que la condition est vraie (voir Section Boucle while),def
: il permet de définir des fonctions (voir Section Fonctions).
If/Elif/Else#
Un des scopes les plus utiles en Python est le if
.
Le code à l’intérieur du scope n’est exécuté que si la valeur de la condition est True
.
#définir 3 variables:
a = 2
b = 3
c = 4
if b > a: #True
print("b est plus grand que a")
if c < a: #False
print("c est plus petit que a")
if 2*a == c: #True
print("2a est egal a c")
b est plus grand que a
2a est egal a c
Dans cet exemple on compare les valeurs de plusieurs variables avec les opérateurs de comparaison ou bien celui d’égalité (==
) et on imprime une phrase selon le résultat de la comparaison.
Il est bien sur possible de comparer d’autres variables comme des strings, utiliser le mot-clé elif
pour faire des tests au cas ou le premier if
soit faux ou bien d’avoir des conditions plus complexes grâce aux mots-clés and
et or
.
couleur = "marron"
taille = "petit"
# qui suis-je?
if couleur == "vert" and taille == "grand":
print("Geant vert...")
elif couleur == "marron" and taille == "petit":
print("Un marron!")
else:
print("C'est une colle")
Un marron!
Dans le cas de dictionaires, il est parfois utile de vérifier qu’une clé est présente dans un dictionnaire avant de faire quelque chose avec.
Pour cela on peut tester si une clé est présente dans la liste des clés du dictionaire en utilisant le mot-clé in
et la méthode keys()
.
dictionaire = {"chat": 1, "chien": 0}
if "chat" in dictionaire.keys():
print("J'ai", dictionaire["chat"], "chat(s)")
J'ai 1 chat(s)
Boucle for#
Le besoin de répéter des opérations a engendré le concept de boucle.
La plus célèbre est la boucle for
qui répète les opérations contenues dans le scope.
Le type de répétition le plus exploité est la répétition sur les éléments d’une liste.
radii=[0.9,1.0,0.95,1.1,1.2,1.0,0.8,0.85,1.05,1.0]
for r in radii:
print("r =",r)
r = 0.9
r = 1.0
r = 0.95
r = 1.1
r = 1.2
r = 1.0
r = 0.8
r = 0.85
r = 1.05
r = 1.0
Dans cette exemple, pour chaque élément noté r
de la liste radii
, on va afficher la valeur de r
.
Pour cela la condition r in radii
créé bien une variable r
qui existe dans le scope et disparait en dehors.
A chaque fois que le contenu du scope est exécuté une fois, une nouvelle valeur de r
est assignée en suivant l’ordre dans la liste radii
et le contenu du scope est répété avec cette nouvelle valeur.
Parfois on n’a pas de liste à utiliser comme condition; c’est pourquoi on va utiliser la fonction range()
qui va remplacer la liste.
radii=[0.9,1.0,0.95,1.1,1.2,1.0,0.8,0.85,1.05,1.0]
n = len(radii)
for index in range(n):
#l'index de la variable va avoir les valeurs 0..9
print("Element",index,"a pour valeur:", radii[index])
Element 0 a pour valeur: 0.9
Element 1 a pour valeur: 1.0
Element 2 a pour valeur: 0.95
Element 3 a pour valeur: 1.1
Element 4 a pour valeur: 1.2
Element 5 a pour valeur: 1.0
Element 6 a pour valeur: 0.8
Element 7 a pour valeur: 0.85
Element 8 a pour valeur: 1.05
Element 9 a pour valeur: 1.0
On remarque que cette fonction range()
donnera une liste de la taille donnée par l’argument commencant toujours à 0.
Exercise 11
Utiliser une boucle for qui va créer deux listes, une contenant tous nombres entiers entre 1 et 10 et l’autre ces mêmes nombres entiers au carré.
Solution to Exercise 11
numbers=[]
squares=[]
for index in range(10):
x=index+1 # il faut decaler de 1 puisque index commence a 0
numbers.append(x)
squares.append(x*x)
print("les nombres sont:",numbers)
print("les carres sont:",squares)
Dans le cas de dictionnaires, on peut utiliser la méthode items()
pour accéder recursivement à tous les éléments d’un dictionnaire.
annuaire = {'Laurent': 6389565, 'Paul': 6356785, 'Jacques': 6356795}
for key, value in annuaire.items():
print(key, value)
Laurent 6389565
Paul 6356785
Jacques 6356795
Exercise 12
On se donne un dictionaire contenant le nombre de kilomètres parcourus pour certains moyens de transport {"pied": 200, "vélo": 50, "voiture":310}
; on souhaite afficher les kilomètres pour les moyens de transport dans la liste\ ["voiture", "velo", "train", "avion"]
et un message “Pas de kilomètres en {moyen de transport}” lorsqu’il n’y a pas de valeur pour ce moyen de transport dans le dictionaire.
Solution to Exercise 12
transport_km = {"pied": 200, "velo": 50, "voiture":310}
liste = ["voiture", "velo", "train", "avion"]
for moyen in liste:
if moyen in transport_km.keys():
print(moyen,transport_km[moyen],"km")
else:
print("Pas de kilomètres en",moyen)
Boucle while#
La boucle while
reprend l’idée de la boucle for
, sauf que la condition de répétition n’est pas forcément la lecture récursive des élements d’une liste.
La boucle while
répète les opérations définies dans son scope tant que la condition est vraie.
Par exemple, on peut créer une boucle for
à partir d’une boucle while
.
radii=[0.9,1.0,0.95,1.1,1.2,1.0,0.8,0.85,1.05,1.0]
i = 0
while i<len(radii):
print("Element",i,"a pour valeur:", radii[i])
i += 1
Element 0 a pour valeur: 0.9
Element 1 a pour valeur: 1.0
Element 2 a pour valeur: 0.95
Element 3 a pour valeur: 1.1
Element 4 a pour valeur: 1.2
Element 5 a pour valeur: 1.0
Element 6 a pour valeur: 0.8
Element 7 a pour valeur: 0.85
Element 8 a pour valeur: 1.05
Element 9 a pour valeur: 1.0
La boucle while
est très intéressante pour des conditions plus complexes, c’est-à-dire lorsqu’il faut répéter les opérations tant qu’une ou plusieurs conditions ne sont pas remplies.
import random
i = 1
valeur = random.random()
while (valeur > 0.1 and i <= 5) or i <= 2:
print('%.3f' % valeur)
i += 1
valeur = random.random()
print("Valeur", i, "au dessus de 0.1:", valeur)
0.429
0.531
0.712
Valeur 4 au dessus de 0.1: 0.02345642159333372
Dans l’exemple ci-dessus, la condition est composée de plusieurs tests: la boucle continue d’être exécutée tant que l’incrément i
est plus petit que 2 ou bien tant que, pour les tirages suivants (entre le troisième et le cinquième) la valeur tirée au hasard est plus grande que 0.1; au delà, pour i>=6
, la boucle doit s’arrêter.
Fonctions#
Jusqu’à présent nous avons vu quelques fonctions: range()
, print()
, len()
, format()
…
Les fonctions peuvent prendre des arguments en entrée (ce n’est pas toujours le cas), effectuer des opérations à partir de ces arguments (la plupart du temps) et donner en sortie d’autres variables (ce n’est pas toujours le cas non plus…).
L’intérêt des fonctions est double: une fois définies, on peut les utiliser autant de fois que nécessaire en évitant ainsi de réécrire plusieurs fois le même code et de rendre le code plus lisible.
Les fonctions se définissent en utilisant le mot-clé def
suivi du nom de la fonction et de ses arguments entre parenthèses.
Ensuite les opérations que doit faire fonction sont définies dans un scope.
def affine(a):
b = 2*a + 1
return b
La fonction affine(a)
définie ci-dessus prend en entrée une variable (notée a
).
Elle calcule au sein de son scope 2*a+1
et retourne cette valeur grâce au mot-clé return
.
Elle pourrait cependant en retourner plusieurs valeurs en utilisant des virgules comme séparateurs 1.
def calculator(a):
b = 2*a + 1
c = a*a +4
return b,c
print("Valeurs calculées avec 4:",calculator(4))
Valeurs calculées avec 4: (9, 20)
Même si le scope de la fonction affine()
est extrêmement simple, les fonctions que l’on peut définir peuvent être aussi compliquées que l’on souhaite.
Elles peuvent contenir des boucles for
, des if
ou encore d’autres fonctions.
def Saluer(un_nom):
print("Salut",un_nom,"!")
def SaluerToutLeMonde(liste):
for nom in liste: # boucle for sur les noms
Saluer(nom)
# Tester la fonction
liste_noms = ["Audrey", "Arthur", "Emile", "Baptiste"]
SaluerToutLeMonde(liste_noms)
Salut Audrey !
Salut Arthur !
Salut Emile !
Salut Baptiste !
Dans l’exemple ci-dessus, nous avons défini deux fonctions: la première prend en entrée le nom d’une personne et sert à afficher le “salut” avec le nom donné en entrée.
La deuxième fonction SaluerToutLeMonde()
prend en entrée une liste de noms et salue tout les noms de cette liste.
On peut voir que dans les deux cas, ces fonctions ne retournent pas de valeur.
Un point important est que toutes les variables définies au sein d’un scope n’existent qu’au sein du scope. Notamment cela permet d’utiliser une fonction à l’intérieur de son propre scope.
def EnleverUn(a):
if a>=1: # a est trop grand, on doit lui enlever un et recommencer
print("Enlever un à ",a)
a=a-1
return EnleverUn(a)
else: # a est strictement plus petit que 1
return a
# Tester la fonction sur le nombre 4
b = EnleverUn(4)
print("Valeur finale:",b)
Enlever un à 4
Enlever un à 3
Enlever un à 2
Enlever un à 1
Valeur finale: 0
Dans l’exemple ci-dessus on définit une fonction EnleverUn()
qui retire 1 à la valeur d’entrée si celle-ci est plus grande que 1.
Elle recommence ce processus jusqu’à ce que la valeur d’entrée soit inférieur à 1.
Cette fonction peut être dite récursive puisqu’elle s’appelle elle-même à l’intérieur de son scope.
Les fonctions récursives sont très intéressantes, mais elles doivent contenir un moyen de briser la récursivité: dans l’exemple ci-dessus, il s’agit du else
qui permet de retourner la valeur a
et non EnlverUn(a)
.
On peut voir que cette séquence d’action utilisant des fonctions récursives est équivalente à une boucle for
ou while
comme donné ci-dessous.
a = 4
while a >= 1:
print("Enlever un à ",a)
a = a-1
print("Valeur finale:",a)
Enlever un à 4
Enlever un à 3
Enlever un à 2
Enlever un à 1
Valeur finale: 0
Exercise 13
Calculer le factoriel de 13 à l’aide d’une fonction récursive (voir la section “Fonctions” du polycopié).
Solution to Exercise 13
def factoriel(n):
if n == 1:
return 1
else:
return n * factoriel(n-1)
print("factoriel(13):", factoriel(13))
factoriel(13): 6227020800
Exercise 14
Créer une fonction qui vérifie si un nombre \(N\) est premier ou non et utiliser cette fonction pour calculer les 10 premiers nombres premiers. Pour cela, on peut regarder le reste de la division euclidienne de \(N\) par tous les nombres entre 2 et \(\sqrt{N}\). Si le reste est nul, alors ce n’est pas un nombre premier.
Solution to Exercise 14
from math import sqrt
def premier(n):
max_n = int(sqrt(n)) # conversion de sqrt en nombre entier
for i in range(2, max_n+1): # test des nombres jusqu'à int(sqrt(n))
if n % i == 0: # reste division euclidienne == 0?
return False
return True
print("13 est premier?", premier(13))
print("169 est premier?", premier(169))
print("997 est premier?", premier(997))
13 est premier? True
169 est premier? False
997 est premier? True
- 1
En réalité, Python rassemble les deux valeurs dans un tuple et retourne ce tuple. Cependant la flexibilité de Python dans son syle d’écriture permet de faire comme si la fonction retournait deux valeurs.