Aller au contenu

3. Structures de contrôle : conditionnelles⚓︎

3.1 Principe⚓︎

On peut imaginer qu'un programme est une suite finie de choix, permettant de s'adapter aux situations rencontrées. Ce type de choix s'appelle un branchement conditionnel1.

Cours

Graphe de contrôle

%%{init:{'theme': 'dark' }}%% graph TD; A[début du programme]-->p("#60;condition à remplir#62;"); p-->|Vrai|B; p-->|Faux|C; B-->D[suite du programme]; C-->D[suite du programme]; class p if;

Une conditionnelle permet d'effectuer une action si une certaine condition est vérifiée.

On peut représenter une telle situation dans un graphe de contrôle (voir schéma ci-contre).

Comprendre les conditionnelles

Dans les exercices ci-dessous, sur une feuille, dessinez le graphe de contrôle correspondant au programme proposé.

Un site de vente en ligne propose la livraison gratuite au-delà de 90€ d'achats. Voici le programme écrit en Français.

1
2
3
4
5
6
7
prix ← prix du panier
si prix <= 90€ alors :
    frais_port ← 7€
sinon :
    frais_port ← 0€
prix_total ← prix + frais_port
afficher prix_total

Solution2 en fin de cours

On donne une autre proposition pour le programme de l'exercice 1. Voici le programme écrit en Français.

1
2
3
4
5
6
frais_port ← 0€
prix ← prix du panier
si prix <= 90€ alors :
    frais_port ← 7€
prix_total ← prix + frais_port
afficher prix_total

Solution3 en fin de cours

Un thermostat permet de réguler la température d'un réfrigérateur à 5°C. Voici le programme écrit en Anglais.

1
2
3
4
5
6
temperature ← measuring the inside temperature of the fridge
if temperature > 5°C then :
    temperature ← temperature - 0.1°C
else:
    temperature ← temperature + 0.1°C
go back to the beginning of the program 

Solution4 en fin de cours

Voici un programme écrit en Python. Remarquez que les instructions sont presque les mêmes qu'en Anglais.

1
2
3
4
5
6
age_client = 15
if age_client <= 12 :
    prix = 5
else:
    prix = 10
print(prix)

Solution5 en fin de cours

Voici un programme écrit en Python. Vous pouvez modifier la valeur de nombre pour vous aider à comprendre le fonctionnement du programme.

nombre = 48bksl-nldiviseur = 1bksl-nlbksl-nlif nombre % 2 == 0 : # si le reste de la division du nombre par 2 égal 0bksl-nl if nombre % 3 == 0 :bksl-nl diviseur = 2 py-str 3bksl-nl else :bksl-nl diviseur = 2bksl-nlelse :bksl-nl if nombre % 3 == 0 :bksl-nl diviseur = 3bksl-nlbksl-nlprint(diviseur)bksl-nl

Solution6 en fin de cours

3.2 Conditionnelle if/else⚓︎

Cours

Graphe de contrôle

%%{init:{'theme': 'dark' }}%% graph TD; A[début code]-->p("condition"); p-->|Vrai|B[bloc code B]; p-->|Faux|C[bloc code C]; B-->D[suite code]; C-->D; class p if;

En Python, la syntaxe des instructions conditionnelles est la suivante :

début code
if condition :
    bloc code B
else:
    bloc code C
suite code

Trois détails importants

  • comme en Anglais, le test conditionnel est réalisé avec if/else ;
  • à la fin d'une ligne contenant if/else, on ajoute deux-points : ;
  • tout le bloc de code B (ou C) doit être indenté avec une tabulation Tab.

Choisissez la syntaxe correcte

  • Proposition 1
    if nombre_points == 20:
        niveau = niveau + 1
    
  • Proposition 2
    if nombre_points = 20:
        niveau = niveau + 1
    
  • Proposition 3
    if nombre_points == 20
        niveau = niveau + 1
    
  • Proposition 4
    if nombre_points == 20: 
    niveau = niveau + 1
    
  • Proposition 1 : correcte !
    if nombre_points == 20:
        niveau = niveau + 1
    
  • Proposition 2 : attention au double égal.
    if nombre_points = 20:
        niveau = niveau + 1
    
  • Proposition 3 : attention aux deux-points manquants.
    if nombre_points == 20
        niveau = niveau + 1
    
  • Proposition 4 : attention à la tabulation qui est obligatoire.
    if nombre_points == 20: 
    niveau = niveau + 1
    

Écrire des conditionnelles

Dans l'éditeur ci-dessous, écrire un programme qui, selon la valeur d'un nombre réel \(n\) :

  • affiche "Strictement positif" si \(n\) est strictement supérieur à 0 ;
  • affiche "Négatif ou nul" sinon.

