# III. Les boucles bornées

### Principe

Une boucle bornée permet de répéter des instructions un nombre donné de fois.
On connait à l'avance le nombre d'itérations à effectuer.

★ Choisir le nombre d'itérations et exécuter le programme.

### Syntaxe

Dans la boucle ci-dessous, la variable k parcourt de gauche à droite chacun des
trois éléments de l'ensemble ordonné (0, 1, 2)
Pour chaque valeur de k, le bloc d'instructions après l'indentation est exécuté.

Le programme ci-dessous exécute trois fois de suite la même séquence d'instructions.
★ Lire ce programme.
★ Prédire l'affichage obtenu.
★ Exécuter le programme.
from turtle import * for k in (0, 1, 2): # on repète 3 fois forward(100) # avancer de 100 left(120) # tourner à gauche de 120°

### Remarque

La fonction range() permet de simplifier l'écriture des boucles parcourant des ensembles de nombres entiers.
★ range(5) permet de parcourir l'ensemble (0, 1, 2, 3, 4).
Attention! La dernière valeur est 4 et non 5.
★ range(3, 8) permet de parcourir l'ensemble (3, 4, 5, 6, 7)
★ range(1, 11, 3) permet de parcourir les entiers de 1 à 10 en faisant des pas de 3, Cela
correspond à l'ensemble (1, 4, 7, 10)

Comme le montrent les exemples ci-dessous, la variable associée à la boucle "for"
peut parcourir des ensembles de nombres entiers ou des chaines de caractères.

### Exemples

#### Exemple 1

Dans le programme ci-dessous, l'appel triangle(4) renvoie le nombre triangulaire T4.
T4 correspond à la somme des entiers de 1 à 4.
def triangle(N): T = 0 for k in range(1, N+1): # Attention: range(1,4) parcours 1, 2 et 3 T = T + k # on ajoute k au cumul à chaque passage return T

★ Exécuter le programme, puis appeler triangle(3) dans la console.
★ Décomposer mentalement les étapes permettant d'obtenir triangle(3).

#### Exemple 2

L'exemple suivant présente une boucle parcourant une chaine de caractères.

def inverse(mot): motinverse = "" # chaine de caractères vide for lettre in mot: motinverse = lettre + motinverse # à chaque passage on concatène la lettre lue return motinverse

★ Exécuter le programme ci-dessus, puis, appeler inverse("soleil"), inverse("kayak") ...
Ne pas oubiler les guillements car nous travaillons avec des chaines de caractères.

#### Exemple 3

L'appel listebis(a, b) renvoie la liste des années bissextiles entre les années a et b.

def listebis(a, b): bissextiles = [] # [] définie une liste vièrge for annee in range(a, b+1): if annee % 4 == 0 and annee % 100 != 0 or annee % 400 == 0: bissextiles.append(annee) # ajout de l'année à la liste return bissextiles

★ Exécuter le programme ci-dessus, puis, appeler listebis(1979, 2022).

#### Exemple 4

Dans cet exemple, la variable couleur de la boucle parcourt la liste:
couleurs = ['red', 'orange', 'yellow', 'lightgreen', 'lightblue', 'violet']

from turtle import * r = 60 couleurs = ['red','orange','yellow','lightgreen','lightblue','violet'] pensize(10) left(90) # on oriente la tortue vers le haut for couleur in couleurs: # la boucle parcourt la liste des couleurs pencolor(couleur) circle(r, 180) left(90) up() # on lève le stylo forward(2*r + 10) # on ramène la tortue vers la droite down() # on abaisse le stylo left(90) r = r + 10 # on augmente le rayon

★ Exécuter le programme puis, analyser les lignes 4, 8 et 9.

### Exercices

#### Exercice 1

★ Lire puis exécuter le programme ci-dessous.

def f(): compteur = 0 for i in range(5): compteur = compteur + 1 print(compteur) def g(): compteur = 0 for i in range(5): compteur = compteur + 1 print(compteur)

★ Appeler f( ), puis g( ).
★ Expliquer la différence des affichages obtenus.

Dans la définition de la fonction f, l'instruction d'affichage est incluse
dans le bloc indenté, elle est donc répétée à chaque passage dans la boucle.
Par contre, pour la fonction g, l'instruction en ligne 11 n'est pas dans le bloc
indenté, l'affichage est donc effectué une seule fois après la sortie de la boucle.

#### Exercice 2

★ Modifier le programme ci-dessous pour obtenir un carré.

from turtle import * couleurs = ["violet", "red", "blue"] for i in range(3): color(couleurs[i]) forward(70) left(120)

#### Exercice 3

La fonction div ci-dessous prend un entier n en paramètre et renvoie la liste de ses diviseurs.
★ Quel est l'ensemble de nombres parcouru par range(1, n) ?
★ Modifier la ligne 3 pour que la boucle parcourt l'ensemble nécessaire.
★ Ajouter le code manquant à la ligne 4 en prenant garde à l'indentation.

def div(n): diviseurs = [] # liste vide des diviseurs for k in range(1, n): diviseurs.append(k) return diviseurs

Après avoir exécuté le programme, appeler plusieurs fois la fonction
div pour différentes valeurs de n .

#### Exercice 4

La pyramide à base carrée ci-contre est constituée de cinq étages. Dans cet exercice, on s'interesse au nombre de cubes nécessaires pour réaliser une pyramide de n étages.
def vol(n): volume = 0 for

★ Compléter la fonction "vol" qui prend le nombre d'étages en paramètre et renvoie le nombre de cubes nécessaires pour réaliser cette pyramide.
★ Exécuter votre programme, puis appeler vol(2), puis vol(10).

### Digression numérique

#### Comment les ordinateurs simulent-ils le hasard ?

Les ordinateurs ne sont pas en mesure de produire des séries de nombres aléatoires. On produit pour approcher le hasard des séries de nombres pseudo-aléatoires générés grâce à des outils mathématiques.
Le programme ci-dessous reproduit le générateur de Marsaglia utilisé sur l'ordinateur VAX11 dans les années 70. Ce générateur à congruence linéaire repose sur la suite récurrente :
Xn+1 = 69069 × Xn modulo 232 avec X0 = 13.
Ce générateur permet d'obtenir une longue liste de nombres pseudo-aléatoires, la séquence ne se répète qu'au bout de 232 nombres.
En exécutant le programme ci-dessous, on génère la liste des 6 premiers nombres pseudo-aléatoires correspondant à une graine de 13.

L = [] X = 13 # 13 est la graine, le nombre de départ choisi for i in range(6): # on génère une série 6 nombres X = X*69069 % 2**32 # congruence linéaire L.append(X) print(L)

### Remarque

Une fois la graine choisie, les séries obtenues sont déterminées et donc prévisibles. La fonction seed du module random permet de changer la graine du générateur. Si les élèves d'une classe saisissent tous seed(13) après avoir importé le module random, la séquence des nombres pseudo-aléatoires générés sera identique pour tous. (Ceci n'est pas très aléatoire mais peut-être pratique en TP).