# Solutions du chapitre 3

# Activité 1

Cet exercice est relativement simple. Il suffit de reprendre l'exemple 4 de la page 8 en utilisant une boucle repeat au lieu de faire du copier-coller pour dessiner chaque côté du polygone.

On obtient alors

Pour faire un polygone à 15 côtés de longueur 30, c'est presque le même programme en modifiant juste le nombre de répétitions et le paramètre du forward:

Pour le dernier, c'est le même refrain

# Activité 2

# Partie A

# Partie B

Remarque

Vous pouvez remarquer que le dessin d'une étoile à 360 branches permet en fait de colorier un disque plein. Pour que cela ressemble vraiment à un disque, il faut augmenter un peu l'épaisseur du trait avec setPenColor(2). On peut aussi peindre le disque en rouge avec setPenColor("red") et accélérer le dessin avec hideTurtle():

Vous utiliserez cette technique pour réaliser une animation d'un système solaire à l'exercice 6, page 41, en fin de chapitre.

# Activité 3

On sait que la tortue doit tourner de 144°144° à chaque sommet car elle fait deux tours complets sur elle-même pour dessiner toute l'étoile. Pour vous en convaincre, il vous suffit de dessiner l'étoile à la main. Elle doit donc tourner à chaque sommet de 2360°5=720°5=144°\frac{2 \cdot 360°}{5} = \frac{720°}{5} = 144°.

Pour que l'étoile soit bien orientée, il suffit de commencer par tourner de 90°90° à droite pour partir à l'horizontale.

Remarque

Notez que la commande right(90) ne se trouve pas dans la commande etoile_5_branches() car elle ne fait pas partie du dessin de l'étoile à proprement parler. Elle a pour unique vocation d'orienter la tortue correctement avant de commencer le dessin.

# Activité 4

Uniquement le corrigé du premier est donné. Vous remarquerez que l'on définit deux commandes différentes, marche() et escalier() pour bien décomposer le problème et rendre le programme plus clair.

Remarque

La commande setPos() est facultative et ne sert qu'à positionner la tortue correctement avant d'effectuer le dessin pour que l'escalier soit visible en entier dans la fenêtre de dessin.

# Activité 5

Le programme à modifier est le suivant:

Il ne suffit pas de diminuer le nombre de répétitions de la boucle. Il faut encore que le programme dessine toujours le même cercle. Pour cela, il faut respecter les conditions suivantes:

  • Le périmètre doit être le même

    nombredereˊpeˊtitionslongueurdesco^teˊs=3602=720=3620\mathrm{nombre\, de\, répétitions\,\cdot\,longueur\, des\, côtés} = 360 \cdot 2 = 720 = 36 \cdot 20

  • L'angle total doit être le même

    nombredereˊpeˊtitionsanglederotation=3601°=360°=3610°\mathrm{nombre\, de\, répétitions\,\cdot\,angle\, de\, rotation} = 360 \cdot 1° = 360° = 36 \cdot 10°

On obtient donc le programme suivant :

Remarque : performances

Vous remarquez que le programme est ainsi bien plus performant car il fait dix fois moins d'opérations. Il n'y a cependant presque aucune différence perceptible à l'écran.

# Activité 6

# Activité 7

Il suffit de modifier le nombre de répétitions et répéter 180 fois au lieu de 360.

# Activité 8

Pour cet exercice, reprenons le code de l'activité 5 qui est plus performant que celui de l'exemple 5. Il suffit de diviser par 4 le nombre de répétitions en ne changeant pas le reste.

Remarque

Au chapitre 4, nous verrons comment passer des paramètres aux fonctions pour éviter de devoir écrire 3 fois la même commande pour faire presque la même chose, ce qui simplifie beaucoup le programme.

# Activité 9

# Activité 10

On voit par contre que la fleur n'est pas vraiment orientée comme sur la consigne, avec le premier pétale bien à la verticale. Pour remédier à cela, il suffit de tourner le tortue un peu vers la gauche avant de commencer le dessin.

# Activité 11

Conseil d'apprentissage

Cet exercice peut se révéler plus périlleux qu'il n'y paraît. Le but n'est simplement de trouver une solution bancale en tâtonnant pendant des heures mais d'élaborer une stratégie réfléchie. Ce qui est attendu de vous à ce stade, c'est que vous ayez le réflexe de prendre une feuille de papier et un crayon et que vous élaboriez vos programmes et votre stratégie de manière réfléchie.