On propose le début du programme avec la valeur de \(n\) que l'on peut faire varier.

n = -12 # valeur donnée par l'utilisateur
if n >= 0: # condition
    print( "Strictement positif" ) # affichage

benchmark = []bksl-nl 5/5
n = -12bksl-nlbksl-nln = -12bksl-nlif n >= 0:bksl-nl print("Strictement positif")bksl-nlelse: bksl-nl print("Négatif ou nul")bksl-nl

Dans l'éditeur ci-dessous, écrire un programme qui, selon la valeur d'un nombre réel \(a\) :

  • affiche 'Pair' si \(a\) est divisible par \(2\) ;
  • affiche 'Impair' sinon.

On propose le début du programme avec la valeur de \(a\) que l'on peut faire varier.

a = 100 # valeur donnée par l'utilisateur
if ... :                            
    ...
else:
    ...

Aide 1

On rappelle qu'un nombre \(a\) est divisible par un nombre \(b\) si le reste de la division euclidienne de \(a\) par \(b\) est égal à \(0\).

Aide 2

En Python, le reste de la division euclidienne de \(a\) par \(b\) s'obtient avec a % b.

On teste si un nombre \(p\) est égal à 0 avec un double égal : p == 0.

benchmark = []bksl-nl 5/5
a = 100bksl-nla = 100bksl-nlif a % 2 == 0:bksl-nl print("Pair")bksl-nlelse:bksl-nl print("Impair")bksl-nl

L'envoi d'un colis d'un poids compris entre \(1\) et \(6,2\) kg coute \(1,4\) € le kilo.

  • Dans l'éditeur ci-dessous, écrire un programme qui, selon la valeur d'un nombre réel positif poids_colis :

  • affiche 'Trop lourd' si poids_colis est strictement supérieur à \(6,2\) kg ;

  • affiche 'Trop léger' si poids_colis est inférieur ou égal à \(1,0\) kg ;
  • calcule et affiche le prix d'envoi du colis sinon.

  • Tester votre programme en modifiant la valeur de poids_colis.

  • Une fois terminé, télécharger votre programme à l'aide de l'icône Down.
Aide 1

Voir le graphe de contrôle7 en fin de cours.

Aide 2

En langage naturel, le programme va s'écrire :

prix_au_kg = 1,4 
poids_colis = 4
si poids_colis > 6,2 alors :
    afficher("Trop lourd")
sinon :
    si poids_colis < 1.0 alors :
        afficher("Trop léger")
    sinon :
        prix_envoi = prix_au_kilo * poids_colis
        afficher(prix_envoi)

benchmark = []bksl-nl 5/5
poidspy-undcolis = 4bksl-nlprixpy-undaupy-undkg = 1.4bksl-nlpoidspy-undcolis = 4bksl-nlprixpy-undaupy-undkg = 1.4bksl-nlbksl-nlif poidspy-undcolis > 6.2:bksl-nl print("Trop lourd")bksl-nlelse:bksl-nl if poidspy-undcolis <= 1:bksl-nl print("Trop léger")bksl-nl else:bksl-nl prix = prixpy-undaupy-undkg py-str poidspy-undcolisbksl-nl print(prix)bksl-nl

Retournons à la poste : l'envoi d'un colis répond maintenant au tableau ci-dessous.

Gamme de poids (en kg) Prix au kilo
\([0; 1]\) 0,55€/kg
\(]1; 6,2]\) 1,4€/kg
\(]6,2; +\infty[\) 2,2€/kg
  • Dans l'éditeur ci-dessous, téléverser le programme de l'exercice précédent grâce à l'aide de l'icône Up ;
  • Modifier votre programme afin qu'il calcule et affiche le prix d'envoi d'un colis, selon la valeur du nombre réel positif poids_colis ;
  • Tester votre programme en modifiant la valeur de poids_colis.
Aide 1

On rappelle le programme corrigé de l'exercice précédent.


Aide 2

Le prix au kilo est maintenant variable : modifiez la valeur référencée par la variable prix_au_kilo en fonction de poids_colis.

benchmark = []bksl-nl 5/5
poidspy-undcolis = 4bksl-nlpoidspy-undcolis = 4bksl-nlbksl-nlif poidspy-undcolis > 6.2:bksl-nl prixpy-undaupy-undkg = 2.2bksl-nlelse:bksl-nl if poidspy-undcolis <= 1:bksl-nl prixpy-undaupy-undkg = 0.55bksl-nl else:bksl-nl prixpy-undaupy-undkg = 1.4bksl-nlbksl-nlprix = prixpy-undaupy-undkg py-str poidspy-undcolisbksl-nlprint(prix)bksl-nl

