Boucles conditionnelles#

Qu'est-ce qu'une boucle conditionnelle ?#

Dans le précédent chapitre, nous avons commencé à programmer notre jeu du Devin, mais avons également remarqué que le problème de ce début de programme était qu'on ne pouvait deviner qu'une seule fois le nombre mystère avant que le programme s'arrête. Grâce à une boucle, il sera alors possible de demander plusieurs fois à l'utilisateur de deviner un nombre jusqu'à ce qu'il ait trouvé le nombre mystère. De manière générale, une boucle conditionnelle permet de répéter l'exécution d'un bloc d'instructions plusieurs fois tant qu'une certaine condition est respectée. On peut typiquement penser à un système de connexion qui ne laisse pas l'utilisateur entrer dans le système avant que le bon mot de passe soit donné. Le programme ressemblerait alors à ceci.

Afficher "Connectez-vous"
Demander le mot de passe à l’utilisateur
Tant que le mot de passe est différent de "Fr1B0urg"
    Afficher "Mot de passe incorrect"
    Redemander le mot de passe à l’utilisateur
Afficher "Mot de passe correct, bienvenue"

Grâce à l'instruction tant que, le bloc d'instruction indenté en dessous est répété en boucle tant que la condition mot de passe est différent de "Fr1B0urg" est vraie. Comme la dernière instruction n'est pas indentée, celle-ci ne sera pas exécutée avant que l'exécution de la boucle soit terminée, et ainsi que le mot de passe soit correct. Ainsi, en fonction des entrées de l'utilisateur, on peut distinguer les exécutions suivantes.

La boucle while#

En Python, la boucle conditionnelle tant que se traduit littéralement par le mot anglais while. Ce mot-clef est suivi d'une expression conditionnelle qui détermine la condition d'arrêt de la boucle, et la ligne se termine par deux points. À chaque fois que le programme passe par cette ligne, l'expression conditionnelle est réévaluée, et, à chaque fois que le résultat de cette évaluation est True, le bloc d'instructions indenté en dessous est exécuté. Après ce bloc indenté, l'exécution remonte à la ligne du while pour réévaluer l'expression conditionnelle. Ainsi, l'exemple du programme de connexion avec un mot de passe peut s'écrire de la manière suivante en Python.

Programme Python de contrôle de mot de passe#
print("Connectez-vous")
mdp = input("Entrez le mot de passe")
while mdp != "Fr1B0urg" :
    print("Mot de passe incorrect")
    mdp = input("Entrez à nouveau le mot de passe")
print("Mot de passe correct")

Etude de cas : le jeu du Devin#

Nous possédons maintenant presque tous les éléments pour créer le jeu du Devin en entier. Pour commencer, reprenons le code que nous avions élaboré dans le chapitre sur les branchements conditionnels.

Jeu du Devin incomplet (un seul essai)#
nombre_mystere = 76
nombre_du_joueur = int(input("À quel nombre est-ce que je pense ?"))
if nombre_du_joueur > nombre_mystere:
    print("Le nombre est trop grand")
elif nombre_du_joueur < nombre_mystere:
    print("Le nombre est trop petit")
else:
    print("Félicitations ! Tu as trouvé le nombre mystère")

Nous voulons ici que toutes les instructions, sauf la première, soient répétées tant que l'utilisateur n'a pas trouvé le nombre mystère, c'est-à-dire tant que le nombre du joueur est différent du nombre mystère. Ainsi, on peut ajouter un while, avec la condition nombre_du_joueur != nombre_mystere, et indenter toutes les autres instructions sous ce while.

Jeu du Devin complet (mais avec un bug !)#
nombre_mystere = 76
while nombre_du_joueur != nombre_mystere:
    nombre_du_joueur = int(input("À quel nombre est-ce que je pense ?"))
    if nombre_du_joueur > nombre_mystere:
        print("Le nombre est trop grand")
    elif nombre_du_joueur < nombre_mystere:
        print("Le nombre est trop petit")
    else:
        print("Félicitations ! Tu as trouvé le nombre mystère")

Ce programme semble contenir tous les éléments nous permettant de jouer à notre jeu du Devin. Toutefois, si vous essayez de l'exécuter, vous obtiendrez l'erreur suivante.

En lisant ce message d'erreur, on peut comprendre ce qui est incorrect dans notre programme. On voit que, lorsque la ligne 2 est exécutée, la variable nombre_du_joueur n'a pas été définie. En effet, on utilise ici cette variable dans une expression avant de l'avoir créée. Pour remédier à ce problème, il faut donc créer cette variable avant la ligne du while. La valeur initiale de cette variable n'a aucune importance, tant qu'elle est différente du nombre mystère. On peut ainsi décider de l'initialiser, par exemple, à -1.

