Jusqu’à présent on a vu que chaque “ligne” de l’interpréteur acceptait une instruction. L’appui sur la touche entrée entrainait ainsi l’exécution de ladite instruction avant que l’interpréteur nous rende la main.
Les instructions composées se comportent d’une façon différente. Elles sont composées d’une entête et d’un corps principal. Ce dernier est lui même composé de différentes instructions. Il est délimité par le niveau d’indentation c’est à dire l’alignement à gauche.
ATTENTION notez bien que la ligne d’entête se finit toujours par le caractère :
Schématiquement une instruction composée ressemble à:
ENTETE:
INSTRUCTION1
INSTRUCTION2
INSTRUCTION3
...
INSTRUCTION_FINALE
NOUVELLE_INSTRUCTION
Le corps principal commence à INSTRUCTION1
et finit à la ligne INSTRUCTION_FINALE
.
ATTENTION le niveau d’alignement n’est pas totalement visuel, car dans de nombreux éditeurs de texte le caractère de tabulation \t
semble visuellement comparable à plusieurs espaces. Cependant l’interpréteur python n’accepte pas de tels mélanges. On prendra soin pour éviter des bogues délicats de paramétrer son éditeur de texte pour qu’il insère 4 espaces lors d’un appui sur la touche tabulation.
REMARQUE il faut bien réaliser que rien n’empêche une (ou plusieurs) des instructions d’un bloc d’être elle aussi composée. C’est même fréquent. On arriverait ainsi au schéma
ENTETE1:
INSTRUCTION1
ENTETE2:
INSTRUCTION2
INSTRUCTION3
INSTRUCTION4
ENTETE3:
ENTETE4:
INSTRUCTION5
INSTRUCTION6
INSTRUCTION7
Le contrôle effectué par l’entête sur le corps de l’instruction composée dépend du type de l’entête utilisée. On va en voir deux exemples maintenant.
if
Le bloc conditionnel a une première entête commençant par if
(si). Il permet d’exécuter du code lorsqu’une certaine condition est satisfaite.
Sa forme la plus simple est schématiquement
if EXPRESSION_BOOLEENNE:
INSTRUCTION1
INSTRUCTION2
...
INSTRUCTION_FINALE
NOUVELLE_INSTRUCTION
EXPRESSION_BOOLEENNE
.True
, il exécute alors INSTRUCTION1
puis INSTRUCTION2
et ainsi de suite jusqu’à INSTRUCTION_FINALE
. Il passe ensuite à NOUVELLE_INSTRUCTION
.False
, l’interpréteur passe directement à NOUVELLE_INSTRUCTION
.Pour des exemples précis.
>>> if True:
... print("INSTRUCTION1")
... print("INSTRUCTION2")
...
INSTRUCTION1
INSTRUCTION2
>>> print("NOUVELLE_INSTRUCTION")
NOUVELLE_INSTRUCTION
>>> if False:
... print("INSTRUCTION1")
... print("INSTRUCTION2")
...
>>> print("NOUVELLE_INSTRUCTION")
NOUVELLE_INSTRUCTION
ATTENTION l’interpréteur n’exécute qu’une instruction à la fois. Il faut donc laisser une ligne vide pour signaler la fin d’un bloc, la nouvelle instruction sera entrée une fois que l’interpréteur nous aura rendu la main. Dans un script on peut par contre se contenter de revenir en arrière dans l’alignement, même si ce n’est jamais une mauvaise idée d’aérer son code!
On a une deuxième version de la structure conditionnelle où on fournit un bloc alternatif au cas où l’expression booléenne évalue à False
. Ceci est fait au moyen d’une deuxième entête else
.
>>> if True:
... print("Cas True")
... else:
... print("Cas False")
...
Cas True
>>> if False:
... print("Cas True")
... else:
... print("Cas False")
...
Cas False
>>>
Finalement on peut intercaler des expressions booléennes intermédiaires pour examiner plus de cas. Ceci est accomplit via des entêtes elif
:
>>> x = 1
>>> if x == 1:
... print("x vaut 1")
... elif x == 2:
... print("x vaut 2")
... else:
... print("x n'est ni 1 ni 2")
...
x vaut 1
>>> x = 2
>>> if x == 1:
... print("x vaut 1")
... elif x == 2:
... print("x vaut 2")
... else:
... print("x n'est ni 1 ni 2")
...
x vaut 2
>>> x = 10
>>> if x == 1:
... print("x vaut 1")
... elif x == 2:
... print("x vaut 2")
... else:
... print("x n'est ni 1 ni 2")
...
x n'est ni 1 ni 2
REMARQUE on peut lire les entêtes de l’instruction composée ci-dessus comme:
ATTENTION les exemples schématiques
if CONDITION1:
CORPS1
elif CONDITION2:
CORPS2
else:
CORPS3
et
if CONDITION1:
CORPS1
if CONDITION2:
CORPS2
else:
CORPS3
sont bien différents.
CONDITION1
et CONDITION2
évaluent à True
alors dans le premier exemple seul CORPS1
est exécuté alors que dans le deuxième à la fois CORPS1
puis CORPS2
sont exécutés!while
On donne maintenant une deuxième instruction composée commençant par l’entête while
(tant que). Elle permet de répéter le corps principal d’instructions tant qu’une condition est satisfaite.
Son schéma est le suivant:
while EXPRESSION_BOOLEENNE:
INSTRUCTION1
INSTRUCTION2
...
INSTRUCTION_FINALE
NOUVELLE_INSTRUCTION
EXPRESSION_BOOLEENNE
False
l’interpréteur passe directement à NOUVELLE_INSTRUCTION
True
l’interpréteur exécute INSTRUCTION1
, puis INSTRUCTION2
et ainsi de suite jusqu’à INSTRUCTION_FINALE
.if
c’est que l’interpréteur revient alors sur l’entête et recommence la procédure.ATTENTION il est crucial que dans le corps des variables intervenant dans l’expression booléenne soient modifiées. On risque sinon d’obtenir une boucle qui se répète à l’infini. (On pourra l’interrompre via la combinaison de touche CTRL-C)
>>> x = 0
>>> while x < 10:
... print(x)
... x = x + 1
...
0
1
2
3
4
5
6
7
8
9
>>> print(x)
10
ATTENTION il s’avère qu’on peut exceptionnellement remplacer les expressions booléennes par différents objets python. L’interpréteur se chargera de faire une conversion implicite vers un booléen pour décider quoi faire. Les règles de conversions sont parfois subtiles, il convient donc d’être prudent dans l’utilisation. Par exemple:
>>> t = (1, 2, 3)
>>> t
(1, 2, 3)
>>> if t:
... print("Le tuple n'est pas vide")
...
Le tuple n'est pas vide
>>> t = tuple()
>>> t
()
>>> if t:
... print("Le tuple n'est pas vide")
...
>>>
et
>>> if "":
... print("chaine non vide")
...
>>> if "abc":
... print("chaine non vide")
...
chaine non vide
>>>
les conteneurs seront donc True
tant qu’ils ne sont pas vides.
Pour les nombres:
>>> x = 0
>>> if x:
... print("AHA")
...
>>> x = 1
>>> if x:
... print("AHA")
...
AHA
il semble que 0
soit False
. Le code n’étant pas d’une lisibilité exemplaire on préférerait clairement ici:
>>> if x != 0:
print("AHA")
x: int
. (La notation est importante et à retenir, elle signifie qu’on a une variable x
pointant vers un objet de type int
) Donner une instruction composée affichant x est pair
ou x est impair
suivant le cas de figure.nombres: tuple[int]
(ici on a une variable nombres
pointant vers un tuple
d’objets int
). Donner un code permettant d’obtenir dans une variable produit: int
le produit de tous les éléments de nombres
.n: int
. Donner un code qui affiche la suite de nombres obtenu via la règle:n
est pair, on remplace n
par son quotient par 2
n
par 3n+1
1
. Par exemple pour n = 7
, on verrait la suite 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1
.Pour la structure if
>>> help("CONDITIONAL")
pour les évaluations implicites en booléens:
>>> help("TRUTHVALUE")
et pour la notion de bloc et un paragraphe sur while
>>> help("LOOPING")
On utilise l’opérateur %
et le test d’égalité
>>> x = 13
>>> if x % 2 == 0:
... print("x est pair")
... else:
... print("x est impair")
...
x est impair
>>> x = 12
>>> if x % 2 == 0:
... print("x est pair")
... else:
... print("x est impair")
...
x est pair
On a besoin d’une variable auxiliaire indice
qui va nous permettre de parcourir les valeurs du tuple
>>> nombres = (1, 2, 3, 4)
>>> indice = 0
>>> produit = 1
>>> longueur = len(nombres)
>>> while indice < longueur:
... produit = produit * nombres[indice]
... indice = indice + 1
...
>>> print(produit)
24
On va proposer aussi une version utiliser la déstructuration
>>> nombres = (1, 2, 3, 4)
>>> produit = 1
>>> while nombres:
... premier, *nombres = nombres
... produit = produit * premier
...
>>> produit
24
>>> nombres
[]
0
)nombres
qui est vide à la fin ce qui n’est pas vraiment recommandée.On anticipe un peu sur une leçon à venir (sur l’instruction composée for
) pour donner la version “pythonique” (ou pythonesque?)
>>> nombres = (1, 2, 3, 4)
>>> produit = 1
>>> for nombre in nombres:
... produit = produit * nombre
...
>>> produit
24
REMARQUE notez ici l’utilisation classique d’un pluriel pour le conteneur et du singulier correspondant pour la variable parcourant ce conteneur!
La suite étudiée ici se nomme la suite de Syracuse
>>> n = 7
>>> while n != 1:
... if n % 2 == 0:
... n = n // 2
... else:
... n = 3 * n + 1
... print(n, end=", ")
...
22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, >>>