# Partie A

Ce problème n'est pas très difficile à décomposer intelligemment. Il s'agit clairement de définir d'abord une commande qui dessine un demi-cercle

On remarque cependant que cette commande demi_cercle() est assez lente. Pour l'optimiser, il suffit de dessiner un demi-polygone avec moins de côtés :

qui ressemble encore tout autant à un cercle. Il suffit ensuite de répéter cette commande 8 fois pour dessiner la figure tout en veillant à replacer la tortue dans le bon sens pour qu'elle puisse dessiner le prochain motif (demi-cercle).

Attention

Les plus attentifs auront remarqué que la tortue ne dessine pas vraiment ce qui est demandé dans la consigne. On le voit mieux si l'on diminue encore le nombre et la taille des côtés.

La raison pour laquelle la tortue monte est assez subtile! Pour bien comprendre ce qui se passe, il faut encore diminuer le nombre de segments utilisés pour dessiner le demi-cercle et agrandir leur longueur.

Pour que le demi-cercle se dessine correctement, il faut en fait modifier la manière de dessiner le demi-cercle. Voyez-vous comment le faire?

Il faut essentiellement répéter le motif

forward(20)
right(30)
forward(20)
1
2
3

au lieu de

forward(40)
right(30)
1
2

On obtient donc le code suivant pour dessiner le demi-cercle de manière symétrique :

En augmentant de nouveau le nombre de côtés, on obtient la forme désirée :

# Partie B

Il y a plusieurs manières intelligentes de dessiner cette figure. Il s'agit dans tous les cas d'identifier les motifs qui se répètent.

Le premier motif consiste à répéter trois carrés :

Remarque

  • Pour raccourcir le programme, on se permet de dessiner le carré de manière un peu spéciale, en répétant 6 fois au lieu de 4. Ceci permet de placer la tortue directement au sommet supérieur droit du carré.

  • La commande setPos(x, y) permet de placer la tortue au pixel de coordonnées (x,y)(x, y) dans la fenêtre de dessin. Elle permet d'éviter de devoir écrire plein de commandes avec penUp(), penDown() etc.

  • On voit que la commande carre() est une sortie de "sous-motif" de la commande motif(). La logique pour répéter un motif est toujours la même :

    def dessine_figure():
        repeat NOMBRE_DE_REPETITIONS:
            dessine_motif()
            repositionne_tortue()
    
    1
    2
    3
    4

La même logique s'applique pour dessiner la figure en entier. Il suffit de faire

def figure():
    repeat 2:
        # répétition du motif
        motif()
        # repositionnement de la tortue pour
        # dessiner le motif suivant
        right(90)
        back(50)
1
2
3
4
5
6
7
8

Cela donne au final le programme suivant :

# Variante

Il est également possible de dessiner le motif en escalier de la manière suivante:

En répétant deux fois cet escalier avec une rotation de 180°180° entre les deux, on obtient à nouveau le motif présenté dans la première version:

Ce programme est même plus naturel que celui qui utilise le carré comme motif de base pour réaliser la commande motif().

# Partie C

Il y a beaucoup de motifs que l'on peut répéter pour obtenir le dessin souhaité. Voici les plus évidents:

# Variante 1

La première variante consiste à répéter une rangée de trois carrés:

Image

que l'on peut dessiner avec la commande

def motif():
    repeat 3:
        carre()
        penUp()
        right(90)
        forward(2 * 50)
        left(90)
        penDown()
1
2
3
4
5
6
7
8

La figure entière s'obtient en répétant ce motif deux fois et en dessinant encore un carré supplémentaire. Il faut bien évidemment repositionner la tortue avec la commande deplacement() entre

# Variante 2

Une deuxième variante consiste à utiliser le motif suivant composé de deux carrés "décalés":

Image

que se dessine avec la commande

def motif():
    repeat 2:
        # sous-motif
        carre()
        # repositionnement pour dessiner
        # le motif suivant
        penUp()
        right(180)
        forward(50)
        penDown()
1
2
3
4
5
6
7
8
9
10

Voici un exemple de programme qui dessine la figure en entier:

Remarque générale

Vous pouvez constater que les programmes présentés sont bien structurés avec différentes commandes. Pour les parties B et C, on a tout d'abord un sous-motif carre() qui est répété un certain nombre de fois pour former un motif motif(), également répété un certain nombre de fois pour réaliser la figure dans son entier avec la commande figure().

