Logique booléenne¶

In [1]:
from IPython.display import YouTubeVideo  # il y a des petites différences avec la feuille
YouTubeVideo('4RCtiy6F_M4')
Out[1]:

La logique booléenne utilise les mots clefs True et False en Python pour indiquer qu'un test est vrai ou faux.

Attention à l'ordre de priorité des opérateurs. On a du plus prioritaire au moins prioritaire :

  1. les [ ] et ( ) liés aux types comme les listes, dictionnaires, tuples
  2. ** la puissance
  3. -x, +x l'opérator unitaire moins ou plus
  4. *, /, //, %
  5. +, -
  6. in, not in, is, is not, <, <=, >=, <>, !=
  7. not x
  8. and
  9. or
In [2]:
print (1 == 3)
print (1 == 1)
print (2 == 2) or (1 == 2) and (3 == 2)
print (1 == 2) or (2 == 2) and (3 == 2)
False
True
True
False
Out[2]:
False

Dans les deux derniers cas on voit bien que le and est calculé avant le or.

A propos, que vaut 2-2**3%2 ?

In [ ]:
2-2**3%2

Tests¶

La logique booléenne permet de faire des tests :

In [3]:
if 2 == 3:
    print("incroyable")  # notre 1ère indentation, c'est émouvant
else:
    print("2 et 3 sont différents")
2 et 3 sont différents

Indentations (<-- Très important)

Python utilise l'indentation pour définir les blocs d'instructions. Dès lors qu'une commande va agir sur un bloc d'instruction, elle finit par 2 points, :, et le bloc qui la suit est indenté.

C'est une grande originalité de Python, aussi faites très attention à vos indentations car elles sont significatives.

L'étiquette veut qu'une indentation soit 4 espaces.


Attention, tout ce qui n'est pas False ou égal à 0 est vrai :

In [4]:
un_demi = 0.5
if un_demi:
    print("vrai")
else:
    print("faux")
vrai

mais cela ne veut pas dire que 0.5 est True :

In [5]:
print(0.5 == True)
print(1 == True)  # pour des raisons historiques
False
True

Les parenthèses du test ne sont pas obligatoires (mais aident à la lisibilité).

In [6]:
if True or not 2 - 3 > 1 and 8 % 2 == 1:
    print("test bon")
    print("très bon") # une seconde ligne dans le bloc pour montrer qu'on peut !
else :
    print("test mauvais")
    print("très mauvais")
test bon
très bon

Pour la lisibilité on peut écrire sur plusieurs lignes en finissant une ligne par \ (ce symbole indique que la ligne continue)

In [7]:
if 2 == (3 or 2) \
   and 8 in [2,4,6,8]:
    print("test bon")
else:
    print("test mauvais")
test mauvais

Notons que le premier test est faux car l'opérateur or retourne la première valeur non fausse ou non nulle donc 3 ici.

In [8]:
print(0 and 1) # si la 1ere condition est fausse, and n'a pas besoin d'evaluer la seconde
print(3 and 2) # ici and est obligé de vérifier toutes les conditions
print(3 or 2)  # or ne vérifie pas la seconde condition si la première est bonne
0
2
3

On teste l'appartenance avec in :

In [9]:
a = [1,2,3]       # liste
print(0 in a)
b = {42 : "explication", 51 : "pastis", 666 : "bête"}  # dictionnaire
print(666 in b)
print("ja" in "jambon")  # chaîne de caratères
False
True
True

Les boucles¶

In [10]:
YouTubeVideo('xPe1jNYYlqY')
Out[10]:

Boucles avec for¶

Les types list, dict, tuple et string sont itérables à savoir qu'il est possible de les parcourir avec le mot clef in :

In [11]:
elements = [1,2,5,10] # une liste donc un type itérable
for e in elements :
    print(e*e)
    print("---")
1
---
4
---
25
---
100
---

Parfois, mais pas souvent, on a besoin au sein de la boucle de savoir quel est l'indice de l'élément sur lequel on travaille. On peut pour cela utiliser enumerate qui retourne deux valeurs :

  • l'indice i dans la boucle
  • la i-ème valeur
In [12]:
for i,e in enumerate(elements):  # puisqu'enumerate retourne 2 valeurs, il faut 2 variables
    print(i,e)