Jeu du Devin complet#
nombre_mystere = 76
nombre_du_joueur = -1
while nombre_du_joueur != nombre_mystere:
    nombre_du_joueur = int(input("À quel nombre est-ce que je pense ?"))
    if nombre_du_joueur > nombre_mystere:
        print("Le nombre est trop grand")
    elif nombre_du_joueur < nombre_mystere:
        print("Le nombre est trop petit")
    else:
        print("Félicitations ! Tu as trouvé le nombre mystère")

À ce point-là, le programme est complètement fonctionnel. Toutefois, le nombre mystère n'est pas si mystérieux que ça puisqu'il ne change pas d'exécution en exécution. Nous allons donc modifier ce nombre mystère pour que celui-ci soit aléatoire. Pour cela, nous allons devoir importer un nouveau module nommé random. Celui-ci importe entre autres la fonction randint(). Elle permet de choisir un nombre entier aléatoire compris entre deux bornes. Ces bornes doivent être écrites entre les parenthèses du randint() et sont séparées par une virgule. Ainsi, voici le programme complet du jeu du Devin.

from random import *
print("Je pense à un nombre entre 1 et 100")
nombre_mystere = randint(1, 100)
while nombre_du_joueur != nombre_mystere:
    nombre_du_joueur = int(input("À quel nombre est-ce que je pense ?"))
    if nombre_du_joueur > nombre_mystere:
        print("Le nombre est trop grand")
    elif nombre_du_joueur < nombre_mystere:
        print("Le nombre est trop petit")
    else:
        print("Félicitations ! Tu as trouvé le nombre mystère")

Etude de cas : calcul d'une moyenne#

Nous allons maintenant créer un programme dans lequel l'utilisateur pourra consécutivement entrer les notes qu'il a faites dans une branche afin que le programme lui calcule sa moyenne. Bien que nous connaissions déjà tous les concepts théoriques permettant de réaliser ce programme, celui-ci nous permettra de découvrir quelques astuces de développement qui vous seront utiles pour la suite.\ Pour commencer, il faut réfléchir à la manière dont on procède normalement pour calculer sa moyenne dans une branche. Typiquement, on commence par additionner toutes les notes que l'on a, puis, on divise ce total par le nombre de notes. C'est également ce que l'on va faire dans notre programme. Il nous faudra donc une variable détenant la somme des notes, ainsi qu'une variable détenant le nombre de notes. Comme l'utilisateur va donner ses notes au fur et à mesure, on ne connaît aucune de ces deux valeurs au début du programme. On va donc les initialiser à 0.

somme_notes = 0
nb_notes = 0

À chaque fois que l'utilisateur entrera une note, on l'ajoutera à la variable somme_notes, et on incrémentera la variable nb_notes de 1. La prochaine étape logique est donc de demander à l'utilisateur d'entrer des notes en boucle.

somme_notes = 0
nb_notes = 0
while ... :
    note = float(input("Entrez une note"))

