Les boucles while
#
En programmation, il y a des ensembles d’instructions qu’il faut répéter plusieurs fois. Par exemple, si vous voulez réaliser une même tâche sur tous les éléments d’une liste.
Quand vous avez besoin de répéter un ensemble d’instructions, parfois vous savez combien de fois vous allez le répéter, d’autres fois vous ne savez pas. Parfois, le nombre de répétitions n’est pas important, et vous voulez répéter le code jusqu’à ce qu’une certaine condition soit remplie.
Pour tous ces usages, vous allez utiliser des boucles.
Le rôle d’une boucle while
est d’exécuter un bloc de code, c’est-à-dire un certain nombre d’instructions, tant qu’une condition est vraie.
Une boucle while en Python commence donc toujours par un test logique. Python vérifie si une condition est vraie : si elle ne l’est pas, on ne rentre même pas dans la boucle ! En revanche, si la condition est vraie, Python exécute le bloc de code qui est juste en dessous.
Une fois la première itération effectuée, Python vérifie à nouveau si la condition est vraie ou non. Tant que la condition est vraie, Python exécute une nouvelle fois le bloc de code.
La boucle while
s’arrête lorsque le test logique n’est plus vérifié. Alors, il n’exécute pas le bloc de code en dessous, et sort de la boucle. La suite du programme prend le relais.
Lorsqu’on écrit une boucle WHILE, il faut faire attention à deux choses :
la première ligne se termine toujours par deux points “:”
le bloc de code qui contient les instructions doit être indiqué par une indentation. C’est comme ça que Python fait la différence entre ce qui est inclus dans la boucle
while
, et le reste du programme.
Exécutez la cellule suivante et observez le résultat :
n = 1
while n <= 5:
print(n)
n = n + 1
1
2
3
4
5
Nous avons réalisé un programme permettant de compter de 1 à 5.
Exercice 1 : première boucle while#
Exécutez la cellule suivante :
n = 1
a = 5
while n <= a:
print(n)
n = n + 1
1
2
3
4
5
Modifiez la valeur de
a
ci-dessus pour obtenir :
Exactement 1 affichage
Exactement 0 affichage
Exactement 4 affichages
Exercice 2 : Panique dans le noir#
Notre fourmi est perdue dans un labyrinthe plongé dans le noir. Elle panique! Avant chaque pas, elle tourne aléatoirement vers la gauche ou vers la droite. Va-t-elle trouver la sortie?
À vous de le découvrir en programmant ce comportement de la fourmi!
Pour simuler le noir, nous avons écrit une fonction qui place la porte de façon aléatoire. Exécutez les deux cellules suivantes. À chaque création du labyrinthe, la porte est placée dans un endroit différent. Le même programme doit toujours fonctionner !
Indications:
Vous pouvez utiliser la condition
regarde() != Sortie
;Pour tirer à pile ou face si la fourmi va tourner à gauche ou à droite, vous pouvez utiliser la fonction
random.randint(0,1)
qui renvoie aléatoirement 0 ou 1.
import random
def porteAleatoire():
s = "o o o o o o o\n"
s += "o → . . . . o\n"
ligne = random.randint(0, 3)
col = random.randint(0, 4)
for i in range(4):
s += "o "
for j in range(5):
if ( i == ligne and j == col ):
s += "x "
else:
s += ". "
s += "o\n"
s += "o o o o o o o\n"
return s
from laby.global_fr import *
Laby(carte = porteAleatoire())
debut()
### BEGIN SOLUTION
while ( regarde() != Sortie ):
if ( random.randint(0,1) == 0 ):
gauche()
else:
droite()
avance()
ouvre()
### END SOLUTION
Exercice 3 : division euclidienne par soustraction#
Observez les cellules suivantes, puis dans la cellule suivante, affectez des valeurs à \(b\) et \(c\) avec \(b > c\) de sorte que, à la fin de la boucle, on ait \(b=3\) :
### BEGIN SOLUTION
b = 18;
c = 5;
### END SOLUTION
while ( b >= c ):
b = b - c
b
3
Test automatique (ne doit rien afficher) :
assert( b == 3 )
Modifiez la cellule ci-dessous en introduisant une variable \(k\) qui compte le nombre d’exécutions de la boucle;
Affectez à \(b\) et \(c\) avant la boucle des valeurs de sorte que, à la fin de la boucle, on ait \(b=3\) et \(k=5\).
### BEGIN SOLUTION
b = 23;
c = 4;
k = 0;
### END SOLUTION
while ( b >= c ):
b = b - c
### BEGIN SOLUTION
k = k + 1
### END SOLUTION
b # doit afficher 3
3
k # doit afficher 5
5
Tests automatiques :
assert( b == 3 )
assert( k == 5 )
Exercice 4 : suite de Syracuse#
Exécutez, sans la modifier, la cellule ci-dessous puis trois fois la deuxième cellule :
d = 5
if ( d % 2 == 0):
d = d // 2;
else:
d = 3 * d + 1
print(d)
16
Vous noterez que lorsque le nombre \(d\) est pair, on le divise par 2
(avec l’opérateur de division entière //
). Lorsqu’il est impair,
on le multiplie par 3 et on ajoute 1.
Réécrivez la cellule en la complétant pour que l’on répète cette action tant que le nombre \(d\) est supérieur à 1. On veut afficher la valeur de \(d\) à chaque fois. Si votre code est correct, il doit afficher 16 8 4 2 1 (en partant de d=5).
### BEGIN SOLUTION
d = 5
while d > 1:
if d % 2 == 0:
d = d // 2;
else:
d = 3 * d + 1
print(d)
### END SOLUTION
16
8
4
2
1
Exercice 5#
Obervez la fonction suivante et essayez de comprendre ce qu’elle calcule en lisant le code et en essayant plusieurs valeurs d’appel :
def mystere(n):
k = 1
while k * k < n:
k = k + 1
return k
mystere(5)
3
Déterminez une valeur de n tel que la valeur renvoyée soit 6 :
n = 0
### BEGIN SOLUTION
n = 36
### END SOLUTION
mystere(n)
6
assert( mystere(n) == 6 )
La boucle while : d’autres exemples#
Cas particulier : condition toujours fausse#
Si la valeur de la condition est fausse dès le départ, alors le bloc d’instructions ne sera jamais exécuté!
n = 1
while n <= 0:
print(n) ## Affiche la valeur de n
n = n + 1;
Cas particulier : condition toujours vraie#
Si la valeur de la condition est toujours vraie, alors le bloc d’instructions sera exécuté indéfiniment!
Avertissement
Attention ⚠️ L’exemple suivant ne va pas s’arrêter! Il faudra redémarrer le noyau (menu Noyau) ⚠️
n = 1
while True:
print(n) # Affiche la valeur de n
n = n + 1
Erreur classique : fin de boucle#
Que vaut \(n\) à la fin du programme suivant?
n = 1
while n <= 5:
n = n + 1
print(n)
6
À retenir :
On sort de la boucle quand la condition vaut «Faux»; le compteur est donc «un cran trop loin».
Bilan#
Vous pouvez à présent vous entraîner sur des exercices supplémentaires en exécutant la cellule suivante, ou retourner à l’index et passer à la feuille sur les boucles for. Vous pourrez, par la suite, aborder l’exercice plus avancé ci-dessous.
Exercices supplémentaires#
import glob, os
from jupylates import Exerciser
os.chdir("../Exercices")
Exerciser(glob.glob("boucles-while/*"), mode="train")
Exercice 6 ♣#
Complétez le code de la fonction suivante pour qu’elle détermine si \(n\) est un carré parfait. Dans ce cas, elle doit renvoyer
true
; sinon elle doit renvoyerfalse
.Rappel: un carré parfait est un nombre qui peut s’écrire \(k\times k\) avec \(k\) un entier. Par exemple \(16\) est un carré parfait car \(16 = 4 \times 4\), mais \(20\) n’est pas un carré parfait.
def carreParfait(n):
### BEGIN SOLUTION
k = 0
while ( k * k < n ):
k = k + 1
return k*k == n
### END SOLUTION
Essayez votre fonction sur les exemples suivants :
carreParfait(16) # doit renvoyer true
carreParfait(20) # doit renvoyer false
Vérifiez que votre fonction passe les tests automatiques suivants :
assert( carreParfait(0) )
assert( carreParfait(1) )
assert( not carreParfait(2) )
assert( not carreParfait(50) )
assert( carreParfait(100) )
assert( not carreParfait(250) )