La clause sinon (else) n'est pas obligatoire. Si elle n'est pas précisée, le bloc code C n'est pas défini et on passe directement à la suite du code (voir exercice 2).

Lorsque plusieurs conditions sont imbriquées les unes dans les autres, la syntaxe devient très lourde. Pour faciliter l'écriture et le maintien des programmes, de nombreux langages font appel à des mots-clés alternatifs. En Python, il s'agit de elif qui permet de créer un nouveau branchement.

Cours

Graphe de contrôle

%%{init:{'theme': 'dark' }}%% graph TD; A[début code]-->p1("condition_1"); p1-->|Vrai|B_1[bloc code B_1]; p1-->|Faux|p2("condition_2"); p2-->|Vrai|B_2[bloc code B_2]; p2-->|Faux|pn1[...]; pn1-->|Vrai|pn("condition_n"); pn-->|Vrai|B_n[bloc code B_n]; pn-->|Faux|C[bloc code C]; B_1-->D[suite code]; B_2-->D; B_n-->D; C-->D; class p1,p2,pn if;

Lorsque plusieurs conditions sont imbriquées, la syntaxe ci-dessous est utilisée :

début code
if condition_1:
    bloc code B_1
elif condition_2:
    bloc code B_2
[...]
elif condition_n:
    bloc code B_n
else:
    bloc code C
suite code
début code
if condition_1:
    bloc code B_1
else:
    if condition_2:
        bloc code B_2
    else:
        [...]
            if condition_n:
                bloc code B_n
            else:
                bloc code C
suite code

Si la condition_1 n'est pas vérifiée, alors on passe à la condition_2, Si la condition_2 n'est pas vérifiée, alors on passe à la condition_3, etc.

Les conditions sont donc effectuées les unes après les autres et le else final n'est effectué que si toutes les autres conditions ne sont pas vérifiées.

Les conditionnelles imbriquées

On vous donne le programme de l'exercice 9.

En utilisant l'instruction elif, modifier ce programme afin de le rendre plus lisible.

benchmark = []bksl-nl 5/5
poidspy-undcolis = 4bksl-nlbksl-nlif poidspy-undcolis > 6.2:bksl-nl prixpy-undaupy-undkg = 2.2bksl-nlelse:bksl-nl if poidspy-undcolis <= 1:bksl-nl prixpy-undaupy-undkg = 0.55bksl-nl else:bksl-nl prixpy-undaupy-undkg = 1.4bksl-nlbksl-nlprix = prixpy-undaupy-undkg py-str poidspy-undcolisbksl-nlprint(prix)bksl-nlpoidspy-undcolis = 4bksl-nlbksl-nlif poidspy-undcolis > 6.2:bksl-nl prixpy-undaupy-undkg = 2.2bksl-nlelif poidspy-undcolis <= 1:bksl-nl prixpy-undaupy-undkg = 0.55bksl-nlelse:bksl-nl prixpy-undaupy-undkg = 1.4bksl-nlbksl-nlprix = prixpy-undaupy-undkg py-str poidspy-undcolisbksl-nlprint(prix)bksl-nl

Dans l'éditeur ci-dessous, écrire un programme qui, selon la valeur d'un nombre réel \(n\) :

  • affiche "Strictement positif" si \(n\) est strictement supérieur à 0 ;
  • affiche "Négatif" si \(n\) est strictement inférieur à 0 ;
  • affiche "Nul" si \(n\) est égal à 0.
n = -12 # valeur donnée par l'utilisateur
if ... : # condition
    print( ... ) # affichage

benchmark = []bksl-nl 5/5
n = -12bksl-nlbksl-nlbksl-nlbksl-nlbksl-nln = -12bksl-nlbksl-nlif n > 0:bksl-nl print("Strictement positif")bksl-nlelif n < 0:bksl-nl print("Strictement négatif")bksl-nlelse:bksl-nl print("Nul")bksl-nl

On choisit une année annee.

