Outils Pour

Identification

Infoforall

8 - Boucles Bornées


Vous auriez vraiment envie de faire cela sans boucle ?
1 2 3 4 5 6 7 8 9 10
import turtle as trt couleurs = ["gold", "white", "blue" ] crayon = trt.Turtle() crayon.speed(0) trt.bgcolor('black') for x in range(800): crayon.pencolor(couleurs[x % 3]) crayon.width(x//100 + 1) crayon.forward(x) crayon.left(59)

Evaluation : 5 questions

  questions 07- 14A- 14B - 17 - 18B - 18C

  question 13D - 18D

Exercices supplémentaires 🏠 : sur le site

Documents de cours PDF : .PDF

Sources latex : .TEX et entete.tex et licence.tex

1 - Boucle POUR : EXACTEMENT la même actoin

Rappels

(RAPPELS) 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.

B - Exemple
1 2 3 4 5 6 7
print("Avant boucle") # Pas tabulée : avant la boucle for _ in range(3): # Déclaration de la boucle print("A") # Tabulée : dans la boucle print("-- B") # Tabulée : dans la boucle print("Après boucle") # Pas tabulée : avant la boucle

Déroulé du programme

L1
L3 - L4 - L5
L3 - L4 - L5
L3 - L4 - L5
L7

Résultat du programme

Avant boucle A -- B A -- B A -- B Après boucle
C - Sémantique
3
for _ in range(3):

Traduction en français : "Réalise 3 fois le bloc d'instructions indentées"

⚙ 01° Voici un programme qui 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 "Fini !".

1 2 3 4 5 6
print("C'est parti !") for _ in range(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 !

Questions

  1. (Action) Placer le programme dans Python Tutor et visualiser l'exécution progressive : la boucle devrait être réalisée 5 fois.
  2. Fournir la succession de lignes que va suivre l'interpréteur Python.
  3. Modifier le programme pour qu'il vous affiche 200 fois "Et un tour de boucle".

...CORRECTION...

  1. .
  2. L1 - L3-L4 - L3-L4 - L3-L4 - L3-L4 - L3-L4 - L6.
  3. Il suffit de noter 200 à la place de 5.

⚙ 02° Réaliser ces deux actions :

  1. Créer un programme qui affiche 1000 fois "Trop facile en programmant".
  2. Fournir la séquence des lignes suivies pour écrire les 3 premiers textes.
Trop facile en programmant Trop facile en programmant Trop facile en programmant ...

...CORRECTION...

1 2 3
texte = "Trop facile en programmant" for _ in range(1000): print(texte)

1 - 2-3 - 2-3 - 2-3...

⚙ 03° Créer un string qui contient 40 symboles étoiles *. Le plus facile est encore de le créer à l'aide d'une répétition. Finaliser le programme pour qu'il affiche 10 lignes qui contiennent chacune 40 étoiles *.

**************************************** **************************************** **************************************** **************************************** **************************************** **************************************** **************************************** **************************************** **************************************** ****************************************

...CORRECTION...

1 2 3
texte = "*" * 40 for _ in range(10): print(texte)

⚙ 04-A° Lancer le code suivant dans Thonny : visualisez qu'il traçe un triangle en faisant appel à la fonction triangle().

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# Partie Importation import turtle as trt # Partie déclaration des fonctions def triangle(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 principal stylo = trt.Turtle() triangle(stylo, 100, 120)

Questions

  1. Fournir les lignes suivies par l'interpréteur sur ce programme.
  2. Lorsqu'on lance l'appel et qu'on revient en ligne 21, donner les contenus de feutre distance angle.

...CORRECTION...

  1. Succession des lignes :
    • L3 - L8 (définition) - L20 - L21 (appel en envoyant stylo, 100, 120)
    • L8 (appel) - L10 - L11 - L12 - L13 - L14 - L15 - retour à la ligne de l'appel
    • L21 (rien à faire de plus) - fin du programme
  2. Pour comprendre où sont stocker les choses qu'on envoie lors de l'appel, il suffit de juxtaposer la déclaration et l'appel :
  3. 8 21
    def triangle(feutre:trt.Turtle, distance:int, angle:int) -> None: triangle(stylo, 100, 120)

    On voit que :

    • feutre reçoit la référence stylo
    • distance reçoit 100
    • angle reçoit 120

⚙ 04-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 Importation import turtle as trt # Partie déclaration des fonctions d'interface def triangle(feutre:trt.Turtle, distance:int, angle:int) -> None: """Fait avancer le crayon de la distance, tourne de l'angle donné. Trois fois.""" for _ in range(3): feutre.forward(distance) feutre.left(angle) # Instructions du programme principal stylo = trt.Turtle() triangle(stylo, 100, 120)

Questions

  1. Fournir les lignes suivies par l'interpréteur sur ce programme.
  2. Lorsqu'on lance l'appel et qu'on revient en ligne 21, donner les contenus de feutre distance angle.

...CORRECTION...

  1. Succession des lignes :
    • L3 - L8 (définition) - L17 - L18 (appel en envoyant stylo, 100, 120)
    • L8 (appel) - L10-L11-L12 - L10-L11-L12 - L10-L11-L12 - retour à la ligne de l'appel
    • L18 (rien à faire de plus) - fin du programme
  2. Pour comprendre où sont stocker les choses qu'on envoie lors de l'appel, il suffit de juxtaposer la déclaration et l'appel :
  3. 8 21
    def triangle(feutre:trt.Turtle, distance:int, angle:int) -> None: triangle(stylo, 100, 120)

    On voit que :

    • feutre reçoit la référence stylo
    • distance reçoit 100
    • angle reçoit 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).

⚙ 05° Répondre aux questions liées à cette fonction :

  1. Ecrire la séquence de lignes suivies par l'interpréteur lors d'un appel imaginaire à exo().
  2. combien de fois va-t-on réaliser la boucle ?
  3. Combien de fois va-t-on réaliser l'instruction "forward / avance" ?
  4. Combien de fois va-t-on réaliser l'instruction "left / tourne à gauche" ?
  5. Tester l'animation suivante pour être certain d'avoir compris le déroulé :
1 2 3 4 5 6 7
def exo(feutre:trt.Turtle, distance:int, angle:int) -> None: """Que fait cette fonction ?""" feutre.forward(distance) for _ in range(5): feutre.forward(distance) feutre.left(angle) feutre.forward(distance)

CLIQUEZ ICI POUR VOIR LE DEROULEMENT SEQUENTIEL

...CORRECTION...

  1. Succession des lignes :
  2. L01(on arrive sur cet appel, attribution des valeurs aux paramètres)

    L03

    L04-L05-L06 (1er tour)

    L04-L05-L06 (2e tour)

    L04-L05-L06 (3e tour)

    L04-L05-L06 (4e tour)

    L04-L05-L06 (5e tour)

    L07

    Notez bien qu'il n'y a pas de return après la ligne 7. Python sort donc de la fonction sans rien renvoyer.

  3. Nombre de tours de boucle
  4. On voit range(5) : la boucle va être réalisée 5 fois.

  5. Nombre de forward
  6. 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.

  7. Nombre de left
  8. Pour l'action "tourne", on ne la réalise qu'une fois par tour de boucle. Il y a donc 5 "tourne" au total.

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.
  • ...

⚙ 06-A° 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 longueur pixels.
    • Tourner de angle degrés.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# Partie Importation import turtle as trt # Partie déclaration des fonctions def polygone(feutre:trt.Turtle, nb:int, longueur:int) -> None: """Crée un polygone à nb cotés, longueur étant la longueur de chaque côté""" pass # Instructions du programme principal stylo = trt.Turtle() polygone(stylo, 6, 100)

Vous devriez obtenir ceci après l'appel fourni sur la dernière ligne du programme :

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# Partie Importation import turtle as trt # Partie déclaration des fonctions d'interface def polygone(feutre:trt.Turtle, nb:int, longueur:int) -> None: """Crée un polygone à nb cotés, longueur étant la longueur de chaque côté""" angle = 360 // nb for _ in range(nb): feutre.forward(longueur) feutre.left(angle) # Instructions du programme principal stylo = trt.Turtle() polygone(stylo, 6, 100)

✔ 06-B° 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 :

✎ 07° Créer une fonction punition() qui possède deux paramètres et qui répondra ainsi à ces exemples :

>>> 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 >>> punition("Vroum", 2) Vroum Vroum
1 2 3
def punition(ligne_a_copier:str, nombre_de_fois:int): """Réalise la punition à la place de l'élève""" pass

Votre fonction devra afficher (afficher donc print()) dans la console la phrase autant de fois que nécessaire.

2 - Boucle POUR : PRESQUE la même action

Demandons-nous maintenant comment réaliser presque la même chose à chaque tour de boucle.

(RAPPELS) 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.

for k in range(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 néanmoins bien au nombre de tours de boucle effectuées : 0-1-2-3-4.
  • La valeur finale de k est 4, obtenue en calculant (5 - 1).
B - Déroulé d'une boucle avec variable de boucle
1 2 3 4 5 6 7
print("Avant boucle") for k in range(3): # Pour k variant de 0 à 2 print("A") # Affiche le string "A" print(k) # Affiche le contenu de k print("Après boucle")

Déroulé du programme

L1
L3(k=0) - L4 - L5
L3(k=1) - L4 - L5
L3(k=2) - L4 - L5
L7

Résultat du programme

Avant boucle A 0 A 1 A 2 Après
C - Sémantique
3
for k in range(3):

Traduction en français : "Pour chaque valeur de k dans [0, 1, 2], réalise le bloc d'instructions indentées"

⚙ 08° Tester l'animation suivante.

Questions

1 2 3 4 5 6 7
def exo(): """Que fait cette fonction ?""" print("Avant la boucle") for k in range(5): print("Un tour de boucle") print(k) print("Après la boucle")

CLIQUEZ ICI POUR VOIR LE DEROULEMENT SEQUENTIEL

k :

  1. Que vaut la variable de boucle k lors du premier tour de boucle ?
  2. Que vaut la variable de boucle k lors du dernier tour de boucle ?
  3. Quelles sont les valeurs successives prises par la variable de boucle k ?
  4. Combien de valeurs successives (et de tous de boucle) k a-t-elle eu lors du déroulé de la boucle ?

...CORRECTION...

  1. La variable de boucle k commence à 0 lors du premier tour de boucle.
  2. La variable de boucle k finit à 4 lors du dernier tour de boucle.
  3. La variable de boucle k a donc pris les valeurs successives 0 puis 1, puis 2, puis 3 et finalement 4.
  4. Il y a donc eu 5 valeurs différentes et donc 5 tours de boucle.

⚙ 09° Regarder le programme ci-dessous puis répondre aux questions.

  1. Quelles vont être les valeurs successives prises par la variable de boucle k ?
  2. Combien de cas différents en tout ?
  3. Ecrire le programme équivalent sans boucle qui permettrait d'obtenir le même affichage.
1 2
for k in range(10): print(k)

Si vous n'êtes pas sûr de vous, Python Tutor est votre ami.

...CORRECTION...

La variable de boucle k commence à 0, puis prend la valeur 1, puis prend la valeur 2... jusqu'à arriver à 9.

ATTENTION : on ne va pas jusqu'à 10, on s'arrête juste avant :!

Les différentes valeurs sont : 0 1 2 3 4 5 6 7 8 9

Il y a bien 10 valeurs différentes qui s'étalent de 0 à 9.

1 2 3 4 5 6 7 8 9 10
print(0) print(1) print(2) print(3) print(4) print(5) print(6) print(7) print(8) print(9)

⚙ 10° Réaliser ces deux actions :

  1. Compléter les ... dans le programme pour qu'il affiche les nombres 0, 10, 20, 30, 40, 50... jusqu'à 100.
  2. Fournir la succession de lignes de code suivies par l'interpréteur.
1 2 3 4 5 6
print("C'est parti !") for k in range(11): ... print("Fini !")

...CORRECTION...

1 2 3 4 5 6
print("C'est parti !") for k in range(11): print(k * 10) print("Fini !")
>>> %Run prog_boucle.py C'est parti ! 0 10 20 30 40 50 60 70 80 90 100 Fini !

Les séquences suivies sont :

L1

L3(k=0)-L4

L3(k=1)-L4

L3(k=2)-L4

L3(k=3)-L4

L3(k=4)-L4

L3(k=5)-L4

L3(k=6)-L4

L3(k=7)-L4

L3(k=8)-L4

L3(k=9)-L4

L3(k=10)-L4

L6

⚙ 11° Créer un programme qui affiche (à l'aide d'une boucle) 0 étoile, puis 1 étoile, puis 2 étoiles... jusqu'à 10 étoiles.

Attention, je veux 10 étoiles, pas 9 !

* ** *** **** ***** ****** ******* ******** ********* **********

...CORRECTION...

1 2
for v in range(11): print("*" * v)
>>> %Run prog_boucle.py * ** *** **** ***** ****** ******* ******** ********* **********

⚙ 13-A° Traçons maintenant (avec Turtle) un motif à l'aide de la boucle sur les lignes 24-25-26 : on avance (d'une longueur qui augmente à chaque tour) et on tourne. Nous utilisons la valeur de la variable de boucle notée k, différente à chaque tour :

Utiliser ce programme pour visualiser le résultat, puis répondre aux questions.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# Partie Importation import turtle as trt # Partie CONSTANTES COULEUR_CHOISIE = "#33AAFF" TAILLE = 25 X = 0 Y = 0 # PROGRAMME PRINCIPAL stylo = trt.Turtle() stylo.pensize(5) stylo.penup() stylo.goto(X, Y) stylo.pendown() # Dessin d'une forme de plus en plus grande for k in range(16): stylo.forward( TAILLE * (k + 1) ) stylo.left(90)

Questions

  1. Fournir les lignes de code suivies par Python jusqu'à avoir fait 3 tours de boucles. N'allez pas jusqu'au bout des 16 tours.
  2. Lors du premier tour :
    • (L1) Que vaut la variable de boucle k ?
    • (L19) De combien de pixels avance-t-on lors du premier tour ?
  3. Lors du deuxième tour :
    • (L1) Que vaut la variable de boucle k ?
    • (L19) De combien de pixels avance-t-on lors du premier tour ?
  4. Lors du troisième tour :
    • (L1) Que vaut la variable de boucle k ?
    • (L19) De combien de pixels avance-t-on lors du premier tour ?

...CORRECTION...

Résultat du programme précédent

Pour les lignes  :

L3-L8-L9-L10-L11-L16-L17-L18-L19-L20-L21- L24(k=0)-L25-L26 - L24(k=1)-L25-L26 - L24(k=2)-L25-L26 ...

Pour les autres questions :

k vaut 0 puis k vaut 1 puis k vaut 2 puis k vaut 3.

On calcule alors les longueurs en utilisant la ligne 19 : TAILLE * (k + 1)

Lorsque k vaut 0, la longueur vaut 25*(0+1) = 25

Lorsque k vaut 1, la longueur vaut 25*(1+1) = 50

Lorsque k vaut 2, la longueur vaut 25*(2+1) = 75

⚙ 13-B° Modifiez l'angle de rotation de la ligne 26 :

  • Placez 120 et lancez.
  • Placez 240 et lancez.
  • Placez 210 et lancez.

Question : la dernière forme est-elle réellement plus complexe à décrire que les autres ou s'agit-il uniquement d'une illusion de complexité si on utilise le mauvais langage de description ?

...CORRECTION...

Le langage humain donnerait effectivement à la dernière forme l'illusion d'une forme complexe car nous serions bien ennuyés pour la décrire précisément.

En réalité, en utilisant le bon langage de description, on se rend compte que ces formes sont toutes équivalentes puisque, dans le code permettant de les dessiner, seule la valeur change.

⚙ 13-C° On utilise ici la variable de boucle pour jouer le rôle d'indice dans un tableau nommé COULEURS contenant différentes couleurs que nous allons afficher en cycle. Ce tableau remplace donc COULEUR_CHOISIE.

Rappel sur la lecture des cases d'un tableau (le type construit list de Python)

>>> COULEURS = ["red", "orange", "green", "cyan", "blue"] >>> COULEURS[0] 'red' >>> COULEURS[1] 'orange' >>> len(COULEURS) 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
# Partie Importation import turtle as trt # Partie CONSTANTES COULEURS = ["red", "orange", "green", "cyan", "blue"] TAILLE = 25 X = 0 Y = 0 # PROGRAMME PRINCIPAL stylo = trt.Turtle() stylo.pensize(5) stylo.penup() stylo.goto(X, Y) stylo.pendown() # Dessin d'un carré for k in range(16): i = k % 5 # i vaut nécessairement 0,1,2,3 ou 4, reste de la division par 5. couleur = COULEURS[i] stylo.pencolor(couleur) stylo.forward( TAILLE * (k + 1) ) stylo.left(90)

Lancer le programme

Vous devriez obtenir ceci maintenant (sans les valeurs de k, je les ai rajouté pour identifier facilement les étapes):

Question

Expliquer comment ce code crée une alternance de couleurs sur les différents traits. Il faudra référencer clairement les lignes impliquées et parler de la valeur de k et du reste de la division euclidienne.

...CORRECTION...

LIGNE 24 : Lors de chaque tour de boucle, la variable de boucle k est incrémentée, sa valeur de départ étant 0. Elle va donc varier de 0 à 15.

LIGNE 25 : On divise k par 5 et on cherche le reste qu'on stocke alors dans i.

i est donc un entier valant 0,1,2,3 ou 4. C'est un indice valide pour le tableau couleur.

LIGNE 26 : on récupère la couleur située dans la case numéro i.

LIGNE 27 : on impose au stylo de prendre cette couleur.

✌ 13-D° Regardons maintenant comment parvenir à rajouter, à chaque début de tour de boucle, le texte au début du trait .

Pour cela, il faut utiliser la méthode write() sur le stylo (voir ligne 28) ainsi que la notion de f-strings (voir la leçon précédente au besoin).

Modifier les ... de la ligne 28 pour parvenir à obtenir l'affichage voulu :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
# Partie Importation import turtle as trt # Partie CONSTANTES COULEURS = ["red", "orange", "green", "cyan", "blue"] TAILLE = 25 X = 0 Y = 0 # PROGRAMME PRINCIPAL stylo = trt.Turtle() stylo.pensize(5) stylo.penup() stylo.goto(X, Y) stylo.pendown() # Dessin de la forme for k in range(16): i = k % 5 # i vaut nécessairement 0,1,2,3 ou 4, reste de la division par 5. stylo.pencolor("black") stylo.write(f"...{...}", font=('Arial', 12, 'normal')) stylo.pencolor(COULEURS[i]) stylo.forward( TAILLE * (k + 1) ) stylo.left(90)

3 - Description complète de range(depart, fin, pas)

Nouveautés

3.3 Boucle POUR : utilisation de range()

Visualisation de range sous forme d'un tableau

L'évaluation de range(5) ne renvoie pas réellement un simple 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.

3.3.1 Un seul argument : borne finale exclue

Lorsqu'on utilise range(10), l'interpréteur Python comprendra :

  • qu'on veut commencer à 0,
  • que la valeur "presque" finale (c'est à dire exclue) est 10 et
  • qu'on incrémentera la variable de boucle de +1 à chaque tour de boucle.

Visualisons cela dans la console. Attention, il faudra appuyer deux fois sur ENTREE (représentée ici par ) pour valider la boucle dans la console.

>>> list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> for k in range(10): print(k) 0 1 2 3 4 5 6 7 8 9
3.3.2 Deux arguments envoyés : valeur initiale, finale exclue

Lorsqu'on utilise range(3, 10), l'interpréteur Python comprendra :

  • qu'on veut commencer à 3,
  • que la valeur "presque" finale (c'est à dire exclue) est 10 et
  • qu'on incrémentera la variable de boucle de +1 à chaque tour de boucle.

Visualisons cela dans la console.

>>> list(range(3, 10)) [3, 4, 5, 6, 7, 8, 9] >>> for k in range(3, 10): print(k) 3 4 5 6 7 8 9
3.3.3 Trois arguments envoyés : initiale, finale exclue, pas

Lorsqu'on utilise range(3, 10, 2), l'interpréteur Python comprendra :

  • qu'on veut commencer à 3,
  • 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

✎ 14-A° Expliquer les valeurs successives que vont prendre les variables de boucle a, b et c dans les cas suivants :

>>> for a in range(250): print(a) ??? >>> for b in range(100, 150, 10): print(b) ??? >>> for c in range(150, 100, -10): print(c) ???

✎ 14-B° 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) ???

⚙ 15-A° Voici un programme qui permet de tracer des cercles positionnés aléatoirement.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# Partie Importation import turtle as trt import random as rd # Partie définitions des fonctions def cercle(r): crayon = trt.Turtle() crayon.penup() crayon.goto(rd.randint(-200, 200), rd.randint(-200, 200)) crayon.pendown() crayon.circle(r) crayon.hideturtle() # PROGRAMME PRINCIPAL for rayon in range(30, 71, 10): cercle(rayon)

Questions

  1. Quelles seront les valeurs prises par la variable de boucle rayon ?
  2. Combien va-t-on dessiner de cercles ?
  3. Décrire mentalement les lignes suivies par l'interpréteur.

...CORRECTION...

  1. Quelles seront les valeurs prises par la variable de boucle rayon ?
  2. 30, 40, 50, 60, 70

  3. Combien va-t-on dessiner de cercles ?
  4. 5 valeurs de rayon, donc 5 tours de boucle avec un cercle par boucle.

  5. Décrire mentalement les lignes suivies par l'interpréteur.
  6. L3-L4-L9(définition)

    L20(rayon=30) - L21(appel) - L9(réception)-L10-L11-L12-L13-L14-L15(sortie) - L21(retour)

    L20(rayon=40) - L21(appel) - L9(réception)-L10-L11-L12-L13-L14-L15(sortie) - L21(retour)

    L20(rayon=50) - L21(appel) - L9(réception)-L10-L11-L12-L13-L14-L15(sortie) - L21(retour)

    L20(rayon=60) - L21(appel) - L9(réception)-L10-L11-L12-L13-L14-L15(sortie) - L21(retour)

    L20(rayon=70) - L21(appel) - L9(réception)-L10-L11-L12-L13-L14-L15(sortie) - L21(retour)

    Fin

    On a donc 5 cercles puisqu'on réalise 5 appels à cercle().

⚙ 15-B° Combien va-t-on dessiner de cercles cette fois ? Justifiez votre réponse.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# Partie Importation import turtle as trt import random as rd # Partie définitions des fonctions def cercle(r): crayon = trt.Turtle() crayon.penup() crayon.goto(rd.randint(-200, 200), rd.randint(-200, 200)) crayon.pendown() crayon.circle(r) crayon.hideturtle() # PROGRAMME PRINCIPAL for rayon in range(30, 71, 10): cercle(rayon) cercle(rayon) cercle(rayon) cercle(rayon)

AIDE optionnelle : si vous avez un peu de mal, voici les lignes de code que va suivre l'interpréteur :

...AIDE...

L3 - L4 - L8(définition)

L20(rayon=30) - L21(appel) - L9...L15 - L21(retour) - L22(appel) - L9...L15 - L22(retour) - L23(appel) - L9...L15 - L23(retour) - L24(appel) - L9...L15 - L24(retour)

L20(rayon=40) - L21(appel) - L9...L15 - L21(retour) - L22(appel) - L9...L15 - L22(retour) - L23(appel) - L9...L15 - L23(retour) - L24(appel) - L9...L15 - L24(retour)

L20(rayon=50) - L21(appel) - L9...L15 - L21(retour) - L22(appel) - L9...L15 - L22(retour) - L23(appel) - L9...L15 - L23(retour) - L24(appel) - L9...L15 - L24(retour)

L20(rayon=60) - L21(appel) - L9...L15 - L21(retour) - L22(appel) - L9...L15 - L22(retour) - L23(appel) - L9...L15 - L23(retour) - L24(appel) - L9...L15 - L24(retour)

L20(rayon=70) - L21(appel) - L9...L15 - L21(retour) - L22(appel) - L9...L15 - L22(retour) - L23(appel) - L9...L15 - L23(retour) - L24(appel) - L9...L15 - L24(retour)

...CORRECTION...

Nous allons avoir 5 tours de boucle avec les valeurs suivantes pour le rayon : 30, 40, 50, 60 et finalement 70.

Mais on trace 4 cercles par tour de boucle.

Nous allons donc avoir 5*4 = 20 cercles.

⚙ 15-C° Combien va-t-on dessiner de cercles cette fois ? Justifiez votre réponse.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# Partie Importation import turtle as trt import random as rd # Partie définitions des fonctions def cercle(r): crayon = trt.Turtle() crayon.penup() crayon.goto(rd.randint(-200, 200), rd.randint(-200, 200)) crayon.pendown() crayon.circle(r) crayon.hideturtle() # PROGRAMME PRINCIPAL for rayon in range(30, 71, 10): for _ in range(4): cercle(rayon)

AIDE optionnelle : si vous avez un peu de mal, voici les lignes de code que va suivre l'interpréteur :

...AIDE...

L3 - L4 - L8(définition)

L20(rayon=30)

L21(1er tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(2e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(3e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(4e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L20(rayon=40)

L21(1er tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(2e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(3e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(4e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L20(rayon=50)

L21(1er tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(2e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(3e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(4e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L20(rayon=60)

L21(1er tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(2e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(3e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(4e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L20(rayon=70)

L21(1er tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(2e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(3e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

L21(4e tour de boucle) - L22(appel) - L9...L15 - L22(retour)

...CORRECTION...

Nous allons avoir 5 tours de boucle avec les valeurs suivantes pour le rayon : 30, 40, 50, 60 et finalement 70.

Mais pour chacun de ces tours de boucle, on fait 4 fois appe à cercle().

Nous allons donc avoir 5*4 = 20 cercles.

⚙ 16° Que va afficher ce programme ? Expliquer l'ordre de l'affichage obtenu.

1 2 3
for a in range(2, 9, 3): for b in range(10, 101, 20): print(f"a = {a} et b = {b}")

...CORRECTION...

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

✎ 17° Expliquer pourquoi le programme suivant crée exactement 16 cercles.

Pour cela, répondre à ces questions avant d'utiliser ces réponses pour batir votre conclusion :

  • Combien dessine-t-on de cercle lors d'un appel à la fonction cercle() (sans s) ?
  • Combien dessine-t-on de cercle lors d'un appel à la fonction cercles() (avec un s) ?
  • Combien dessine-t-on de cercle lors d'un appel à la fonction dessin() (avec un s) ?

Voici le programme utilisé pour réaliser ce dessin.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
import turtle as trt def cercle(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) def cercles(angle:int): """Fonction qui trace DES cercles en utilisant... cercle()""" for rayon in range(50, 150, 25): cercle(rayon, angle) def dessin(): """Fonction qui trace un dessin en utilisant cercles()""" for angle in range(0, 360, 90): cercles( 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...).

3.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é.

4 - Sommes et concaténations successives

Voici l'une des actions fondamentales à savoir faire : additionner des nombres et récupérer la somme.

4.1 Boucle POUR : somme avec additions successives

Nous voudrions faire la somme de plusieurs nombres 0 + 1 + 2 + 3 + 4 + 5 + 6 ... + 1000 jusqu'à un entier final au choix (1001 sur l'exemple).

Nous allons calculer la somme par additions successives, en écrasant la version précédente par la nouvelle version.

La signature de l'addition d'entiers' est int + int -> int.

Cela reviendrait à faire ceci à la main (et jusqu'à 1000, ça risque d'être long à taper...) :

1 2 3 4 5 .. 1001
somme = 0 somme = somme + 1 # donc 1 somme = somme + 2 # donc 3 somme = somme + 3 # donc 6 somme = somme + 4 # donc 10 ... somme = somme + 1000

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 compteur for nombre in range(1, 1001): # Pour chaque nombre entier de 1 à 1000 somme = 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.

⚙ 18-A° Voici un premier programme permettant de calculer progressivement 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
somme = 0 somme = somme + 0 somme = somme + 1 somme = somme + 2 somme = somme + 3 somme = somme + 4 somme = somme + 5 somme = somme + 6 somme = somme + 7 somme = somme + 8 somme = somme + 9 somme = somme + 10 ...

Questions

  1. Comment se nomme la variable qui va stocker progressivement les valeurs qu'on ajoute ?
  2. Compléter la ligne 15 pour afficher le résultat final.

...CORRECTION...

La variable est bien entendu somme.

Il suffit de noter ceci en ligne 15 : print(somme)

✎ 18-B° Nous voudrions maintenant faire la somme des entiers de 0 à 100 et nous n'avons pas trop envie de faire 100 incrémentations. Compléter les ... ci-dessous pour permettre au programme de faire son travail. Pour cela, quelques questions qui devraient vous aider :

  • L03 : comment se nomme la variable de boucle qui aura 0 comme valeur lors du premier tour, puis 1, puis 2, ect... ?
  • L03 : que faut-il mettre dans les parenthèses de la fonction range() pour aller jusqu'à 100 ?
  • L04 : pour obtenir l'équivalent des lignes 3 à 13 de la question 05-A, que faut-il rajouter à somme à chaque tour de boucle ? 0, 1, 2, v, somme ou 10 
1 2 3 4 5 6
somme = 0 for v in range(...): somme = somme + ... print(somme)

✎ 18-C° 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.

Compléter la fonction somme() pour qu'elle fonctionne correctement :

1 2 3 4 5 6
def somme(n:int) -> int: """Renvoie la somme des entiers de 1 jusqu'à n INCLUS""" s = ... for v in range(..., ..., ...): s = s + ... return ...
>>> somme(3) 6 >>> somme(4) 10 >>> somme(5) 15 >>> somme(6) 21

Tant que la fonction ne renvoie pas cela, c'est que votre fonction ne fonctionne pas !

Notez bien que la variable locale se nomme s et pas somme, puisque somme() est déjà le nom de la fonction. Cela risquerait de créer de la confusion dans la tête du lecteur humain.

✌ 18-D° Vous décidez d'organiser une fête, payante.

Le premier arrivé doit payer un euro, le deuxième 2 euros, le troisième 3 euros...

Vous avez eu 600 clients avant que plus personne n'accepte de payer.

Quelle somme d'argent avez-vous récolté ?

4.2 - Boucle POUR : concaténations successives

Nous voudrions créer une chaîne de caractères contentant "0 1 2 3 4 5 6 ... 1000" jusqu'à un entier final au choix (1000 sur l'exemple).

La signature de la concaténation de strings est str + str -> str.

Cela reviendrait à faire ceci à la main (et jusqu'à 1000, ça risque d'être long à taper...) :

1 2 3 4 5 .. 1002
chaine = "" chaine = chaine + str(0) + " " # on obtient "0 " chaine = chaine + str(1) + " " # on obtient "0 1 " chaine = chaine + str(2) + " " # on obtient "0 1 2" chaine = chaine + str(3) + " " # on obtient "0 1 2 3 " ... chaine = chaine + str(1000) + " "

Utilisons une boucle dont la variable de boucle se nommerait nombre.

1 2 3
chaine = "" for nombre in range(1001): chaine = chaine + str(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.

⚙ 19° Lancer ce programme et vérifier que la chaine obtenue est correcte. Répondre ensuite aux questions proposées.

1 2 3
chaine = "" for nombre in range(1001): chaine = chaine + str(nombre) + " "
>>> chaine '0 1 2 3 4 5 6 7 8 9 ... 1000'

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 ?

1 2 3
chaine = "" for nombre in range(1001): chaine = chaine + str(nombre) + " "

Question B : expliquer l'erreur obtenue si on ne place pas la ligne 1 ?

1 2 3
for nombre in range(1001): chaine = chaine + str(nombre) + " "
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.

⚙ 20° Fournir deux programmes permettant d'obtenir les deux chaînes ci-dessous.

>>> chaine '10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 '
>>> chaine '100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 '

...CORRECTION...

1 2 3
chaine = "" for nombre in range(10, 41, 2): chaine = chaine + str(nombre) + " "
1 2 3
chaine = "" for nombre in range(100, 9, -5): chaine = chaine + str(nombre) + " "

5 - Mode DEBUG de Thonny

REMARQUE

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.

1 2 3
chaine = "" for nombre in range(2, 10, 2): chaine = chaine + str(nombre) + " "

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.

6 - DEBUG avec Pythontutor

Vous pouvez également faire la même chose avec le site Pythontutor bien entendu.

DEBUG 7° Placer ce code sur le site Pythontutor. Il faut

  1. cliquer sur Start visualizing your code now,
  2. placer votre code.
  3. cliquer sur Visualize Execution
  4. avancer instruction par instruction avec Next
1 2 3
chaine = "" for nombre in range(2, 10, 2): chaine = chaine + str(nombre) + " "

Au final, vous arriverez bien entendu au même point qu'avec Thonny, à savoir ceci :

7 - Pour les plus rapides : les étoiles

Conclusion-01° Utiliser le programme ci-dessous pour vérifier qu'il trace bien une étoile. 100 lignes...

Le programme :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
# 1 - Importations import turtle as trt # 2 - CONSTANTES FOND = "black" COULEUR_ETOILE = "yellow" TAILLE_ETOILE = 100 EPAISSEUR_RAYON = 4 # 3 - Programme principal trt.bgcolor(FOND) # On définit un fond coloré noir crayon = trt.Turtle() # On définit un crayon crayon.color(COULEUR_ETOILE) crayon.pensize(EPAISSEUR_RAYON) # Rayon d'angle 0° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(0) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 30° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(30) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 60° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(60) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 90° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(90) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 120° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(120) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 150° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(150) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 180° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(180) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 210° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(210) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 240° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(240) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 270° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(270) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 300° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(300) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance # Rayon d'angle 330° crayon.penup() crayon.goto(0, 0) # on part au point de départ crayon.pendown() crayon.setheading(330) # on s'oriente vers la droite crayon.forward(TAILLE_ETOILE) # on affiche de la bonne distance crayon.hideturtle()

Conclusion-02° Utiliser le programme ci-dessous pour vérifier qu'il trace bien une étoile. Moins de lignes puisqu'on remarque qu'on utilise souvent les mêmes instructions à quelques valeurs près. Autant créer une fonction trait() qui réalise ces instructions lorsqu'on l'appele.

40 lignes, c'est déjà mieux.

Le programme :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
# 1 - Importations import turtle as trt # 2 - CONSTANTES FOND = "black" COULEUR_ETOILE = "yellow" TAILLE_ETOILE = 100 EPAISSEUR_RAYON = 4 # 3 - Déclaration de fonction def trait(feutre, angle, distance, coord): crayon.penup() crayon.goto(coord[0], coord[1]) # on part au point de départ crayon.pendown() crayon.setheading(angle) # on s'oriente vers la droite crayon.forward(distance) # on affiche de la bonne distance # 3 - Programme principal trt.bgcolor(FOND) # On définit un fond coloré noir crayon = trt.Turtle() # On définit un crayon crayon.color(COULEUR_ETOILE) crayon.pensize(EPAISSEUR_RAYON) trait(crayon, 30, TAILLE_ETOILE, (0,0)) # Rayon d'angle 0° trait(crayon, 30, TAILLE_ETOILE, (0,0)) # Rayon d'angle 30° trait(crayon, 60, TAILLE_ETOILE, (0,0)) # Rayon d'angle 60° trait(crayon, 90, TAILLE_ETOILE, (0,0)) # Rayon d'angle 90° trait(crayon, 120, TAILLE_ETOILE, (0,0)) # Rayon d'angle 120° trait(crayon, 150, TAILLE_ETOILE, (0,0)) # Rayon d'angle 150° trait(crayon, 180, TAILLE_ETOILE, (0,0)) # Rayon d'angle 180° trait(crayon, 210, TAILLE_ETOILE, (0,0)) # Rayon d'angle 210° trait(crayon, 240, TAILLE_ETOILE, (0,0)) # Rayon d'angle 240° trait(crayon, 270, TAILLE_ETOILE, (0,0)) # Rayon d'angle 270° trait(crayon, 300, TAILLE_ETOILE, (0,0)) # Rayon d'angle 300° trait(crayon, 330, TAILLE_ETOILE, (0,0)) # Rayon d'angle 330° crayon.hideturtle()

Conclusion-03° On se rend compte que les appels aux fonctions sont presque les mêmes : la seule chose qui change, c'est la valeur de l'angle ! Il est tant de demander à Python de faire la même chose, ou presque.

Nous allons lui demander poliment de faire la même chose pour un angle de 0°, puis d'augmenter de 30° à chaque fois qu'il refait un tour de boucle. Il ne devra par contre par refaire 360° puisque cet angle correspond à l'angle 0° en réalité : nous avons fait un tour complet.

28 29
for angle in range(0, 360, 30): trait(crayon, angle, TAILLE_ETOILE, (0,0)) # angle va avoir plusieurs valeurs

Le programme :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
# 1 - Importations import turtle as trt # 2 - CONSTANTES FOND = "black" COULEUR_ETOILE = "yellow" TAILLE_ETOILE = 100 EPAISSEUR_RAYON = 4 # 3 - Déclaration de fonction def trait(feutre, angle, distance, coord): crayon.penup() crayon.goto(coord[0], coord[1]) # on part au point de départ crayon.pendown() crayon.setheading(angle) # on s'oriente vers la droite crayon.forward(distance) # on affiche de la bonne distance # 3 - Programme principal trt.bgcolor(FOND) # On définit un fond coloré noir crayon = trt.Turtle() # On définit un crayon crayon.color(COULEUR_ETOILE) crayon.pensize(EPAISSEUR_RAYON) for angle in range(0, 360, 30): trait(crayon, angle, TAILLE_ETOILE, (0,0)) # angle va avoir plusieurs valeurs crayon.hideturtle()

Conclusion-04° Les traits pleins, c'est un peu triste. Et si nous faisons un pointillé !

Après tout, c'est juste une succession en boucle de deux actions :

  • J'avance en traçant
  • J'avance sans tracer

Voici un nouveau programme qui fait quelque chose de plus complexe avec 3 lignes de plus.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
# 1 - Importations import turtle as trt # 2 - CONSTANTES FOND = "black" COULEUR_ETOILE = "yellow" TAILLE_ETOILE = 100 EPAISSEUR_RAYON = 4 # 3 - Déclaration de fonction def trait(feutre, angle, distance, coord): crayon.penup() crayon.goto(coord[0], coord[1]) # on part au point de départ crayon.pendown() crayon.setheading(angle) # on s'oriente vers la droite for _ in range(5): crayon.forward(distance//10) # on affiche de la bonne distance crayon. penup() crayon.forward(distance//10) # on affiche de la bonne distance crayon. pendown() # 3 - Programme principal trt.bgcolor(FOND) # On définit un fond coloré noir crayon = trt.Turtle() # On définit un crayon crayon.color(COULEUR_ETOILE) crayon.pensize(EPAISSEUR_RAYON) for angle in range(0, 360, 30): trait(crayon, angle, TAILLE_ETOILE, (0,0)) # angle va avoir plusieurs valeurs crayon.hideturtle()

Conclusion-05° Finalement, nous amerions bien faire une deuxième série de traits, plus fins, moins longs et décalés de quelques degrés pour que cela ressemble à une vrai étoile. Facile, il suffit de rajouter une boucle (3 lignes en plus):

Le programme :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
# 1 - Importations import turtle as trt # 2 - CONSTANTES FOND = "black" COULEUR_ETOILE = "yellow" TAILLE_ETOILE = 100 EPAISSEUR_RAYON = 4 # 3 - Déclaration de fonction def trait(feutre, angle, distance, coord): crayon.penup() crayon.goto(coord[0], coord[1]) # on part au point de départ crayon.pendown() crayon.setheading(angle) # on s'oriente vers la droite for _ in range(5): crayon.forward(distance//10) # on affiche de la bonne distance crayon. penup() crayon.forward(distance//10) # on affiche de la bonne distance crayon. pendown() # 3 - Programme principal trt.bgcolor(FOND) # On définit un fond coloré noir crayon = trt.Turtle() # On définit un crayon crayon.color(COULEUR_ETOILE) crayon.pensize(EPAISSEUR_RAYON) for angle in range(0, 360, 30): trait(crayon, angle, TAILLE_ETOILE, (0,0)) # angle va avoir plusieurs valeurs crayon.pensize(EPAISSEUR_RAYON//3) for angle in range(30, 360+30, 30): trait(crayon, angle+15, TAILLE_ETOILE//5*4, (0,0)) # angle va avoir plusieurs valeurs crayon.hideturtle()

8 - FAQ

Rien pour le moment

Voilà pour les boucles bornées qui permettent donc de faire plusieurs fois la même chose, ou presque.

Reste à voir comment utiliser les boucles sur les types construits.

Activité publiée le 01 11 2020
Dernière modification : 15 12 2024
Auteur : ows. h.