Cette manière de structurer un programme en programmes et sous-programmes est l'essence même de la programmation modulaire et constitue une compétence fondamentale en programmation. Cela permet d'écrire des programmes plus courts, mieux structurés, plus facilement compréhensibles et comportant moins d'erreurs.

# Activité 12 (facultatif)

Aucun corrigé n'est disponible pour cette activité peu importante.

# Activité 13

Exercices 13-16

Les exercices 13 à 16 sont facultatifs dans le cadre de ce chapitre. Ils pourront être réalisés de manière bien plus efficace en définissant des commandes avec paramètres qui permettront de réaliser une seule commande permettant de colorier des rectangles de n'importe quelle dimension.

Nous dessinerons l'échiquier de l'exercice 16 de cette manière bien plus appropriée au chapitre 4. Pour le moment, vous pouvez donc sans problème ignorer les activités 13 à 16 et tout ce qui concerne le coloriage de carrés et de rectangles.

La raison pour laquelle la commande carre_plein() est

def carre_plein():
    repeat 99:
        ligne_epaisse()
1
2
3

et répète ainsi 99 fois ligne_epaisse() est que si l'on ne répète ligne_epaisse() qu'une seule fois, on colorie déjà deux colonnes de pixels comme le montre le programme suivant :

À chaque fois que la commande ligne_epaisse() est exécutée, une des deux colonnes de pixels peinte recouvre en fait une autre colonne de pixels déjà peinte précédemment. Donc si l'on appelle ligne_epaisse() deux fois de suite, il y a trois colonne de pixels peintes. De ce fait, pour colorier NN colonnes, il faut répéter N1N-1 fois la commande ligne_epaisse().

Discussion (facultatif : optimisation)

On pourrait évidemment proposer plusieurs optimisations pour réaliser le dessin de manière plus efficace.

Modifier la commande ligne_epaisse() pour ne pas repasser à chaque fois sur chaque colonne de pixels. Pour cela, il suffirait de modifier la commande de la manière suivante:

Le problème avec cette commande est qu'il n'est plus possible de colorier un nombre impair de colonnes. En revanche, avec cette variante de la commande ligne_epaisse(), il suffit de répéter N/2N/2 fois la boucle repeat. Si l'on veut colorier un nombre impair de colonnes, il suffit ensuite peindre uniquement la dernière.

# Activité 14

La solution est donnée ici sans explication car cet exercice sera de toute manière réalisé de manière plus efficace en utilisant les paramètres au chapitre. Il faut modifier à la fois la commande ligne_epaisse() et le nombre de répétitions

# Activité 15 (facultatif)

La solution n'est pas donnée car cet exercice est très similaire au précédent.

# Activité 16 (facultatif)

Conseil

L'exercice 16 est un projet de plus grande envergure qui vise à assembler tous les exercices précédents. Il faut procéder par étapes et identifier les différents motifs à répéter qui constituent un échiquier.

Le problème est facultatif car il sera traité de manière plus détaillée et plus efficace aux pages 53 à 55 du chapitre 4 sur les commandes avec paramètres.

# Activité 17, page 39 (facultatif)

Conseil

Le problème 17 est facultatif. Nous allons plutôt entraîner les animations dans les projets 6 et 7 à la page 41 du livre.

# Questions de compréhension, page 40

  1. Le mot-clé repeat permet de répéter des bouts de programmes sans avoir à faire du copier-coller. Cela permet de respecter le principe DRY de l'informatique.

    DRY

    En programmation, principe DRY = Don't Repeat Yoursel est fondamental. Il s'agit en quelque sorte du "premier commandement" de la programmation. Le code ci-dessous pour dessiner un hexagone n'est par exemple pas DRY car il s'obtient par copier-coller.

    forward(50)
    right(60)
    forward(50)
    right(60)
    forward(50)
    right(60)
    forward(50)
    right(60)
    forward(50)
    right(60)
    forward(50)
    right(60)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    Une manière DRY d'écrire le même code avec la boucle repeat est la suivante:

    repeat 6:
        forward(50)
        right(60)
    
    1
    2
    3

    L'utilisation des boucles repeat économise donc beaucoup de temps dans les situations suivantes:

    • Dessin de formes qui présentent des régularités (motifs récurrents)
    • Dessin de polygones réguliers
    • De manière générale, pour effectuer des actions répétitives
    • Bien d'autres situations que nous traiterons plus tard, notamment la lecture de données depuis le capteur d'un robot ou d'une carte de développement Oxocard ou la gestion des événements (clavier, souris et autres).

    Remarque

    La boucle repeat permet uniquement de répéter un bout de code qui est toujours identique. Il exsite en Python encore deux autres types de boucles permettant de répéter des bouts de codes et qui s'utilisent dans des situations différents : la boucle for qui permet d'exécuter un programme pour chaque élément d'une liste et la boucle while qui permet de répéter un programme tant qu'une condition reste vraie.

  2. La syntaxe de la boucle repeat est la suivante:

    repeat NOMBRE_DE_REPETITIONS:
        corps_de_la_boucle()
    
    1
    2
  3. Le corps de la boucle est décalé par rapport au repeat et indique ce qui doit être répété. Le corps de la boucle doit être décalé par rapport à l'en-tête de la boucle.

  4. Pour dessiner des animations, il faut dessiner et effacer successivement et un grand nombre de fois une forme qui se déplace légèrement d'une fois à l'autre. Sans les boucles, il faudrait recopier des centaines de lignes de code qui peuvent simplement être répétées avec la boucle repeat. `

  5. Oui, il est tout-à-fait possible d'utiliser une boucle repeat dans le corps d'une autre boucle repeat. On parle dans ce cas de boucle imbriquée. L'exemple 7 à la page 36 montre un bon exemple de boucle imbriquée.

  6. Bien qu'il soit possible d'imbriquer les boucles les unes dans les autres, il vaut généralement la peine d'inclure la boucle imbriquée dans une commande qui lui est propre. Cette commande pourra ensuite être utilisée dans le corps de la boucle repeat principale. Cela permet de rendre le programme plus compréhenisble.

    L'exemple 8 fait la même chose que l'exemple 7 mais il est bien plus compréhensible car la boucle interne est insérée dans la commande quart_cercle()

  7. Non. Mathématiquement, on peut définir un cercle comme la limite lorsque NN \to \infty (Prononcer "lorsque NN tend vers l'infini") d'un polygone régulier à NN côté. Dit plus simplement pour le commun des mortels, un cercle est un polygone régulier possédant "une infinité de côtés". Le problème est qu'il est absolument impossible de stocker une infinité de choses dans un ordinateur ni d'ailleurs de lui faire faire une infinité de choses. L'ordinateur peut donc au mieux dessiner de manière approximative un cercle par un polygone régulier à NN côtés.

  8. Plus le nombre de côtés du polygone régulier est grand, plus il ressemblera à un cercle mais plus cela demandera de travail à l'ordinateur. Puisque l'oeil humain a des capacités finies également et que l'écran de l'ordinateur ne possède de toute manière qu'un nombre limité de pixels, on pourra généralement se contenter de dessiner un cercle par un polygone régulier de 36 côtés. Cela dépend toutefois du rayon du cercle. Plus le rayon du cercle est grand, plus le nombre de côtés nécessaire sera élevé pour que les côtés ne puissent pas être distingués à l'oeil.

# Exercice 1, page 41

Pour répondre à la question sans ordinateur il faut se munir d'une feuille de papier et d'un crayon en faisant attention aux éléments suivants:

  • Où se trouve la tortue avant et après l'exécution d'un bout de code (par exemple avant et après chaque répétition de la boucle repeat 4)

  • Il faut aussi faire bien attention à l'orientation de la tortue avant et après un dessin.

Commande setPos(x,y)

Comme l'indique la documentation de WebTigerJython, la commande setPos(x, y) permet de positionner la tortue à une coordonnée absolue de la fenêtre de dessin. Elle est utilisée ici pour que le dessin tienne dans la partie visible de la fenêtre mais elle ne change rien au dessin.

# Exercice 2, page 41

La conception modulaire consiste à décomposer le problème en sous-problèmes plus simples qu'il est ensuite facile d'assembler pour résoudre le problème dans son ensemble. Dans notre cas, la boucle interne repeat 4: gagnerait à se trouver dans une commande à part qui décrit ce que cette boucle fait. Elle dessine un carré. Il vaut donc mieux la placer au sein d'une commande carre()

def carre30():
    repeat 4:
        forward(30)
        right(90)
1
2
3
4

Cela donne au final le programme suivant bien plus compréhensible:

Note

La commande setPos(x, y) utilisée à la ligne 13 ne sert qu'à centrer l'image dans le fenêtre de dessin pour que tout le dessin soit visible lorsque la fenêtre est réduite.

# Exercice 3, page 41

L'exercice 3 n'est pas d'une importance capitale dans ce chapitre. Il mêle cependant deux manière de répéter du texte:

  1. Utiliser l'instruction repeat
  2. Utiliser l'opérateur * qui "multiplie du texte par un nombre" en répétant le texte en question.

Fondamentalement, le programme est équivalent à

print 5 * "pomme "
print 5 * "pomme "
print 5 * "pomme "
print 2 * "pomme ", "ver ", 2 * "pomme "
print 5 * "pomme "
print 5 * "pomme "
1
2
3
4
5
6

Remarque

Pour bien effectuer cet exercice, il faut procéder petit-à-petit pour chacune des commandes.

La commande print 5 * "pomme " donne par exemple le résultat

pomme pomme pomme pomme pomme
1

et la commande print 2 * "pomme ", "ver ", 2 * "pomme " est équivalente à la commade

print "pomme pomme ", "ver ", "pomme pomme "
1

qui donne la sortie

pomme pomme ver pomme pomme

Le programme dans son ensemble

donne donc la sortie

pomme pomme pomme pomme pomme
pomme pomme pomme pomme pomme
pomme pomme pomme pomme pomme
pomme pomme  ver  pomme pomme
pomme pomme pomme pomme pomme
pomme pomme pomme pomme pomme
1
2
3
4
5
6

# Exercice 4, page 41

Le motif de base à répéter dans cet exercice est assez évident. Il s'agit d'une "branche" du flocon de neige. Pour que l'on puisse facilement dessiner tout le flocon de neige en répétant la branche et en tournant de 60°60°, il faut que la tortue débute et termine la branche au centre du flocon et dans la même orientation.

Image

Remarque

Remarquez que la tortue débute et termine le dessin au même endroit, au centre du flocon, à savoir en bas de la branche, en regardant dans la même direction. Cela permet ensuite de simplement répéter plusieurs fois la commande branche() depuis le centre du flocon en tournant simplement de 60°60° entre chaque branche.

def branche():
    forward(40)
    left(45)
    repeat 3:
        forward(40)
        back(40)
        right(45)
    left(90)
    back(40)
1
2
3
4
5
6
7
8
9

Voici le programme en entier.

# Exercice 5, page 41

Comme pour l'activité 11, page 37, il faut utiliser le motif suivant pour dessiner un demi-cercle si l'on veut qu'il soit symétrique:

repeat NOMBRE_DE_SEGMENTS:
    forward(LONGUEUR_SEGMENT / 2)
    right(180 / NOMBRE_DE_SEGMENTS)
    forward(LONGUEUR_SEGMENT / 2)
1
2
3
4

et non le motif

repeat NOMBRE_DE_SEGMENTS:
    forward(LONGUEUR_SEGMENT)
    right(180 / NOMBRE_DE_SEGMENTS)
1
2
3

qui ne donne pas un beau demi-cercle. Le programme complet est donc

Remarque

Nous verrons dans le prochain chapitre comment écrire un tel programme de manière plus élégante et succincte en n'écrivant qu'une seule commande arc_cercle(angle, perimetre) qui permet de dessiner tous les arcs de cercles qui apparaissent dans ce problème.

# Exercice 6, page 41 (Projet)

Information

La solution du projet n'est pas donnée sur cette page. Il est important que vous fassiez votre maximum pour résoudre ce problème par vous-mêmes. Si vous avez l'occasion de travailler ce problème en classe, mettez-vous par deux pour le réaliser.

Une solution détaillée sera livrée ultérieurement dans la partie "Travaux pratiques et projets" du site.

# Exercice 7, page 41 (Projet)

Information

La solution du projet n'est pas donnée sur cette page. Il est important que vous fassiez votre maximum pour résoudre ce problème par vous-mêmes. Si vous avez l'occasion de travailler ce problème en classe, mettez-vous par deux pour le réaliser.

Une solution détaillée sera livrée ultérieurement dans la partie "Travaux pratiques et projets" du site.

Dernière modification: 3/17/2020, 12:14:11 PM