Aller au contenu

Variables

A propos du chapitre

Objectif :

  • Utiliser une variable pour paramétrer un dessin
  • Comprendre l'idée d'intention dans le code.
  • Comprendre qu'une variable représente une valeur abstraite
  • Associer une valeur à une variable
  • Effectuer des calculs basiques en python
  • Dessiner une jolie petite grange paramétrique avec un style rétrogaming:

example grange

Modalités :

  • Programmation (Basthon)
  • De la réflexion autour du code

Prérequis : "Programmation/Séquence et Turtle"

Difficulté : facile mais un peu perché ...

remarque prof : les activités de l'introduction demandent de se chronométrer. Comme les téléphones sont interdits, les faire utiliser un chronomètre sur l'ordi (par 2, un chrono et un code) ou solo en affichant un chrono au tableau.

*FIXME prof : dans le cours on utilise beaucoup "l'utilisateur", faudrait essayer de trouver un truc plus neutre. Peut être "qui vous demande" au lieu de "qui demande à l'utilisateur" ?

Introduction : paramètre ?

Dans l'introduction, j'ai dit que le but du dessin paramétrique était de pouvoir modifier un dessin le plus rapidement et simplement possible.

Mesurons un peu.

Activité : briefing !

Mettez-vous par paires. Il est aussi possible de rester en solo.

Par groupe :

  • Vous aurez besoin de deux ordinateurs.
  • Sur l'un, mettez ce chapitre du cours et Basthon
  • Sur l'autre, ouvrez le chrono en cliquant sur ce lien
  • La personne qui a le chronomètre donne le départ pour résoudre la mission.
  • L'autre doit alors résoudre la mission le plus vite possible.
  • N'hésitez pas à alterner les rôles.

En solo :

  • Vous n'avez besoin que d'un ordinateur.
  • Vous pouvez utiliser le chrono à ce lien
  • Ou alors utiliser le chrono au tableau,
  • Pour plus de simplicité, commencez pile sur une minute.

Déroulement d'une mission :

  • Lisez le sujet de l'activité et le descriptif de la mission sans ouvrir les dépliants.
  • Quand le départ est donné, la personne qui résouds la mission a le droit d'ouvrir les dépliants, et doit résoudre la mission le plus vite possible.
  • Si la mission a une limite de temps, la personne chargée du chrono prévient l'autre quand la limite est atteinte.
  • N'oubliez pas de noter votre score !

Activité : C'est carré !

Votre mission

L'agent Félix nous a envoyé un code Turtle qui dessine le carré suivant.

alt text

Malheureusement, il a été distrait par une pelote de laine, et le carré est trop petit.

Vous devez ABSOLUMENT doubler la taille du carré en moins de 3 minutes !

Vite, le temps presse !

Dépliant avec le code
from turtle import *

speed(0)

begin_fill()
forward(100)
left(90)
forward(100)
left(90)
forward(100)
end_fill()


done()

Activité : c'esT moiNS carré !

Votre mission

L'agent Félix nous a envoyé une version améliorée du code Turtle !

Il dessine maintenant la figure suivante :

alt text

