Table des matières

Sujet précédent

6. Sous-programmes

Sujet suivant

8. Structures de données

7. Structures de contrôle

Les structures de contrôle décrivent l’enchaînement des instructions. Elles permettent des traitements séquentiels, conditionnels ou répétitifs (itératifs).

7.1. Bloc et séquence

Dans les langages impératifs tels que le Python, les instructions d’un même bloc sont exécutées séquentiellement, c’est-à-dire, les unes après les autres, donc dans l’ordre où elles sont écrites. Les blocs d’instructions sont matérialisés par leur indentation (décalage depuis la marge de gauche). C’est par exemple ce que nous avons fait pour définir le corps de fonctions.

def nom_fonction(param1, param2):
    instruction1            #      ^
    instruction2            #      | ceci est
    instruction3            #      | un bloc
    instruction4            #      v

En Python, il est conseillé d’indenter en utilisant des espaces, par multiples de 4 (comme indiqué dans PEP 8).

Les termes blocs et séquences sont des synonymes.

7.2. Conditionnelles

7.2.1. La conditionnelle Si ... Alors ...

La conditionnelle permet d’exécuter une séquence d’instruction, seulement si une condition est vraie.

if condition:
    sequence
suite

La condition est nécessairement une expression booléenne.

Évaluation :

  • la condition est évaluée;
  • si la condition est vraie, la séquence est exécutée puis le contrôle passe à la suite;
  • si la condition est fausse, le contrôle passe à la suite, sans exécuter la séquence.
Organigramme Si Alors
def bonjour_quand_positif(nombre):
    """ affiche 'Bonjour !' si le paramètre est positif """
    if nombre >= 0:
        print('Bonjour !')
>>> bonjour_quand_positif(0)
Bonjour !
>>> bonjour_quand_positif(12)
Bonjour !
>>> bonjour_quand_positif(-3)

7.2.2. La conditionnelle Si ... Alors ... Sinon ...

La conditionnelle Si...Alors...Sinon... permet de poser une alternative.

if condition:
    sequence1
else:
    sequence2
suite

Si la condition est vraie, c’est la séquence1 qui sera exécutée, sinon c’est la séquence2 qui sera exécutée. Dans tous les cas, l’exécution continuera à suite.

Organigramme Si Alors Sinon
def max(a, b):
    """ renvoie le plus grand des deux paramètres """
    if a > b:
        max = a
    else:
        max = b
    return max
>>> max(-8, 3)
3
>>> max(-2, -3)
-2

7.2.3. Imbrication de Si

Naturellement, il est possible d’imbriquer les structures de contrôle conditionnelles les unes à l’intérieur des autres, comme ceci :

if condition1:
    if condition2:
        sequence
suite

Toutefois, on préfèrera l’utilisation d’une conjonction dans la condition (car les opérateurs booléens s’exécutent en court-circuit) :

if condition1 and condition2:
   sequence
suite

7.2.4. La clause SinonSi

On peut ajouter autant de clause SinonSi (elif en Python, contraction de else if) que de conditions à tester si les précédentes ont renvoyé faux.

if condition1:
    sequence1
elif condition2:
    sequence2
elif condition3:
    sequence3
else:
    sequence4
suite

Évaluation : Les conditions sont évaluées dans l’ordre. Si une condition s’évalue à vraie, la séquence associée est exécutée puis l’exécution continue à suite, sinon la condition suivante est envisagée. La partie else n’est donc exécutée que si aucune des conditions ne s’est évaluée à vrai.

Organigramme Si SinonSi
def signe_entier(n):
    '''Affiche 'strictement positif', 'strictement négatif'
       ou 'nul' suivant la valeur du paramètre'''
    if n > 0:
        print(n, 'est strictement positif')
    elif n < 0:
        print(n, 'est strictement négatif')
    else:
        print(n, 'est nul')
