On va s’attaquer pour cette leçon à un nouveau type de données. Il permet d’effectuer des opérations logiques. Il s’agit des booléens (bool en python).
Il n’y en en fait que deux exemplaires, VRAI et FAUX ou en python:
>>> True
True
>>> False
False
>>> type(True)
<class 'bool'>Noter qu’il n’y a qu’une seule façon valide de les écrire!
>>> false
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'false' is not defined
>>> TRUE
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'TRUE' is not definedOn peut combiner plusieurs booléens de trois manières distinctes.
La négation via not
>>> not True
False
>>> not False
TrueLa conjonction via and
>>> False and False
False
>>> False and True
False
>>> True and False
False
>>> True and True
TrueElle renvoie True lorsque toutes les opérandes sont True.
La disjonction via or
>>> False or False
False
>>> False or True
True
>>> True or False
True
>>> True or True
TrueElle renvoie True lorsqu’au moins une des opérandes est True.
Notez que les deux derniers opérateurs se généralisent à des conteneurs de booléens via les fonction any et all.
>>> vrais = (True, True, True)
>>> any(vrais)
True
>>> all(vrais)
True
>>> faux = (False, False, False)
>>> any(faux)
False
>>> all(faux)
False
>>> mixte = (False, True, False)
>>> all(mixte)
False
>>> any(mixte)
TrueL’intérêt des booléens est de permettre de raisonner suivant que certains propriétés sont vraies ou fausses. On produit des booléens via des opérateurs de comparaisons.
Le test d’égalité via == permet de savoir si deux objets ont même valeurs.(ATTENTION = est réservé à l’affectation!)
>>> x = 123456789
>>> y = 123456789
>>> z = 987654321
>>> x == y
True
>>> x == z
FalseREMARQUE deux séquences (tuple pour l’instant mais list d’ici peu) sont égales si toutes leurs valeurs le sont (et à la même position)
>>> (1, 2) == (1, 2)
True
>>> (1, 2) == (2, 1)
False
>>> (1, 2, 3) == (1, 2)
FalsePour tester au contraire la différence de valeurs, on peut utiliser la négation not ou l’opérateur !=
>>> x = 123456789
>>> y = 123456789
>>> z = 987654321
>>> not (x == y)
False
>>> x != y
False
>>> not (x == z)
True
>>> x != z
TrueComme on l’a déjà vu plusieurs fois, en python on fait la différence entre l’égalité (qui concerne la valeur de l’objet) et l’identité (qui concerne l’objet lui même). Pour tester l’identité on utilise is
>>> x = 123456789
>>> y = x
>>> z = 123456789
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
FalseREMARQUE lorsque on veut nier l’identité on peut utiliser is not qui se lit plus naturellement que l’utilisation de la négation en tête:
>>> x = 123456789
>>> y = x
>>> z = 123456789
>>> not (x is y)
False
>>> not (x is z)
True
>>> x is not y
False
>>> x is not y
FalseOn peut comparer la grandeur des nombres via les opérateurs strictement plus petit et strictement plus grand:
>>> 1 < 2
True
>>> 2 < 1
False
>>> 1 > 2
False
>>> 2 > 1
TrueLes opérateurs de comparaison relatifs sont <= et >= (le signe = vient en deuxième car on dit ou égal en second)
>>> 1 < 1
False
>>> 1 <= 1
True
>>> 1 >= 1
TrueREMARQUE pour les séquences on utilise l’ordre dit lexicographique, c’est à dire qu’on fait les comparaisons des valeurs de gauche à droite. Plus succinctement les séquences sont ordonnées comme leur première composante non égale!
>>> (1, 2) < (3, 0)
True
>>> (1, 2) > (1, 1)
Truetuples sont 1 et 3 qui sont dans l’ordre demandé, on ne regarde pas la suite et l’expression évalue à True.1 et 1, on va comparer les secondes. Comme 2 et 1 sont dans l’ordre demandé, l’expression évalue à True.ATTENTION les str sont elles aussi comparables via l’ordre lexicographique (et pas par leurs longueurs), mais cela permet juste de ramener la comparaison caractère par caractère. En première approche on peut utiliser l’ordre alphabétique pour analyser la situation.
>>> "a" < "b"
True
>>> "d" < "z"
True
>>> "f" < "b"
FalseEn fait la situation est plus délicate, ce qui est réellement comparé est l’unicode correspondant aux caractères (qu’on avait vu via l’échappement \uXXXX), cela rend certaines comparaisons peu intuitives (on utilisera donc avec modération!)
>>> "." < "a"
True
>>> "A" < "a"
TrueNotez qu’on peut comprendre un peu mieux ce qui se passe en utilise la fonction ord pour récupérer l’unicode correspondant:
>>> ord(".")
46
>>> ord("a")
97
>>> ord("A")
65not (x and y) et (not x) or (not y) pour toutes les valeurs possibles (booléennes) de x, y et z.x and (y or z) et (x and y) or (x and z) pour toutes les valeurs possibles (booléennes) de x, y et z.E1 or E2 (où E1 et E2 sont des expressions booléennes) entre les deux scénarios suivants:
E1 puis on évalue E2 et seulement ensuite on applique or.E1, si on a True on n’évalue pas E2 mais on renvoie directement True (puisqu’après tout True and n’importe quoi fait toujours True)On pourra essayer
>>> help("BOOLEAN")et
>>> help("COMPARISON")On utilise le code
>>> x, y = True, True
>>> (not (x and y)) == ((not x) or (not y))
True
>>> x, y = True, False
>>> (not (x and y)) == ((not x) or (not y))
True
>>> x, y = False, True
>>> (not (x and y)) == ((not x) or (not y))
True
>>> x, y = False, False
>>> (not (x and y)) == ((not x) or (not y))
TrueOn voit que les deux expressions évaluent toujours identiquement, on a le même résultat en échangeant or et and.
On code de manière laborieuse (là encore on appréciera les boucles!)
>>> x, y, z = True, True, True
>>> (x and (y or z)) == ((x and y) or (x and z))
True
>>> x, y, z = True, True, False
>>> (x and (y or z)) == ((x and y) or (x and z))
True
>>> x, y, z = True, False, True
>>> (x and (y or z)) == ((x and y) or (x and z))
True
>>> x, y, z = True, False, False
>>> (x and (y or z)) == ((x and y) or (x and z))
True
>>> x, y, z = False, True, True
>>> (x and (y or z)) == ((x and y) or (x and z))
True
>>> x, y, z = False, True, False
>>> (x and (y or z)) == ((x and y) or (x and z))
True
>>> x, y, z = False, False, True
>>> (x and (y or z)) == ((x and y) or (x and z))
True
>>> x, y, z = False, False, False
>>> (x and (y or z)) == ((x and y) or (x and z))
TrueOn peut constater que les deux expressions booléennes sont égales indépendamment des valeurs des variables booléennes. On dit qu’on a distributivité, notez que si l’on substitue and et or le résultat est encore vrai. On pourra aller regarder ici pour plus d’informations sur les deux premières questions.
Ici on va choisir pour E2 une expression dont l’évaluation fait planter python.
>>> (12 / 0) != 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> (1 == 1) or (12 / 0 != 5)
TrueOn constate que c’est le deuxième scénario qui a lieu, on dit qu’on a une évaluation fainéante. Le même phénomène a lieu pour E1 and E2 si E1 évalue à False. On signale ce phénomène car il est utilisée de manière passablement astucieuses dans différentes situations. (et malheureusement assez impénétrable pour qui ne connait pas le phénomène)