(RAPPELS) 1.1 Booléen : vrai ou faux
Booléens
Lorsqu'on utilise certains opérateurs booléens, l'interpréteur évalue votre expression en répondant :
- True si c'est vrai ou
- False sinon.
Pas de réponse de type "peut être". Néanmoins, la demande peut provoquer une erreur.
Opérateurs renvoyant une valeur booléenne
- relation strictement supérieur avec >
- opérateur d'égalité avec ==
- opérateur de différence avec !=
- autres opérateurs de comparaison :
- appartenance avec in
int|float > int|float -> bool
Le signe | veut dire OU. On peut donc placer un entier ou un flottant.
>>> 40 > 30
True
On pose la question suivante à l'interpréteur Python : "40 est-il strictement supérieur à 30 ?".
str > str -> bool
>>> "crocodile" > "tortue"
False
On pose la question suivante à l'interpréteur Python : "Le mot "crocodile" est-il derrière le mot "tortue" dans le dictionnaire ?".
On voit qu'on utilise ici l'ordre lexicographique, l'ordre du dictionnaire (si tout est en minuscule).
Dans une autre activité, nous détaillerons un peu plus comment cela fonctionne, notamment la gestion des majuscules ou des autres caractères.
Puisque = est déjà utilisé pour l'affectation des variables (a = 50 par exemple), les concepteurs de Python ont choisi la syntaxe d'un double signe égal pour le test d'égalité.
>>> 40 == 3 * 10
False
On pose la question suivante à l'interpréteur Python : "40 est-il identique à 3 * 10 ?".
>>> 40 == 4 * 10
True
On pose la question suivante à l'interpréteur Python : "40 est-il identique à 4 * 10 ?".
>>> 0.3 == 3 * 0.1
False
On pose la question suivante à l'interpréteur Python : "0.3 est-il identique à 3 * 0.1 ?". Pourquoi obtient-on False ? Simplement car 0.1 n'a pas été mémorisé de façon exacte, et donc 3 * presque 0.1, ca ne donne pas presque 0.3 !
Puisque ≠ n'est pas facilement accessible sur un clavier, les concepteurs de Python ont choisi la syntaxe != pour le test de différence. Dans d'autres langages, c'est parfois <>.
>>> 40 != 3 * 10
True
On pose la question suivante à l'interpréteur Python : "40 est-il différent de 3 * 10 ?".
>>> 40 != 4 * 10
False
On pose la question suivante à l'interpréteur Python : "40 est-il différent de 4 * 10 ?".
>>> 40 < 30
False
On pose la question suivante à l'interpréteur Python : "40 est-il strictement inférieur à 30 ?".
>>> 40 <= 30
False
On pose la question suivante à l'interpréteur Python : "40 est-il inférieur ou égal à 30 ?".
>>> 40 >= 30
False
On pose la question suivante à l'interpréteur Python : "40 est-il supérieur ou égal à 30 ?".
Le mot-clé in permet de savoir si un élément a est présent dans un élément b : a in b
Si la réponse est True, c'est que a apparaît dans b. Sinon, la réponse sera False.
Voici un moyen de tester facilement si quelqu'un d'allergique au soja peut manger un produit dont on connaît la composition :
>>> "soja" in "Sucre ; huile de colza ; eau ; chocolat en poudre 15 % (sucre, pâte de cacao) ; farine de blé ; poudre d’œuf ; stabilisants : glycérol, gomme xanthane ; cacao en poudre 2,5 % ; poudre à lever : E450, E500 ; amidon de blé ; conservateur : E202 ; sel. Traces de lait."
False
La question posée est Le mot "soja" apparaît-il dans la composition fournie" ?
Et si vous étiez intolérant au blé ?
>>> "blé" in "Sucre ; huile de colza ; eau ; chocolat en poudre 15 % (sucre, pâte de cacao) ; farine de blé ; poudre d’œuf ; stabilisants : glycérol, gomme xanthane ; cacao en poudre 2,5 % ; poudre à lever : E450, E500 ; amidon de blé ; conservateur : E202 ; sel. Traces de lait."
True
La question posée est Le mot "blé" apparaît-il dans la composition fournie" ?
01° Utiliser ces instructions dans la console pour comprendre le principe de l'évaluation du booléen obtenu.
>>> a = 12
>>> b = 20
>>> b > a
True
>>> b < a
False
>>> b == a
False
>>> b != a
True
On peut stocker le résultat d'une expression booléenne dans une variable. Cette variable contiendra alors soit True, soit False.
Questions
- Formuler en français la question équivalente aux différentes expressions booléennes dont les résultats seront stockés dans les variables c, d, e et f.
- Trouver le contenu stocké dans les différentes variables c, d, e et f. Vérifier à l'aide de la console.
>>> a = 12
>>> b = 20
>>> c = b > a
>>> d = b < a
>>> e = b == a
>>> f = b != a
...CORRECTION...
Les questions équivalentes sont :
>>> c = b > a
Le contenu de b est-il strictement supérieur au contenu de a ?
>>> d = b < a
Le contenu de b est-il strictement inférieur au contenu de a ?
>>> e = b == a
Le contenu de b est-il identique au contenu de a ?
>>> f = b != a
Le contenu de b est-il différent du contenu de a ?
Pour les valeurs, il suffit de vérifier :
>>> a = 12
>>> b = 20
>>> c = b > a
>>> c
True
>>> d = b < a
>>> d
False
>>> e = b == a
>>> e
False
>>> f = b != a
>>> f
True
(RAPPELS) 1.2 Expression - Instruction - Affectation
Expression
Une expression est un ensemble de valeurs associées à des opérateurs. L'interpréteur peut évaluer l'expression pour en fournir la valeur.
Une expression ne modifie pas l'état du programme.. Elle fournit simplement une valeur, sans la stocker définitivement.
Dans un programme :
1 |
|
Ce programme n'a aucun effet, ni en mémoire, ni à l'affichage. Sa ligne est bien simplement une expression.
Dans la console interactive :
>>> "bon" * 2
'bonbon'
Attention, l'affichage obtenu est juste dû au fait qu'on soit dans la console : puisqu'on ne fait rien du résultat de l'expression, il est redirigé vers la sortie console. La même ligne n'aurait aucun effet dans un programme.
Instruction
Une instruction modifie l'état du programme (soit sa mémoire, soit en modifiant l'IHM).
- L'instruction la plus fondamentale est l'affectation : on crée une variable en mémoire.
- L'utilisation d'une méthode du module Turtle est bien une instruction : on modifie l'affichage à l'écran et donc l'état de l'interface graphique.
Dans un programme :
1 |
|
Dans la console :

