Soit une situation où l'on voudrait afficher les multiples croissants de 2 jusqu'à 20 ( par exemple...).
Comment faudrait-il écrire un tel programme ?
valeur = 2
print( valeur ) # affiche 2
valeur = valeur + 2
print( valeur ) # affiche 4
valeur = valeur + 2
print( valeur ) # affiche 6
valeur = valeur + 2
print( valeur ) # affiche 8
valeur = valeur + 2
print( valeur ) # affiche 10
valeur = valeur + 2
print( valeur ) # affiche 12
valeur = valeur + 2
print( valeur ) # affiche 14
valeur = valeur + 2
print( valeur ) # affiche 16
valeur = valeur + 2
print( valeur ) # affiche 18
valeur = valeur + 2
print( valeur ) # affiche 20
Pas vraiment élégant, n'est-ce pas ? Il y a sûrement plus efficace que d'écrire 10 fois la même chose !
Très souvent, on a effectivement ainsi besoin de répéter plusieurs fois les mêmes séquences d'instructions
D'où l'existence de structures de boucles qui font partie, comme l'instruction if
, des structures de contrôle de flux.
En Python, deux structures de boucle existent :
for
( boucle inconditionnelle )Vous avez en fait déjà utilisé ce type de structure, mais sous une forme un peu différente, avec la boucle for ... in ...
qui permet de parcourir un objet itérable comme une chaîne de caractères.
for compteur in range( intervalle de variation du compteur ) :
Instruction(s) à exécuter dans la boucle
..............
..............
Cette boucle "tourne" en exécutant à chaque "tour" la (ou des) instruction(s) du bloc.
La variable compteur de boucle ( nommée ici compteur, mais on peut bien entendu utiliser n'importe quel nom..) permet de compter le nombre de "tours" de la boucle; elle est automatiquement incrémentée ( ou décrémentée ! ) d'une certaine valeur ( = le pas de la boucle ) à la fin de chaque "tour"; la boucle "tournera" alors tant que la valeur du compteur se trouve dans l'intervalle de variation indiqué.
Il existe plusieurs façons d'indiquer les bornes de cet intervalle :
for compteur in range( N ) :
⇨ intervalle de 0 jusqu’à N - 1 avec un pas de variation de 1 ( pour N = 10, le compteur varie donc de 0 à 9 par pas de 1, soit 10 "tours" )
for compteur in range( N1 , N2 ) :
⇨ intervalle de N1 jusqu'à N2 - 1 avec un pas de variation de 1 ( pour l'exemple précédent, on aurait : N1 = 0 et N2 = 10 )
for compteur in range( N1 , N2 , pas ) :
⇨ intervalle de N1 jusqu'à N2 - 1 avec un pas de variation quelconque
On constate donc que l'intervalle va toujours de la borne inférieure à la borne supérieure -1 avec un pas par défaut de 1.
for i in range( 4 ) :
⇨ le compteur i prendra les valeurs : 0, 1, 2, 3 soit 4 "tours" de boucle.
for i in range( 3 , 10 ) :
⇨ le compteur i prendra les valeurs : 3, 4, 5, 6, 7, 8, 9 soit 7 "tours" de boucle.
for i in range( 10 , 2 , -2 ) :
⇨ le compteur i prendra les valeurs : 10, 8, 6, 4 ( le pas est de -2 ) soit 4 "tours" de boucle.
L'exemple d'introduction du chapitre deviendrait alors :
valeur = 2
for i in range( 10 ) :
print( valeur )
valeur = valeur + 2
⇨ 4 lignes au lieu de 18 !!
Vous remarquez que les instructions à exécuter dans la boucle appartiennent donc au même bloc logique, elles sont donc indentées
de la même façon par rapport au mot clé for
.
A l'intérieur de la boucle, on aura souvent besoin d'utiliser la valeur de la variable compteur pour réaliser certaines opérations.
Par exemple, pour afficher tous les multiples d'un certain nombre, on écrira une instruction qui, à chaque tour de boucle, multipliera ce nombre par la valeur du compteur, de façon à obtenir tous les multiples :
nombre = 2
for i in range(10):
print(nombre, "x", i, "=", nombre*i)
On a aussi parfois besoin de la structure suivante :
for i in range(3):
for j in range(4):
print("i =", i, "j =", j)
En étudiant l'indentation, on constate la présence dans ce code :
print()
qui affiche les valeurs de i et jÉtudiiez l’exécution de ce code :
i = 0 j = 0
i = 0 j = 1
i = 0 j = 2
i = 0 j = 3
i = 1 j = 0
i = 1 j = 1
i = 1 j = 2
i = 1 j = 3
i = 2 j = 0
i = 2 j = 1
i = 2 j = 2
i = 2 j = 3
Voila ce qu'il se passe :
print()
s'éxécute : on obtient donc l'affichage des lignes 2 à 5 ci-dessus.→ la boucle j a donc été éxécutée autant de fois que de tours de la boucle i.
Cette structure particulière où "une boucle tourne dans une autre boucle" est appelée boucles imbriquées; elle n'est pas évidente à comprendre, étudiez-la bien : elle sert dans de nombreuses situations ( vous verrez un premier exemple ci-dessous ), notamment dès que l'on a à parcourir un objet en deux dimensions comme les pixels d'une image, ou une liste de listes ( vous verrez cela plus tard ).
while
( boucle conditionnelle )
while ( condition ) :
Instruction(s)
.......
Cette boucle « tourne » tant que ( = while ) la condition évaluée est vraie, autrement dit jusqu'à ce qu'elle devienne fausse...
Bien remarquer que cette condition est évaluée au début de chaque "tour".
Dès que la condition devient fausse, le programme "sort" donc de la boucle et passe aux instructions suivantes...
La condition est une expression, plus ou moins complexe, à évaluer à l'aide d'opérateurs de comparaison.
Ce sont les mêmes que ceux rencontrées au chapitre précédent :
Opérateur | Signification | Commentaire |
---|---|---|
== |
égal à | Bien noter qu'il s'agit là-aussi d'un DOUBLE SIGNE ÉGAL... |
!= |
différent de | |
> |
supérieur à | |
< |
inférieur à | |
>= |
supérieur ou égal à | |
<= |
inférieur ou égal à | |
in |
est dans | |
not in |
n'est pas dans |
La (ou les) instruction(s) constituent le bloc qui sera exécuté à chaque "tour" de boucle ; elles sont donc indentées d'un même retrait par rapport à l'instruction "parente" ( ici, l'instruction while
) pour indiquer à Python qu'il s'agit du même bloc logique.
i = 0
valeur = 2
while ( i < 10 ) :
print( valeur )
valeur = valeur + 2
i +=1
Ce mode de fonctionnement sous-entend que quelque chose doit, dans le bloc d'instructions, agir sur la variable testée dans la condition évaluée, sinon la condition ne deviendra jamais fausse, et la boucle peut alors ne jamais s'arrêter de "tourner" !!!
ATTENTION donc au risque de boucle infinie !!
for
ou la boucle while
???Dans certains cas....les deux !!
On peut très bien par exemple réécrire les exemples précédents avec une boucle while
au lieu du for
:
Boucle for |
Boucle while |
---|---|
|
|
|
|
|
|
On constate cependant qu'avec la boucle while
, le code est plus "lourd", d'autant plus qu'il faut soi-même gérer l'évolution du compteur ( ce qui est "automatique" avec une boucle for
), avec les risques de "boucle infinie" que cela entraîne...; l'utilisation de la boucle conditionnelle n'est donc pas judicieuse dans ces exemples...
Quel est son intérêt alors ? Et bien, le nombre de "tours" d'une boucle while
n'est pas fixé à l'avance, au contraire de la boucle for
, dont le nombre de tours est fixé à son début.
Dans quel cas cela est-il utile ? Par exemple, l'entrée d'un mot de passe par un utilisateur : tant que l'entrée n'est pas la bonne, on redemande le mot de passe...et cela peut durer un nombre de fois indeterminé à l'avance !!
motDePasse = 'sdhfj7$ff'
entree = '' # initialisation de l'entrée utilisateur à "vide"
while ( entree != motDePasse ) :
entree = input('Entrez le mot de passe :')
print('Accès autorisé')
for
quand on connaît le nombre de "tours" à effectuer.while
quand on ne le connaît pas.
for i in range( 6 ) :
Instruction 1
Instruction 2
......
for i in range( 5 , -1 , -1 ) :
Instruction 1
Instruction 2
......
compteur = 1
while ( compteur < 8 ) :
compteur+=1
compteur = 0
while ( compteur < 6 ) :
compteur+=1
compteur = 15
while ( compteur < 15 ) :
compteur+=1
compteur = 0
a = 1
while ( compteur < 10 ) :
print ( a )
a = a * 2
Corriger et réécrire ce programme plus judicieusement.
compteur = 0 # une seule variable pour tout faire...
while ( compteur < 10 ) :
print ( 2 ** compteur )
compteur += 1
Que s'affiche-t-il à la fin de l'exécution de chacun des scripts suivants ?
Pour ces applications, boucle for
ou while
, à vous de choisir la mieux adaptée selon la situation...
Écrire une boucle qui affiche 20 fois le mot "Echo".
1 3 6 9 12 15 18 21 24 27 30
Une contrainte : utiliser la valeur du compteur elle-même pour effectuer le calcul des multiples.
print
, utiliser la syntaxe suivante :
print( affichage , end = ' ') # un espace entre les guillemets
Pour revenir à la ligne ( ou également pour en sauter une ) :
print()
Écrire une boucle qui affiche un compte à rebours de 20 à 0 INCLUS
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Écrire un programme qui permette d'afficher un calendrier pour un mois de 28 jours avec chaque semaine sur une ligne différente.
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
Le but du jeu : le programme tire un nombre entier au hasard ( entre 1 et 100 par exemple ) ; le joueur doit essayer de deviner le nombre, et doit faire des propositions. Chaque proposition est évaluée, et le programme doit afficher " Trop grand", "Trop petit", ou "Gagné !" après chaque proposition.
Le programme doit "tourner" tant que le joueur n'a pas donné la bonne réponse...
Il sera nécessaire d’utiliser la fonction randint
( tirage aléatoire d'un nombre entier ) qu'il faudra importer depuis le module random
.
On pourra n'importer que cette fonction ou bien le module entier...
Pour utiliser ensuite la fonction dans le programme :
nombre = randint( borne1 , borne2 )
→ renvoie un entier dans une plage entre deux bornes ( incluses ).
Pour importer la fonction tirage aléatoire d'entier :
from random import randint
Pour les bornes sur le nombre à tirer au hasard entre 1 et 100 :
n = randint( 1 , 100 )
nombre ← tirage au hasard entier entre 1 et 100 entree ← 0 tant que entree != nombre : entree ← entree utilisateur si entree > nombre alors afficher "Trop grand !" si entree < nombre alors afficher "Trop petit !"
sinon afficher "Bravo !" fin si fin tant que