Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Les boucles while

Motivation: répéter ou ne pas se répéter?

Un ordinateur est capable d’effectuer des tâches répétitives très rapidement et sans s’ennuyer. Pas nous! Aussi le principe suivant de programmation va revenir comme un leitmotiv tout au long de ce cours :

«Ne te répètes pas».

En anglais cela donne l’acronyme mnémotechnique «DRY»:

Don’t Repeat Yourself

Nous avions vu un premier exemple de ce principe dans la fiche on regarde devant soi avec ce labyrinthe:

from laby.global_fr import *

Laby(niveau="2a")

La proposition de solution ci-dessous n’est pas satisfaisante: elle est longue et répétitive. De plus, elle n’est pas générale: il faut compter le nombre de cases du couloir et écrire une solution différente selon le cas.

debut()
avance()
avance()
avance()
avance()
avance()
avance()
avance()
avance()
avance()
avance()
avance()
ouvre();

Pour palier cela, nous avions alors découvert un premier outil pour éviter les répétitions dans le code: la boucle while. Cet outil nous a permis de programmer la consigne: «Tant que c’est vide devant toi, avance!».

Dans cette fiche, nous allons introduire formellement les boucles while. C’est un premier exemple d’instructions itératives: ces instructions permettent de répéter un certain nombre de fois l’exécution d’un bloc d’instructions sous certaines conditions. De façon imagée, on appelle boucle cette méthode permettant de répéter l’exécution d’un bloc d’instructions.

La boucle while : syntaxe et sémantique

Une boucle while s’écrit de la façon suivante:

et est exécutée par Python comme suit:

Une boucle while commence donc toujours par une condition. Python vérifie si celle-ci 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 d’instructions qui est juste en dessous. Une fois cette première itération effectuée, Python vérifie si la condition est encore vraie, et si oui exécute une nouvelle fois le bloc d’instructions; et ainsi de suite, jusqu’à ce que la condition ne soit plus vérifiée. Alors, l’exécution sort de la boucle et la suite du programme prend le relais.

Premiers exemples

Voici le programme que nous avions écrit pour le couloir:

from laby.global_fr import *

Laby(niveau="2a")
debut();

while regarde() == Vide:
    avance()

ouvre();

Notez la condition regarde() == Vide et le bloc d’instruction réduit à une seule instruction avance(). Notez aussi l’indentation de quatre espaces devant avance(), tandis que ouvre() -- qui vient après la boucle -- n’est pas indenté.

Exécutez maintenant la cellule suivante et observez le résultat :

n = 1

while n <= 5:
    print(n)
    n = n + 1

Nous avons réalisé un programme permettant de compter de 1 à 5. Quelle est la condition? Quelles sont les instructions dans le bloc d’instructions?

Exercice 1 : première boucle while

n = 1
a = 5
while n <= a:
    print(n)
    n = n + 1

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:

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

### BEGIN SOLUTION
b = 18
c = 5
### END SOLUTION
while b >= c:
    b = b - c
b

Test automatique (ne doit rien afficher) :

assert b == 3
### 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
k  # doit afficher 5

Tests automatiques :

assert b == 3
assert k == 5

Exercice 4 : suite de Syracuse

d = 5
if d % 2 == 0:
    d = d // 2
else:
    d = 3 * d + 1
print(d)

Vous noterez que lorsque le nombre dd 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.

### BEGIN SOLUTION
d = 5
while d > 1:
    if d % 2 == 0:
        d = d // 2
    else:
        d = 3 * d + 1
    print(d)
### END SOLUTION

Exercice 5

def mystere(n):
    k = 1
    while k * k < n:
        k = k + 1
    return k
mystere(5)
n = 0
### BEGIN SOLUTION
n = 36
### END SOLUTION
mystere(n)
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!

n = 1

while True:
    print(n)  # Affiche la valeur de n
    n = n + 1

Erreur classique : fin de boucle

Que vaut nn à la fin du programme suivant?

n = 1

while n <= 5:
    n = n + 1

print(n)

À retenir :

Bilan

Vous pouvez à présent vous entraîner sur des exercices supplémentaires en exécutant la cellule suivante, ou 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 ♣

def carreParfait(n):
    ### BEGIN SOLUTION
    k = 0
    while k * k < n:
        k = k + 1
    return k * k == n
    ### END SOLUTION
carreParfait(16)  # doit renvoyer true
carreParfait(20)  # doit renvoyer false
assert carreParfait(0)
assert carreParfait(1)
assert not carreParfait(2)
assert not carreParfait(50)
assert carreParfait(100)
assert not carreParfait(250)