Quelle devrait être la condition d'arrêt de cette boucle ? On aimerait en sortir lorsque l'utilisateur a terminé d'entrer toutes ses notes. Comme nous ne savons pas quand cela va se produire, il faut que l'utilisateur ait un moyen de nous le communiquer. Une idée est que si l'utilisateur n'entre pas une note valide (c'est-à-dire supérieure ou égale à 1 et inférieure ou égale à 6), alors on sort de la boucle et le programme se termine. Comme il s'agit d'une condition sur la variable note, il est également impératif de la créer avant le while, même si sa valeur initiale n'a pas vraiment d'importance. Nous pouvons donc ajouter cette nouvelle variable à notre programme avec une expression conditionnelle utilisant l'opérateur logique and pour contrôler les deux bornes d'une note valide.

somme_notes = 0
nb_notes = 0
note = 4
while note >= 1 and note <= 6 :
    note = float(input("Entrez une note. Entrez une note invalide pour terminer"))

Il faut maintenant mettre à jour les variables somme_notes et nb_notes en faisant attention à ne pas changer leur valeur lorsque la note entrée est invalide. Pour cela, on peut utiliser un branchement conditionnel avec un seul if contrôlant la validité de la note. Il ne reste alors plus qu'à afficher la moyenne, qui correspond à la division de somme_notes par nb_notes, à la fin du programme. Ainsi, le programme suivant est terminé et permet de facilement calculer une moyenne.

somme_notes = 0
nb_notes = 0
note = 4
while note >= 1 and note <= 6 :
    note = float(input("Entrez une note. Entrez une note invalide pour terminer"))
    if note >= 1 and note <= 6:
        somme_notes += note
        nb_notes += 1
print("Votre moyenne est de", somme_notes / nb_notes)

En programmation, on retrouve souvent des variables ayant un comportement similaire à somme_notes et nb_notes. On appelle somme_notes une variable accumulateur, puisqu'on y accumule constamment de nouvelles valeurs. nb_notes est appelé une variable compteur, puisqu'elle compte combien de fois une certaine action est effectuée. Retenez bien ces concepts, car ils vous seront souvent utiles ! Par exemple, quand vous développerez plus tard un petit jeu vidéo, vous aurez très probablement besoin d'un accumulateur pour stocker les points que le joueur marque au fur et à mesure de sa progression. De plus, un compteur pourrait vous être utile pour connaître le nombre d'ennemis éliminés une fois la partie terminée.

(exo_boucles_cond=)

Exercices#

Exercice 1#

Expliquez la différence entre les deux programmes suivants.

Programme 1#
n = 5
if n < 10:
    n += 1
    print(n)
Programme 2#
n = 5
while n < 10:
    n += 1
    print(n)

Exercice 2#

Faites le tableau d'état et donnez l'affichage de l'exécution du programme suivant.

x = 0
y = 20
while x < y:
    y -= x * 2
    x = x + 2
    print(x + y)

Exercice 3#

Faites le tableau d'état et donnez l'affichage de l'exécution du programme suivant.

n = 30
x = 0
while n != 20:
    n -= 2
    if n < 26:
        x += 2
    else:
        x -= 1
    x = x * 2

Exercice 4#

  1. Écrivez un programme utilisant seulement 2 instructions print() affichant un compte à rebours de 1000 jusqu'à 0. L'exécution du programme ressemblera à ceci :

1000
999
998
...
2
1
0
BOOM
  1. Complétez ce programme avec une nouvelle instruction print() de manière à ce qu'à chaque fois qu'il affiche un nombre inférieur à 10 il affiche également le texte "FUYEZ !", comme suivant :

1000
999
998
...
2 FUYEZ
1 FUYEZ
0 FUYEZ
BOOM`

Exercice 5#

Écrivez un programme dans lequel l'utilisateur peut choisir un nombre pour lequel il souhaite voir apparaître sa table de multiplication jusqu'à 10. Un message d'au revoir sera également affiché à la fin. Votre programme ne doit utiliser que 2 instructions print(). Un exemple d'exécution pourrait être le suivant :

Quelle table de multiplication voulez-vous voir ?4
1x4 = 4
2x4 = 8
3x4 = 12
...
10x4 = 40

Exercice 6#

Lisez attentivement le programme suivant. Décrivez ensuite précisément son fonctionnement. Testez-le ensuite pour vérifier votre raisonnement.

pizza = "sauce tomate, mozarella"
prix_base = 12.5
prix_jambon = 4
prix_ananas = 2
prix_champignons = 2.5
prix_pepperoni = 3
ingredient = ""
while ingredient != "fin":
    ingredient = input("Que voulez-vous ajouter sur la pizza ?")
    ingredient_ok = True
    if ingredient == "jambon":
        prix_base += prix_jambon
    elif ingredient == "ananas":
        prix_base += prix_ananas
    elif ingredient == "pepperoni":
        prix_base += prix_pepperoni
    elif ingredient == "fin" :
        print("Commande terminée")
        ingredient_ok = False 
    else:
        print("On ne peut pas faire cela...")
        ingredient_ok = False
    if ingredient_ok:
        print(ingredient, " a été ajouté sur la pizza")
        pizza += ", " + ingredient
print("Votre pizza est composée de", pizza)
print("Coût :", prix_base)

Exercice 7#

Écrivez un programme dans lequel l'utilisateur peut consécutivement entrer les notes qu'il a faites dans une branche. À la fin, le programme affichera le nombre de notes insuffisantes qui ont été entrées. Les notes invalides seront simplement ignorées. Pour terminer le programme, l'utilisateur entrera la note 99. Un exemple d'exécution peut être le suivant.

Entrez une note : 4.5
Entrez une note : 3.4
Entrez une note : 6
Entrez une note : 3.9
Entrez une note : 5.1
Entrez une note : 99
Vous avez fait 2 notes insuffisantes

Exercice 8#

Ecrivez un programme correspondant à une mini machine à calculer. Dans celle-ci, l'utilisateur pourra choisir de faire une addition, soustraction ou multiplication entre 2 nombres. Le programme demandera alors à l'utilisateur quel type d'opération il souhaite faire, avant de lui demander les 2 nombres à utiliser. Le programme demandera à l'utilisateur des opérations à faire en boucle, jusqu'à ce que celui-ci écrive "STOP". Un exemple d'utilisation est donné ci-dessous.

Bienvenue dans la mini calculatrice !
Quelle opération souhaitez-vous effectuer ?addition
Quel est le premier nombre ?4
Quel est le deuxième nombre ?7
Le résultat de 4 + 7 est 11

Quelle opération souhaitez-vous effectuer ?multiplication
Quel est le premier nombre ?9
Quel est le deuxième nombre ?11
Le résultat de 9 * 11 est 99

Quelle opération souhaitez-vous effectuer ?STOP
Au revoir !