TD2. Opérateurs booléens
Le sujet de ce TD est disponible au format pdf ici.
L'objectif de ce TD est de se familiariser avec les opérateurs logiques manipulant des valeurs booléennes, c'est-à-dire True et False en python, et avec la structure de contrôle conditionnelle if.
Exercice 1 : opérateurs logiques
On considère le programme suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Question 1
Exécuter le programme en notant, comme dans le TD précédent, l'évolution des variables au cours de l'exécution. Noter également ce qu'affiche le programme sur la sortie standard.
Correction question 1
Cliquez ici pour révéler la correction.
Après avoir exécuté les lignes 4, 5 et 6, les variables sont les suivantes :
| Nom | Type | Valeur | Portée |
|---|---|---|---|
| a | int | 10 | Globale |
| b | int | 20 | Globale |
| c | int | 30 | Globale |
L'opérateur < appliqué à des entiers renvoie True si l'opérande de gauche est strictement plus petite que celle de droite et False sinon.
Après avoir exécuté la ligne 7, les variables sont donc les suivantes :
| Nom | Type | Valeur | Portée |
|---|---|---|---|
| a | int | 10 | Globale |
| b | int | 20 | Globale |
| c | int | 30 | Globale |
| d | bool | True | Globale |
L'exécution de la ligne 8 va afficher d = True.
Ici il est important de noter plusieurs choses concernant la fonction print, qui :
- peut recevoir un nombre variable d'arguments et que chacun d'entre eux sera affiché, deux arguments;
- applique la fonction
strsur chacun des arguments qui n'est pas une chaîne de caractère pour le convertir en chaîne,ddans notre exemple; - possède un paramètre optionnel
sepdont la valeur par défaut est" "qui indique la chaîne de caractère à afficher entre chacun des arguments, c'est pourquoi il y a un espace dans l'affichage entre=etTrue;
Pour comprendre ce qu'il se passe lorsque la ligne 9 est exécutée, il faut :
- se rappeler que dans une affectation, on commence par évaluer la partie droite (logique : il faut connaître la valeur à affecter à la variable pour faire l'affectation)
- connaître les priorités entre les opérateurs, autrement dit savoir ici dans quel ordre on va appliquer les opérateurs
<,andet>. Pour python, la table des priorité est disponible ici. Pour ce qui nous intéresse ici,<et>sont prioritaires sur leand. - connaître la table de vérité du et logique (ci-dessous), autrement dit savoir ce que fait l'opérateur
and.
| a | b | a et b |
|---|---|---|
| Vrai | Vrai | Vrai |
| Vrai | Faux | Faux |
| Faux | Faux | Faux |
| Faux | Vrai | Faux |
Donc pour l'exécution de la ligne 9, l'interpréteur va d'abord évaluer b < c qui donne True puis a > b qui donne False et enfin faire le and entre les deux qui donne False.
L'affectation à e peut ensuite avoir lieu, et donc une fois la ligne 9 exécutée, les variables sont les suivantes :
| Nom | Type | Valeur | Portée |
|---|---|---|---|
| a | int | 10 | Globale |
| b | int | 20 | Globale |
| c | int | 30 | Globale |
| d | bool | True | Globale |
| e | bool | False | Globale |
L'exécution de la ligne 10 va donc afficher e = False sur la sortie standard.
Pour comprendre ce que fait l'exécution de la ligne 11, voici la table de vérité de l'opérateur logique ou, c'est à dire or en python :
| a | b | a ou b |
|---|---|---|
| Vrai | Vrai | Vrai |
| Vrai | Faux | Vrai |
| Faux | Faux | Faux |
| Faux | Vrai | Vrai |
Après l'exécution de la ligne 11, les variables sont donc les suivantes :
| Nom | Type | Valeur | Portée |
|---|---|---|---|
| a | int | 10 | Globale |
| b | int | 20 | Globale |
| c | int | 30 | Globale |
| d | bool | True | Globale |
| e | bool | False | Globale |
L'exécution de la ligne 12 va afficher d = True.
Pour savoir ce que l'exécution de la ligne 13 va donner, il faut retourner voir la table des priorité entre opérateurs et prendre en compte les parenthèses.
L'interpréteur va ici commencer par évaluer la partie gauche du or, à savoir not d, qui va donner False car l'opérateur not inverse la valeur booléenne qui lui est donnée.
Ensuite, la partie droite est évaluée, c'est à dire a + b > c and e.
La table des priorités nous dit que l'on commence par appliquer + puis > et enfin and.
La partie droite du or est donc évaluée à False et dont le or lui même est évalué à False car ses deux opérandes valent False.
Après l'exécution de la ligne 13, les variables sont donc les suivantes :
| Nom | Type | Valeur | Portée |
|---|---|---|---|
| a | int | 10 | Globale |
| b | int | 20 | Globale |
| c | int | 30 | Globale |
| d | bool | True | Globale |
| e | bool | False | Globale |
| f | bool | False | Globale |
L'exécution de la ligne 14 va afficher f = False.
Exercice 2 : opérateurs logiques toujours
On considère le programme suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Question 1
Qu'affiche ce programme sur la sortie standard quand on l'exécute ?
Correction question 1
Cliquez ici pour révéler la correction.
Voici le résultat :
1 2 3 4 | |
Pour comprendre ce qu'il se passe ici, il faut savoir que:
- l'opérateur
a % n(modulo) renvoie le reste de la division euclidienne deaparn; 2 < 3 < 4est un raccourci d'écriture de2 < 3 and 3 < 4;- les opérateurs
oretandsont des opérateurs dit "court-circuit". C'est à dire que pour l'opérateurorl'opérande de droite n'est pas évaluée si l'opérande de gauche est vraie. Pour l'opérateurandl'opérande de droite n'est pas évaluée si l'opérande de gauche est fausse. Voir la documentation officielle ici
Comme un appel à la fonction est_pair produit des effets de bords, c'est à dire des effets visibles à l'extérieur de la fonction, en l'occurrence un affichage sur la sortie standard, le court-circuit est visible sur cet exemple.
Exercice 3 : réécritures
On considère le programme suivant :
1 2 3 4 5 6 7 8 9 10 11 12 | |
Question 1
Comment simplifier ce code ?
Correction question 1
Cliquez ici pour révéler la correction.
1 2 3 4 5 6 7 | |
Question 2
En sachant que int(False) vaut 0 et que int(True) vaut 1, trouver une expression arithmétique calculant la valeur de b en fonction de a.
Correction question 2
Cliquez ici pour révéler la correction.
1 | |
Question 3
On suppose maintenant que a est entier compris entre 0 et 6.
À l'aide d'un tuple de 7 éléments, supprimer toutes les comparaisons pour affecter la bonne valeur à b.
Correction question 3
Cliquez ici pour révéler la correction.
1 2 | |
if, elif et else ?
Il n'y a pas de "bonne" réponse à cette question, c'est le contexte ainsi que les habitudes de chacun qui permettront de choisir entre les deux versions.
Question 4
Pour ceux qui connaissent déjà python, comment raccourcir le test suivant sachant que s est une chaîne de caractères, i un entier et t un tuple ?
1 2 | |
Correction question 4
Cliquez ici pour révéler la correction.
1 2 | |
if.
Autrement dit, quand un booléen est attendu et qu'un autre type est fourni, il y a une conversion automatique vers un booléen.
Comme on le voit dans la correction ci-dessus, en supposant qu'elle soit juste (à vérifier absolument dans un interpréteur interactif pendant la prochaine séance de TP), :
- une chaîne de caractères est convertie en
Truesi sa longueur est strictement plus grande que zéro et enFalsesinon ; - un entier est converti en
Truesi il est différent de0et enFalsesi il est égal à0; - un tuple est converti en
Truesi sa longueur est strictement plus grande que zéro et enFalsesinon.
Exercice 4 : date correcte
Question 1
Écrire la fonction date_correcte(jour, mois, annee) qui renvoie True si les trois entiers donnés en argument forment une date correcte et False sinon. On considère pour cette première question que le mois de février a toujours 28 jours.
Correction question 1
Cliquez ici pour révéler la correction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Question 2
Prendre en compte les années bissextiles. Une année est bissextile si elle rentre dans l'un des deux cas suivants :
- l'année est divisible par 4 et non divisible par 100 ;
- l'année est divisible par 400.
Par exemple, l'an 2000 était bissextile mais 2100 ne le sera pas.
Correction question 2
Cliquez ici pour révéler la correction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
Exercice 5 : surprenant non ? (pour aller plus loin)
Question 1
Qu'affiche le programme suivant ?
1 2 3 | |
Question 2
Qu'affiche le programme suivant ?
1 2 3 | |
Correction question 2
Cliquez ici pour révéler la correction.
Faisons quelques tests dans un interpréteur interactif (ipython ci-dessous) :
1 2 3 4 5 | |
Le premier programme affiche donc toto et le second 41.
Pour comprendre pourquoi, il faut aller là.
Exercice 6 : fizzbuzz ? (pour aller plus loin)
Question 1
Écrire le plus "joliment" possible une fonction fizzbuzz(nombre) retournant :
"fizz"sinombreest un multiple de 3"buzz"sinombreest un multiple de 5"fizzbuzz"sinombreest un multiple de 3 et de 5str(nombre)sinon
Correction question 1
Cliquez ici pour révéler la correction.
Ce programme est célèbre, paraît-il, parcequ'il est utilisé dans des entretiens d'embauche. Voici différente implémentation dont on peut discuter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |