Pour faire s'afficher fois la même chose plusieurs fois, on peut écrire ce programme :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Déclaration des CONSTANTESTEXTE="J'aime bien les copier coller !"# Programme principalprint(TEXTE)print(TEXTE)print(TEXTE)print(TEXTE)print(TEXTE)print(TEXTE)print(TEXTE)print(TEXTE)print(TEXTE)print(TEXTE)
Heureusement, on peut faire mieux ! Nous allons revoir et compléter la notion de boucle bornée :
1
2
3
4
5
6
# Déclaration des CONSTANTESTEXTE="J'aime bien les copier coller !"# Programme principalfor_inrange(10):print(TEXTE)
Rappels
(RAPPELS) 1.1 Boucle POUR : réaliser plusieurs fois EXACTEMENT la même action
A - Principe
Pour réaliser plusieurs fois exactement la même série d'actions, il suffit d'utiliser une boucle bornée POUR, qu'on déclare à l'aide du mot-clé for en Python.
Traduction en français : "Réalise 5 fois le bloc d'instructions indentées"
01° Placer le code suivant en mémoire : il affiche le message "C'est parti !" puis 5 fois le message "Et un tour de boucle" sur la console. Une fois la boucle terminée, il affiche "Go !".
Questions
1
2
3
4
5
6
print("C'est parti !")for_inrange(5):print("Et un tour de boucle")print("Fini !")
>>>%Run prog_boucle.py C'est parti !
Et un tour de boucle
Et un tour de boucle
Et un tour de boucle
Et un tour de boucle
Et un tour de boucle
Fini !
Question
Lancer le programme pour vérifier qu'il fonctionne.
Que trouve-t-on à la fin de la déclaration de la boucle for (et qu'on trouve aussi à la fin d'une déclaration de fonction) ?
Comment indique-t-on à l'interpréteur Python que la ligne 4 fait partie des choses à faire en boucle, et que la ligne 6 sera à faire après avoir fait entièrement la boucle ?
Placer le programme dans Python Tutor et visualiser l'exécution progressive : la boucle devrait être réalisée 5 fois.
Modifier le programme pour qu'il vous affiche 200 fois "Et un tour de boucle".
Complément d'informations Thonny
Thonny permet de placer automatiquement votre script sur Python Tutor à l'aide du menu Exécuter -> Visualiser le script au Python Tutor.
...CORRECTION...
Le programme fonctionne.
Comme pour les déclarations de fonction, la SYNTAXE impose la présence du symbole :.
Comme dans les fonctions, c'est la tabulation (ou 4 espacesà qui indique à l'interpréteur que le bloc d'instructions fait partie de la boucle, ou pas. La ligne 6 est ainsi réalisée après avoir fait la boucle de multiple fois, puisqu'elle n'est pas tabulée.
Il suffit de noter 200 à la place de 5.
02 ✔° Réaliser les deux actions suivantes :
02-A : Placer le code suivant en mémoire : il permet de tracer un triangle en faisant appel à la fonction triangle().
Lancer le code pour visualiser que vous avez bien créé un triangle.
# Partie Importationimportturtleastrt# Partie déclaration des fonctions d'interfacedeftriangle(feutre:trt.Turtle,distance:int,angle:int)->None:"""Fait avancer le crayon de la distance, tourne de l'angle donné. Trois fois."""feutre.forward(distance)feutre.left(angle)feutre.forward(distance)feutre.left(angle)feutre.forward(distance)feutre.left(angle)# Instructions du programme principalstylo=trt.Turtle()triangle(stylo,100,120)
02-B : Remplacer la fonction triangle() par cette version qui utilise une boucle POUR / FOR. Tester pour visualiser qu'on continue bien à obtenir un triange semblable au précédent.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Partie Importationimportturtleastrt# Partie déclaration des fonctions d'interfacedeftriangle(feutre:trt.Turtle,distance:int,angle:int)->None:"""Fait avancer le crayon de la distance, tourne de l'angle donné. Trois fois."""for_inrange(3):feutre.forward(distance)feutre.left(angle)# Instructions du programme principalstylo=trt.Turtle()triangle(stylo,100,120)
Vous avez dû comprendre le principe : l'association du mot-clé for et du mot-clé in provoque l'apparition d'une boucle : on réalise les lignes 11 et 12 trois fois à cause, visiblement, de la présence de range(3).
03-A° Observer la fonction suivante sans utiliser l'animation : combien de fois va-t-on réaliser la boucle ? Combien de fois va-t-on réaliser l'instruction "avance" ? Combien de fois va-t-on réaliser l'instruction "tourne à gauche" ?
Tester l'animation suivante pour être certain d'avoir compris le déroulé :
1
2
3
4
5
6
7
defexo(feutre:trt.Turtle,distance:int,angle:int)->None:"""Que fait cette fonction ?"""feutre.forward(distance)for_inrange(5):feutre.forward(distance)feutre.left(angle)feutre.forward(distance)
CLIQUEZ ICI POUR VOIR LE DEROULEMENT SEQUENTIEL
...CORRECTION...
On voit range(5) : la boucle va être réalisée 5 fois.
On va donc "avancer"
1 fois avant la boucle,
5 fois avec les boucles et
une fois après la boucle
Soit 7 fois "avance" au total.
Pour l'action "tourne", on ne la réalise qu'une fois par tour de boucle. Il y a donc 5 "tourne" au total.
03-B° Si on utilise la fonction exo(), combien de fois va-t-on faire d'instructions "avance" et combien va-t-on faire d'instructions "tourne à gauche" ? Pour répondre, il faut se demander quelles sont les lignes qui appartiennent à la boucle POUR et quelles sont les lignes qui n'en font pas partie.
1
2
3
4
5
6
7
defexo(feutre:trt.Turtle,distance:int,angle:int)->None:"""Que fait cette fonction ?"""for_inrange(3):feutre.forward(distance)feutre.left(angle)feutre.forward(distance)feutre.left(angle)
...CORRECTION...
Les lignes 4 et 5 appartiennent à la boucle : on réalise donc trois fois l'action "avance" et "tourne".
Ensuite, on sort de la boucle.
On réalise donc les lignes 6 et 7 et donc "avance" et "tourne" une fois de plus.
En tout, on réalise donc 4 "avance" et 4 "tourne".
Voyons comment tracer plein de formes différentes avec une même fonction en utilisant une variable de boucle.
Un triange équilatéral, c'est trois actions "avance et tourne de 120°". On trouve facilement l'angle de 120° en calculant 360° / 3.
Un carré, c'est quatre actions "avance et tourne de 90°". On trouve facilement 90° en calculant 360° / 4.
...
04° Compléter la fonction polygone() pour qu'elle réalise les actions suivantes :
Calcule l'angle en faisant la division euclidienne de 360 par le nombre de côtés nb voulus : angle=360//nb
Réalise une boucle POUR où on fait nb fois les actions ci-dessous :
Avancer de la longueur longueur
Tourner de l'angle angle
La documentation est fournie. A vous de compléter le code.
# Partie Importationimportturtleastrt# Partie déclaration des fonctionsdefpolygone(feutre,nb,longueur):"""Crée un polygone à nb cotés, longueur étant la longueur de chaque côté:: param feutre(trt.Turtle) :: un objet-Turtle:: param nb(int) :: le nombre de côtés, PRECONDITION > 2:: param longueur(int) :: la longueur de chaque côté en pixels. Entier positif.:: return(None) :: trace uniquement la forme"""pass# Instructions du programme principalstylo=trt.Turtle()polygone(stylo,6,100)
Vous devriez obtenir ceci après l'appel fourni sur la dernière ligne du programme :
# Partie Importationimportturtleastrt# Partie déclaration des fonctions d'interfacedefpolygone(feutre,nb,longueur):"""Crée un polygone à nb cotés, longueur étant la longueur de chaque côté:: param feutre(trt.Turtle) :: un objet-Turtle:: param nb(int) :: le nombre de côtés, strictement supérieur à 2:: param longueur(int) :: la longueur de chaque côté en pixels. Entier positif.:: return(None) :: trace uniquement la forme"""angle=360//nbfor_inrange(nb):feutre.forward(longueur)feutre.left(angle)# Instructions du programme principalstylo=trt.Turtle()polygone(stylo,6,100)
On peut maintenant s'amuser et réaliser plein de formes différentes. Imaginons qu'on fasse un appel du type polygone(stylo,10,50), il devrait provoquer cela :
Ou tracer un triangle avec un appel du type polygone(stylo,3,150), il devrait provoquer cela :
✎ 05° Créer une fonction punition() qui possède deux paramètres :
1
2
3
4
5
6
7
8
9
defpunition(ligne_a_copier,nombre_de_fois):"""Réalise la punition à la place de l'élève :: param ligne_a_copie(str) :: la ligne qu'on va devoir recopier :: param nombre_de_fois(int) :: le nombre de lignes à faire au total :: return (None) :: ne renvoie rien, "procédure Python". """pass
Votre fonction devra afficher (afficher donc print()) dans la console la phrase autant de fois que demandé.
Exemple d'utilisation :
>>> punition("Je ne dois pas sortir mon téléphone portable en classe", 3)
Je ne dois pas sortir mon téléphone portable en classe Je ne dois pas sortir mon téléphone portable en classe Je ne dois pas sortir mon téléphone portable en classe
Reste un point à voir : qu'est-ce que ce _ qui traîne dans la boucle ?
En réalité, l'underscore _ joue ici le rôle d'une variable particulière qu'on nomme variable de boucle.
Lorsqu'on sait qu'on ne va pas utiliser la valeur de cette variable mais juste réaliser la même action plusieurs fois, la convention Python est de la nommer "underscore", pour montrer que son nom n'a pas d'importance puisqu'on ne l'utilise pas.
Regardons maintenant ce que contient cette variable de boucle lors du déroulé de la boucle. Nous allons la renommer k, plutôt que de la rendre "invisible".
(RAPPELS) 1.2 Boucle POUR : réaliser plusieurs fois PRESQUE la même action
A - Valeurs successives de la variable de boucle
On réalise des actions un peu différentes car utilisant une variable de boucle dont le nom se situe derrière le mot clé for.
forkinrange(5):
Sur cet exemple :
k est la variable de boucle.
k commence à 0
k est incrémentée de 1 à chaque tour de boucle.
Ainsi, k va prendre les valeurs 0 puis 1 puis 2 puis 3 puis 4.
Attention
k n'ira pas jusqu'à 5, c'est une borne exclue.
5 correspond au nombre de tours de boucle effectués : 0-1-2-3-4.
La valeur finale de k est 4, obtenue en calculant (5 - 1).
Pour visualiser la valeur de la variable de boucle à l'aide de Turtle, nous pourrions réaliser une boucle où on avance d'une longueur variant avec la variable de boucle, avant de tourner comme avant.
# Partie Importationimportturtleastrt# Partie déclaration des fonctionsdefvisualiser(feutre:trt.Turtle):"""Permet de visualiser la valeur de la variable de boucle"""forkinrange(5):feutre.pensize(1+k)feutre.forward(50+k*50)feutre.left(90)# Instructions du programme principalstylo=trt.Turtle()stylo.speed(1)visualiser(stylo)
Questions après analyse de la fonction
Que valent la largeur du trait et la longueur du trait lors du premier tour de boucle (lorsque k vaut 0) ?
Que vaut la largeur du trait et la longueur du trait lors du deuxième tour de boucle (lorsque k vaut 1) ?
Quelle va être la valeur finale de la variable de boucle k ?
...CORRECTION...
Lors du premier tour de boucle, k vaut 0.
Ligne 11 : on voit que la largeur du trait sera 1 + k, donc 1.
Ligne 12 : on voit qu'on avance de 50 + k*50, donc 50.
Lors du deuxième tour de boucle, k vaut 1.
Ligne 11 : on voit que la largeur du trait sera 1 + k, donc 2.
Ligne 12 : on voit qu'on avance de 50 + k*50, donc 50 + 2*50 ce qui donne 150.
Lors du dernier tour de boucle, k vaut 4.
Ligne 11 : on voit que la largeur du trait sera 1 + k, donc 5.
Ligne 12 : on voit qu'on avance de 50 + k*50, donc 50 + 4*50 ce qui donne 250.
08-B° On également utiliser la variable de boucle pour jouer le rôle d'indice dans un tableau. On reprend le même programme en rajoutant simplement cette fois une tableau de couleurs et une modification du crayon à chaque tour de boucle : on va lire une case du tableau en fonction de la valeur de la variable de boucle x.
Vous devriez obtenir ceci maintenant (sans les valeurs de x, je les ai rajouté pour identifier facilement les étapes):
# Partie Importationimportturtleastrt# Partie déclaration des fonctionsdefvisualiser(feutre:trt.Turtle):"""Permet de visualiser la valeur de la variable de boucle"""couleurs=["grey","red","blue","green","purple"]forxinrange(5):feutre.color(couleurs[x])feutre.pensize(1+x)feutre.forward(50+x*50)feutre.left(90)# Instructions du programme principalstylo=trt.Turtle()stylo.speed(1)visualiser(stylo)
Question
Expliquer pourquoi le crayon est gris au premier tour de boucle puis rouge au deuxième tour de tour. Un rappel est fourni ci-dessous si vous en avez besoin
Rappel sur la lecture des cases d'un tableau (le type construit list de Python)
# Partie Importationimportturtleastrt# Partie déclaration des fonctionsdefvisualiser(feutre:trt.Turtle):"""Permet de visualiser la valeur de la variable de boucle"""couleurs=["grey","red","blue","green","purple"]forxinrange(5):feutre.color(couleurs[x])feutre.write(f"x = {x}")feutre.pensize(1+x)feutre.forward(50+x*50)feutre.left(90)# Instructions du programme principalstylo=trt.Turtle()stylo.speed(1)visualiser(stylo)
Vous devriez maintenant obtenir la même image que celle de la sous-question précédente.
le f-String
On notera qu'on utilise ici un f-String : c'est un string dont les guillemets d'ouverture sont précédés d'un f. A l'intérieur du string, on peut alors placer des accolades {} qui vont jouer un rôle particulier : l'interpéteur Python évalue l'expression fournie entre les accolades et place la valeur obtenue à cet endroit dans le string.
Exemple :
>>> a = "Alice"
>>> b = "Bob"
>>> c = f"Bonjour à {a} et à {b}"
>>> c
'Bonjour à Alice et Bob'>>> n1 = 20
>>> n2 = 20
>>> f"La moyenne est de {n1} et {n2} donne {(n1 + n2) / 2}"
'La moyenne de 20 et 15 donne 17.5'
Question
Après avoir tapé les exemples précédents dans la console (et les avoir réellement compris), modifier la fonction pour qu'elle provoque un affichage : "Sur cette étape, x vaut 0", "Sur cette étape, x vaut 1"...
Nouveautés
1.3 Boucle POUR : utilisation de range()
Visualisation de range sous forme d'un tableau
L'évaluation de range(5) n'est un tableau mais on peut représenter la réponse sous forme d'un tableau à l'aide de la fonction native list().
>>> list(range(5))
[0, 1, 2, 3, 4]
Cela va nous permettre de donner du sens à cette syntaxe.
que la valeur "presque" finale (c'est à dire exclue) est 10 et
qu'on incrémentera la variable de boucle de +2 à chaque tour de boucle (on dira que le pas est de +2).
Visualisons cela dans la console.
>>> list(range(3, 10, 2))↲[3, 5, 7, 9]>>> for k in range(3, 10, 2):↲
print(k)↲↲ 3
5
7
9
On peut fournir un pas négatif. Ca complique la compréhension de la vraie valeur finale : si la valeur finale est 1 en décroissant, la dernière valeur disponible est donc... 2.
>>> list(range(10, 1, -3))↲[10, 7, 4]>>> for k in range(10, 1, -3):↲
print(k)↲↲ 10
7
4
✌ 09° Expliquer les valeurs successives que vont prendre les variables de boucle a, b et c dans les cas suivants :
>>> for a in range(100):↲
print(a)↲↲ ???>>> for b in range(80, 101, 10):↲
print(b)↲↲ ???>>> for c in range(100, 49, -10):↲
print(c)↲↲ ???
10-A° Combien va-t-on dessiner de cercles ?
On imaginera que la fonction dessiner_un_cercle() dessine un cercle...
Nous allons faire 5 tours de boucles en L1 avec une variable de boucle a qui prendra les valeurs 0, 1, 2, 3 et 4 mais dont on utilisera pas la valeur pendant la boucle.
Et lors de chacun des tours de boucle, on dessine 4 cercles.
A chaque fois qu'on réalise entiérement la boucle présente en L2 (qu'on nommera Boucle 2), on dessine 4 cercles.
Or, on réalise la boucle présente en L1 5 fois. Or pendant chaque tour de la boucle 1, on exécute 4 fois la boucle 2. 5*4 = 20.
Description au cas par cas :
D'abord a vaut 0 et
Une exécution de la ligne 3 avec b valant 0 : 1 cercle.
Une exécution de la ligne 3 avec b valant 1 : 2 cercles.
Une exécution de la ligne 3 avec b valant 2 : 3 cercles.
Une exécution de la ligne 3 avec b valant 3 : 4 cercles.
Fin de la boucle 2
Puis a vaut 1 et
Une exécution de la ligne 3 avec b valant 0 : 5 cercles.
Une exécution de la ligne 3 avec b valant 1 : 6 cercles.
Une exécution de la ligne 3 avec b valant 2 : 7 cercles.
Une exécution de la ligne 3 avec b valant 2 : 8 cercles.
Fin de la boucle 2
Puis a vaut 2 et
Une exécution de la ligne 3 avec b valant 0 : 9 cercles.
Une exécution de la ligne 3 avec b valant 1 : 10 cercles.
Une exécution de la ligne 3 avec b valant 2 : 11 cercles.
Une exécution de la ligne 3 avec b valant 2 : 12 cercles.
Fin de la boucle 2
Puis a vaut 3 et
Une exécution de la ligne 3 avec b valant 0 : 13 cercles.
Une exécution de la ligne 3 avec b valant 1 : 14 cercles.
Une exécution de la ligne 3 avec b valant 2 : 15 cercles.
Une exécution de la ligne 3 avec b valant 2 : 16 cercles.
Fin de la boucle 2
Finalement a vaut 4 et
Une exécution de la ligne 3 avec b valant 0 : 17 cercles.
Une exécution de la ligne 3 avec b valant 1 : 18 cercles.
Une exécution de la ligne 3 avec b valant 2 : 19 cercles.
Une exécution de la ligne 3 avec b valant 3 : 20 cercles.
Fin de la boucle 2
Fin de la boucle 1
Tout cela peut se résumer à 5 tours de boucle 1 comportant à chaque fois 4 tours de boucle 2, soit 5 * 4 = 20 cercles dessinés.
11° Que va afficher ce programme ? Expliquer l'ordre de l'affichage obtenu.
1
2
3
forainrange(2,9,3):forbinrange(10,101,20):print(f"a = {a} et b = {b}")
...CORRECTION 1-2...
La variable de boucle a va prendre les valeurs 2, 5, 8.
Lors du premier tour de boucle, la valeur de a est donc 2.
La variable de boucle b va prendre les valeurs 10, 30, 50, 70, 90. Soit 5 tours de boucles différents.
On va donc obtenir ceci lors du premier tour de boucle sur a :
a = 2 et b = 10
a = 2 et b = 30
a = 2 et b = 50
a = 2 et b = 70
a = 2 et b = 90
Ensuite, on va revenir sur un nouveau tour de boucle pour a qui devient 5.
a = 5 et b = 10
a = 5 et b = 30
a = 5 et b = 50
a = 5 et b = 70
a = 5 et b = 90
Enfin, on fait le dernier tour de boucle pour a qui devient 8.
a = 8 et b = 10
a = 8 et b = 30
a = 8 et b = 50
a = 8 et b = 70
a = 8 et b = 90
✎ 12° Expliquer clairement pourquoi le programme suivant crée exactement 16 cercles. Pour cela, il "suffit" de savoir répondre aux question suivantes (si vous n'y arrivez pas seul, Python Tutor n'est pas votre ami car il n'intègre pas Turtle !) :
Combien de fois cercles() (avec un s) va être appelée pendant l'exécution de la fonction dessin() ?
Autrement dit : combien de valeurs différentes va prendre la variable de boucle angle de la ligne 18 ?
Lors des appels à cercles(), comprendre ce que vont recevoir les paramètres rmax, rmin et pas.
Lors de chacun des appels à cercles() (avec un s) combien d'appels à cercle() (sans s) ?
Autrement dit : combien de valeurs différentes va prendre la variable de boucle rayon de la ligne 13 ?
Voici le programme utilisé pour réaliser ce dessin.
importturtleastrtdefcercle(rayon:int,angle:int):"""Fonction qui trace UN cercle."""feutre=trt.Turtle()feutre.color("red")feutre.pensize(5)feutre.setheading(angle)feutre.circle(rayon,360)defcercles(rmin:int,rmax:int,pas:int,angle:int):"""Fonction qui trace DES cercles en utilisant... cercle()"""forrayoninrange(rmin,rmax,pas):cercle(rayon,angle)defdessin():"""Fonction qui trace un dessin en utilisant cercles()"""forangleinrange(0,360,90):cercles(50,150,25,angle)dessin()
Pour info (ça ne sert à rien pour résoudre la question), la méthode setheading() permet de forcer la tortue à regarder dans une direction précise (qu'on fournit sous forme d'un angle : 0° veut dire de regarder vers la droite, 180° vers la gauche...).
1.4 Boucle POUR : boucle BORNEE
Les boucle POUR sont des boucles bornées : on ne peut pas boucler à l'infini puisqu'on pourrait prévoir à l'avance combien de fois le bouclage sera réalisé.
Plutôt que de tout faire à la main, utilisons une boucle dont la variable de boucle se nommerait nombre.
1
2
3
somme=0# Initialisation du compteurfornombreinrange(1, 1001):# Pour chaque nombre entier de 1 à 1000somme=somme+nombre# Incrémente somme avec ce nombre
Attention à la phase d'initialisation de la ligne 1. Elle est très importante et nous allons la retrouver très souvent cette année.
✎ 13-A° On veut réaliser une fonction somme() qui renvoie la somme des n premiers entiers.
Par exemple, somme(4) doit renvoyer la somme de 0+1+2+3+4, soit 10.
Nous allons donc faire cela en boucle.
On crée une variable de stockage qu'on nommera s.
A chaque étape, on va donc rajouter la valeur de la valeur de boucle à la variable s et remettre le résultat dans la variable s.
On aura ainsi :
Initialisation : s = 0
Premier tour de boucle : s = s + 0, soit s = 0
Deuxième tour de boucle : s = s + 1, soit s = 1
Troisième tour de boucle : s = s + 2, soit s = 3
Quatrième tour de boucle : s = s + 3, soit s = 6
...
Compléter la fonction somme() pour qu'elle fonctionne correctement :
1
2
3
4
5
6
defsomme(n:int):"""Renvoie la somme des entiers de 1 jusqu'à n INCLUS"""s=...forxinrange(...,...,...):s=s+...return...
Question A : dans ce programme de concaténations successives, que contient chaine avant le premier tour de boucle ? Comment se nomme la phase correspondant à la ligne 1 ?
chaine = chaine + str(nombre) + " "
NameError: name 'chaine' is not defined
Question C : pourquoi un humain parviendrait-il à exécuter cela si on lui donner des instructions en oubliant la ligne 1 ?
...CORRECTION...
Question A
La chaine contient une première valeur d'initialisation.
Question B
On voit que l'initialisation est indispensable car, sinon, python ne serait pas en capacité d'évaluer chaine = chaine + .... Puisqu'il commence l'évaluation à droite, il ne connaît pas chaine et ne peut donc pas l'évaluer.
Question C
L'humain a un avantage énorme sur la machine : il peut remplir les trous avec son intuition et sa capacité d'analyse. Il est libre d'interpréter à sa guise et de donner du sens à l'instruction : il manque une première valeur ? Ok, prenons un caractère vide. La machine ne fait qu'exécuter, sans réflexion ni analyse. C'est juste une machine.
15° Fournir deux programmes permettant d'obtenir les deux chaînes ci-dessous.
Ils affichent l'un et l'autre ceci dans la console :
20
8
18
12
(RAPPELS) 3.3 n-UPLET : accèder à toutes les cases
On utilise une boucle for .. in couplée à la fonction len() pour connaitre l'indice i limite.
Ainsi avec ("In Borderland", "Alice", 18, True), on a 4 éléments d'indices 0 à 3.
1
2
3
4
eleve = ("In Borderland", "Alice", 18, True)foriinrange(len(eleve)):# Pour chaque indice possible dans eleveprint(eleve[i])# Affiche le contenu de la case i
Ils affichent l'un et l'autre ceci dans la console :
'In Borderland'
'Alice'
18
True
16° Compléter la fonction somme_tableau() qui renvoie la somme des entiers POSITIFS contenus dans le tableau.
1
2
3
4
5
6
7
defsomme_tableau(t:list[int]):"""Renvoie la somme des entiers dans le tableau t"""s=...foriin...:ift[i]...0:s=...return...
>>> somme_tableau([10, 20, -50, 30])
60
...CORRECTION...
1
2
3
4
5
6
7
defsomme_tableau(t:list[int]):"""Renvoie la somme des entiers dans le tableau t"""s=0# Initialisation d'un compteurforiinrange(len(t)):# Pour chaque indice possible dans tift[i]>=0:# Si le contenu de la case i est positifs=s+t[i]# On incrémente s de la valeur dans la casereturns# APRES avoir fait tous les tours
3.4 Boucle POUR : somme d'un tableau
1
2
3
4
5
6
defsomme_tableau(t:list[int]):"""Renvoie la somme des entiers dans le tableau t"""s=0# Initialisation d'un compteurforiinrange(len(t)):# Pour chaque indice possible dans ts=s+t[i]# On incrémente s de la valeur dans la casereturns# APRES avoir fait tous les tours
L'un des intérêts d'obtenir les indices est notamment de pouvoir modifier toutes les cases correspondantes d'un tableau.
(RAPPELS) 3.5 TABLEAU STATIQUE : muable en Python (modification possible)
En Python, les tableaux sont muables (ou mutables en anglais) : on peut modifier le contenu d'une case après la création du tableau.
Imaginons qu'on ai oublié des points à Bob (l'élève d'indice 1) : il n'a pas 8 mais 11 finalement. Voici comment nous pourrions modifier le tableau APRES création
Ce n'est pas une affectation sur le tableau lui-même : l'affectation est faite sur l'une des cases notes[i] du tableau.
17° Lancer le programme suivant, comprendre ce qu'il réalise pour compléter les commentaires pour donner la signification en français de chacune des lignes.
1
2
3
4
5
6
7
8
9
10
t=[5,2,-7,15,-10]# ?print("Avant la boucle")print(t)# ?foriinrange(len(t)):# ?ift[i]<0:# ?t[i]=-t[i]# ?print("Après la boucle")print(t)# ?
...CORRECTION...
1
2
3
4
5
6
7
8
9
10
t=[5,2,-7,15,-10]# Création du tableau tprint("Avant la boucle")print(t)# Affichage sur la console du tableauforiinrange(len(t)):# Pour chaque indice possible dans le tableauift[i]<0:# Si le contenu de la case i est négatift[i]=-t[i]# On remplit la case à 0print("Après la boucle")print(t)# Affichage sur la console du tableau
defsomme_dict(d:dict[(str,int)]):"""Renvoie la somme des entiers dans le dictionnaire d"""s=0# Initialisation d'un compteurforcleind.keys():# Pour chaque clé du dictionnaire difd[cle]>=0:# Si la valeur associée à cette clé est positives=s+d[cle]returns
4.2 Boucle POUR : somme d'un dictionnaire
1
2
3
4
5
6
7
defsomme_dict(d:dict[(str,int)]):"""Renvoie la somme des entiers dans le dictionnaire d"""s=0# Initialisation d'un compteurforcleind.keys():# Pour chaque clé du dictionnaire ds=s+d[cle]returns
L'un des intérêt d'avoir connaissance des clés une par une est de pouvoir modifier les cases du dictionnaire.
(RAPPELS) 4.3 DICTIONNAIRE : muable en Python (modification possible)
En Python, les dictionnaires sont muables (ou mutables en anglais) : on peut modifier le contenu d'une case après la création du dictionnaire.
Modification d'un couple existant
Imaginons qu'on ai oublié des points à Bob : il n'a pas 8 mais 11 finalement. Voici comment nous pourrions modifier le tableau APRES création
Notez bien que ce n'est pas une affectation sur le dictionnaire : l'affectation est faite sur l'un des contenus des associations clé-valeur du dictionnaire, pas sur le dictionnaire lui-même.
Rajout d'un nouveau couple
On peut rajouter de la même façon un couple qui n'existe pas encore.
Imaginons un nouvel élève nommé David qui a eu 15.
19° Lancer le programme suivant, comprendre ce qu'il réalise pour compléter les commentaires pour donner la signification en français de chacune des lignes.
1
2
3
4
5
6
7
8
9
10
d={"A":12,"B":20,"C":7}# ?print("Avant la boucle")print(d)# ?forcleind.keys():# ?if(d[cle]%2)==0:# ?d[cle]=d[cle]+1# ?print("Après la boucle")print(d)# ?
...CORRECTION...
1
2
3
4
5
6
7
8
9
10
d={"A":12,"B":20,"C":7}# Création du dictionnaire dprint("Avant la boucle")print(d)# Affichage sur la console du dictionnaireforcleind.keys():# Pour chaque clé possible dans le dictionnaireif(d[cle]%2)==0:# Si la valeur (le contenu de la case) est paired[cle]=d[cle]+1# On rajoute 1 à la caseprint("Après la boucle")print(d)# Affichage sur la console du dictionnaire
La syntaxe permettant d'accéder à tous les indices ou toutes les clés est un peu lourde.
Or, elle n'est indispensable que si on désire MODIFIER le contenu de la structure.
Si on désire simplement lire le contenu, on peut utiliser une autre syntaxe qui permet d'accéder directement au contenu, sans passer par les étiquettes (indices ou clés).
5.1 STRING : accèder à toutes les VALEURS
Si on désire uniquement LIRE les caractères d'un string, on PEUT utiliser une boucle for ... in en l'associant directement au nom du string.
La variable de boucle va alors contenir les caractères un par un, et non plus l'indice du caractère.
Ainsi avec "bonjour", on a 7 caractères.
1
2
3
4
s="bonjour"forcins:# Pour chaque caractère possible dans sprint(c) # Affiche le caractère c
Ils affichent l'un et l'autre ceci dans la console :
20
8
18
12
5.3.2 Impossible de MODIFIER avec cette boucle
Notez bien qu'on ne peut que LIRE.
Le code suivant ne modifie pas le tableau.
3
4
fornoteint:# Pour chaque valeur possible dans tnote=note+5# Ne modifie absolument pas le contenu du tableau !
5.4 DICTIONNAIRE : accèder à toutes les VALEURS
5.4.1 Syntaxe
Si on désire uniquement LIRE les valeurs d'un dictionnaire, on PEUT utiliser une boucle for ... in en utilisant la méthode values() sur le dictionnaire.
1
2
3
4
ds = {"Alice":13, "Bob":8, "Charlie":12}forvinds.values():# Pour chaque valeur possible dans dsprint(v)# Affiche la valeur lue sur ce tour de boucle
Ils affichent l'un et l'autre ceci dans la console :
13
8
12
5.4.2 Impossible de MODIFIER avec cette boucle
Notez bien qu'on ne peut que LIRE.
Le code suivant ne modifie pas le contenu du dictionnaire.
3
4
forvinds.values():# Pour chaque valeur possible dans dsv=v+5# Ne modifie pas le contenu du dictionnaire !
20° Modifier la fonction somme() pour qu'elle réalise bien la somme des éléments du tableau. On impose l'utilisation de la lecture directe des valeurs plutôt que de passer par les indices.
1
2
3
4
5
6
7
8
9
10
11
12
13
t=[10,20,30]defsomme(t:list[int])->int:"""Renvoie la somme des valeurs contenues dans le tableau"""s=...# Initialisation de la variable sommeforvin...:# Pour chaque valeur du tableau...=...+...# Incrémente s de cette valeurreturn...# Après avoir fait toute la boucleprint(somme(t))
...CORRECTION...
1
2
3
4
5
6
7
8
9
10
11
12
13
t=[10,20,30]defsomme(t:list[int])->int:"""Renvoie la somme des valeurs contenues dans le tableau"""s=0# Initialisation de la variable sommeforvint:# Pour chaque valeur du tableaus=s+v# Incrémente s de cette valeurreturns# Après avoir fait toute la boucleprint(somme(t))
Cette partie sera à faire ensemble : c'est un ensemble de manipulation. Ce n'est pas compliqué mais lire les manipulations à faire est plus difficile que de les faire directement.
Si vous n'utilisez pas Thonny, vous pouvez passer à la partie suivante.
Le logiciel Thonny possède une fonctionnalité que vous avez déjà rencontré le mode PAS A PAS. Il permet d'exécuter du code ligne par ligne. Nous allons voir comment il fonctionne sur les boucles (et plus généralement les blocs d'instructions).
DEBUG 1° Placer ce code dans Thonny SANS LE LANCER. Ouvrir l'onglet VIEW-VARIABLES pour observer les variables.
Pour lancer le mode DEBUG / PAS A PAS, il faut appyer sur le bouton "BUG" situé à DROITE de la flèche verte permettant juste de lancer le script.
Appuyer sur ce bouton et suivre les indications ci-dessous.
Vous devriez obtenir la première ligne en surbrillance : Thonny attend que vous validiez cette ligne. Pour l'instant, il n'a rien fait.
Pour lui demander d'exécuter cette ligne, il faut appuyer sur le bouton qui se trouve à droite du BUG et qui se nomme STEP OVER :
DEBUG 2° Appuyer sur le bouton STEP OVER.
On constate alors bien l'apparition d'une variable chaine ne contenant rien.
On voit que Thonny attend patiemment qu'on lui donne l'autorisation d'exécuter ce bloc en surbrillance.
Or, nous voulons voir comment s'exécute ce bloc pas à pas, nous ne voulons pas l'exécuter d'un coup. Pour cela, il va encore falloir appuyer sur un autre bouton : le bouton STEP INTO, qui permet de rentrer dans l'évaluation du bloc.
DEBUG 3° Appuyer sur le bouton STEP INTO.
On rentre bien dans le bloc et Thonny vous demande s'il peut commencer à évaluer l'ensemble des valeurs qu'il va devoir générer une à une :
DEBUG 4° Appuyer sur le bouton STEP OVER pour autoriser Thonny à exécuter cette évaluation (sans rentrer dans le détail de l'évaluation)
On obtient alors bien la première valeur de la suite, à savoir 2.
DEBUG 5° Appuyer encore sur le bouton STEP OVER pour autoriser Thonny à exécuter cette évaluation (sans rentrer dans le détail de l'évaluation)
On voit à droite qu'il a créé une variable nombre valant 2.
Il attend donc de pouvoir exécuter la ligne en surbrillance.
DEBUG 6° Valider chacune des instructions pour voir la création progressive de la chaîne de caractères.
Voici le résultat :
Lorsqu'on validera cette ligne, Python va donc concaténer '2 ' + '4' + ' ' qui sera évaluée à '2 4 ' et placée à nouveau dans la variable chaine. Résultat en image ci-dessous :
Lorsqu'on validera cette ligne, Python va donc concaténer '2 4 ' + '6' + ' ' qui sera évaluée à '2 4 6 ' et placée à nouveau dans la variable chaine. Résultat en image ci-dessous :
Nous arrivons ici à la dernière instruction puisque la variable de boucle ne pourra plus augmenter de 2. La chaîne de caractères va donc subir une dernière concaténation avant d'arriver à son état final.
Lorsqu'on validera cette ligne, Python va donc concaténer '2 4 6 ' + '8' + ' ' qui sera évaluée à '2 4 6 8 ' et placé à nouveau dans la variable chaine. Résultat en image ci-dessous :
Nous reviendrons régulièrement sur ce mode DEBUG. Dès qu'on change vous semble étrange, pensez à l'utiliser : cela vous permet de voir ce que Python fait VRAIMENT avec votre code.