Full Transcript

## 2. Instructions conditionnelles (cours) PSL - Université Paris Dauphine Informatique **L1 LSO 2024-2025** ### 2. Instructions conditionnelles (cours) Dans la plupart des langages de programmation, il existe des structures de contrôle qui permettent d'introduire des conditions et des répétitio...

## 2. Instructions conditionnelles (cours) PSL - Université Paris Dauphine Informatique **L1 LSO 2024-2025** ### 2. Instructions conditionnelles (cours) Dans la plupart des langages de programmation, il existe des structures de contrôle qui permettent d'introduire des conditions et des répétitions. Dans ce chapitre, nous nous intéressons aux instructions conditionnelles en Python. Dans le chapitre 3 suivant, nous présenterons une instruction répétitive. ### 2.1 Instruction conditionnelle de base Un programme est une suite d'instructions qui, lors de son exécution, s'exécutent invariablement les unes à la suite des autres (on parle d'exécution séquentielle des instructions). Or, on peut vouloir dire dans un programme que l'on exécutera certaines instructions uniquement si une certaine condition est vérifiée, ce qui permet d'aiguiller le déroulement d'un programme dans différentes directions et de modifier son comportement. L'instruction conditionnelle de base est introduite en Python par le mot-clé *if* avec la syntaxe suivante : ```python if condition: BlocInstructions ``` où *BlocInstructions* est une suite d'instructions qui sera exécutée uniquement si la condition est vérifiée. Si la condition n'est pas vérifiée, alors il ne se passera rien. Une condition est une expression dite logique qui renvoie soit la valeur booléenne VRAI, désignée par *True* en Python, soit la valeur booléenne FAUX, désignée par *False* en Python. **Exemple:** Si *age* est une variable qui référence la valeur 17, l'expression ```python age > 17 ``` est une expression logique qui renvoie *False*. Alors que ```python age < 18 ``` est une expression logique qui renvoie *True*. Les opérateurs de comparaison qui peuvent être utilisés en Python pour écrire des conditions sont : >, <, == pour l'égalité, != pour la différence, <=, >=. On notera que, pour tester si 2 éléments sont égaux, il faut doubler le signe = (car un unique signe = réalise une affectation). Nous reviendrons plus en détail dans une section ultérieure sur la définition et la construction d'expressions logiques plus complexes. Le début du bloc d'instructions est spécifié par le caractère ':' placé après la condition du *if*. Les instructions du bloc doivent être indentées (décalées vers la droite) par rapport au mot-clé *if* et la fin du bloc d'instructions est spécifiée par la première instruction alignée avec le mot-clé *if*. ### Exemple Voici un programme Python qui, étant donné l'âge d'une personne, identifie si elle n'a pas le droit à la carte jeune de la SNCF. ```python print('Quel est votre age ?') age = input() age = int(age) if age > 27: print("Vous n'avez malheureusement plus le droit à la carte Jeune") ``` Le bloc d'instructions peut contenir des instructions de lecture, d'écriture, d'affectation et des instructions conditionnelles (on parle alors d'instructions conditionnelles imbriquées). ### Illustration ```python print('Quel est votre age ?') age = input() age = int(age) if age >= 0: if age < 18: print("Vous êtes mineur.e.") print("Vous serez majeur.e dans", 18 - age, "ans.") if age >= 18: print("Vous êtes majeur.e depuis", age - 18, "ans.") ``` Le *BlocInstructions* ne peut pas être vide. C'est bien l'indentation (le décalage vers la droite) qui délimite les blocs. ### Illustration Que se passe-t-il lors de l'exécution du programme ci-dessous lorsque l'utilisateur saisit au clavier la valeur 4? ```python x = int(input("Donner l'inconnue x positive ou nulle: ")) if x >= 10: print("x n’est pas constitué d’un unique chiffre") print("parce qu’il est plus grand que 10") ``` L'ensemble des instructions contenues dans: ```python if condition: BlocInstructions ``` constitue une première forme d'instruction conditionnelle qui commence avec l'évaluation de la condition et se termine avant la prochaine instruction se trouvant au même niveau d'indentation que le *if*. Il existe une autre forme d'instruction conditionnelle, introduisant une alternative à la condition du *if*, présentée dans la section suivante. ### 2.2 Instruction conditionnelle if-else Il est également possible d'indiquer en plus au programme de traiter le cas où la condition n'est pas vérifiée à l'aide du mot-clé *else*. La structure de base devient alors : ```python if condition: BlocInstructions1 else: BlocInstructions2 ``` **Attention:** Ne pas oublier les *:* ni l'indentation après *else* Le programme exécutera les instructions de *BlocInstructions1* si le résultat de l'évaluation de la condition est vrai et dans le cas contraire, il exécutera les instructions de *BlocInstructions2*. Comme le résultat est nécessairement dans l'un des 2 cas, le programme exécutera l'un ou l'autre des blocs d'instructions. Cette structure constitue une nouvelle instruction conditionnelle qui commence avec l'évaluation de la condition et se termine avant la prochaine instruction se trouvant au même niveau d'indentation que le *else*. Reprenons l'exemple précédent et maintenant dans le cas où l'âge est inférieur ou égal à 27, le programme affichera qu'il existe une réduction. ### Illustration ```python print('Quel est votre age ?') age = input() age = int(age) if age > 27: print("Vous n’avez malheureusement plus le droit à la carte Jeune") else: print('Vous bénéficiez de réductions SNCF') ``` Il est tout à fait possible d'imbriquer des instructions conditionnelles *if-else*. ### Illustration ```python print('Quel est votre age ?') age = input() age = int(age) if age > 27: print("Vous n’avez malheureusement plus le droit à la carte Jeune") else: if age >= 10: print('Vous pouvez acheter une carte Jeune') else: if age < 4: print("Bonne nouvelle : c’est gratuit!") else: print("Sans carte, vous bénéficiez d’une réduction de 50%") ``` Mais pour éviter les imbrications, le langage Python propose une troisième forme d'instruction conditionnelle. ### 2.3 Instruction conditionnelle if-elif Il existe en Python, une possibilité supplémentaire pour différencier le sinon et introduire des cas intermédiaires, en utilisant le mot clé *elif* qui est une contraction de *else if*: ```python if Condition1: BlocInstructions1 elif Condition2: BlocInstructions2 elif Condition3: BlocInstructions3 … else: BlocInstructionsK ``` Si le résultat de *Condition1* est vrai alors seul le bloc d'instruction *BlocInstructions1* sera exécuté. Dans le cas contraire (c'est-à-dire si le résultat de *Condition1* est faux) alors le programme va tester la *Condition2*. Si le résultat de *Condition2* est vrai, alors seul le bloc d'instruction *BlocInstructions2* sera exécuté. Dans le cas contraire (c'est-à-dire si le résultat de *condition2* est faux) alors le programme va tester la *Condition3* ... Au final, un seul parmi les K blocs d'instructions potentiels sera exécuté et le bloc *BlocInstructionsK* sera exécuté si le résultat de *Condition1* est faux et le résultat de *Condition2* est faux et le résultat de *Condition3* est faux... et le résultat de *ConditionK-1* est faux. Il est possible de mettre autant de *elif* que l'on veut et le mot clé *else* n'est pas obligatoire à la fin (auquel cas, il peut ne rien se produire); mais s'il est présent, il ne peut y en avoir qu'un. ### Illustration ```python print('Quel est votre age ?') age = input() age = int(age) if age > 27: print("Vous n’avez malheureusement plus le droit à la carte Jeune") elif age >= 10: print('Vous pouvez acheter une carte Jeune') elif age < 4: print("Bonne nouvelle : c’est gratuit!") else: print("Sans carte, vous bénéficiez d’une réduction de 50%") ``` On exécute les instructions du *else* si *age < 10* et *age >=4*. ### 2.4 Le type booléen bool et les expressions logiques Les valeurs booléennes *True* et *False* constituent les deux seules valeurs du type *bool*, pour booléen, en Python. **Attention:** *True* et *False* sont des mots clé pour Python; si la majuscule est omise, ils ne sont pas reconnus en tant que tel. Si on veut écrire des conditions plus complexes en combinant plusieurs comparaisons, comme par exemple ```python (age >= 18) et (age < 21) ``` on va utiliser des opérateurs du type *bool*. Cette condition ne peut pas s'écrire ```python (age >= 18) + (age < 21) ``` car *+* n'est pas un opérateur pour des valeurs de type *bool*. Les opérateurs qu'il est possible d'utiliser sur des valeurs *True* et *False* sont : *not*, *and* et *or*. Ces opérateurs sont appelés opérateurs logiques. * **not** (négation) : en logique souvent notée NON(E1) ou E1, où E1 est une expression logique. Si l'expression E1 est VRAI, alors le résultat de !E1 est FAUX et si E1 est FAUX, alors le résultat de !E1 est VRAI. Cela se représente dans ce que l'on appelle une table de vérité qui donne les différents résultats possibles d'une expression logique en fonction des valeurs des expressions logiques la constituant. Pour la négation, la table de vérité associée est : | E1 | !E1 | |---|---| | VRAI | FAUX | | FAUX | VRAI| **Exemple** Pour *age* valant 17, l'évaluation de l'expression *age < 18* est *True* et par conséquent l'évaluation de l'expression *not(age < 18)* est *False*. * **or** (disjonction) : en logique souvent notée E1 OU E2 ou E1 V E2, où E1 et E2 sont toutes deux des expressions logiques. La table de vérité associée à l'opérateur OU est : | E1 | E2 | E1 OU E2 | |---|---|---| | VRAI | VRAI | VRAI | | VRAI | FAUX | VRAI | | FAUX | VRAI | VRAI | | FAUX | FAUX | FAUX | **Exemples** Soit l'expression E = (age < 25) or (age > 65). Pour *age* valant 6, E aura la valeur *True* et pour *age* valant 40, E prendra la valeur *False*. Si on souhaite tester qu'une variable *var* référence une valeur égale à 0 ou 1, on doit écrire: *var == 0 or var == 1*. Attention, on ne doit pas écrire *var == 0 or 1*. En effet, avec *var == 5*, l'expression *var == 0 or var == 1* renvoie *False* alors que l'expression *var == 0 or 1* renvoie *True*! * **and** (conjonction) : en logique souvent notée E1 ET E2 ou E1 ∧ E2, où E1 et E2 sont toutes deux des expressions logiques. La table de vérité associée à l'opérateur ET est : | E1 | E2 | E1 ET E2 | |---|---|---| | VRAI | VRAI | VRAI | | VRAI | FAUX | FAUX | | FAUX | VRAI | FAUX | | FAUX | FAUX | FAUX | **Exemple** Soit l'expression E = (age >= 18) and (age < 21). Pour *age* valant 19, E aura la valeur *True* et pour *age* valant 50, E prendra la valeur *False*. ### Propriété 1 **NON (A OU B) = NON (A) ET NON (B)** **Démonstration Propriété 1** En utilisant les tables de vérité et en montrant que les tables de vérité de chacune des expressions logiques sont équivalentes. | A | B | A OU B | NON(A OU B) | NON(A) | NON(B) | NON(A) ET NON(B) | |---|---|---|---|---|---|---| | V | V | V | F | F | F | F | | V | F | V | F | F | V | F | | F | V | V | F | V | F | F | | F | F | F | V | V | V | V | **Exemple** *not(x>=0 or y==4)* est équivalent à *not(x>=0) and not(y==4)* qui est équivalent à l'expression logique: *(x<0) and (y!=4)*. ### Propriété 2 **NON (A ET B) = NON (A) OU NON (B)** **Démonstration Propriété 2:** à faire en exercice. **Exemple** *not(x!=0 and y<8)* est équivalent à *not(x!=0) or not(y<8)*, équivalent à l'expression logique: *(x==0) or (y>=8)*. Les propriétés 1 et 2 sont particulièrement utiles pour les tests avec SINON dans le cas où la condition initiale est du type (A ET B) ou (A OU B). ### Remarques La distributivité des opérateurs est la suivante, mais mieux vaut prendre l'habitude de mettre des parenthèses : * A ET (B OU C) = (A ET B) OU (A ET C) * A OU (B ET C) = (A OU B) ET (A OU C) En Python, sans parenthèse, l'opérateur *and* est prioritaire sur l'opérateur *or* et l'opérateur *not* est prioritaire sur les opérateurs *and* et *or*.