Dans l'éditeur ci-dessous, écrire un programme qui, grâce à un affichage, indique à l'utilisateur si cette année est bissextile (366 jours sur l'année). On rappelle qu'une année est bissextile :

  • si elle est divisible par 400.
  • si elle n'est pas divisible par 100 ;
  • si elle est divisible par 4 ;

Quelques exemples : 2000 est bissextile mais 1700 ne l'est pas. Par contre 1712 est bissextile.

Aide 1

On rappelle qu'un nombre \(a\) est divisible par un nombre \(b\) si le reste de la division euclidienne de \(a\) par \(b\) est égal à \(0\).

Aide 2

En Python, le reste de la division euclidienne de \(a\) par \(b\) s'obtient avec a % b.

benchmark = []bksl-nl 5/5
n = 1492bksl-nlbksl-nlbksl-nlbksl-nlbksl-nln = 1492bksl-nlbksl-nlif n % 400 == 0:bksl-nl print(n, " est bissextile.")bksl-nlelif n % 100 == 0:bksl-nl print(n, " n'est pas bissextile.")bksl-nlelif n % 4 == 0:bksl-nl print(n, " est bissextile.")bksl-nlelse:bksl-nl print(n, " n'est pas bissextile.")bksl-nl

Voici deux programmes écrits en Python :

Programme 1 Programme 2
if a >= 60:
    a = a - 60
elif a >= 30:
    a = a - 30
else:
    a = 0
print("La valeur de a est", a)
if a >= 60:
    a = a - 60
if a >= 30:
    a = a - 30
else:
    a = 0
print("La valeur de a est", a)

Tableau

a = 130 a=45 a=15
Programme 1
Programme 2
  • Dessiner les graphes de contrôle de ces programmes.
  • En utilisant ces graphes, recopier et compléter le tableau ci-contre, présentant les résultats du programme 1 et du programme 2 si :
    • a = 130;
    • a = 45;
    • a = 15.
  • Vérifiez votre réponse en écrivant les programmes dans l'éditeur ci-dessous :

Solution
a = 130 a=45 a=15
Programme 1 70 15 0
Programme 2 40 15 0

Dans le programme 1, le test a >= 30 n'est réalisé que si a < 60. Il est impossible de faire deux soustractions.

Dans le programme 2, le graphe de contrôle montre clairement que le test a >= 30 est toujours réalisé. Ainsi, dans le cas où a >= 60, on retranche 60 à a. Si la nouvelle valeur référencée par la variable a est alors supérieure ou égale à 30 a >= 30, on retranche à nouveau 30. On a donc retranché 90.

3.3 Booléens⚓︎

3.3.1 Syntaxe en Python⚓︎

La nature des booléens

Quelqu'un affirme 4 est égal à 4. Que lui répondez-vous ?

Réponse

Ben, c'est VRAI !

Quelqu'un affirme 7 est égal à 12. Que lui répondez-vous ?

Réponse

Ben, c'est FAUX !

Cours

Les booléens constituent la réponse logique à une affirmation. Cette réponse logique ne peut avoir que deux valeurs : en Python, elles se notent True ou False.

Pour écrire une affirmation, on utilise les symboles mathématiques : <, <=, >, >=, != et ==.

Affirmation Symbole Exemple 1 Exemple 2
a est strictement plus petit que b a < b 38 < 23 est égal à False 'a' < 'z' est égal à True (ordre du dictionnaire)
a est plus petit ou égal à b a <= b 23 <= 23 est égal à True 'a' <= 'A' est égal à False (voir exercices ci-dessous)
a est strictement plus grand que b a > b 5.3 > 5.3 est égal à False 'abc' > 'aab' est égal à True
a est plus grand ou égal à b a >= b 5.3 >= 6/2 est égal à True '712' >= '1560' est égal à True ('7' >= '1')
a est différent de b a != b 12 != 12 est égal à False 'Vive le 01!' != 'Vive le 75!' est égal à True ('0' != '7')
a est égal à b a == b 5 == 12 est égal à False 'Hello' == 'Hello!' est égal à False

Attention

  • En Python, on aime coder avec style : PEP8 stipule qu'il convient de laisser un espace avant et après chaque opérateur.
  • Notez bien qu'on teste l'égalité avec un double égal et la différence avec point d'exclamation égal.
  • Comme nous le verrons dans le chapitre sur les nombres flottants, l'égalité ou la différence ne s'utilise jamais avec des nombres à virgule (type float).

Ordre lexicographique

L'ordre du dictionnaire est aussi appelé l'ordre lexicographique.

Pour ranger dans l'ordre lexicographique, on compare les deux premiers caractères de chaque texte. S'ils sont égaux, on compare le deuxième, etc.

Exemple

L'affirmation oiseau < oisif est-elle vraie ou fausse?

En effet : la première lettre o est la même pour chaque chaîne de caractères. De même pour la deuxième et la troisième lettre. On compare la quatrième lettre : e < i.

On conclue que la question oiseau < oisif est True.

Toutefois, les caractères peuvent aussi être spéciaux. Que fait-on avec "1", "A", "!" ou 😄. Dans ce cas, on compare leur code Unicode que nous étudierons en classe.

Exercice

Cocher la case si le booléen est True.

  • 8 == 7
  • 7 != 12
  • "abc" < "abe"
  • "abc" <= "abcd"
  • 65 = 65
  • -12 < 9.0
  • 12 <= "nsi"
  • 4 + 8 > 12
  • "abc"*3 >= "abcabcabc"
  • 8 == 7 : l'expression est clairement fausse False.
  • 7 != 12
  • "abc" < "abe" : "c" est avant "e" dans l'alphabet donc l'expression est True.
  • "abc" <= "abcd" : la deuxième expression est plus longue que la première donc "inférieure"
  • 65 = 65 : ce n'est pas un booléen ! Un égal simple est une affectation.
  • -12 < 9.0
  • 12 <= "nsi" : cette expression renvoie : TypeError: '<=' not supported between instances of 'int' and 'str'.
  • 4 + 8 > 12 : 12 est égal à 12.
  • "abc"*3 >= "abcabcabc" :#!python "abc"*3répète trois fois la phrase#!python "abc"donc#!python "abcabcabc"`.

Cours

Il est tout à fait possible d'affecter une valeur booléenne à une variable. On parle alors de variable booléenne.

Pour des raisons de clarté et de lisibilité, il est recommandé de mettre des parenthèses autour des expressions booléennes lors d'une telle affectation.

Exemple

  • entrée_autorisée = age >= 18 est tout à fait correct mais,
  • entrée_autorisée = (age >= 18) est beaucoup plus facile à comprendre.

3.3.2 Subtilités booléennes⚓︎

Introduction

Avec les mots-clés dont nous disposons actuellement, certaines conditions logiquement simples sont complexes à écrire.

Prenons l'exemple d'un site de rencontres.

  • Si l'utilisateur est un homme et s'il a plus de 18 ans, alors il doit payer.
  • Si l'utilisatrice est une femme et si elle a plus de 18 ans, alors elle ne paie pas.
  • Sinon, l'inscription n'est pas autorisée.

Voici le programme correspondant :

inscription_non_autorisée = False
if genre == "homme":
    if age > 18:
        inscription_payante = True
    else:
        inscription_non_autorisée = True
else:
    if age > 18:            
        inscription_payante = False
    else:
        inscription_non_autorisée = True

Ce serait bien de pouvoir connecter les deux expressions booléennes : l'utilisateur est homme et il a plus de 18 ans !

Le chapitre 3 sur la logique booléenne a introduit trois opérateurs logiques :

  • le non : \(\bar A\)
  • le et : \(A \cdot B\)
  • le ou : \(A + B\).

Ces trois opérateurs peuvent simplifier grandement l'écriture de certaines conditions.

Cours

Soit deux expressions booléennes c1 et c2.

En accord avec la logique booléenne, en Python, il est possible d'utiliser les opérateurs booléens suivant :

Opérateur Nom Effet Exemple
and conjonction c1 and c2 est True si c1 et c2 sont simultanément True. 4 <= 8 and 8 <= 12 est True
or union c1 or c2 est True si au moins une condition est True. 4 <= 8 or 7 == 12 est True
not négation not c1 est True si c1 est False. not (1 + 1 == 3) est True car
1 + 1 == 3 est False.

Priorité opératoire

Les règles de priorité sont les mêmes qu'en logique boolénne. La négation est prioritaire sur la conjonction qui est prioritaire sur l'union.

Exemple

a or b and not c and d est équivalent à a or (b and (not c) and d) car la négation est prioritaire sur la conjonction.

Privilégiez les expressions booléennes simples et l'utilisation de parenthèses !

Pour aller plus loin

En Python, l'évaluation des expressions booléennes est dite paresseuse.

Dans une expression avec deux expressions booléennes telle que c1 and c2, Python va d'abord évaluer c1.

Si cette expression est False, Python s'arrête et évalue c1 and c2 à False. En effet, c1 and c2 est vraie si les deux expressions sont simultanément True.

C'est un comportement intéressant dans la gestion de cas limites, susceptibles de générer des erreurs.

Exemple

Testez ces expressions ou programme dans le terminal ci-dessous :

1 / 0 == 2

8 == 3 and 1 / 0 == 2

a = 0
if a == 0 or (1 / a > 1e6):
    print("Underflow")

Retour sur l'exemple introductif

Dans l'éditeur ci-dessous, on rappelle le programme proposé pour le site de rencontre.

  • Un affichage a été ajouté. Expliquer à quoi sert la ligne 16.
  • Tester ce programme avec pour valeurs initiales genre, age = "homme", 14 et genre, age = "homme", 34.
  • Simplifier ce programme à l'aide des opérateurs booléens (négation not, conjonction and, union or).

benchmark = []bksl-nl 5/5
genre, age = "femme", 21bksl-nlbksl-nlinscriptionpy-undnonpy-undautorisée = Falsebksl-nlif genre == "homme":bksl-nl if age > 18:bksl-nl inscriptionpy-undpayante = Truebksl-nl else:bksl-nl inscriptionpy-undnonpy-undautorisée = Truebksl-nlelse:bksl-nl if age > 18: bksl-nl inscriptionpy-undpayante = Falsebksl-nl else:bksl-nl inscriptionpy-undnonpy-undautorisée = Truebksl-nlbksl-nlprint(f"Interdit : {inscriptionpy-undnonpy-undautorisée}")bksl-nlif not inscriptionpy-undnonpy-undautorisée:bksl-nl print(f"Payant : {inscriptionpy-undpayante}")bksl-nlgenre, age = "femme", 21bksl-nlbksl-nlinscriptionpy-undnonpy-undautorisée = Falsebksl-nlif age > 18 and genre == "homme":bksl-nl inscriptionpy-undpayante = Truebksl-nlelif age > 18 and genre == "femme":bksl-nl inscriptionpy-undpayante = Falsebksl-nlelse:bksl-nl inscriptionpy-undnonpy-undautorisée = Truebksl-nlbksl-nlprint(f"Interdit : {inscriptionpy-undnonpy-undautorisée}")bksl-nlif not inscriptionpy-undnonpy-undautorisée:bksl-nl print(f"Payant : {inscriptionpy-undpayante}")bksl-nl

Rappel

Pour voir la correction, appuyez sur l'icone gendarme cinq fois de suite.

Exercices autour des booléens

Soit a et b deux variables booléennes.

Écrire la table de vérité (voir Chapitre 2 du cours) correspondant au booléen ci-dessous.

var_booléenne = not a and b

Solution
\(a\) \(b\) \(\overline a\) \(\bar a \cdot b\)
0 0 1 0
0 1 1 1
1 0 0 0
1 1 0 0

L'opérateur "Union exclusive" \(\oplus\) peut être écrit comme une combinaison d'autres opérateurs booléens. Pour deux variables booléennes \(a\) et \(b\), on écrit \(a \oplus b = \overline a \cdot b + a \cdot \overline b\).

Compléter le programme permettant d'afficher la valeur booléenne de \(a \oplus b\).

benchmark = []bksl-nl 5/5
a, b = True, False # à modifier lors des testsbksl-nlvarpy-undbooléenne = () # à compléterbksl-nlbksl-nlprint(varpy-undbooléenne)bksl-nla, b = True, False # à modifier lors des testsbksl-nlvarpy-undbooléenne = (not(a) and b) or (a and not b)bksl-nlbksl-nlprint(varpy-undbooléenne)bksl-nl

Soit a, b et c trois variables booléennes.

En testant dans l'éditeur ci-dessous pour différentes valeurs de a, b et c, dire si ces deux programmes sont équivalents.

Programme 1 Programme 2
if (not a and b) and c:
    print(True)
else:
    print(False)
if (not a and b):
    print(True)
elif c:
    print(True)
else:
    print(False)

Solution

Dans ce corrigé, on prend pour convention : 1 = True ; 0 = False.

Dans le programme 1, le seul ensemble de valeurs renvoyant True est \((a=0, b=1, c=1)\).

Dans le programme 2, il y a plusieurs ensembles de valeurs qui renvoyant True. Par exemple \((a=0, b=1, c=1)\) ou \((a=0, b=1, c=0)\) ou \((a=0, b=1, c=1)\).

Les programmes ne sont donc pas équivalents.

Soit a, b et c trois variables booléennes.

En testant dans l'éditeur ci-dessous pour différentes valeurs de a, b et c, dire si ces deux programmes sont équivalents.

Programme 1 Programme 2
if (not a and b) or c:
    print(True)
else:
    print(False)
if (not a and b):
    print(True)
elif c:
    print(True)
else:
    print(False)

Solution

Dans ce corrigé, on prend pour convention : 1 = True ; 0 = False.

Dans le programme 1, dès que \(c=1\), le programme renvoie True. Il reste donc à ajouter \((a=0, b=1, c=0)\).

Dans le programme 2, le premier branchement ne concerne pas c. Il renvoie donc True si \((a=0, b=1, c=0)\) ou \((a=0, b=1, c=1)\). Sinon, on arrive au second branchement testant c : si \(c=1\), on renvoie True. Cela correspond à \((a=0, b=0, c=1)\) ou \((a=1, b=0, c=1)\) ou \((a=1, b=1, c=1)\).

En résumé, les valeurs renvoyant True dans le programme 2 correspondent à celles du programme 1 : les programmes sont équivalents... Mais que c'est désagréable à analyser !

Cours

Dans le cadre d'inégalités entre nombres (entiers ou flottants), plutôt que d'utiliser des connecteurs logiques and ou or, il est possible de combiner n'importe quel opérateur :

  • 3 < 5 < 7 est équivalent à 3 < 5 and 5 < 7. Le résultat est True.
  • 8 > 5 >= 7 est équivalent à 8 > 5 and 5 >= 7. Le résultat est False.
  • 3 < 5 != 7 est équivalent à 3 < 5 and 5 != 7. Le résultat est True.

Attention

S'il est possible de combiner n'importe quel opérateur, il faut éviter de faire n'importe quoi pour des questions de lisibilité.

En particulier, on évitera :

  • les inégalités contre nature tel 12 > 5 < 7 qui est True.
  • les longues expressions tel 6 != 12 < 5 != 7 == 7 qui est False car 12 < 5est False.

3.4 Bonnes pratiques⚓︎

Cours

L'indentation est très importante et vous devez être très rigoureux sur ce point. Toute instruction non indentée ne fera pas partie de votre conditionnelle. Pour vous en convaincre, exécutez ces deux exemples de code :

La ligne 8 est exécutée uniquement si le mot Titanic n'apparaît pas dans la phrase : elle ne s'affiche donc pas.

phrase = "Le Titanic sombra rapidement."bksl-nlbksl-nlif "Titanic" in phrase:bksl-nl print("Ce fut un drame ;")bksl-nl print("même si l'orchestre continua de jouer.")bksl-nlelse:bksl-nl print("Ce ne fut pas un drame ;")bksl-nl print("et l'orchestre continua de jouer.")bksl-nl

La ligne 8 n'est pas inclue dans la clause else : elle s'affiche donc toujours.

phrase = "Le Titanic sombra rapidement."bksl-nlbksl-nlif "Titanic" in phrase:bksl-nl print("Ce fut un drame ;")bksl-nl print("même si l'orchestre continua de jouer.")bksl-nlelse:bksl-nl print("Ce ne fut pas un drame ;")bksl-nlprint("et l'orchestre continua de jouer.")bksl-nl

Si, dans une instruction conditionnelle, vous faites appel à une variable booléenne var_bool, il est important de ne pas écrire if var_bool == True:.

En effet, var_bool est déjà un booléen dont la valeur est soit True ; soit False.

souquez_les_artibuses = (nombre_artibuses > 42)
if souquez_les_artibuses: 
    # si souquez_les_artibuses est True, à l'attaque
    print("À l'attaque")
else:
    print("Demi-tour")
souquez_les_artibuses = (nombre_artibuses > 42)
if souquez_les_artibuses == True: 
    # si souquez_les_artibuses, qui vaut déjà True, est égal à True, à l'attaque
    print("À l'attaque")
else:
    print("Demi-tour")

Exercices récapitulatifs

L'utilisation d'une grille est la méthode la plus répandue pour faire des simulations numériques de phénomènes physiques. Dans cette méthode, le plan est divisée en cellules carrées dans lesquelles évoluent des particules de matière. Ces particules peuvent se déplacer dans n'importe quel sens et sont repérées par leurs coordonnées \((x, y)\).

Le plan simulé ne pouvant pas être infini, il est courant d'imposer des conditions périodiques au bord du carré de simulation. Ainsi, si l'abscisse et l'ordonnée d'une particule dépasse la taille du carré, on leur retranche (ou on leur ajoute) le côté du carré.

On se place ici dans un carré de côté 10.

  • Expliquer ce qui ne convient pas avec le programme ci-dessous.
  • Proposez une simple modification.
  • Quel opérateur permettrait d'éviter l'utilisation des conditionnelles ?
if x >= 10:
    x = x - 10
elif y >= 10:
    y = y - 10
if x < 0:
    x = x + 10
elif y < 0:
    y = y + 10
Solution
  • Dans ce programme, si x et y sont simultanément supérieurs à 10, seul x est ramené entre 0 et 10.
  • Il faut simplement changer tous les elif en if.
  • Une astuce consiste à utiliser l'opérateur modulo %. Par exemple x = 11.1 % 10 est égal à 1.1.

Le programme proposé ci-dessous génère aléatoirement deux entiers, compris entre 1 et 6. Si la somme de ces nombres est supérieure ou égale à 10, alors vous devez payer une taxe spéciale (36 pièces). Sinon, vous payez deux fois la somme des nombres. Si vous êtes chanceux et que la somme est strictement inférieure à 4, vous n'avez rien à payer.

Votre programme devra afficher selon le cas le texte Taxe spéciale !, Taxe régulière, ou Pas de taxe suivi de la somme à payer (sans indiquer l'unité).

benchmark = []bksl-nl 5/5
import randombksl-nlde1 = random.randint(1,6)bksl-nlde2 = random.randint(1,6)bksl-nlprint(f"La valeur du dé 1 est {de1} et celle du dé 2 est {de2}.")bksl-nl# Programme à commencer ici #bksl-nlbksl-nlimport randombksl-nlde1 = random.randint(1,6)bksl-nlde2 = random.randint(1,6)bksl-nlprint(f"La valeur du dé 1 est {de1} et celle du dé 2 est {de2}.")bksl-nl# Programme à commencer ici #bksl-nlsomme = de1 + de2bksl-nlif somme >= 10:bksl-nl print('Taxe spéciale !', 36)bksl-nlelif 4 <= somme < 10:bksl-nl print('Taxe régulière', somme py-str 2)bksl-nlelse :bksl-nl print('Pas de taxe', 0)bksl-nl

3.5 Résumé⚓︎

Résumé

Dans ce chapitre, j'ai appris :

  • ce qu'était un branchement conditionnel ;
  • la syntaxe des branchements conditionnels en Python ;
  • l'importance de la logique booléenne et la manière de l'utiliser en Python ;
  • les bonnes pratiques avec les branchements conditionnels.

  1. Il existe également des branchements inconditionnels qui ont lieu sans qu'aucune condition soit vérifiée (voir schéma ci-dessous où on passe directement de l'instruction 1 à l'instruction n). Nous utiliserons de tels branchements lorsque nous travaillerons sur l'assembleur. Sachez toutefois que ces branchements sont à proscrire en programmation de haut niveau.

    %%{init:{'theme': 'dark' }}%% graph TD; A[instruction 1]-->B("saut vers l'instruction n"); C[instruction 2]-->D[instruction 3] D-->|"..."|E B---->E[instruction n]; class B if;
     

  2. Cliquez sur la flèche pour revenir au cours

    %%{init:{'theme': 'dark' }}%% graph TD; A["prix ← prix du panier"]-->p("prix <= 90€"); p-->|Vrai|B["frais_port ← 7€"]; p-->|Faux|C["frais_port ← 0€"]; B-->D["prix_total ← prix + frais_port
    afficher prix_total"]; C-->D; class p if;
     

  3. Cliquez sur la flèche pour revenir au cours. On passe directement à la suite du code si la condition est fausse.

    %%{init:{'theme': 'dark' }}%% graph TD; A["frais_port ← 0€
    prix ← prix du panier"]-->p("prix <= 90€"); p-->|Vrai|B["frais_port ← 7€"]; p-->|Faux|D; B-->D["prix_total ← prix + frais_port
    afficher prix_total"]; class p if;
     

  4. Cliquez sur la flèche pour revenir au cours

    %%{init:{'theme': 'dark' }}%% graph TD; A["temperature ← measuring the inside temp..."]-->p("temperature > 5°C"); p-->|Vrai|B["temperature ← temperature - 0.1°C"]; p-->|Faux|C["temperature ← temperature + 0.1°C"]; B-->D[go back]; C-->D[go back]; D-..->A; class p if;
     

  5. Cliquez sur la flèche pour revenir au cours

    %%{init:{'theme': 'dark' }}%% graph TD; A["age_client = 15"]-->p("age_client <= 12"); p-->|Vrai|B["prix = 5"]; p-->|Faux|C["prix = 10"]; B-->D["print(prix)"]; C-->D; class p if;
     

  6. Cliquez sur la flèche pour revenir au cours

    %%{init:{'theme': 'dark' }}%% graph TD; A["nombre = 48
    diviseur = 1"]-->p1("nombre % 2 == 0"); p1-->|Vrai|p2("nombre % 3 == 0"); p2-->|Vrai|B["diviseur = 6"]-->p4["print(diviseur)"]; p2-->|Faux|C["diviseur = 2"]-->p4; p1-->|Faux|p3("nombre % 3 == 0"); p3-->|Vrai|D["diviseur = 3"]-->p4; p3--->|Faux|p4; class p1,p2,p3 if;
     

  7. Appuyez sur la flèche pour revenir à l'exercice.

    %%{init:{'theme': 'dark' }}%% graph TD; A["prix_au_kg = 1,4 €
    poids_colis = 4 kg"]-->p("poids_colis strictement supérieur à 6,2 kg"); p-->|Vrai|B["affiche 'Trop lourd'"]; p-->|Faux|p1("poids_colis inférieur ou égal à 1,0 kg"); p1-->|Vrai|C["affiche 'Trop léger'"]; p1-->|Faux|p2["calcule et affiche le prix d'envoi du colis."]; class p,p1 if;
     

Retour en haut de la page