Exemples
>>> "bon" * 2 # EXPRESSION (comme elle est seule et qu'on est dans la console, on obtient son affichage)
'bonbon'
>>> a = "bon" * 2 # INSTRUCTION : AFFECTATION
>>> print("bon" * 2) # INSTRUCTION (on agit sur l'IHM Console)
bonbon
Notez bien que la console Python affiche le résultat d'une expression non redirigée ailleurs.
(RAPPELS) 1.3 - Créer un booléen avec bool()
La fonction native bool() reçoit une donnée quelconque et renvoie True ou False.
!!! A SAVOIR PAR COEUR !!!
En Python, un contenu VIDE ou NUL est évalué à False si on demande un résulat booléen.
Dans tous les autres cas, le résultat est True.
D'où l'intérêt de savoir ce que veut dire nul ou vide pour les différents types de base.Voici quelques exemples d'évaluation en booléen :
>>> bool(0)
False
>>> bool(5)
True
>>> bool(5.2)
True
>>> bool(0.0)
False
>>> bool("5")
True
>>> bool("5.2")
True
>>> bool("bonjour")
True
>>> bool("")
False
2 - Instruction conditionnelle SI, SINON SI, SINON
C'est l'indentation à droite qui permet à Python de comprendre les actions que vous voulez qu'il réalise si une condition est vérifiée. Il faut donc placer une tabulation ou 4 espaces de suite pour savoir qu’elles sont les instructions rattachées au bloc.
(RAPPELS) 2.1 Instruction conditionnelle
Une instruction conditionnelle permet d'exécuter un bloc d'instructions uniquement si la condition évaluée est vraie (True en Python).
Ci-dessous, un exemple où on change l'appréciation si la note est bonne (if en anglais)
1
2
3
4
5
6 |
fatigue = "En forme !"
appreciation = "Moyen"
note = 20
if note > 15:
appreciation = "Très bien"
fatigue = "Grosse fatigue"
|
TABULATION : le bloc d'instructions à effectuer est décalé de 4 espaces (ligne 5). Ce décalage permet à l'intepréteur Python de signaler le début et la fin du bloc. La ligne 6 n'appartient donc pas au bloc.
Déroulé pour note = 20 : L1-L2-L3-L4-L5-L6
Déroulé pour note = 10 : L1-L2-L3-L4-L6
Traduction :
- L3 : note vaut 20.
- L4 : si la note fournie est strictement supérieure à 15
- L5 tabulée : alors appreciation passe à "Très bien".
- L6 : fatigue passe à "Grosse fatigue" (sans condition car pas de tabulation).
2.2 Instruction conditionnelle : structure générale
Quelque soit le langage, on retrouve toujours une structure qui ressemble à ceci :
1
2
3
4
5
6
7
8
9
10
11 |
|
Nombre de blocs
- Un unique bloc SI et il doit toujours être en première position
- 0, 1 ou autant de blocs SINON SI que vous voulez (il peut ne pas y en avoir)
- 0 ou 1 bloc SINON et il doit toujours être en dernière position : c'est le bloc par défaut. Si aucun autre n'a été activé, on prend celui-ci.
2.3 Instruction conditionnelle : un seul bloc exécuté
A SAVOIR IMPERATIVEMENT
L'interpréteur Python n'exécute que l'un des blocs A, B ou C d'une structure if-elif-else.
Il exécute les instructions du bloc de la première expression évaluée à True puis quitte la structure même si les autres expressions sont vraies également.
Un exemple de déroulement
Instructions Avant 1
Instructions Avant 2
if note > 11: # BLOC A (unique et obligatoire)
Instruction A1
Instruction A2
Instruction A3
elif note < 9: # BLOC B (optionnel(s))
Instruction B1
Instruction B2
Instruction B3
else: # BLOC C (unique et optionnel)
Instruction C1
Instruction C2
Instructions Après 1
Instructions Après 2
Bloc A if : SI l'expression A (note > 11) est évaluée à True, il exécute A1-A2-A3 puis atteint directement Après 1. Sinon, il passe au bloc B.
Bloc B elif : SINON, SI l'expression B (note < 9) est évaluée à True, il exécute B1-B2-B3 puis atteint directement Après 1. Sinon, il passe au bloc C.
Bloc C else : on réalise forcément les instructions C1-C2 si on atteint ce bloc car c'est le bloc else qui veut dire SINON, sous entendu "dans tous les autres cas".
02° Tester la fonction suivante en lui fournisant différents paramètres entre 1980 et 2010 par exemple.
1
2
3
4
5
6
7
8
9
10 |
|
>>> creer_message(1981)
???
>>> creer_message(1991)
???
>>> creer_message(2021)
???
Questions :
- La fonction renvoie-t-elle systématiquement la même réponse pour 1980, 1991 et 2050 ?
- Ligne 4 : si le paramètre reponse référence 1987, comment est évaluée l'expression reponse > annee_creation_python ? Va-t-on alors activer la ligne 5 ?
- Ligne 6 : si le paramètre reponse référence 1987, comment est évaluée l'expression reponse < annee_creation_python ? Va-t-on activer la ligne 7 ?
- Quel est mot-clé correspondant à SI en Python ?
- Quel est mot-clé correspondant à SINON SI en Python ?
- Quel est mot-clé correspondant à SINON en Python ?
...CORRECTION...
On constate bien que la fonction renvoie des réponses différentes en fonction de la valeur que reçoit la fonction en entrée :
>>> creer_message(1981)
'Python a été créé après 1981'
>>> creer_message(1991)
'Oui, Python est sorti pour la première fois en 1991'
>>> creer_message(2021)
'Python a été créé avant 2021'
L'expression reponse > annee_creation_python
est évaluée progressivement de cette façon :
reponse > annee_creation_python
1987 > annee_creation_python
1987 > 1991
False
On n'exécute donc pas la ligne 5 de ce bloc puisque l'expression booléenne n'est pas vraie.
L'expression reponse < annee_creation_python
est évaluée progressivement de cette façon :
reponse < annee_creation_python
1987 < annee_creation_python
1987 < 1991
True
Du coup, on va exécuter la ligne 7 qui appartient à ce bloc.
Le SI se code avec le mot-clé if.
Le SINON SI se code avec le mot-clé elif.
Le SINON (tout court) se code avec le mot-clé else.
03° Quelques questions générales :
- Que trouve-t-on à la fin de chacune des lignes contenant if, elif ou else ?
- Comment sont positionnées les instructions conditionnelles par rapport aux mots-clés précédents ?
- L'interpréteur continue-t-il à effectuer le reste des tests à partir du moment où il valide l'un des blocs d'instructions ?
...CORRECTION...
- On finit chaque condition par
:
. - On retrouve la structure d'une fonction ou d'un for : on décale de 4 espaces pour signaler les limites du bloc.
- L'interpréteur ne traitera bien que l'un des blocs. Dès qu'il rencontre une expression évaluée VRAIE, il exécute les instructions du bloc correspondant puis quitte la structure conditionnelle SANS tester les possibilités restantes.
04° Compléter la fonction appreciation() ci-dessous. Elle doit renvoyer "Bien" si le paramètre note est strictement supérieur à 13, "Insuffisant" si le paramètre est inférieur à 9 et "Moyen" sinon. Contrainte : on ne veut qu'un seul return.
1
2
3
4
5
6
7
8 |
|
...CORRECTION...
Version un seul endroit où on gère l'envoi de la réponse.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
|
05° Quelqu'un propose cette version 02 (elle est valide) permettant de répondre dès qu'on sait quoi répondre plutôt que de traiter les différents cas et d'envoyer la réponse à la fin.
Version 2 valide (plusieurs sorties)
1
2
3
4
5
6
7
8
9
10
11
12
13 |
|
AVANTAGE : cette structure permet au lecteur humain de savoir immédiatement la réponse qui va être donner dans ce cas.
DESAVANTAGE : il va être plus difficile de vérifier et surveiller les réponses de cette fonction. C'est comme surveiller un batiment : c'est plus facile de contrôler les sorties s'il n'y a qu'une seule sortie.
Version 3 valide (plusieurs sorties, pas de else final)
Une autre personne pense qu'on peut encore faire plus rapide en supprimant le else final avec cette version 03. Cette version 03 est valide également puisque si on arrive en ligne 12, c'est que les autres return n'ont pas été rencontrés.
1
2
3
4
5
6
7
8
9
10
11
12 |
|
AVANTAGE : on gagne une ligne. Bof.
Version 4 incorrecte (une sortie, pas de else final)
Un enthousiaste pense du coup à modifier la première version et propose une version 04 (incorrecte attention).
1
2
3
4
5
6
7
8
9
10
11
12
13 |
|
Question
Expliquer pourquoi on peut se passer du else dans la version 3 mais pas dans la version 4.
...CORRECTION...
La version 03 fonctionne car dès qu'on rencontre un return, on répond et on sort de la fonction.
Si on atteint les lignes 9 ou 11, on quitte donc la fonction. Cela veut dire qu'on ne peut arriver à la ligne 12 que si la note n'est ni supérieure à 13, ni inférieure à 9.
Par contre, dans la version 04, il ne place pas de return. Cela veut dire que même si on rentre dans l'un des blocs if ou elif, on affectera la variable app mais on ne sortira pas de la fonction.
Du coup, on va simplement atterir ligne 12 à chaque fois et écraser la version précédente de notre variable !
Ici, le else est donc obligatoire.
2.4 Instruction conditionnelle et fonction
RAPPEL : on sort d'une fonction et on fait disparaître l'espace des noms dédié dès qu'on rencontre un return.
Version propre avec une seule "porte de sortie"
- AVANTAGE : plus facile de surveiller la correction de la fonction (le fait que la fonction réponde toujours correctement)
- DESAVANTAGE : il faut stocker la réponse dans une variable et lire ensuite séquentiellement la fonction jusqu'à trouver l'unique sortie.
1
2
3
4
5
6
7
8 |
|
Version avec plusieurs "portes de sortie"
- DESAVANTAGE : moins facile à surveiller (plusieurs portes de sortie à contrôler).
- AVANTAGE : on n'a pas besoin en tant que lecteur humain de continuer à lire le reste du code lorsqu'on rencontre une sortie.
1
2
3
4
5
6
7 |
|
Ou encore :
1
2
3
4
5
6 |
|
Exemple
Voici quelques autres exemples d'utilisation pour mieux comprendre comment structurer vos demandes :
- La fonction trop_gentil() qui renvoie une note augmentée de +2 si la note d'entrée est inférieure à 10 et, sinon, +1 pour une note inférieure à 19.
- La fonction beaucoup_trop_gentil() qui renvoie une note augmentée de +5 si la note d'entrée est inférieure à 10 et, sinon, +3 dans les autres cas. La fonction ne doit jamais renvoyer de notes supérieures à 20 : on impose L8-L9 cette condition juste avant de renvoyer la réponse par l'unique porte de sortie.
- La fonction beaucoup_trop_gentil() pas top car elle possède plusieurs "portes de sortie" : on se retrouve à faire du copier-coller de la vérification des valeurs des sorties (L6-L7 et L12-L13). La correction de la fonction est plus compliquée à faire.
1
2
3
4
5
6 |
|
1
2
3
4
5
6
7
8
9
10 |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
|
Passons à la pratique :
✎ 06° Compléter la fonction traduction() ci-dessous. Elle doit renvoyer :
- "vert" si le paramètre color est "green",
- "rouge" pour "red",
- "bleu" pour "blue",
- "jaune" pour "yellow".
- si la couleur est inconnue, elle doit répondre "traduction inconnue pour cette couleur".
Remarque : on veut une structure if-elif if-else. Mais nous sommes d'accord qu'un dict aurait mieux fait l'affaire !
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
|
3 - Prédicat : fonction renvoyant un booléen
3.1 Opérateurs == et =
Attention à ne pas confondre
- l'opérateur d'égalité de contenu ==
- l'opérateur d'affectation =
Avec a == b, l'interpréteur comprend qu'il doit tester l'égalité des variables a et b. Il va donc évaluer cette expression et obtenir vrai si les deux contenus sont les mêmes.
Avec a = b, l'interpréteur comprend qu'il faut stocker b dans la variable a. On génère donc un alias.
3.2 FONCTION : Prédicat
On peut nommer de cette façon une fonction qui renvoie toujours un booléen : elle répondra soit True soit False.
On parle de prédicat puisque la fonction prédit une propriété à partir des paramètres reçus.
Ce cas de figure est très courant en informatique : créer un prédicat ne requiert donc forcément pas d'utiliser un if : il suffit de fournir l'expression qu'on veut évaluer derrière votre return.
Exemple avec une expression qui évalue si une note de 10 permet de valider un semestre :
>>> note = 9
>>> note >= 10
False
>>> note = 12
>>> note >= 10
True
Le prédicat validant le semestre donnerait simplement ceci :
1
2
3 |
|
07° Que va renvoyer la fonction est_valide() si le paramètre note vaut 7 ?
1
2
3 |
|
...CORRECTION...
note >= 10
7 >= 10
08° Un élève propose cette version : est-elle bonne, fausse, correcte mais inutilement longue ?
1
2
3
4
5
6 |
|
...CORRECTION...
Bonne mais inutilement longue.
Si vous préférez cette version pendant quelques temps, utilisez la. Vous aurez les points.
Mais dès que vous serez à l'aise, passez plutôt à la version courte return note >= 10.
09° Compléter la fonction- prédicat comparer() pour qu'elle renvoie True si les deux paramètres sont égaux. Aucune condition de type sur les deux paramètres.
1
2
3 |
|
...CORRECTION...
Il est probable que vous ayez tapé quelque chose qui ressemble à cela :
1
2
3
4
5
6 |
|
Si vous avez mémorisé l'histoire du return qui provoque une sortie de la fonction, vous avez même surement tapé ceci :
1
2
3
4
5 |
|
Et pourtant, il a eu encore une manière plus courte de répondre (les explications sont ci-dessous si vous ne comprennez pas bien comment ça fonctionne) :
1
2
3 |
|
4 - Opérateurs booléens
Nous allons voir comment décrire certaines conditions logiques de façon plus élégante et concise qu'avec une suite de if-elif-else.
Vous avez déjà vu des opérations qui renvoient un booléen. En voici trois avec leur signature :
L'opérateur d'appartenance
type_quelconque in type_structure -> bool
L'opérateur d'égalité de contenu
un_type_quelconque == un_type_quelconque -> bool
L'opérateur de différence de contenu
un_type_quelconque != un_type_quelconque -> bool
Nous allons maintenant voir les opérateurs booléens : ils renvoient un booléen mais doivent également recevoir des booléens en entrée.
4.1 Instruction conditionnelle : prédicat à True
RAPPEL : un prédicat est une fonction qui répondra True ou False sur toutes les entrées qu'on lui fournit.
Présentation du prédicat-exemple
Imaginons qu'on dispose d'un prédicat contient() qui permet de tester si une chaine de caractères contient un mot précis qu'on recherche, en comparant les deux en minuscules.
1
2
3
4
5 |
|
Un exemple d'utilisation :
>>> contient("Je veux me plaindre de mes notes bla bla", "PLAINDRE")
True
Bonne pratique de programmation
On se souvient qu'on exécute le bloc si l'expression booléenne fournie derrière le if est évaluée à True.
Voici un programme qui permet de récupérer tous les plats qui contiennent des poivrons parmi une liste de plats qu'on aime bien par exemple :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
|
On voit donc qu'il suffit de placer le prédicat : s'il est interprété à True, on effectue le bloc. Sinon, non.
Mauvaise pratique de programmation
Nous aurions pu écrire ceci mais c'est plus long et inutile puisque le principe est bien de faire le bloc si l'expression est évaluée à True :
16
17
18 |
|
Evitez d'utiliser cette version : elle fonctionne mais montre que vous n'avez pas vraiment compris le principe du if.
10° Imaginons qu'on veuille tester si une moyenne est suffisante pour valider un bloc d'enseignement à l'université. Créons pour cela la fonction est_valide().
1
2
3 |
|
Les deux utilisations ci-dessous sont-elles valides ? L'une des deux versions elle-est à privilégier ?
Version A
1
2 |
|
Version B
1
2 |
|
...CORRECTION...
Par défaut, Python évalue la condition et réalise les actions du bloc si la condtion est évaluée à True. Mais comme ici nous obtenons directement un booléen, pas la peine d'en rajouter : le cas A est suffisant et clair.
Ok |
|
Vous auriez pu taper ceci également, mais c'est inutile :
Ok mais bof bof |
|
Voyons maintenant, l'inverse : comment réaliser une action uniquement si on vous répond FAUX.
4.2 Instruction conditionnelle : not pour tester un prédicat à False
Imaginons qu'on veuille récupérer les plats qui ne contiennent pas de poivron. On dispose du prédicat contient() qui permet de savoir si un mot (un ingrédient par exemple) est contenu dans une chaîne de caractères (la recette par exemple).
Très mauvaise pratique de programmation
A éviter absolument !
On veut agir lorsque le prédicat est évalué à False. De façon naïve, on pourrait se dire : si le prédicat est vrai, on ne fait rien, sinon on agit.
16
17
18
19
20 |
|
Assez mauvaise pratique de programmation
On se souvient qu'on exécute le bloc si l'expression booléenne fournie derrière le if est évaluée à True.
On pourrait donc placer comme expression le fait que le prédicat soit évaluée à False !
16
17
18 |
|
Evitez d'utiliser cette version : nous allons voir ci-dessous qu'il existe une meilleure façon de faire, celle qui sera utiliser par n'importe quel développeur.
Bonne pratique de programmation : utiliser not
On peut faire mieux en utilisant le mot-clé not : ce mot-clé inverse la valeur du booléen situé derrière lui.
not bool -> bool
>>> b = False
>>> b
False
>>> not b
True
On peut alors écrire plus proprement le fait d'agir uniquement si le mot "Poivron" n'apparaît pas :
16
17
18 |
|
Le programme dans sa totalité :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
|
11° Imaginons qu'on veuille convoquer à un oral de rattrapage les étudiants ayant raté leur semestre. Nous voulons toujours utiliser la fonction est_valide().
1
2
3 |
|
Les deux utilisations ci-dessous sont-elles valides ? L'une des deux versions elle-est à privilégier ?
Version A
1
2 |
|
Version B
1
2 |
|
...CORRECTION...
La version A est la plus élégante.
Ok et élégant |
|
Comme la fonction renvoie un booléen, nous pourrions également utiliser la version B mais c'est moins "propre" :
Ok mais bof bof |
|
Ok mais bof bof |
|
12° Quelle va être la ligne interprétée (L2 ou L4) si comparer() renvoie False sur cet appel.
1
2
3
4 |
|
...CORRECTION...
La ligne 1 va être progressivement évaluée de cette manière :
if not comparer(choix, m)
if not False
if True
Comme la condition de la ligne 1 donne True, on effectue son bloc et on exécute donc la fonction tache_1().
4.3 Instruction conditionnelle : and pour utiliser plusieurs conditions en même temps
Imaginons qu'on veuille récupérer les plats qui contiennent du poivron et de l'aubergine. On dispose du prédicat contient() qui permet de savoir si un mot (un ingrédient par exemple) est contenu dans une chaîne de caractères (la recette par exemple).
Méthode possible mais problématique dans certains cas
On commence par filtrer sur les poivrons et on rajoute une instruction conditionnelle dans la première.
16
17
18
19 |
|
Si on ne doit rien faire lorsque c'est faux, c'est correct.
Par contre, si on doit agir lorsque ce n'est pas vrai, cela pose problème puisqu'il est possible qu'on soit obligé de faire du copier-coller ou qu'on oublie un cas.
16
17
18
19
20
21
22
23 |
|
Bonne pratique de programmation : utiliser and
On peut faire mieux en utilisant le mot-clé and : ce mot-clé est un opérateur booléen qui
- renvoie Vrai uniquement si les entrées sont toutes vraies
- renvoie Faux dans tous les autres cas.
bool and bool -> bool
>>> a = True
>>> b = True
>>> a and b
True
>>> b = False
>>> a and b
False
Pour afficher proprement les plats qui contiennent des poivrons et des aubergines :
16
17
18 |
|
Notez bien la présence d'une condition à gauche et à droite du mot-clé and.
De plus, si on veut agir lorsque ce n'est pas vrai, la structure ne nécessite plus de faire des copier-coller :
16
17
18
19
20 |
|
Le programme dans sa totalité :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
|
4.4 Table de vérité du and
Voici la table de vérité de l'opérateur ET :
Valeur de a | Valeur de b | a and b |
---|---|---|
False | False | False |
False | True | False |
True | False | False |
True | True | True |
A RETENIR : le ET est VRAI uniquement lorsque toutes les entrées sont à VRAI.
Imaginons qu'on veuille créer une fonction est_valide() qui vérifie qu'une note est bien comprise entre 0 et 20.
1
2
3
4
5
6
7 | def est_valide(n:int) -> bool:
"""Prédicat qui renvoie True si n est un entier dans [0;20]"""
if n > 20:
return False
elif n < 0:
return False
return True
|
13° Expliquer pourquoi la fonction est_valide() ne renvoie pas systématiquement True alors qu'il s'agit de la dernière ligne de cette fonction.
...CORRECTION...
Tout simplement car on sort de la fonction dès qu'on rencontre un return.
Si l'un des deux tests précédents renvoie True, on va donc exécuter le return False
et sortir de la fonction.
✎ 14° Un élève propose la fonction ci-dessous. Expliquer clairement pourquoi sa fonction n'est pas correcte alors qu'elle ne déclenche pas d'erreur et qu'elle renvoie bien True pour une note n de 15 par exemple.
1
2
3
4
5
6
7 | def est_valide(n:int) -> bool:
"""Prédicat qui renvoie True si n est un entier dans [0;20]"""
if n <= 20:
return True
elif n >= 0:
return True
return False
|
Si vous ne trouvez pas, demandez-vous ce qu'elle renvoie pour une note de -15.
Pour obtenir un code plus lisible et concis, il existe l'opérateur and qui permet d'associer plusieurs conditions.
Revoyons comment cela fonctionne.
15° Tapez les instructions ci-dessous dans la console.
>>> note = 15
>>> note >= 0
True
>>> note < 0
False
>>> note <=20
True
>>> note > 20
False
>>> note >= 0 and note <= 20
True
>>> note = 25
>>> note >= 0 and note <= 20
False
Question : que doivent valoir a et b pour que l'expression booléenne a and b soit évaluée à True ?
...CORRECTION...
L'expression n'est évaluée à True qui si les deux expressions a b sont True. Il s'agit d'un ET logique.
Voici donc une manière plus simple de créer notre fonction est_valide(). Cela ne change en rien son utilisation : pour l'utilisateur, le changement est totalement invisible.
1
2
3 | def est_valide(n:int) -> bool:
"""Fonction qui renvoie True si n est un entier dans [0;20]"""
return n >= 0 and n <= 20
|
Une seule ligne, hors documentation. Pas mal non ?
✎ 16° Un élève propose une autre version de cette fonction. Expliquer clairement pourquoi vous pensez que sa fonction est correcte ou fausse (pensez à regarder les préconditions sur le paramètre n).
1
2
3 | def est_valide(n:int) -> bool:
"""Prédicat qui renvoie True si n est un entier dans [0;20]"""
return n > -1 and n < 21
|
4.5 Instruction conditionnelle : or pour utiliser plusieurs conditions au choix
Imaginons qu'on veuille récupérer les plats qui contiennent soit du poivron, soit de l'aubergine, voire les deux à la fois. On dispose du prédicat contient() qui permet de savoir si un mot (un ingrédient par exemple) est contenu dans une chaîne de caractères (la recette par exemple).
Méthode possible mais qui nécessite du copier-coller
On commence par filtrer sur les poivrons, sinon, on filtre sur les aubergines.
16
17
18
19
20 |
|
Ici, on a bien deux fois la même instruction sur les lignes 18 et 20.
Bonne pratique de programmation : utiliser or
On peut faire mieux en utilisant le mot-clé or : ce mot-clé est un opérateur booléen qui
- renvoie Faux uniquement si les entrées sont toutes fausses
- renvoie Vrai dans tous les autres cas (c'est à dire, lorsque une des entrées au moins est vraie).
bool or bool -> bool
>>> a = True
>>> b = True
>>> a or b
True
>>> b = False
>>> a or b
True
Pour afficher proprement les plats qui contiennent des poivrons OU des aubergines, ou les deux :
16
17
18 |
|
Notez bien la présence d'une condition à gauche et à droite du mot-clé or.
Le programme dans sa totalité :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
|
4.6 Table de vérité du or
Le OU logique
Voici la table de vérité de l'opérateur OU :
Valeur de a | Valeur de b | a or b |
---|---|---|
False | False | False |
False | True | True |
True | False | True |
True | True | True |
A RETENIR : le OU est FAUX uniquement lorsque toutes les entrées sont à FAUX.
Le OU exclusif
Le OU logique n'est pas celui de la vie de tous les jours. Si on vous dit "fromage ou dessert" à la cantine, cela veut dire malheureusement que vous ne pouvez en prendre qu'un.
Ce OU particulier se nomme le OU-EXCLUSIF en informatique, XOR an anglais. Si deux entrées sont vraies, le XOR sera faux.
Voici sa table de vérité :
Valeur de a | Valeur de b | a or b |
---|---|---|
False | False | False |
False | True | True |
True | False | True |
True | True | False |
17° Compléter la table de vérité du OU :
Valeur de a | Valeur de b | a or b |
---|---|---|
True | True | ? |
False | True | ? |
True | False | ? |
False | False | ? |
Cela revient à chercher cela avec Python :
a or b
...CORRECTION...
Valeur de a | Valeur de b | a or b |
---|---|---|
True | True | True |
False | True | True |
True | False | True |
False | False | False |
✎ 18° QCM : On demande à quatre élèves de créer une fonction-prédicat note_invalide(). Elle doit renvoyer True si la note n n'est pas dans [0;20].
On vous fournit ci-dessous la réponse de leur fonction. Quel élève fournit la bonne façon de répondre ?
- A : return n >= 0 or n <= 20
- B : return n <= 0 or n >= 20
- C : return n > 0 or n < 20
- D : return n < 0 or n > 20
4.7 Table de vérité du not
Voici la table de vérité de l'opérateur NON :
Valeur de a | not a |
---|---|
False | True |
True | False |
4.8 Priorité des opérateurs logiques (P.A.C.Bo)
Entre eux
- D'abord not
- Ensuite and (équivalent de la multiplication)
- Enfin or (équivalent de l'addition)
Par rapport aux autres opérateurs : P.A.C.Bo
- P - Les plus prioritaires : les parenthèses ()
- A - Ensuite les opérateurs arithmétiques
- **
- * / // %
- + -
- C - Ensuite les opérateurs de comparaison
- les opérateurs d'appartenance in et not in
- les opérateurs de comparaison supérieur et inférieur : >, >=...
- les opérateurs d'égalité et différence ==, !=
- BO - Ensuite les opérateurs logiques booléens
- not
- and
- or
- Les moins prioritaires : if, elif, else
Exemple
Inutile de savoir le refaire par coeur : en cas de doute, mettez des parenthèses. C'est l'habitude qui créera la connaissance de l'ordre P.A.C.Bo
if not a + 8 > b * 2 and a > 0
Op. Arithmétiques : if not (a + 8) > (b * 2) and a > 0
O. de Comparaison : if not ((a + 8) > (b * 2)) and (a > 0)
Op. Booléen (not) : if (not ((a + 8) > (b * 2))) and (a > 0)
Le - prioritaire : if ((not ((a + 8) > (b * 2))) and (a > 0))
5 - If sans condition booléenne ?
Avec un IF, on exécute un bloc tabulé si l'expression booléenne est True.
1
2
3
4 | if expression_booléenne_1:
fait un truc
elif expression_booléenne_2:
fait autre chose
|
Mais que se passe-t-il si on place une expression non booléenne derrière le if ou le elif ?
5.1 Instruction conditionnelle : condition non booléenne
Cas d'une expression booléenne
Lorsque l'interpréteur Python lit un if ou un elif, il s'attend à trouver une expression booléenne derrière.
Exemple : if a >= 0:
Ici, l'expression est bien une expression booléenne.
Cas d'une expression non booléenne
Il peut arriver par contre que l'expression fournie ne soit pas une expression booléenne.
Exemple : if a:
Python ne va alors pas s'embêter : il va chercher à l'interpréter comme un booléen, comme si vous aviez tapé ceci :
Exemple : if bool(a):
Ainsi :
- Si a est 0 ou 0.0 ou "" ou [] ou () ou {} ou None, a sera équivalent à un False.
- Dans tous les autres cas, a sera équivalent à True.
19° Donner les contenus des variables r1, r2, r3, r4 obtenus après exécution du programme ci-dessous.
1
2
3
4
5
6
7
8
9
10 |
|
...CORRECTION...
r1 : avec le premier envoi, la condition de la ligne 3 est évaluée à True, et la fonction renvoie donc 20.
r2 : avec le premier envoi, la condition de la ligne 3 est évaluée à False car la variable n'est qu'une chaîne de caractères vide, et la fonction renvoie donc 10.
r3 : avec le premier envoi, la condition de la ligne 3 est évaluée à True, et la fonction renvoie donc 20.
r4 : avec le premier envoi, la condition de la ligne 3 est évaluée à False car la variable n'est qu'un tableau vide, et la fonction renvoie donc 10.
5.2 Instruction conditionnelle : tableau vide
On peut agir en fonction de l'état vide ou pas d'un type structuré en utilisant une simple instruction conditionnelle sur la variable référençant votre structure.
Voici comment agir de façon différente si le tableau n'est pas vide ou s'il est vide :
1
2
3
4
5 |
|
En utilisant not, on peut bien entendu mettre en avant que le tableau n'est pas vide :
1
2
3
4
5 |
|
CONCLUSION :
Si t fait référence à un type structuré :
- if t se traduit par "Si t n'est pas vide".
- if not t se traduit par "Si t est vide".
On peut maintenant réaliser une fonction qui peut nous aider à gérer les réservations d'un restaurant.
✎ 20-difficile° Donner et expliquer le contenu des variables possible et numero si elle existe.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 |
|
Le programme commence en ligne 21, le reste étant de la déclaration de fonctions.
21
22
23
24 |
|
Pour répondre, il faudra suivre le déroulé exact du programme, expliquer lors des appels ce que contient tel ou tel paramètre... Tenter de comprendre le programme dans sa globalité, sans suivre réellement son cheminement n'a que peu de chance d'aboutir. Séquentialité.
Demandez de l'aide s'il le faut, ce n'est pas si facile que cela lorsqu'on vient de découvrir ces notions.
5.3 Instruction conditionnelle : une erreur typique
Voici une erreur que tout le monde va faire un jour ou l'autre, et qui nécessite pas mal des connaissances que vous avez vu aujourd'hui pour la comprendre.
Imaginions qu'on veuille vérifier que deux notes soient bien supérieures à 10 : en français, nous dirions que note1 et note2 sont supérieures à 10.
La faute courante
La mauvaise et fausse façon de traduire cela :
1 |
|
Et voilà sans doute une belle erreur sémantique. Pourquoi est-ce que cela ne fonctionne pas comme vous le voulez ?
- D'abord car les opérateurs de comparaison sont plus prioritaires que les opérateurs logiques. En réalité, vous avez écrit ceci :
- L'opérateur and travaille donc sur les deux propositions suivantes :
- note1
- note2 > 10
- La première propriété étant juste note1, elle revient donc à demander si note1 contient quelque chose puisqu'elle sera évaluée à VRAI si note1 n'est ni vide ni nulle.
1 |
|
La traduction qui fait Python de cette ligne est donc : est-ce que note1 contient quelque chose et est-ce que note2 est supérieure à 10.
Cela n'est donc pas ce que nous voulions au départ...
La bonne façon de traduire ceci en Python
Nous n'avons pas le choix. Il faut parler à Python comme il le désire : il faut donc placer une propriété à gauche du and et une propriété à droite du and.
1 |
|
Puisqu'on sait que les opérateurs de comparaison sont prioritaires sur les opérateurs logiques, c'est comme si nous avions placé les parenthèses suivantes :
1 |
|
On voit bien que cela veut bien dire ce qu'on voulait au départ : est-ce que note1 est supérieure à 10 et est-ce que note2 est supérieure à 10.
Bien entendu, en français, on évitera la répétition de la propriété car nous avons un cerveau. Ce qui n'est pas le cas de votre interpréteur Python. A vous de vous plier à son niveau de compréhension.
6 - FAQ
On peut tester le type des variables ?
Oui. Les deux manières de faire les plus courantes sont fournies ci-dessous :
Première méthode : tester le type de la variable.
>>> a = 5.0
>>> type(a) == float
True
>>> type(a) == int
False
>>> type(a) == str
False
>>> a = "5.0"
>>> type(a) == float
False
>>> type(a) == int
False
>>> type(a) == str
True
Deuxième façon de faire : utiliser la fonction native isinstance.
>>> a = 5
>>> isinstance(a, float)
False
>>> isinstance(a, int)
True
>>> isinstance(a, str)
False
7 -
Activité publiée le 01 11 2020
Dernière modification : 20 07 2023
Auteur : ows. h.