0 1
1 2
2 5
3 10

Il est également possible d'utiliser la fonction range pour avoir les indices et ensuite chercher la i-ème valeur avec elements[i]. Dans les anciens temps c'était la seule facon de faire, donc on faisait ainsi mais les temps ont changé, aussi il n'est plus utile d'introduire un indice que l'on fait varier et d'appeler la i-ème valeur d'élément qui est une opération qui prend du temps :

In [13]:
elements = [1,2,5,10]

for i in range(len(elements)):
    print(elements[i]*elements[i])
    
# est plus lourd, moins lisible et moins efficace que

for e in elements:
    print(e*e)
1
4
25
100
1
4
25
100

Par contre range peut servir à créer une liste :

In [14]:
res = []
for i in range(5):
    res.append(i*i)
print(res)
[0, 1, 4, 9, 16]

Mais ce n'est pas la bonne facon de faire.

Dictionnaire: On peut parcourir un dictionnaire comme tout type itérable. On parcourt les clefs du dictionnaire par défaut :

In [18]:
dico = {1:'A', 2:'B', 3:'C'}
for i in dico:           # same as  for i in dico.keys():
    print(i, dico[i])
1 A
2 B
3 C
In [19]:
for i in dico.items():  # items() returns pairs (key, value)
    print(i)
(1, 'A')
(2, 'B')
(3, 'C')

Liste en compréhension¶

Il est possible de remplir directement une liste en partant d'une autre liste avec la syntaxe suivante :

[f(x) for x in another_list if some_condition]

Cette facon de faire est à privilégier. Elle offre lisibilité et efficacité (testez avec %timeit !).

On peut aller plus loin avec la création en compréhesion de la liste qui sert de support ou avec plusieurs listes en même temps.

[f(x) for x in [g(y) for y in a_list] ]

[f(x,y) for y in [[1,2], [5,6]] for x in y]   # the 2nd for use y from the first for

[f(x,y) for x,y in zip(list1, list2)]

La fonction zip accouple les éléments des deux listes données (x,y sont en premier list1[0], list2[0]).

In [20]:
res = [i*i for i in range(5)]
print(res)
print(res[3])
[0, 1, 4, 9, 16]
9
In [27]:
[x+max(y) for y in [[1,2], [5,6]] for x in y if min(y) > 3]
Out[27]:
[11, 12]

La construction en compréhension fonctionne aussi pour les dictionnaires :

In [22]:
res = {x : y for x,y in zip(range(1,10),"anticonstitutionnellement")}  # range with 2 arguments
print(res)
print(res[3]) # here 3 is a key, not an index
{1: 'a', 2: 'n', 3: 't', 4: 'i', 5: 'c', 6: 'o', 7: 'n', 8: 's', 9: 't'}
t

Boucle avec while¶

In [23]:
age = 24
while age < 65 :  # si on met != comme test, on part dans une boucle infinie (et la machine souffre)
    print("travail")
    age += 10
print("retraite")
travail
travail
travail
travail
travail
retraite

Vous pouvez vous entraîner à faire une boucle infinie

  • sur votre machine dans un terminal (Crtl-c pour arrêter la boucle)
  • ici mais alors SVP utilisez le bouton ▶ pour lancer le calcul et ⬛ à coté pour l'arrêter VITE.

Break et Continue¶

Il existe une facon de sortir immédiatement d'une boucle : utiliser le mot clef break :

In [24]:
age = 24
while age != 65 :  # va faire une boucle infinie
    print("travail")
    age += 10
    if age > 150:
        print("oulala je suis mort !")
        break         # sortie immédiate de la boucle
        print("!!!")  # ne sera jamais affiché
print("retraite")
travail
travail
travail
travail
travail
travail
travail
travail
travail
travail
travail
travail
travail
oulala je suis mort !
retraite

Parfois on ne désire pas sortir de la boucle mais seulement passer immédiatement à l'itération suivante. Pour cela on utilise continue :

In [25]:
for i in range(10):  # et oui, break et continue fonctionnent aussi pour les boucles for
    if i % 2 == 0:
        continue
    print("%d est impair" % i)
1 est impair
3 est impair
5 est impair
7 est impair
9 est impair

{{ PreviousNext("02 - Les types.ipynb", "04 - Les fonctions.ipynb") }}

In [ ]: