Soit une situation où l'on voudrait afficher les multiples croissants de 2 jusqu'à 20 ( par exemple...).
Comment faudrait-il écrire un tel programme ?
valeur = 2
print( valeur ) # affiche 2
valeur = valeur + 2
print( valeur ) # affiche 4
valeur = valeur + 2
print( valeur ) # affiche 6
valeur = valeur + 2
print( valeur ) # affiche 8
valeur = valeur + 2
print( valeur ) # affiche 10
valeur = valeur + 2
print( valeur ) # affiche 12
valeur = valeur + 2
print( valeur ) # affiche 14
valeur = valeur + 2
print( valeur ) # affiche 16
valeur = valeur + 2
print( valeur ) # affiche 18
valeur = valeur + 2
print( valeur ) # affiche 20
Pas vraiment élégant, n'est-ce pas ? Il y a sûrement plus efficace que d'écrire 10 fois la même chose !
Très souvent, on a effectivement ainsi besoin de répéter plusieurs fois les mêmes séquences d'instructions
D'où l'existence de structures de boucles qui font partie, comme l'instruction if
, des structures de contrôle de flux.
En Python, deux structures de boucle existent :
for
( boucle bornée )Vous avez en fait déjà utilisé ce type de structure, mais sous une forme un peu différente, avec la boucle for ... in ...
qui permet de parcourir un objet itérable comme une chaîne de caractères.
for compteur in range( intervalle de variation du compteur ) :
Instruction(s) à exécuter dans la boucle
..............
..............
Cette boucle "tourne" en exécutant à chaque "tour" la (ou des) instruction(s) du bloc.
La variable compteur de boucle ( nommée ici compteur, mais on peut bien entendu utiliser n'importe quel nom..) permet de compter le nombre de "tours" de la boucle; elle est automatiquement incrémentée ( ou décrémentée ! ) d'une certaine valeur ( = le pas de la boucle ) à la fin de chaque "tour"; la boucle "tournera" alors tant que la valeur du compteur se trouve dans l'intervalle de variation indiqué.
Il existe plusieurs façons d'indiquer les bornes de cet intervalle :
for compteur in range( N ) :
⇨ intervalle de 0 jusqu’à N - 1 avec un pas de variation de 1 ( pour N = 10, le compteur varie donc de 0 à 9 par pas de 1, soit 10 "tours" )
for compteur in range( N1 , N2 ) :
⇨ intervalle de N1 jusqu'à N2 - 1 avec un pas de variation de 1 ( pour l'exemple précédent, on aurait : N1 = 0 et N2 = 10 )
for compteur in range( N1 , N2 , pas ) :
⇨ intervalle de N1 jusqu'à N2 - 1 avec un pas de variation quelconque
On constate donc que l'intervalle va toujours de la borne inférieure à la borne supérieure -1 avec un pas par défaut de 1.
for i in range( 4 ) :
⇨ le compteur i prendra les valeurs : 0, 1, 2, 3 soit 4 "tours" de boucle.
for i in range( 3 , 10 ) :
⇨ le compteur i prendra les valeurs : 3, 4, 5, 6, 7, 8, 9 soit 7 "tours" de boucle.
for i in range( 10 , 2 , -2 ) :
⇨ le compteur i prendra les valeurs : 10, 8, 6, 4 ( le pas est de -2 ) soit 4 "tours" de boucle.
L'exemple d'introduction du chapitre deviendrait alors :
⇨ 4 lignes au lieu de 18 !!
Vous remarquez que les instructions à exécuter dans la boucle appartiennent donc au même bloc logique, elles sont donc indentées
de la même façon par rapport au mot clé for
.
A l'intérieur de la boucle, on aura souvent besoin d'utiliser la valeur de la variable compteur pour réaliser certaines opérations.
Par exemple, pour afficher tous les multiples d'un certain nombre, on écrira une instruction qui, à chaque tour de boucle, multipliera ce nombre par la valeur du compteur, de façon à obtenir tous les multiples :
On a aussi parfois besoin de la structure suivante :
En étudiant l'indentation, on constate la présence dans ce code :
print()
qui affiche les valeurs de i et j
Voila ce qu'il se passe :
print()
s’exécute.print()
s’exécute.→ la boucle j a donc été exécutée autant de fois que de tours de la boucle i.
Cette structure particulière où "une boucle tourne dans une autre boucle" est appelée boucles imbriquées; elle n'est pas évidente à comprendre, étudiez-la bien : elle sert dans de nombreuses situations ( vous verrez un premier exemple ci-dessous ), notamment dès que l'on a à parcourir un objet en deux dimensions comme les pixels d'une image, ou un tableau de tableaux ( vous verrez cela plus tard ).
while
( boucle non bornée, ou conditionnelle )
while ( condition ) :
Instruction(s)
.......
Cette boucle « tourne » tant que ( = while ) la condition évaluée est vraie, autrement dit jusqu'à ce qu'elle devienne fausse...
Bien remarquer que cette condition est évaluée au début de chaque "tour".
Dès que la condition devient fausse, le programme "sort" donc de la boucle et passe aux instructions suivantes...
La condition est une expression, plus ou moins complexe, à évaluer à l'aide d'opérateurs de comparaison.
Ce sont les mêmes que ceux rencontrées au chapitre précédent :
Opérateur | Signification | Commentaire |
---|---|---|
== |
égal à | Bien noter qu'il s'agit là-aussi d'un DOUBLE SIGNE ÉGAL... |
!= |
différent de | |
> |
supérieur à | |
< |
inférieur à | |
>= |
supérieur ou égal à | |
<= |
inférieur ou égal à | |
in |
est dans | |
not in |
n'est pas dans |
La (ou les) instruction(s) constituent le bloc qui sera exécuté à chaque "tour" de boucle ; elles sont donc indentées d'un même retrait par rapport à l'instruction "parente" ( ici, l'instruction while
) pour indiquer à Python qu'il s'agit du même bloc logique.
i = 0
valeur = 2
while ( i < 10 ) :
print( valeur )
valeur = valeur + 2
i +=1
Ce mode de fonctionnement sous-entend que quelque chose doit, dans le bloc d'instructions, agir sur la variable testée dans la condition évaluée, sinon la condition ne deviendra jamais fausse, et la boucle peut alors ne jamais s'arrêter de "tourner" !!!
ATTENTION donc au risque de boucle infinie !!
for
ou la boucle while
???Dans certains cas....les deux !!
On peut très bien par exemple réécrire les exemples précédents avec une boucle while
au lieu du for
:
Boucle for |
Boucle while |
---|---|
|
|
|
|
|
|
On constate cependant qu'avec la boucle while
, le code est plus "lourd", d'autant plus qu'il faut soi-même gérer l'évolution du compteur ( ce qui est "automatique" avec une boucle for
), avec les risques de "boucle infinie" que cela entraîne...; l'utilisation de la boucle conditionnelle n'est donc pas judicieuse dans ces exemples...
Quel est son intérêt alors ? Et bien, le nombre de "tours" d'une boucle while
n'est pas fixé à l'avance, au contraire de la boucle for
, dont le nombre de tours est fixé à son début.
Dans quel cas cela est-il utile ? Par exemple, l'entrée d'un mot de passe par un utilisateur : tant que l'entrée n'est pas la bonne, on redemande le mot de passe...et cela peut durer un nombre de fois indeterminé à l'avance !!
motDePasse = 'sdhfj7$ff'
entree = '' # initialisation de l'entrée utilisateur à "vide"
while ( entree != motDePasse ) :
entree = input('Entrez le mot de passe :')
print('Accès autorisé')
for
quand on connaît le nombre de "tours" à effectuer.while
quand on ne le connaît pas.
for i in range( 6 ) :
Instruction 1
Instruction 2
......
for i in range( 5 , -1 , -1 ) :
Instruction 1
Instruction 2
......
compteur = 1
while ( compteur < 8 ) :
compteur+=1
compteur = 0
while ( compteur < 6 ) :
compteur+=1
compteur = 15
while ( compteur < 15 ) :
compteur+=1
compteur = 0
a = 1
while ( compteur < 10 ) :
print ( a )
a = a * 2
Corriger et réécrire ce programme plus judicieusement.
compteur = 0 # une seule variable pour tout faire...
while ( compteur < 10 ) :
print ( 2 ** compteur )
compteur += 1
Que s'affiche-t-il à la fin de l'exécution de chacun des scripts suivants ?
Pour ces applications, boucle for
ou while
, à vous de choisir la mieux adaptée selon la situation...
Écrire une boucle qui affiche un compte à rebours de 20 à 0 INCLUS
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Écrire une boucle qui affiche la table de multiplication de 3 (10 premiers multiples
1 3 6 9 12 15 18 21 24 27 30
Une contrainte : utiliser la valeur du compteur elle-même pour effectuer le calcul des multiples.
print
, utiliser la syntaxe suivante :
print( affichage , end = ' ') # un espace entre les guillemets
Pour revenir à la ligne ( ou également pour en sauter une ) :
print()
table_multiplication()
qui prend en paramètre n'importe quel entier n, et qui renvoie sa table de multiplication ( sous forme de chaîne de caractère )Écrire un script qui affiche les unes à la suite des autres les tables de multiplication de 1,2,.... et 10.
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Vous avez vu que avec n bits, on peut coder une valeur maximale égale à 2n-1.
Par exemple, avec n = 10 bits on peut coder au maximum le nombre : 210-1 = 1023.
A l'inverse, si l'on souhaite coder un nombre N quelconque, peut-on déterminer le nombre n de bits nécessaires ?
Par exemple si l'on souhaite coder la valeur N = 3 789 147(10), combien de bits sont nécessaires ?
Une des possibilités pour cela est de tester différentes valeurs de 2n-1 ( en augmentant n de un en un ) jusqu'à dépasser la valeur N fournie.
Écrire une fonction qui prend comme paramètre un nombre N en base 10, et renvoie le nombre n de bits nécessaire pour le coder en base 2.
Le but du jeu : le programme tire un nombre entier au hasard ( entre 1 et 100 par exemple ) ; le joueur doit essayer de deviner le nombre, et doit faire des propositions. Chaque proposition est évaluée, et le programme doit afficher " Trop grand", "Trop petit", ou "Gagné !" après chaque proposition.
Le programme doit "tourner" tant que le joueur n'a pas donné la bonne réponse...
Il sera nécessaire d’utiliser la fonction randint
( tirage aléatoire d'un nombre entier ) qu'il faudra importer depuis le module random
.
Pour utiliser ensuite la fonction dans le programme :
nombre = randint( borne1 , borne2 )
→ renvoie un entier dans une plage entre deux bornes ( incluses ).
Pour importer la fonction tirage aléatoire d'entier :
from random import randint
Pour les bornes sur le nombre à tirer au hasard entre 1 et 100 :
n = randint( 1 , 100 )
nombre ← tirage au hasard entier entre 1 et 100 entree ← 0 tant que entree != nombre : entree ← entree utilisateur si entree > nombre alors afficher "Trop grand !" si entree < nombre alors afficher "Trop petit !"
sinon afficher "Bravo !" fin si fin tant que
Écrire un script qui tire un entier au hasard entre 1 et 100, et demande à l'utilisateur de le deviner en lui donnant des indications à chaque tentative.
Vous connaissez bien maintenant ( bien sûr... ) la manière de parcourir les caractères d'une chaîne avec l'instruction for ... in ...
Cette structure permet de parcourir par valeur la chaîne, mais il y aussi possibilité de faire un parcours par indice, à l'aide d'une boucle bornée.
Écrire une fonction indice_chaine
, qui affiche chaque caractère d'une chaîne, et l'indice de ce caractère.
Exemple : indice_chaine("informatique")
doit afficher :
0 : 'i'
1 : 'n'
2 : 'f'
3 : 'o'
4 : 'r'
5 : 'm'
6 : 'a'
7 : 't'
8 : 'i'
9 : 'q'
10 : 'u'
11 : 'e'
Quelles doivent être les bornes de la boucle bornée ? Revoir le chapitre sur les chaînes en cas de besoin !
Écrire une fonction comparer_chaines
, qui :
Exemple : comparer_chaine("informatique", "imformatikhe")
doit renvoyer 3
( caractères différents aux indices 1, 9 et 10).
Il faut donc parcourir les deux chaînes "en même temps"; à vous de choisir : parcours par valeur, ou parcours par indice ?
Un palindrome est un mot ( ou une phrase ) qui s'écrit de la même façon, qu'on le lise de gauche à droite ou de de droite à gauche; par exemple, les mots non, elle, kayak, radar,... sont des palindromes.
Le but sera d'écrire une fonction qui teste si un mot qu'on lui a passé en argument est un palindrome ou pas.
Attention, ce n'est pas évident...Une indication : il faut parcourir chaque caractère de la chaîne, et le comparer à son caractère "symétrique" dans la chaîne : le premier avec le dernier, le deuxième avec l'avant-dernier,...Sil n'y a pas concordance pour TOUS les caractères de la chaîne, alors le mot n'est pas un palindrome.
Rappelez-vous bien comment on adresse un caractère dans une chaîne de caractères ! Il est sans doute bon de prendre un papier et un crayon et de travailler sur un exemple...
est_palindrome()
qui prend en paramètre un mot ( chaîne de caractères ) et qui renvoie un booléen True
si le mot est un palindrome,
False
sinon.