Les boucles



Tout comme les conditionnelles, les boucles sont des structures de contrôle fondamentales de la programmation.

Par l'intermédiaire d'une boucle, on peut demander à un ordinateur de répéter une partie de code.

Il existe deux manières d'écrire un boucle en Python: la boucle while et la boucle for.

Pour illustrer nos explications, nous utiliserons le problème de l'affichage de nombres consécutifs (c'est à dire, des nombres entiers qui se suivent).

Avec ce que vous avez vu jusqu'ici, vous sauriez écrire un programme affichant un nombre fixe de nombres consécutifs. Par exemple, pour afficher trois entiers consécutifs à partir d'un entier donné N, vous commencez par lire la valeur de N, puis vous affichez N, N+1 et N+2. Cela vous demandera trois instructions d'affichage.

Par contre, vous seriez plus embêté si l'on vous demandait d'afficher 1000 nombres consécutifs à partir d'un entier donné. Sans les boucles, il vous faudrait écrire 1000 instructions d'affichage. Avec les boucles, nous verrons qu'il vous suffira d'en écrire une seule, en précisant à l'ordinateur comment la répéter.

D'autre part, les boucles n'ont pas comme seul intérêt d'éviter la répétition inutile d'instructions. Un problème bien plus difficile (sinon impossible) à traiter sans boucle surgit lorsque le nombre de répétitions dépend des données. Comment feriez vous par exemple pour afficher un nombre M de nombres consécutifs à partir d'un entier N donné ? Vous ne pouvez pas savoir combien il vous faudra écrire d'instructions d'affichage, puisque cela dépendra de la valeur de M !

I - Présentation des exemples

Pour expliquer le fonctionnement des boucles en Python, nous nous appuyerons sur trois exemples de programme affichant des nombres entiers consécutifs. Vous les trouverez dans le répertoire Exemple-Python-StrucControle.

Deux de ces programmes permettent d'afficher tous les nombres consécutifs compris entre deux nombres donnés:

Exemple d'exécution (le comportement des deux programmes est identique du point de vue de l'utilisateur) :

Du1er-Au-Dernier.jpg, 19kB

Le troisième programme permet d'afficher tous les nombres consécutifs jusqu'au premier multiple de 7 rencontré. Il se nomme NC-Jusqua-Mult7 et fonctionne avec une boucle while.

Exemple d'exécution :

Jusqua-Mult7.jpg, 12kB

II - Les boucles while

Commencons par quelques généralités sur les boucles while.

Une boucle while permet de répéter du code tant qu'une certaine condition est vraie.

Elle s'écrit de la manière suivante :

while condition :
  Bloc d'instructions à répéter
  tant que la condition est vraie

Comme dans les conditionnelles, toutes les instructions du bloc doivent être alignés verticalement à gauche.

Chaque exécution du bloc d'instruction à répéter s'appelle une itération

La condition est une expression logique quelconque. Dans une boucle while elle est évaluée avant chaque itération.

Passons à présent aux deux exemples de programme utilisant while.


Exemple 1

Voilà comment nous affichons les nombres consécutifs compris entre deux nombres avec le programme NC-Du1er-Au-Dernier-W :

premier = int(input("Premier nombre : "))
dernier = int(input("Dernier nombre : "))

n = premier
print("Liste: ",end="")

while n <= dernier :
    print(str(n)+" ", end="")
    n+=1

La variable n est utisée pour mémoriser successivement les différentes valeurs des entiers. Commençons par l'intérieur de la boucle. On y trouve deux instructions. La première affiche la valeur de n, puis, afin que la prochaine itération affiche l'entier suivant, la seconde incrémente n.

Une variable de type entier que l'on incrémente (ou décrémente) à chaque itération porte le nom de compteur.

Ces deux opérations doivent être répétées tant que n est inférieur ou égal au dernier nombre souhaité. D'où la condition (n <= dernier).

Pour commencer l'affichage au premier nombre souhaité, on affecte à n la valeur de ce nombre (instruction n = premier ) avant d'exécuter la boucle.


Exemple 2

Le deuxième exemple que nous présentons ici se nomme NC-Jusqua-Mult7. Il affiche tous les nombres entiers supérieurs à un nombre donné jusqu'à rencontré un mutltiple de 7.

premier = int(input("Nombre de depart : "))

print("Liste: "+str(premier)+" ",end="")

if premier % 7 != 0 :
    n = premier + 1
    while n % 7 != 0 :
        print(str(n)+" ", end="")
        n+=1   
    print(str(n))

Nous en profitons ici pour présenter l'opérateur %, qui donne le reste de la division entière d'un nombre entier par un autre nombre entier. Par exemple, 18 % 7 = 4 car 18 = 2 X 7 + 4. Cet opérateur permet en particulier de savoir si un nombre entier est un multiple d'un autre nombre entier, puisque dans ce cas le reste de la division du premier par le second est 0. Par exemple, n % 7 vaudra 0 si et seulement si n est un multiple de 7.

Revenons à notre problème. Nous voulons afficher une suite de nombres consécutifs se terminant par un multiple de 7.

On remarque qu'une liste de nombres de ce type n'est jamais vide. Si le premier nombre est un multiple de 7, elle s'arrête là. Sinon, elle contiendra plus d'un nombre. En conclusion, le nombre de départ sera de toute facon dans la liste. C'est la raison pour laquelle nous affichons tout de suite le premier nombre dans la première instruction print.

Nous testons ensuite si le premier nombre est un multiple de 7. Si c'est le cas, il n'y a plus rien à faire. Sinon, on rentre dans une boucle while qui démarre à n = premier+1 et continue tant que n n'est pas un multiple de 7 (condition n % 7 != 0).