Malheureusement, il a été distrait par une souris (d'ordinateur, aucun animal n'a été maltraité pour l'écriture de ce chapitre !), et le carré en haut à gauche est trop grand !

Vous devez ABSOLUMENT DIVISER PAR 2 la taille du carré en haut à gauche en moins de 5 minutes !

VITE, le temps presse !

Dépliant avec le code
from turtle import *

speed(0)

begin_fill()
forward(100)
left(90)
forward(100)
left(90)
forward(100)
end_fill()

forward(100)
left(90)
forward(100)
left(90)
forward(100)
right(180)

begin_fill()
forward(100)
left(90)
forward(100)
left(90)
forward(100)
end_fill()

forward(100)
left(90)
forward(100)
left(90)
forward(100)

done()

Activité : C'357 P45 C4rr3 !

Votre mission

L'agent Félix nous a envoyé une version encore plus puissante du code Turtle !

Il dessine maintenant la figure suivante :

alt

Malheureusement, il a été distrait par un pointeur laser , et la figure est un peu trop petite !

Vous devez ABSOLUMENT multiplier la taille de la figure par 1.25 en moins de 5 minutes !

VITE, le temps PRESSE !

Dépliant avec le code
from turtle import *

speed(0)

begin_fill()
forward(100)
left(120)
forward(50)
right(30)
forward(60)
left(60)
forward(100)
left(140)
forward(40)
right(55)
forward(145)
left(70)
forward(40)
right(35)
forward(75)
left(110)
forward(100)
left(88)
forward(40)


end_fill()


done()

Activité : 3'& 🟦 🚹 i 🟦 !

Votre mission

L'agent Félix nous a envoyé la version ULTIME du code Turtle !

Il dessine maintenant la figure suivante :

alt text

Malheureusement, il a été distrait par le rébus de zinzin dans le titre de l'activité1 ! Le carré noir le plus bas dans la colonne de droite est trop petit !

Vous devez ABSOLUMENT multiplier par 1,5 la taille du carré noir le plus bas dans la colonne de droite en moins de 3 minutes !

VITE, LE TEMPS PRESSE !!!

Dépliant avec le code
from turtle import *

speed(7)

begin_fill()
forward(200)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
right(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
left(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(200)
end_fill()


done()

Bon, bravo agent NOM, PRENOM, la planète n'est pas sauvée 2, mais vous avez fait de votre mieux !

Rejoignez la salle de SNT pour le debriefing !

Activité : debriefing

Vous n'avez peut-être pas réussi à faire les modifications des deux dernières missions dans le temps imparti.

Ne vous inquiétez pas, c'est normal.

Elles illustrent chacune une difficulté que l'on peut rencontrer quand on modifie un programme.

Prenez quelques minutes pour réfléchir à ce que peuvent être ces deux difficultés. (optionel : expliquez pourquoi elles posent un gros problème pour développer des programmes)

N'hésitez pas à échanger avec vos camarades.

Solution

L'avant dernière mission demande un changement qui n'est pas très compliqué à comprendre en principe, mais long parce qu'il faut modifier presques toutes les lignes du code pour un seul petit changement : le code est redondant.

La dernière mission demande un changement qui ne modifie pas énormément de lignes de code, mais qui demande de comprendre un code complexe.

Elles posent un problème dans la programmation : même avec un code de quelques lignes, c'est déjà la galère. A titre de comparaison, voici l'ordre de grandeur de quelques programmes :

Logiciel Usage Ordre de grandeur sloc Principaux langages
OpenFlappyBird Une version Libre de Flappy Bird 600 Java
SuperTux Une version Libre de Super Mario 100K C++
Terasology Une version Libre de Minecraft 130K Java
KDenLive Editeur vidéo non-linéaire 150K C++, C
Audacity Enregistrement et traitement audio 1M Python, C, C++
CPython Interpréteur Python le plus répandu 1.5M Python, C
Blender Modélisation 3D 2.3M C++, C, Python
llvm Suite de compilation pour les langages de la famille du C. 11M C++, C, Python, LLVM IR, ASM, CMake[^cmake], Objective C
Firefox Navigateur Web 25M C++, C, Python, JavaScript, ASM, Rust

Bon, si on peut faire des programmes aussi complexes, c'est qu'il y a une technique.

DES techniques :

  • Dans ce chapitre et le suivant, je vous explique comment résoudre la redondance, avec la généralisation et plus précisément la factorisation.
  • Dans le chapitre encore après, on verra comment résoudre la complexité, avec l'abstraction et le découpage.

Remarque prof

Diriger les élèves sur l'activité suivante (l'intention qui compte) en leur introduisant le problème, puis les laisser répondre et continuer en autonomie.

Intention

Perché !

le but de cette activité est de vous faire comprendre un concept important, mais un peu perché.

Les activités sont donc... un peu perchées également !

Prenez-les au sérieux et exposez toujours votre réponse à votre prof avant de regarder la solution !

Activité : c'est l'intention qui compte

Voici un programme qui ne marche pas :

from turtle import *

forward(100)
left(90)
forward(100)
left(90)
forward(180)
left(90)
forward(100)

done()

Expliquez ce que vous ne savez pas, et pourquoi ce manque d'information rends ce code difficile, voir impossible à réparer.

Solution

On sait que le programme ne marche pas, mais on n'a aucun moyen de savoir pourquoi : on ne sait pas ce que le code doit faire !

Est-ce qu'il doit dessiner un carré de côté 100 ?

Est-ce qu'il doit dessiner un carré de côté 180 ?

Une figure un peu biscornue ?

Ca, c'est l'intention de notre programme : ce qu'on voudrait qu'il fasse.

Si l'intention de notre programme est bien exprimée, c'est beaucoup plus facile de le comprendre et de le modifier, que ce soit pour corriger une erreur ou pour changer son comportement.

Parfois, l'interpréteur peut même nous aider.

Activité : une solution ?

Disons que le programme proposé à l'activité précédente a bien pour but de dessiner un carré de côté 100.

Exprimez cette intention dans le code, et corrigez-le.

Non, vous j'ai pas complètement craqué, vous avez déjà vu une manière de faire.

Si vous ne vous en rappelez plus, relisez rapidement l'introduction du chapitre précedent, en sautant les activités.

Solution

On peut utiliser un commentaire :

from turtle import *

# ici, on dessine un carré de côté 100
forward(100)
left(90)
forward(100)
left(90)
forward(100)
left(90)
forward(100)

done()

remarque : j'ai corrigé

Activité : c'est bien, mais 🐐 ...

Quand je lui ai montré la solution de l'activité précédente, mon double maléfique, Xilef, a dit :

C'est pas mal, mais ça n'exprime pas que les 4 différents 100 sont en fait une seule et même valeur.

Expliquez ce qu'il voulait dire.

Quelle est cette "valeur" dont il parle ?

Pourquoi c'est important de savoir ça ?

Solution

En fait, les 4 différents 100 sont des valeurs différentes : on peut modifier chacune des valeurs indépendamment dans le code

Mais d'un autre côté, ces 4 différents 100 sont une seule et même valeur : la taille du carré.

C'est important de savoir ça, parce que si on modifie une des valeurs, il faut modifier les trois autres, sans quoi on ne dessinera plus un carré.

Pour exprimer ce dernier aspect, on pourrait utiliser un commentaire. Mais Python nous fournis un bien meilleur outils : les variables.

Variable

Une variable est une valeur abstraite que l'on désigne par un nom, eventuellement associée à une valeur concrète (par exemple 100).

Quand je parle de la taille du carré, c'est une valeur abstraite : je ne précise pas sa valeur concrète (par exemple, 100).

Et bien évidemment, la taille du carré, est le nom de la taille du carré.

DONC

Donc une variable sert, entre autres, à nommer une valeur, et le nom exprime une partie de l'intention du code !

Voici ce que ça donne en Python pour le code des activités précédentes :

from turtle import *

# on définit la valeur abstraite 
#  "taille_carre" : c'est une variable
# et on lui associe la valeur 100
taille_carre = 100

# une fois définie, 
# On peut utiliser une variable dans la suite du code,
# partout où on peut utiliser une valeur numérique
# ici, on remplace 100 par la variable 
forward(taille_carre)
left(90)
forward(taille_carre)
left(90)
forward(taille_carre)
left(90)
forward(taille_carre)

done()

Activité : la magie des variables

Reprenez le code ci-dessus, et modifiez plusieurs fois la taille du carré.

Constatez que c'est très rapide une fois que vous avez compris le principe.

N'oubliez pas d'exécuter votre code pour vérifier que tout marche

Solution

On modifie juste la valeur concrête associée à la variable :

from turtle import *

taille_carre = 200 #ici

forward(taille_carre)
left(90)
forward(taille_carre)
left(90)
forward(taille_carre)
left(90)
forward(taille_carre)

done()

Et puis ... c'est tout !

Activité : Mission 3, edition magique

Vous vous rappelez de votre score à la mission 3 ?

Vous avez mis quoi... une minute au moins ?

Vous trouverez dans le dépliant ci-dessous son code, mais modifié avec un coup de variable magique3.

Chronometrez le temps que vous mettez à faire la modification (multiplier la taille de la figure par 1,25) sur cette version. Constatez la puissance de la magie !

Dépliant avec le code
from turtle import *

taille_figure = 100

speed(0)

begin_fill()
forward(100)
left(120)
forward(50 * taille_figure / 100)
right(30)
forward(60 * taille_figure / 100)
left(60)
forward(100 * taille_figure / 100)
left(140)
forward(40 * taille_figure / 100)
right(55)
forward(145 * taille_figure / 100)
left(70)
forward(40 * taille_figure / 100)
right(35)
forward(75 * taille_figure / 100)
left(110)
forward(100 * taille_figure / 100)
left(88)
forward(40 * taille_figure / 100)


end_fill()


done()

C'était tellement rapide et simple que vous n'avez pas eu à vous poser de question sur le reste du code. C'est ça la puissance de l'expressivité des variables !

Activité : triangle equilateral

Ecrivez le code d'un triangle équilatéral.

Utilisez une variable pour sa taille.

Solution
from turtle import *

# On utilise une variable pour la taille du triangle
taille_triangle = 100

forward(taille_triangle)
left(120)
forward(taille_triangle)
left(120)
forward(taille_triangle)

done()

Activité : rectangle

Ecrivez le code d'un rectangle.

Utilisez des variables pour qu'on puisse modifier sa longueur et sa largeur.

Solution
from turtle import *

#deux variables, une pour la largeur, une pour la longueur
largeur_rectangle = 100
longueur_rectangle = 200

#et on alterne les deux.
forward(largeur_rectangle)
left(90)
forward(longueur_rectangle)
left(90)
forward(largeur_rectangle)
left(90)
forward(longueur_rectangle)


done()

Un peu de calcul

En Python, on peut effectuer des calculs sur des nombres avec les opérateurs suivants :

opérateur description exemples
A + B Additionne A et B 10 + 10, 5.5 + 2.3, -3 + 2.1
A * B Multiplie A et B 10 * 10, 5.5 * 2.3, -3 * 2.1
A - B Soustrait B à A 10 - 10, 5.5 - 2.3, -3 - 2.1
A / B Divise A par B 10 / 10, 5.5 / 2.3, -3 / 2.1

Rappel

On peut utiliser une variable à la place d'une valeur.

Ce code :

a = 10
b = 20

resultat = a * b

print(resultat)

est valide et affiche 200.

Activité : ratio

Qui dessine un rectangle deux fois plus long que large

On doit pouvoir modifier sa largeur par le biais d'une variable, et sa longueur doit être modifée automatiquement en conséquences.

Solution
from turtle import *

largeur_rectangle = 100
#ici, on calcule la longueur à partir de la largeur
longueur_rectangle = largeur_rectangle * 2

couleur_rectangle = "blue"

color(couleur_rectangle)
fillcolor(couleur_rectangle)

begin_fill() 
forward(largeur_rectangle)
left(90)
forward(longueur_rectangle)
left(90)
forward(largeur_rectangle)
left(90)
forward(longueur_rectangle)
end_fill()

done()

Activité : carré centré

Ecrivez un programme qui dessine un carré en utilisant une variable pour sa taille.

Le carré doit être centré dans la zone de dessin, et doit rester centré si on modifie sa taille !

carre centré carre centré

Solution : forward

Il y a plusieurs manières de faire. Je vous en présente une ici.

On se décale vers le haut à gauche de la moitié de la taille du carré, puis on trace un carré qui s'étends vers le bas à droite.

from turtle import *

taille_carre = 200

speed(7)

# déplacement vers le haut à gauche, sans dessiner.
penup()memevc
right(180)
forward(taille_carre / 2)
right(90)
forward(taille_carre / 2)
right(90)
pendown()

# on trace le carré
forward(taille_carre)
right(90)
forward(taille_carre)
right(90)
forward(taille_carre)
right(90)
forward(taille_carre)

done()
Solution : goto

Cette solution est un peu plus calculatoire, mais peut être plus "propre" à lire si vous êtes à l'aise en maths.

On calcule les coordonnées et 4 points du carré et on les rejoins avec des goto

from turtle import *

taille_carre = 200

t = taille_carre / 2 #t est la moitié de la taille du carré

speed(7)

penup()
goto(-t, -t) #on rejoint un coin sans dessiner
pendown()

#on dessine les quatre coins. Attention l'ordre a une importance !
goto(-t, t)
goto(t, t)
goto(t, -t)
goto(-t, -t)

done()

On aura l'occasion de refaire du calcul dans les chapitres suivants.

Grange rétrogaming

Gardez votre code

Vous allez améliorer le code d'une activité à l'autre, et le réutiliser dans les prochains chapitres.

Si possible GARDEZ-LE précieusement quelque part où vous pourrez le retrouver (par exemple, dans un document texte) !

TODO (prof) ajouter une extension pour le doc texte

Dans tous les cas, pas de panique. Je vous fournirai des points de sauvegarde du code quand on en aura besoin dans le prochains chapitres.

Par le passé, les ordinateurs et consoles avaient une puissance extrêmement limités, et étaient donc incapables de faire un vrai rendu 3D. Les jeux en 2D étaient alors la norme. De nombreux jeux contournaient cette limitation en dessinant une partie des éléments du décor avec un léger effet 3D, tout en gardant l'arrangement général en 2D.

C'est par exemple le cas des premières versions de Pokémon. Voici un exemple d'un fanart de Ditto209 sur DevianArt :

alt text

Cette image est en vue du dessus. Le haut et l'écran est donc le Nord, et le bas le Sud. Certains éléments sont pourtant dessinés en 3/4, montrant à la fois leur face avant (face Sud), et leur dessus. Par exemple : la façade des batiments.

On peut aussi remarquer que l'image est orthographique : les éléments plus lointains ne sont pas plus petits.

Activité : briefing

Voici une image de grange sur ce principe :

exemple grange

Je vais vous présenter, pas à pas, les étapes pour dessiner une telle grange, et la paramétriser pour pouvoir changer sa hauteur, sa largeur et sa profondeur.

Si vous voulez du défi

Essayez de dessiner la grange avec uniquement les informations présentes dans ce briefing.

Vous aurez peut-être besoin des outils présentés dans l'extension Code RGB du chapitre précédent

Vous pouvez à tout instant arrêter de galérer et suivre le pas-à-pas. Ou aussi demande à votre prof des conseils pour vous débloquer.

Même si vous réussissez sans, je vous conseille de lire le pas-à-pas pour ne pas manquer une info.

Remarque : vous pouvez cacher la tortue avec l'instruction :

hideturtle()

Pro tip : incrémentale

Pour écrire un programme un peu compliqué, il faut procéder de manière incrémentale :

  • On écrit une version simplifiée du programme
  • On vérifie qu'elle marche en lancant et testant le programme
  • On ajoute ensuite une fonctionnalité
  • On vérifie que le programme marche avec sa nouvelle fonctionnalité
  • etc jusqu'à avoir le programme complet.

Dans le cas de notre grange, on va :

  • Dessiner la face avant sans la porte, paramétrisée sur la largeur et la hauteur
  • Dessiner le dessus du toit, paramétrisé sur la largeur et la profondeur
  • Dessiner les pans droits et gauche du toit, paramétrisés sur la profondeur
  • Centrer la grange au milieu de l'écran
  • Ajouter une porte

Activité : face avant

Dessinez la face avant comme suit :

grange face

(oui, c'est juste un rectangle ) !

Pour avoir la même couleur, vous pouvez utiliser les instruction suivantes :

fillcolor("hsl(33 42.5% 85.8%)")
color("hsl(33 42.5% 85.8%)")

Si besoin, les explication sont dans l'extension Code RGB du chapitre précédent, mais il n'est pas obligatoire de les lire pour comprendre le reste.

Solution
from turtle import *
speed(0)

largeur = 150
hauteur = 100

#face avant
fillcolor("hsl(33 42.5% 85.8%)")
color("hsl(33 42.5% 85.8%)")

begin_fill()
forward(largeur)
left(90)
forward(hauteur)
left(90)
forward(largeur)
left(90)
forward(hauteur)
end_fill()

done()

Pro tip : rôles et groupes

Votre code va bientot faire plusieurs choses à la fois :

  • dessiner la face
  • replacer la tortue pour dessiner le toit
  • dessiner le dessus du toit
  • ...

Chaque chose est un rôle qu'une partie du programme remplit.

Faites apparaitre ces rôles dans la structure du code :

  • Groupez les lignes d'un même rôle
  • Espacez les groupes de lignes pour bien les délimiter
dessiner
la
face

replacer 
la
tortue

dessiner 
le
dessus du toit

Activité : dessus du toit

Dessinez le dessus du toit comme suit :

dessus range

Pour avoir la même couleur, vous pouvez utiliser les instruction suivantes :

color("hsl(0 80.7% 63.5%)")
fillcolor("hsl(0 80.7% 63.5%)")
Solution
from turtle import *
speed(0)

largeur = 150
hauteur = 100
profondeur = 60

#face avant
fillcolor("hsl(33 42.5% 85.8%)")
color("hsl(33 42.5% 85.8%)")

begin_fill()
forward(largeur)
left(90)
forward(hauteur)
left(90)
forward(largeur)
left(90)
forward(hauteur)
end_fill()

#on se positionnne pour le dessus
penup()
left(180)
forward(hauteur)
right(90)
forward(40)
pendown()

#dessus
color("hsl(0 80.7% 63.5%)")
fillcolor("hsl(0 80.7% 63.5%)")

begin_fill()
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
left(90)
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
end_fill()

done()

Pro tip : commentaires concis

Les commentaires longs sont fatiguants à lire.

Un bon commentaire est concis: il va droit au but

On évite :

# ici, on dessine la face avant de la grange, que l'activité 1 nous demande, 
# et qui doit etre beige a peu pres. C'est un rectangle de largeur et hauteur.

On préfère :

# face avant

ou encore :

# On dessine la face avant

Ca ne veut pas dire qu'un commentaire ne peut pas être long, mais il doit être synthétique.

Activité : pan gauche du toit

Dessinez le pan gauche du toit comme suit :

pan gauche

Vous pouvez remarquer que la couleur est légèrement plus claire que le dessus. Celà simule un soleil qui arrive de la gauche, et donc éclaire plus le pan gauche que le dessus. Ça renforce l'effet de 3D et permet de mieux distinguer les pans du toit.

Pour avoir la même couleur, utilisez :

color("hsl(0 80.4% 69.6%)")
fillcolor("hsl(0 80.4% 69.6%)")
Solution
from turtle import *
speed(0)

largeur = 150
hauteur = 100
profondeur = 60

#face avant
fillcolor("hsl(33 42.5% 85.8%)")
color("hsl(33 42.5% 85.8%)")

begin_fill()
forward(largeur)
left(90)
forward(hauteur)
left(90)
forward(largeur)
left(90)
forward(hauteur)
end_fill()

#on se positionnne pour le dessus
penup()
left(180)
forward(hauteur)
right(90)
forward(40)
pendown()

#dessus
color("hsl(0 80.7% 63.5%)")
fillcolor("hsl(0 80.7% 63.5%)")

begin_fill()
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
left(90)
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
end_fill()

#pan gauche
color("hsl(0 80.4% 69.6%)")
fillcolor("hsl(0 80.4% 69.6%)")

begin_fill()
right(45)
forward(60)
right(135)
forward(profondeur)
right(45)
forward(60)
right(135)
forward(profondeur)
end_fill()

done()

Pro tip : commentaires bonus

Avoir trop de commentaire dans le code peut créer une surcharge d'information : on se perds dans les commentaires en plus de se perdre dans le code.

Un bon commentaire n'apporte que des informations qui ne sont pas déjà présentes dans le code.

On évite :

forward(100) #avance de 100
right(90) #tourne de 90
forward(100) #avance de 100
right(90) #tourne de 90
forward(100) #avance de 100
right(90) #tourne de 90
forward(100) #avance de 100

On préfère :

#carré taille 100
forward(100) 
right(90) 
forward(100) 
right(90) 
forward(100) 
right(90) 
forward(100) 

*Remarque : "Les information déjà présentes dans le code" peut être un peu subjectif. A vous de juger !

Remarque : c'est souvent une bonne idée de commenter pour préciser le rôle d'un groupe de lignes

Activité : pan droit du toit

Dessinez le pan droit du toit comme suit :

pan droit

Vous pouvez remarquer que la couleur est légèrement plus foncée que le dessus. C'est pour être cohérent avec le soleil qui vient de la gauche : le pan droit recoit moins de lumière que le dessus.

Si vous voulez utiliser les même couleurs :

color("hsl(0 80.7% 56.8%)")
fillcolor("hsl(0 80.7% 56.8%)")
Solution
from turtle import *
speed(0)

largeur = 150
hauteur = 100
profondeur = 60

#face avant
fillcolor("hsl(33 42.5% 85.8%)")
color("hsl(33 42.5% 85.8%)")

begin_fill()
forward(largeur)
left(90)
forward(hauteur)
left(90)
forward(largeur)
left(90)
forward(hauteur)
end_fill()

#on se positionnne pour le dessus
penup()
left(180)
forward(hauteur)
right(90)
forward(40)
pendown()

#dessus
color("hsl(0 80.7% 63.5%)")
fillcolor("hsl(0 80.7% 63.5%)")

begin_fill()
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
left(90)
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
end_fill()

#pan gauche
color("hsl(0 80.4% 69.6%)")
fillcolor("hsl(0 80.4% 69.6%)")

begin_fill()
right(45)
forward(60)
right(135)
forward(profondeur)
right(45)
forward(60)
right(135)
forward(profondeur)
end_fill()

#on se positionne pour le pan droit

penup()
left(90)
forward(largeur - 40 * 2)
pendown()

#on dessine le pan droit
color("hsl(0 80.7% 56.8%)")
fillcolor("hsl(0 80.7% 56.8%)")

begin_fill()
right(45)
forward(60)
left(135)
forward(profondeur)
left(45)
forward(60)
left(135)
forward(profondeur)
end_fill()

done()

Activité : centrage de la maison

Pour le moment, c'est l'angle bas-gauche de la face avant qui se trouve au centre de l'image.

Faites en sorte que la grange soit plus ou moins centrée sur l'image, peu importe les dimensions qu'on lui choisit.

centrage

Solution

Il faut "reculer" et "descendre" de respectivement la moitié de la largeur, et de la moitié de la hauteur totale (hauteur + profondeur) avant de dessiner.

from turtle import *
speed(0)

largeur = 150
hauteur = 100
profondeur = 60

# On se déplace pour centrer la maison
left(180)
forward(largeur/2)
left(90)
forward(hauteur / 2 + profondeur / 2)
#on oublie pas de se réorienter correctement
left(90)

#face avant
fillcolor("hsl(33 42.5% 85.8%)")
color("hsl(33 42.5% 85.8%)")

begin_fill()
forward(largeur)
left(90)
forward(hauteur)
left(90)
forward(largeur)
left(90)
forward(hauteur)
end_fill()

#on se positionnne pour le dessus
penup()
left(180)
forward(hauteur)
right(90)
forward(40)
pendown()

#dessus
color("hsl(0 80.7% 63.5%)")
fillcolor("hsl(0 80.7% 63.5%)")

begin_fill()
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
left(90)
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
end_fill()

#pan gauche
color("hsl(0 80.4% 69.6%)")
fillcolor("hsl(0 80.4% 69.6%)")

begin_fill()
right(45)
forward(60)
right(135)
forward(profondeur)
right(45)
forward(60)
right(135)
forward(profondeur)
end_fill()

#on se positionne pour le pan droit

penup()
left(90)
forward(largeur - 40 * 2)
pendown()

#on dessine le pan droit
color("hsl(0 80.7% 56.8%)")
fillcolor("hsl(0 80.7% 56.8%)")

begin_fill()
right(45)
forward(60)
left(135)
forward(profondeur)
left(45)
forward(60)
left(135)
forward(profondeur)
end_fill()

done()

Activité : une porte

Maintenant, il ne reste qu'à ajouter une belle porte en bois à notre grange.

Elle doit avoir une hauteur et largeur fixe, et être à 20 du bord gauche de la grange :

porte grange

La couleur utilisée est :

color("hsl(14 67.8% 28.7%)")
fillcolor("hsl(14 67.8% 28.7%)")

J'ai pris 40 de large pour 30 de haut, mais vous pouvez faire autrement.

Solution
from turtle import *
speed(0)

largeur = 150
hauteur = 100
profondeur = 60

# On se déplace pour centrer la maison

left(180)
forward(largeur/2)
left(90)
forward(hauteur / 2 + profondeur / 2)
#on oublie pas de se réorienter correctement
left(90)

#face avant
fillcolor("hsl(33 42.5% 85.8%)")
color("hsl(33 42.5% 85.8%)")

begin_fill()
forward(largeur)
left(90)
forward(hauteur)
left(90)
forward(largeur)
left(90)
forward(hauteur)
end_fill()

#on se positionnne pour le dessus
penup()
left(180)
forward(hauteur)
right(90)
forward(40)
pendown()

#dessus
color("hsl(0 80.7% 63.5%)")
fillcolor("hsl(0 80.7% 63.5%)")

begin_fill()
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
left(90)
forward(largeur - 40 * 2)
left(90)
forward(profondeur)
end_fill()

#pan gauche
color("hsl(0 80.4% 69.6%)")
fillcolor("hsl(0 80.4% 69.6%)")

begin_fill()
right(45)
forward(60)
right(135)
forward(profondeur)
right(45)
forward(60)
right(135)
forward(profondeur)
end_fill()

#on se positionne pour le pan droit

penup()
left(90)
forward(largeur - 40 * 2)
pendown()

#on dessine le pan droit
color("hsl(0 80.7% 56.8%)")
fillcolor("hsl(0 80.7% 56.8%)")

begin_fill()
right(45)
forward(60)
left(135)
forward(profondeur)
left(45)
forward(60)
left(135)
forward(profondeur)
end_fill()

#on se place pour la porte
penup()
left(90)
forward(40)
right(90)
forward(hauteur)
right(90)
forward(largeur - 20)
pendown()

#on trace la porte
color("hsl(14 67.8% 28.7%)")
fillcolor("hsl(14 67.8% 28.7%)")

begin_fill()
right(90)
forward(30)
right(90)
forward(40)
right(90)
forward(30)
right(90)
forward(40)
end_fill()

hideturtle()

done()

Super ! Vous arrivez au bout du chapitre, avec une superbe grange en prime.

Grange que vous aimeriez bien rénover et transformer en maison habitable... Et donc lui ajouter des fenêtres.

Mais ce sera le sujet du prochain chapitre, qui introduit un outil particulièrement utile : les boucles for.

Récap

Récap

Les variables sont des valeurs abstraites que l'on désigne par un nom.

On peut utiliser une variable en lieu et place d'une valeur littérale:

a = 10 #on crée la variable a, et on lui associe la valeur 10 
print(10) #OK
print(a) # OK

Les variables sont utiles pour rendre le programme plus clair : elles expriment une intention, ce que doit faire le programme.

Elles permettent également de le paramétriser : plutôt que d'avoir plusieurs fois la même valeur littérale, on utilise une variable, et on peut alors modifier le programme en changeant simplement la variable.

taille_carre = 100 # pour changer la taille du carré, 
                   # on ne modifie que cette ligne

forward(taille_carre)
left(90)
forward(taille_carre)    
left(90)
forward(taille_carre)    
left(90)
forward(taille_carre)

On peut effectuer des calculs sur les variables et les valeurs à l'aide des opérateurs suivants :

opérateur description exemples
A + B Additionne A et B 10 + 10, 5.5 + 2.3, -3 + 2.1
A * B Multiplie A et B 10 * 10, 5.5 * 2.3, -3 * 2.1
A - B Soustrait B à A 10 - 10, 5.5 - 2.3, -3 - 2.1
A / B Divise A par B 10 / 10, 5.5 / 2.3, -3 / 2.1

Extensions

Projections graphiques et perspective

TODO ajouter extension (entre autres, pourquoi la maison a l'air de s'élargir avec la profondeur)

Mission 4 : la "revanche"

A propos de l'extension

Objectif :

  • Vous retourner le cerveau avec un défi dont vous sortirez avec beaucoup de fierté (ou de déception...)
  • Transformer la mission 4 en dessin paramétrique pour pouvoir modifier la taille du carré à votre guise.

Modalités :

  • Programmation (Basthon)
  • De la réflexion autour du code.
  • Du calcul
  • (Peut être quelques larmes aussi)

Prérequis : Avoir vu le chapitre en entier

Difficulté : Cataclysmique

Activité : bon courage !

Dessinez la figure de la mission 4 de manière paramétrique en utilisant une variable, pour pouvoir modifier facilement la taille du carré cible (le carré noir en bas dans la colonne la plus à droite.)

Les colorations doivent être préservées, ainsi que la taille et le contact entre les carrés. Le carré en bas à droite doit être "tiré" ou "poussé" pour toujours être collé au carré cible.

Votre code doit marcher avec les tailles petites, normales, grandes et gigantesque, par exemple, respectivement, 50, 100, 125, 220.

Au cas où, voici le code de la mission dans le dépliant.

Dépliant avec le code
from turtle import *

speed(7)

begin_fill()
forward(200)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
right(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
left(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(200)
end_fill()


done()

Mais vous pouvez aussi repartir de 0 si vous préférez.

Solution

Il y a des tas de méthodes, je vous donne celle que je trouve la plus simple, parce qu'elle permet de gérer facilement les cas extrêmes.

Elle se passe en deux étapes. D'abord, on "dévie" la tortue pour qu'elle ne dessine pas :

  • Le carré noir bas à droite qui doit changer de taille
  • Le carré blanc bas à droite qui doit changer de position pour s'adapter.

C'est une modification de code non paramétrique. Comme la tortue fait deux passes dans la zone qu'on veut effacer, on doit modifier le code à deux endroits.

example

(en rouge/fin : le tracé actuel de la première passe, en vert/épais : le tracé voulu de la première passe.)

Je vous mets le code dans le dépliant au cas où :

Le code qui efface les carrés
from turtle import *

speed(10)

begin_fill()
forward(200)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
right(90)

#Ici on dévie la première passe
forward(200) # 400 -> 200
right(90)
forward(100)
#on ajoute la deuxième partie de la déviation
left(90)
forward(200)
right(180)

#on reprends le tracé
forward(400)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
left(90)


#ici on dévie la seconde passe
forward(300) # 400 -> 300
left(90)     
forward(100)
left(90)
forward(300) # 400 -> 300
right(90)
forward(100)
right(90)
forward(200)
end_fill()


done()

Ca donne :

resultat isolation

Maintenant, on va dessiner les deux carrés restant de manière paramétrique.

(En violet/fin : les traits non paramétriques, en vert/epais : les traits paramétriques)

Remarquez qu'on fait bien le tour des carrés à chaque fois, ça assure qu'ils seront fermés même si ils "dépassent" de la grille.

Voici le code :

Le code final
from turtle import *

#ajout d'une variable pour le dessin paramétrique
taille_carre = 50


speed(0)

begin_fill()
forward(200)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
right(90)

#Ici on dévie la première passe
forward(200) # 400 -> 200
right(90)
forward(100)
#on ajoute la deuxième partie de la déviation
left(90)
forward(200)
right(180)

#on reprends le tracé
forward(400)
left(90)
forward(100)
left(90)
forward(400)
right(90)
forward(100)
right(90)
forward(400)
left(90)
forward(100)
left(90)
forward(400)
left(90)


#ici on dévie la seconde passe
forward(300) # 400 -> 300
left(90)     
forward(100)
left(90)
forward(300) # 400 -> 300
right(90)
forward(100)
right(90)
forward(200)
end_fill()

#ici, on dessine les carrés en isolation

# on se place au bon endroit pour tracer le carré variable
forward(100)

#on trace le carré paramétrique, rempli en noir
begin_fill()
forward(taille_carre)
right(90)
forward(taille_carre)
right(90)
forward(taille_carre)
right(90)
forward(taille_carre)
end_fill()

#on se place au bon endroit pour le dernier carré
right(180)
forward(taille_carre)

#on dessine le dernier carré 
forward(100)
left(90)
forward(100)
left(90)
forward(100)
left(90)
forward(100)

done()

Vous pouvez l'essayer avec les valeurs clés mentionnées plus haut, et constater qu'il marche.


  1. "C'est carrément horrible !". 3ème lettre de l'alphabet, C. ' inchangé. & esperluette, utilisé pour dire "et". 🟦 : carré. 🚹 toilettes hommes, hommes en anglais : mens. : heure. i inchangé. 🟦 bleu. ↩

  2. sauf si vous avez vraiment réussi à faire le dernier en moins de 3 minutes, dans ce cas là bravo, perso j'ai même pas essayé, LOL. ↩

  3. A la place d'une baguette. Une variguette ? Une baguiable ? ↩