>>> signe_entier(123)
123 est strictement positif
>>> signe_entier(-2)
-2 est strictement négatif
>>> signe_entier(0)
0 est nul

On pourrait se passer de elif. L’avantage d’un elif est que l’on voit clairement que les différentes séquences sont exclusives.

if condition1:
    sequence1
else:
    if condition2
        sequence2
    else:
        if condition3
            sequence3
        else:
            sequence4
suite

7.3. Répétitions

Les répétitions permettent d’exécuter plusieurs fois une même séquence d’instructions. Il est important de vérifier qu’une répétition se termine effectivement (notion de variant).

7.3.1. La répétition TantQue

La répétition TantQue permet d’exécuter une séquence d’instructions tant qu’une condition est vraie.

Évaluation :

  1. La condition est évaluée.
  2. Si la condition est vraie, on exécute la séquence et on recommence en 1.
  3. Si la condtion est fausse, on exécute la suite (on sort donc de la boucle).
Organigramme TantQue
while condition:
    sequence
suite

Attention : afin de garantir la terminaison du programme, il faut s’assurer que la condition va finir par être fausse, et ainsi que le programme ne restera pas infiniment dans la boucle. C’est pour cela que la séquence d’instructions doit modifier la condition. Attention, c’est une condition nécessaire mais pas suffisante.

Variant : On appelle variant une entier positif qui décroit strictement à chaque itération. Si on est capable de mettre en évidence un tel variant, on a prouvé que la boucle se termine.

def decompter(n):
    """ affiche un décompte en partant de n, et jusqu'à 0 """
    i = n
    while i >= 0:
        print(i)
        i = i - 1

decompter(5)
5
4
3
2
1
0

Ici le variant est i+1. Il est positif au départ, il décroit de 1 à chaque itération, il reste positif à chaque itération.

7.3.2. La répétition PourChaque

La répétition PourChaque permet d’exécuter une séquence d’instructions un nombre connu de fois, pour chaque élément...

Nous venons de voir qu’il est possible de répéter une séquence d’instructions tant qu’une condition est vraie. Il existe une deuxième manière pour effectuer des répétitions : en parcourant élément par élément une structure de données itérable. Ainsi nous allons pouvoir répéter une séquence pour chaque élément d’un tableau, pour chaque élément d’une liste ... (voir chapitre Structures de données pour plus d’informations sur les listes et les tableaux)

Dans un premier temps, nous allons répéter une séquence \(n\) fois. Pour cela, nous allons itérer sur un range (ou gamme, portée, échelle). Un range est défini par trois nombres entiers (int) : un début, une fin et un pas. Il contient tous les entiers, à partir de début (inclus), jusqu’à fin (exclus), en avançant d’un pas.

Il existe trois façons de définir un range :

>>> range(4, 10, 2)  # range(début, fin, pas) : 4, 6, 8
range(4, 10, 2)
>>> range(4, 10)     # range(début, fin)  pas=1 : 4, 5, 6, 7, 8, 9
range(4, 10)
>>> range(10)        # range(fin)  début=0, pas=1 : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
range(0, 10)

Si le pas n’est pas précisé, il vaut 1. Si le début n’est pas précisé, il vaut 0.

Il est possible de construire une liste à partir de ces ranges afin de visualiser les valeurs qu’ils contiennent :

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(0, 30, 5))
[0, 5, 10, 15, 20, 25]
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> list(range(0))
[]
>>> list(range(1, 0))
[]

A présent, nous allons pouvoir répéter une séquence d’instructions avec for. La séquence sera répétée pour chaque élément contenu dans l’itérable :

for element in iterable:
    instructions
suite

Nous pouvons utiliser le for conjointement avec range :

def print_carres(n):
    """ affiche les carrés des entiers entre 0 (inclus)
        et n (exclus) """
    for i in range(n):
        print(i**2)

print_carres(4)
0
1
4
9

Il est aussi possible d’itérer sur les chaînes de caractères, les listes, les tuples...