Un programme capable de faire des choix

Par Poulet, dernière mise à jour le 29/05/2010 à 17:37:39
Retour au sommaire

Introduction

- Source

Reprenons un des exemples de la leçon 1 :

print("Entrez votre âge :")
age = int(input())
print("Encore", 18-age, "ans avant la majorité !")

Que se passe-t-il si l'utilisateur rentre un âge supérieur à 18 ans ? Nous affichons alors un message qui n'a aucun sens. Cependant, nous ne pouvons pas connaître l'âge de notre utilisateur au moment où nous écrivons notre programme. Il faut donc donner la possibilité à ce dernier d'examiner la situation, et de choisir quel comportement adopter (même si ces comportements resteront ceux que nous avons programmés, bien sûr).

Ceci est rendu possible par une construction du langage Python appelée le test conditionnel. Il permet de choisir, en fonction d'une condition, d'exécuter un bloc de code plutôt qu'un autre. Sa syntaxe est la suivante :

if condition:
    instruction 1
    instruction 2
instruction 3

Un bloc de code est un ensemble d'instructions groupé, qui est mis en valeur par rapport au reste du code parce qu'il n'est pas exécuté dans les mêmes conditions (ici, il n'est exécuté que si la condition est remplie). On fera attention au fait que ce bloc de code est indenté, Python ne plaisantant pas à ce sujet (l'indentation définit les blocs de code).

Ainsi, dans l'exemple précédent, instruction 1 et instruction 2 ne sont exécutées que si la condition est satisfaite. En revanche, instruction 3 est toujours exécutée, car elle ne fait plus partie du bloc.

Il est possible de vouloir exécuter du code uniquement si la condition n'est pas remplie. On utilise alors le mot else (qui veut dire "sinon"). Il est également possible de vouloir raffiner les tests, à l'aide du mot elif (contraction de "else" et "if"). Revoici notre exemple, désormais infaillible :

print("Entrez votre âge :")
age = int(input())
if age < 18:
    print("Encore", 18-age, "ans avant la majorité.")
elif age > 18:
    print("Vous êtes majeur depuis déjà", age-18, "ans.")
else:
    print("Vous venez d'avoir vos 18 ans.")
    print("Joyeux anniversaire !")

Si vous avez déjà utilisé un langage dont la syntaxe est plus ou moins proche de celle du C, notez qu'en Python on évitera de mettre des parenthèses dans les conditions quand elles ne sont pas nécessaires.

L'écriture de conditions

- Source

Dans le code précédent, nous utilisons un nouveau type d'opérateurs qui vous sont très certainement déjà familiers : les > et <, qui signifient "strictement supérieur à" et "strictement inférieur à". Ce sont des opérateurs de comparaison, qui ne servent pas à effectuer des calculs, mais à comparer les objets entre eux.

Ils renvoient ce que l'on appelle un booléen : le type booléen comporte deux valeurs, True (pour "vrai") et False (pour "faux"). Un test conditionnel comme ceux qui précèdent a pour effet d'exécuter le bloc de code qui lui est attaché si la condition est évaluée à True.

Les opérateurs de comparaison sont <, >, <=, >=, == et !=. Une source d'erreur fréquente est de confondre = et == au sein d'une condition. Bien que l'affectation à l'aide de = soit impossible à un tel endroit, on fera attention à ne pas confondre ces deux opérateurs. Le premier sert à lier un nom et une valeur, le second sert à tester l'égalité.

Notez que par un mécanisme appelé la surcharge des opérateurs, sur lequel nous reviendrons, on peut utiliser les opérateurs de comparaison sur un grand nombre de types. Par exemple, le test

"foo" > "Foo"

renverra True (essayez dans le shell Python). Cependant, il ne faut pas demander l'impossible : Python n'acceptera pas les comparaisons qui n'ont aucun sens, comme celle d'un entier et d'une chaîne de caractères.

Les valeurs booléennes sont du type bool, et sont manipulables comme les autres. Elles supportent des opérations qui leur sont propres, à l'aide des opérateurs suivant

  • and, qui renvoie True si les deux opérandes sont évalués à True

  • or, qui renvoie True si l'un au moins des deux opérandes est évalué à True

  • not, qui nie une valeur booléenne (False devient True et inversement)

Répétition d'instructions

- Source

Les programmes informatiques sont souvent conçus pour effectuer un certain nombre d'opérations répétitives, produisant un certain résultat. On peut notamment vouloir répéter un bloc de code tant qu'une certaine condition est vérifiée (nous verrons des exemples en exercice). Ceci ne peut pas se faire à l'aide de ce que nous avons déjà rencontré : il faut utiliser une construction du langage appelée boucle conditionnelle. En Python, elle se note while :

while condition:
    bloc d'instructions indentées

Attention, bien souvent il faudra penser à inclure dans le bloc indenté le nécessaire pour que la condition cesse d'être vraie - sans quoi vous vous retrouverez avec une boucle infinie. Considérez l'exemple suivant :

i = 10
while i > 0:
    print(i)
    i = i - 1
print("Boum !")

De même qu'avec les tests conditionnels, dès que l'indentation cesse, le code suit un déroulement normal (il n'est pas répété). Remarquez que dans la boucle précédente nous utilisons la boucle conditionnelle while conjointement à une variable nommée i qui joue un rôle particulier : celui d'un compteur. C'est une variable que nous mettons à jour à chaque tour de boucle pour compter quelque chose.

Nous pouvons aussi utiliser une boucle pour nous assurer que l'utilisateur respecte les conditions d'utilisation du programme :

age = -1
while age <= 0:
    print("Entrez votre âge :")
    age = int(input())

if age < 18:
    print("Encore", 18-age, "ans avant la majorité.")
elif age > 18:
    print("Vous êtes majeur depuis déjà", age-18, "ans.")
else:
    print("Vous venez d'avoir vos 18 ans.")
    print("Joyeux anniversaire !")

Ici la boucle sera exécutée au moins une fois puisque la condition est initialement vérifiée. Elle bouclera tant que l'utilisateur ne rentre pas d'âge correct.

Une remarque importante : les blocs de code peuvent naturellement contenir d'autres blocs de code. Il suffit de différencier les niveaux d'indentation, c'est à dire le nombre de caractères utilisés pour indenter. Généralement, on conseille en Python d'indenter à raison de 4 espaces par niveau d'indentation. Voici un exemple de deux boucles while imbriquées :

i = j = 1
while i <= 10:
    while j <= 10:
        print(i*j, end=" ")
        j = j + 1
    j = 1
    i = i + 1
    print("")

Nous initialisons deux compteurs à 1. Nous faisons ensuite varier i de 1 à 10, et pour chaque valeur de i nous faisons varier j de 1 à 10, en affichant à chaque fois le produit i*j : naturellement, nous affichons une table de multiplications classique. Il est important de réaffecter la valeur 1 à j après la boucle interne, sans quoi la boucle externe bouclerait, et la condition "j <= 10" serait toujours fausse : on n'entrerait alors même pas dans la boucle concernant j.

Remarquez que ce code joue avec un paramètre spécial pour print, le paramètre end : il permet de spécifier la chaîne étant affichée après les arguments de print. Par défaut, end vaut "n", ce qui est une façon de dire "retour à la ligne"... Voilà pourquoi print revient toujours à la ligne quand on affiche quelque chose ! Notez que cette modification est spécifique à l'appel courant de print. Il y a d'ailleurs un second print dans le code qui est censé afficher la chaîne vide - en fait, nous l'utilisons cette fois-ci pour revenir à la ligne.

Exécutez ce code pour comprendre comment marchent les boucles imbriquées, et les print.

Exercices :

  • Reprenez l'exemple cherchant à lire l'âge de l'utilisateur pour ajouter une condition vérifiant que l'âge entré est inférieur à 130 ans.

  • Vérifiez qu'un nombre n est premier : pour cela, écrivez la définition sur une feuille, la démarche à adopter devrait vous sembler évidente. Trouvez ensuite une façon de le faire en un minimum de tours de boucle possible.

  • Affichez la liste des multiples de 2 ou 3 jusqu'à 100, puis des multiples de 2 et 3 à la fois en modifiant le moins possible votre code... puis en étant un peu efficace. Améliorez la lisibilité de votre programme en affichant au plus 10 nombres par ligne.