SNT Python 2

Identification

Infoforall

2 - Programme


Nous allons continuer à parler de ça :

Aujourd'hui, nous parlerons de programme, de séquentialité dans le but de réaliser ceci :

Final

Documents de cours : pdf ou odt.

Ce TP est destiné à vous "montrer" la notion de séquentialité. C'est une notion simple et évidente, ... une fois qu'on a a compris comment l'interpréteur fonctionne lorsqu'il est confronté à plusieurs lignes d'instructions.

1 - Programme

Thonny
Ecran de Thonny

Nous allons utiliser Thonny, un environnement de développement gratuit, léger, efficace et multiplateforme créé par l'université d'Estonie.

Vous pouvez le télécharger sur la page d'accueil du projet : https://thonny.org/

La dernière fois, nous avons utilisé la zone la bas (la console), aujourd'hui nous allons utiliser la zone du haut (la zone de programmation).

1 - Séquentialité

Séquentialité

L'interpréteur Python exécute les lignes une par une.

Tant qu'il n'a pas fini une ligne, il ne passera pas à la suivante.

Une fois qu'une ligne est exécutée, on ne peut pas revenir en arrière : elle est réalisée.

Pour comprendre un programme Python, il est donc vital de ne pas "sauter" d'instructions mais de comprendre TOUTES les lignes DANS L’ORDRE d’exécution.

Programme

On écrit l'intégralité des lignes mais l'interpréteur ne va pas les exécuter immédiatement.

Pour les exécuter, il faut

  1. L'enregistrer
  2. Le lancer en utilisant la flêche verte.

Vous pouvez alors exécuter votre programme autant de fois que vous le désirez.

Vous pouvez modifier le programme mais si vous voulez voir les modifications, il faut le relancer.

2 - Premier programme avec turtle

Cette partie est destinée à être faite ensemble en classe.

A° Réaliser les actions suivantes :

  1. Placer le programme ci-dessous dans la zone de programmation.
  2. Sauvegarder le programme en le plaçant dans un répertoire SNTPYTHON sous le nom axes.py
  3. Important : n'utilisez jamais un nom correspondant à l'un des modules importés, sinon vous ne pourrez plus importer le module turtle, math ou autre. Donc, pas de math.py, turtle.py...

  4. Lancer le programme (à l'aide de la flèche verte dans Thonny, ou du bouton exécuter dans Basthon).
  5. Visualiser le résultat dans la nouvelle fenêtre qui a dû apparaître (Thonny : voir la barre des tâches, Basthon : voir le bouton Image qui est devenu jaune, en bas à droite).
1 2 3 4 5 6 7 8 9 10
from turtle import * write("Origine") goto(0, 100) write("y > 0")

Questions

A votre avis :

  1. Sur quelle ligne demande-t-on d'afficher "Origine" ? Quelle fonction utilise-t-on ?
  2. Sur quelle ligne demande-t-on d'afficher "y > 0" ? Quelle fonction utilise-t-on ?
  3. Pourquoi les deux messages ne sont-ils pas au même endroit ?

...CORRECTION...

  1. Ligne 2, avec write()
  2. Ligne 4, avec write()
  3. En ligne 3, on modifie la localisation du crayon et les affichages qui auront lieu sur les lignes 4+ utiliseront donc ces coordonnées.

B° Modifier le programme en supprimant les lignes précédentes pour les remplacer par celles-ci. Relancer le programme pour visualiser le résultat.

1 2 3 4 5 6 7 8 9 10
from turtle import * write("Origine", font=('Arial', 28, 'normal')) goto(0, 100) write("y > 0", font=('Arial', 28, 'normal'))

Question

Pourquoi l'affichage est-il plus grand cette fois ?

...CORRECTION...

On fournit à la fonction write() des informations supplémentaires sur la police d'écriture (font) qui passe en taille 28.

C° Analyser ce code (sans le lancer donc) où on rajoute quelques lignes par rapport au programme précédent, puis répondre aux questions.

Questions

  1. Sur quelle ligne demande-t-on l'affichage de "y < 0" ? A quelles coordonnées ?
  2. "x > 0" va-t-il être affiché ?
  3. Lancer le code pour vérifier si vous aviez trouvé la bonne réponse.
1 2 3 4 5 6 7 8 9 10
from turtle import * write("Origine", font=('Arial', 28, 'normal')) goto(0, 100) write("y > 0", font=('Arial', 28, 'normal')) goto(0, -100) write("y < 0", font=('Arial', 28, 'normal')) goto(300, 0) write("x > 0", font=('Arial', 28, 'normal')) goto(-300, 0) write("x < 0", font=('Arial', 28, 'normal'))

...CORRECTION...

  1. L'affichage de "y < 0" est demandé en ligne 6. On doit donc regarder la dernière position du crayon avant cette ligne 6. On la trouve en ligne 5, en (0, -100).
  2. L'affichage de "x > 0" est demandé en ligne 8. On doit donc regarder la dernière position du crayon avant cette ligne 8. On la trouve en ligne 7, en (300, 0).

Voici le résultat attendu du programme précédent :

Système d'axes dans Turtle
Les axes dans Turtle

On voit ainsi que l'interpréteur exécute les instructions UNE par UNE en commençant par celle de la ligne 1. Il ne lance pas le programme d'un bloc en tentant d'en deviner le sens, comme un humain pourrait le faire.

Pour programmer, il faut donc avoir la capacité de se mettre "à la place" de l'interpréteur pour comprendre comment il va réagir. Pas d'intuition humaine, juste de la logique et de la syntaxe pure et dure.

Quatre remarques importantes pour éviter de perdre du temps : savoir identifier une erreur de programmation.

D° Voici un programme qui correspond au précédent mais avec un ordre aléatoire dans les lignes fournies.

Questions

  • Provoque-t-il le même affichage ?
  • Un développeur peut-il concevoir son programme sans se demander comment l'interpréteur va réagir ?
1 2 3 4 5 6 7 8 9 10
from turtle import * write("Origine", font=('Arial', 28, 'normal')) write("y > 0", font=('Arial', 28, 'normal')) write("y < 0", font=('Arial', 28, 'normal')) goto(0, -100) goto(300, 0) write("x > 0", font=('Arial', 28, 'normal')) write("x < 0", font=('Arial', 28, 'normal')) goto(-300, 0) goto(0, 100)

...CORRECTION...

Puisque l'interpréteur exécute les lignes une par une, l'ordre a bien entendu une grande importance.

Importance de l'ordre de transmission
Les axes dans Turtle

E° Voici un programme qui correspond au précédent mais avec une importation plus tardive.

Questions

  • Que signifie le message d'erreur ?
  • A quoi est-ce dû ?
1 2 3 4 5 6 7 8 9 10
write("Origine", font=('Arial', 28, 'normal')) write("y > 0", font=('Arial', 28, 'normal')) write("y < 0", font=('Arial', 28, 'normal')) from turtle import * goto(0, -100) goto(300, 0) write("x > 0", font=('Arial', 28, 'normal')) write("x < 0", font=('Arial', 28, 'normal')) goto(-300, 0) goto(0, 100)
Traceback (most recent call last): File "/home/rv/axes.py", line 1, in <module>: write("Origine", font=('Arial', 28, 'normal')) NameError: name 'write' is not defined

...CORRECTION...

L'interpréteur signale qu'il y a un problème en ligne 1 : in ne connait pas le nom write.

C'est normal puisque ce nom de fonction est inclu dans le module turtle qui n'est importé qu'à partir de la ligne 4.

F° Ce programme provoque une erreur. L'interpréteur ne comprend pas ce qu'on lui demande.

  1. Sur quelle ligne se situe le problème ?
  2. Quel est le problème ?
1 2 3 4 5 6 7 8 9 10
from turtle import * write("Origine", font=('Arial', 28, 'normal')) goto(0, 100) write("y > 0", font=('Arial', 28, 'normal')) goto(0, -100) write("y < 0", font=('Arial', 28, 'normal')) goto(300, 0) write(x > 0, font=('Arial', 28, 'normal')) goto(-300, 0) write("x < 0", font=('Arial', 28, 'normal'))
Traceback (most recent call last): File "/home/rv/axes.py", line 8, in <module>: write(x > 0, font=('Arial', 28, 'normal')) NameError: name 'x' is not defined

...CORRECTION...

Le problème vient du fait qu'on doit transmettre un string et qu'on a "oublié" de placer les guillemets autour du texte à afficher.

Remarquez bien qu'il a exécuté le programme sur les lignes 1 à 7. Il stoppe à la 8.

G° Ce programme provoque une erreur. L'interpréteur ne comprend pas ce qu'on lui demande.

  1. Sur quelle ligne se situe le problème ?
  2. Quel est le problème ?
1 2 3 4 5 6 7 8 9 10
from turtle import * write("Origine", font=('Arial', 28, 'normal')) goto(0, 100} write("y > 0", font=('Arial', 28, 'normal')) goto(0, -100) write("y < 0", font=('Arial', 28, 'normal')) goto(300, 0) write("x > 0", font=('Arial', 28, 'normal')) goto(-300, 0) write("x < 0", font=('Arial', 28, 'normal'))
Traceback (most recent call last): File "/home/rv/axes.py", line 3, in <module>: goto(0, 100} ^ SyntaxError: closing parenthesis '}' does not match opening parenthesis '('

...CORRECTION...

Le problème vient du fait qu'on veut fermer les informations transmises à la fonction avec un accolade. Or, on doit utiliser une parenthèse. L'interpréteur Python signale donc qu'il ne comprend rien à ce qu'on désire. Par contre, il a exécuté le programme sur les lignes 1 et 2.

Bilan de ce que nous venons de voir sur le module turtle.

2.1 - Turtle : afficher du texte avec write()

Ouverture d'un écran Turtle

Pour importer les fonctions du module Turtle, il suffit de taper ceci :

>>> from turtle import *
Ecriture avec write()

On peut écrire à l'endroit où se trouve la tortue en tapant write("bonjour").

Le texte à afficher doit être transmis sous forme de string.

>>> write("Bonjour !")

Mais on peut faire mieux : on peut écrire avec une taille de police plus grande par exemple.

>>> write("Bonjour !", font=('Arial', 28, 'normal'))
2.2 - Turtle : déplacement absolu avec goto()

Système d'axes choisi pour Turtle

Le module utilise le système cartésien habituel.

  • Le point (0,0) est au centre de l'écran.
  • L'axe Ox est l'axe des abscisses, vers la droite.
  • L'axe Oy est l'axe des ordonnées, vers le haut.
Système d'axes dans Turtle
Les axes dans Turtle
Déplacement avec goto()

On peut déplacer le curseur à l'écran et utilisant goto(x,y).

>>> goto(0, 100)

En tapant ceci, on part en (x=0, y=100).

3 - Des points... et des couleurs

3.1 - Turtle : placer des points avec dot()

Créer un point avec dot()

On peut dessiner un point de taille variable en tapant ceci :

>>> dot(100) >>> dot(200)

La valeur transmise correspond au diamètre du point en pixels.

La position courante du crayon correspond au centre du point.

01° Que faut-il taper pour afficher un point de 200 pixels de diamètre, centré sur le point (x=100, y=50) ?

Vérifiez votre exécution en comparant avec la solution fournie.

Pensez à appeler si vous bloquez.

...CORRECTION...

1 2 3 4
from turtle import * goto(100, 50) dot(200)
3.2 - Turtle : changer de couleur avec color()

Couleurs RGB

On peut demander des couleurs prédéfinies en utilisant leurs noms en anglais (red", "yellow"...) mais parfois on veut un réglage plus fin. Comment faire ?

Il suffit de fournir un string commençant par # (ALT-GR et 3) suivi par la valeur de rouge/red (R), de vert/green (G) et de bleu/blue (B).

Aucune intensité se dit 00.

Intensité maximale (à "fond") se note FF.

Quelques exemples :

  • #000000" code le noir.
  • #FF0000" code le rouge.
  • #0000FF" code le vert.
  • #FFFF00" code le jaune.
  • #999999" code du gris.
  • #FFFFFF" code du blanc.
Modifier la couleur avec color()

Voici un exemple d'affichage et le code correspondant :

points et couleurs
>>> color("red") >>> dot(200) >>> color("#FF00FF") >>> dot(100)

On choisit d'abord la couleur rouge et on trace un point de 200 pixels.

On choisit ensuite la couleur magenta et on trace un point plus petit.

Valeur transmise

Comme en HTML, on peut transmettre

  • Soit une couleur prédéfinie en anglais, attention à bien transmettre un string (blue", pas juste blue)
  • Soit un string contenant une couleur RGB précédée d'un # (exemple FFFF00" pour du jaune : rouge à fond, vert à fond, pas de bleu)

02° Que faut-il taper pour afficher un point de couleur RGB AA, 99, 00 de 300 pixels de diamètre, centré sur le point (x=100, y=50) ?

Vérifiez votre exécution en comparant avec la solution fournie.

Pensez à appeler si vous bloquez.

...CORRECTION...

1 2 3 4 5
from turtle import * goto(100, 50) color("#AA9900") dot(300)
Les points

03° Utiliser maintenant ce programme qui vous permettra d'obtenir le début de l'image voulue :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
from turtle import * bgcolor("black") goto(-100, -50) color("#FF0000") dot(50) goto(-50, 0) color("#FFFF00") dot(25) goto(0, 50) color("#00FF00") dot(50)

Voilà le résulat que vous devriez avoir :

points et couleurs 2

Questions

  1. Comment a-t-on demandé à obtenir un fond noir ?
  2. De combien de varie x entre chaque tracé de points ?
  3. De combien de varie y entre chaque tracé de points ?

...CORRECTION...

Le fond est obtenu en utilisant la fonction bgcolor(), le bg voulant bien entendu signifié background.

3
bgcolor("black")

Pour x et y, on peut constater qu'on les augmente l'un et l'autre de 50 à chaque fois.

  • x passe de -100 à -50 puis 0.
  • y passe de -50 à 0 puis 50.

✌ 04° Compléter maintenant le programme pour qu'il affiche ceci (texte y compris) :

Final

Reste les traits résiduels, pas terrible.

Voyons comment gérer cela en demandant à l'interpréteur de ne pas nécessairement tracer un trait lorsqu'il déplace le crayon.

4 - Lever et poser le crayon

4 - Lever et abaisser le stylo avec penup() et pendown()

Lever le stylo avec penup()

Lorsqu'on veut déplacer le crayon sans avoir le trace du stylo, il faut "lever" le stylo avec la fonction penup(), sans argument.

1 2 3 4 5 6 7 8 9 10 11
from turtle import * goto(0, 0) color("#0000AA") dot(50) # on dessine le point bleu en (0, 0) goto(100, 0) # vers (100, 0) pointe baissée donc trait penup() # on baisse la pointe à partir de cette ligne goto(200,0) # et ce déplacement ne provoque donc pas de trait
penup

Plus de trait sur les lignes qui suivront la ligne 9.

Abaisser le stylo avec pendown()

Pour réactiver la fonction traçage, il suffit de placer pendown(). Sur les lignes qui suivront, les traits vont réapparaitre lors des déplacements.

A titre d'exemple, voici comment faire des pointillés.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
from turtle import * goto(50, 0) penup() goto(100, 0) pendown() goto(150, 0) penup() goto(200, 0) pendown() goto(200, 0)
pendown

On voit donc qu'on trace des traits lignes 3, 9, 15 mais pas sur les lignes 6 et 12.

✌ 05° Compléter maintenant le programme pour qu'il affiche ceci (c'est à dire sans trait entre les points) :

Final sans trait

5 - Complément

5.1 - Turtle : déplacement relatif avec forward(), left(), right()

Orientation de la tortue

Si vous regardez l'écran de turtle, vous pourrez constater qu'on y voit une sorte de flèche : elle indique la direction vers laquelle pointe la tortue.

Initialement, la tortue pointe vers la droite (angle 0°).

depart
Avancer avec forward()

Cette fonction permet de faire avancer la tortue dans la direction qu'elle regarde en partant de sa position actuelle.

On doit lui transmettre la distance en pixels.

1 2 3 4 5 6
from turtle import * dot(15) forward(50) # veut dire d’avancer de 50 pixels. dot(15) forward(100) # veut dire d’avancer de 100 pixels.
forward
Tourner avec left()

Cette fonction permet de faire tourner la tortue sur place en fournissant un angle en degrés. Elle tourne sur elle-même vers la gauche, en sens anti-horaire donc.

1 2 3 4 5 6 7
from turtle import * dot(15) forward(50) # veut dire d’avancer de 50 pixels. dot(15) left(90) # rotation à angle droit forward(100) # veut dire d’avancer de 100 pixels.
left
Tourner avec right()

Cette fonction permet de faire tourner la tortue sur place en fournissant un angle en degrés. Elle tourne sur elle-même vers la droite, en sens horaire donc.

1 2 3 4 5 6 7
from turtle import * dot(15) forward(50) # veut dire d’avancer de 50 pixels. dot(15) right(90) # rotation à angle droit forward(100) # veut dire d’avancer de 100 pixels.
right
5.2 - Turtle : taille du crayon avec pensize()

Cette fonction permet de faire modifier la taille du trait OU de récupérer la taille du trait.

Modifier la taille du crayon
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
from turtle import * pensize(32) forward(50) pensize(16) forward(50) pensize(8) forward(50) pensize(4) forward(50) pensize(2) forward(50)
pensize
Récupérer la taille du crayon

Si on envoie aucun argument à la fonction, elle ne modifie pas la taille mais renvoie la valeur actuelle.

On peut ainsi l'utiliser pour modifier la taille du trait. Exemple avec un appel qui sert à multiplier la taille par deux à chaque fois.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
from turtle import * pensize(2) forward(50) pensize( pensize()*2 ) forward(50) pensize( pensize()*2 ) forward(50) pensize( pensize()*2 ) forward(50) pensize( pensize()*2 ) forward(50)
pensize
5.3 - Turtle : tracer un arc de cercle avec circle()

Tracer un cercle complet

La fonction circle() trace un cercle dont on doit fournir le rayon. La position actuelle correspond au point de départ sur le périmètre du cercle.

1 2 3 4
from turtle import * circle(100) circle(50)
circle
Tracer un arc de cercle

On peut envoyer deux arguments à la fonction circle() : le premier est le rayon, le deuxième est l'angle vers lequel le crayon va s'arrêter lors du tracé. Pas facile à utiliser.

  1. 360° de rotation sur soi-même en suivant la trajectoire du cercle : facile, ça fait un cercle.
  2. 180° de rotation sur soi-même en suivant la trajectoire du cercle imaginaire : facile, ça fait un demi-cercle.
  3. 90° de rotation sur soi-même en suivant la trajectoire du cercle imaginaire : facile, ça fait un quart de cercle.

Regardons quelques exemples.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
from turtle import * pensize(10) color("red") circle(100, 90) color("blue") circle(100, 90) color("green") circle(100, 90) color("orange") circle(100, 90)
circles
5.4 - Turtle : choisir l'orientation absolue avec setheading()

left() permet de modifier l'orientation relative du crayon (par rapport à son orientation actuelle). Voyons comment le faire pointer vers une orientation absolue : vers la droite, la gauche, le haut ou le bas.

Les angles

Voici un descriptif visuel des différents angles :

Exemples d'orientation
Les différents angles absolus d'orientation
Modifier l'orientation du crayon

La fonction setheading() permet d'imposer la direction absolue vers lequel le crayon est orienté.

1 2 3 4 5 6 7
from turtle import * setheading(45) forward(200) setheading(-90) forward(200)
setheading

6 - FAQ

On peut faire d'autres choses avec turtle ?

Oui, beaucoup de choses.

Mais pour cela, il faut aller lire la documentation sur python.org.

Ou attendre l'activité Python que nous allons faire qui en parle.

Mes programmes turtle ne fonctionnent pas sous Basthon !

C'est sans doute car vous ne saviez pas qu'il faut faire une légère modification à vos programmes : il faut rajouter une instruction finale pour lancer la demande d'affichage : done().

Voici un exemple avec un petit programme :

Final

Activité publiée le 01 12 2023
Dernière modification : 01 12 2023
Auteur : ows. h.