Tant que n n'est pas un multiple de 7, on l'affiche puis on incrémente n. La boucle s'arrête dès que n est un multiple de 7. Ce dernier nombre ne sera donc pas affiché par la boucle ! Par conséquent, nous devons encore ajouter une instruction d'affichage à la sortie de la boucle.

III - Les boucles for

Les boucles for sont un raccourci d'écriture pour un certain type de boucle while. Plus particulièrement, les boucles while dans lesquelles on fait varier un compteur entre une valeur de départ VD et une valeur finale VF:

compteur = VD
while compteur < VF :
    Bloc d'instructions à répéter
    i+= 1

Avec une boucle for, ceci peut s'écrire:

for  compteur in range (VD,VF) :
   Bloc d' instructions à répéter

Ici le programmeur n'a plus à se préoccuper du compteur. Il est automatiquement initialisé à la valeur de départ et incrémenté à chaque itération.

Remarquez que la dernière valeur du compteur est VF - 1 et non pas VF.

Voilà comment nous affichons les nombres consécutifs compris entre deux nombres avec le programme NC-Du1er-Au-Dernier-F :

premier = int(input("Premier nombre : "))
dernier = int(input("Dernier nombre : "))

print("Liste: ",end="")

for  n in range (premier,dernier+1) :
    print(str(n)+" ", end="")

Pour comparer ce code avec la version utilisant une boucle while,cliquez ici.

V - Les boucles de saisie des données

Jusqu'à présent pour tester un programme sur différentes données vous étiez obliger de le relancer. Avec les boucles, il est possible d'éviter ceci en organisant les programmes différement. On écrit une boucle de saisie des données dans le programme principal. A chaque itération de cette boucle, l'utilisateur peut effectuer différents choix correspondant à différents traitements de données. Un de ces choix lui permet d'arrêter le programme. Tant que l'utilisateur n'effectue pas ce choix, le programme continue de tourner.

Pour fixer les idées, nous vous présentons ici un exemple de programme contenant une boucle de saisie des données. Il s'agit du projet NombresConsecutifs que vous trouverez dans le dossier Exemple-Python-StructControle.

Lorsque vous lancez le programme, il vous affiche ceci:

NbrConsec1.jpg, 15kB

Le choix 1 permet d'obtenir tous les nombres entiers compris entre deux nombres:

NbrConsec2.jpg, 32kB

Le choix 2 permet d'obtenir tous les nombres consécutifs à partir d'un certain nombre jusqu'à rencontrer un multiple de 7:

NbrConsec3.jpg, 46kB

et le choix 3 permet de s'arrêter. Mais tant que l'utilisateur n'effectue pas ce choix, le programme ne s'arrête pas et continuera indéfiniment à lui proposer les trois choix.

Voici, le code du programme:

choix = 0

while choix != 3 :

    print("1: Du premier au dernier") 
    print("2: Jusqu'a un multiple de 7") 
    print("3: Arreter") 

    choix = int(input("Votre choix: "))
            
    if choix == 1 :
        .
        .      
    elif choix == 2 : 
        .
        .

Pour ne pas surcharger l'exemple, une partie du code a été ommise. Après choix == 1 se trouve le code du programme NC-Du1er-Au-Dernier-F et après choix == 2, celui du programme NC-Jusqua-Mult7.

VI - Erreurs fréquentes

De manière générale, les instructions répétées à l'intérieur d'une boucle vont modifier certaines variables, que j'appelerais variables de la boucle. Dans les cas les plus simple, il n'y en a qu'une seule (comme par exemple le compteur de la boucle).

Erreur d'initialisation

Initialiser une variable signifie lui donner une valeur de départ.

Afin que la boucle se déroule correctement, avant le démarrage de la boucle, les variables de la boucle doivent être initialisées de manière adéquate, puisque la suite des valeurs que prendrons ces variables dépend nécessairement de leurs valeurs de départ.

Une erreur fréquente est d'oublier d'initialiser les variables de la boucle ou de mal les initialiser.

Voilà par exemple une erreur d'initialisation dans le programme NC_Jusqua-Mult-7:

premier = int(input("Nombre de depart : "))

print("Liste: "+str(premier)+" ",end="")

if premier % 7 != 0 :
    n = premier 
    while n % 7 != 0 :
        print(str(n)+" ", end="")
        n+=1   
    print(str(n))

Nous avons intialisé n à Premier au lieu de Premier + 1. Dans ce cas le premier nombre de la suite sera affiché deux fois !

Boucle infinie

La condition d'arrêt d'une boucle dépend en général de certaines variables. Si ces variables ne sont jamais modifiées dans la boucle, on obtient ce que l'on appelle une boucle infinie: la condition d'arrêt n'est jamais réalisée. Dans ce cas l'ordinateur va continuer indéfiniment à répéter les instructions de la boucle, ce qui se traduira par un temps de réponse extrèmement long. La seule solution dans ce cas est de forcer d'une manière ou d'une autre l'arrêt du programme (ne débranchez pas l'ordinateur !). Vous pouvez par exemple fermer la fenêtre d'exécution ou taper CTRL C (maintenez la touche ctrl appuyée tout en appuyant sur la touche C) .

Voilà par exemple, une manière d'obtenir une boucle infinie dans le programme NC-Du1er-Au-Dernier-W :

premier = int(input("Premier nombre : "))
dernier = int(input("Dernier nombre : "))

n = premier
print("Liste: ",end="")

while n <= dernier :
    print(str(n)+" ", end="")

Nous avons simplement omis l'incrémentation du compteur n. Par conséquent la condition de la boucle sera toujours vraie (en supposant premier <= dernier) .