Découvrir le python – Chapitre 2 – Diamonds in the skaaaaaaye

Wèèèèèsh lecteurtrice !! Bien ou bien ?

T’as lu mon article précédent et t’as grave kiffé au taquet de ouf’ ? Sois jouasse, en rev’là une gorgée !

Avant qu’on s’y remette, j’espère que t’as fait tes devoirs, ou que t’as au moins essayé.

Si ce n’est pas le cas, ce n’est pas grave, je vais simplement prévenir mes robots correcteurs. Ils te jetteront du sable fin sur les sourcils, puis te pendront par les pieds et te fouetteront jusqu’à ce que tes larmes aient entièrement nettoyé tes sourcils.

Voici la solution du devoir, avec plein de commentaires qui expliquent comment c’est gaulay.

Un diamant

Let’s go sur un truc simple pour commencer. Retourne dans Trinket, ton bel environnement de dev, enlève le programme initial et ajoute les deux lignes habituelles au début : « import turtle », « turtle.speed(0) ». On va commencer simple, tu vas me dessiner un diam’s.

♫ C’est le python qui va dicter ton code. ♪ Génération Oui-Oui. ♬♪

Un diamant, c’est quatre quarts de cercle. Sauf qu’après chaque quart, la tortue fait demi-tour, pour changer le sens de tracé du quart suivant.

On n’est pas des prolos et on veut un gros diam, alors tu me fais des quart de cercles de 100 pixels de rayon. Tu as le droit de le réaliser d’abord à la crade, c’est à dire en copiant-collant 4 fois le même morceau de programme. Mais ensuite, tu me met ça sous forme d’une boucle.

Tu devrais réussir à bling-blinguer un diamant cossu comme ça :

Lien vers la réponse si tu as du mal à te remettre dans la vibe.

Laissez-moi vos coordonnées

Si tu as fait quelques années d’école, lecteurtrice, tu as sûrement placé des points sur une feuille, pour faire un graphique ou pour tracer une droite. Tu utilisais alors des coordonnées : un nombre en X, un autre en Y.

Si tu es Muriel Robin, lecteurtrice, tu pourrais faire la blague « laissez-moi vos cordonniers, je vous rappellerais », et tu aurais été super drôle, pour l’époque.

La tortue se déplace dans un espace défini par des coordonnées. Cet espace est orienté de la même manière qu’en cours de maths :

  • La coordonnée (0, 0) correspond au milieu de la zone de dessin.
  • Lorsqu’on va vers la droite, la première valeur (le X) augmente, elle diminue lorsqu’on va vers la gauche.
  • Lorsqu’on va vers le haut, la deuxième valeur (le Y) augmente, elle diminue lorsqu’on va vers le bas.

C’est pas du tout orienté selon les conventions habituelles en informatique. On va pas s’attarder là-dessus pour l’instant, sinon je vais encore traiter les matheux de ringards.

La fonction « turtle.setpos » permet de positionner la tortue à des coordonnées données (Wesh, lecteurtrice ! « coordonnées données » ça fait une répétition lolilol !).

Voici un lien vers la doc de la fonction.

Au début de ton programme, ajoute un setpos pour positionner la tortue aux coordonnées X = -40, Y = +30.

Le déplacement va dessiner un trait moche. On réglera ça au chapitre suivant.

Mais avant, tu vas mettre ces coordonnées dans deux variables, intitulées « pos_x » et « pos_y ». Tu te souviens de ce qu’est une variable ?

Au début du programme, tu définis la variable « pos_x » à -40 et la variable « pos_y » à 30.

Ensuite, dans l’instruction « turtle.setpos », tu n’utilises plus directement les valeurs -40 et 30, mais les deux variables que tu viens de définir.

Pour l’instant, ces variables servent à R (Wesh lecteurtrice, langage de jeune !!), mais ce sera utile très bientôt.

Lien vers le code, si t’en chie.

Attention, les majuscules-minuscules sont importantes. « pos_x » et « Pos_x », ce n’est pas la même chose.

Les conventions de codage en python conseillent d’écrire les noms de variables tout en minuscules. Lorsqu’un nom est composé de plusieurs mots, on les sépare par des « _ » (le tiret bas). Un jour, jeune programmeurtrice dont les poils n’ont pas encore poussés, je te parlerai plus en détail de la notion de « convention de codage » et du PEP-8.

Si t’as envie d’appeler tes variables « posx » et « posy », t’as le droit, tu fais tout qu’est-ce que tu veux, c’est ta création, c’est bonheur. Il faudra juste que tu t’en rappelles, parce que dans la suite de l’article je continue de les appeler « pos_x » et « pos_y ».

Il n’est pas rare de s’over-prendre la tête en boucle pendant des heures sur la manière de nommer une variable.

Up and Down

C’est trognon ces variables, mais ça règle pas le problème du trait dégueubeurk que fait le setpos.

Je te donne juste le nom des deux fonctions permettant de régler le problème : « turtle.penup », « turtle.pendown ». Tu te débrouilles pour savoir ce que ça fait, comment ça marche, est-ce que ces fonctions ont besoin de paramètres, où les appeler, etc. Peut-être que tu peux commencer par les taper dans un moteur de recherche.

Tu regardes des docs et des exemples de code, tu testes dans ton programme, si ça fait des trucs pétés, tu testes autre chose. Azy lecteur, fais pas ta tafiolle, azy lectrice, fait pas ton tafiot (Wesh lecteurtrice, t’as vuuuu ? Écriture inclusive sur le mot « tafiolle » !)

Quand tu auras réussi, ça fera le même diam’s qu’au tout début, mais sans le trait moche.

Lien vers la réponse, si t’es au bout de ta vie.

Tout ça pour ça ? Je t’entends penser d’ici : « you you foutay de magl, ou bien ? ».

Ne brûle pas cet article tout de suite lecteurtrice, la suite est plus intéressante.

lofteurs.up() and lofteurs.down()

Pléthore de diam’s

Ce serait le top de la bling-bling-itude de pouvoir dessiner des diamants où on veut. Mais pas en copiant-collant le code, sinon ce serait le top de la cra-cra-itude. Alors on va créer une fonction.

Tu ne sais pas ce qu’est une fonction ? Eh bien si. Tu en utilises depuis le début : « print », « turtle.circle », « turtle.penup », … Maintenant, tu vas en créer une nouvelle qui sera rien qu’à toi.

Lorsqu’on crée une fonction, on lui associe un bloc de code, qu’on appelle le corps de la fonction. Comme tu as bien retenu la leçon précédente, tu sais déjà que ce bloc peut éventuellement contenir des sous-blocs, sous-sous-blocs, etc.

Ensuite on exécute la fonction (on peut aussi dire « appeler la fonction »), ce qui revient à exécuter son corps. Ça fait très bizarre de dire « exécuter son corps », alors dites-le uniquement dans votre tête, d’à-corps ?

Tu vas donc me créer une fonction, sans paramètre, intitulée « dessiner_diams ». Dans le corps, tu mets ce que tu as déjà écrit, depuis « turtle.penup » jusqu’à la boucle dessinant les quarts de cercle. Tu n’y mets pas l’initialisation des variables pos_x et pos_y, c’est fait exprès.

Voilà un lien de doc qui pourra t’aider : https://courspython.com/fonctions.html, à lire jusqu’au chapitre « Fonction avec paramètre ». Cela dit, les chapitres d’après peuvent t’aider pour la suite, et c’est assez bien expliqué. Y’a juste pas de fun, contrairement à mes articles qui regorgent d’espiègleries toutes pailletées de saveurs foisonnantes prestige t’as vu wesh ?

Seulement voilà. Si t’exécutes ton code là maintenant, t’auras queud’. Zéro diams. Retour à l’âge de prolétaire.

C’est normal, il faut appeler la fonction que tu as créée. À la fin du programme, ajoute « dessiner_diams() », et re-bling-bling !

Si tu appelles plusieurs fois de suite la fonction, ça ne changera pas le dessin final, car tu dessines plusieurs fois au même endroit.

Or, la fonction utilise les variables pos_x et pos_y pour se positionner avant de dessiner. Il suffit donc de les modifier puis de re-appeler la fonction.

Tant qu’on y est, tu vas ranger un peu ton code. En général on met les imports au début, puis la définition des fonctions, puis le code principal. Ça va donc donner un truc comme ça :

import turtle
# Cette ligne, y'a qu'à la laisser au tout début.
turtle.speed(0)

# Ici, il y a la définition de la fonction "dessiner_diams"

# Ensuite, la définition des variables pos_x et pos_y, 
# avec les mêmes valeurs qu'avant : -40 et +30

# Appel de la fonction.
dessiner_diams() 

# On redéfinit les variables pos_x et pos_y, 
# avec, disons : pos_x = 10 et pos_y = 60

# Re-fonction.
dessiner_diams()

Et ça devrait donner deux diamants, à deux endroits différents :

Lien vers la réponse, si t’es en PLS.

Avec des paramètres

On a fait un truc bizarre dans le chapitre précédent. On a utilisé les variables pos_x et pos_y à l’intérieur d’une fonction, alors qu’on ne les a pas définies dans la fonction elle-même. Ça n’a pas planté, grâce à la manière dont le langage python gère la portée des variables.

  • Ton programme principal est dans un certain contexte, avec des variables.
  • Tu exécutes la fonction « dessiner_diams », qui se crée un petit sous-contexte pour elle toute seule, avec ses variables.
  • Le python autorise l’accès aux variables d’un contexte englobant, mais uniquement en lecture.

Tu verras peut-être, dans les différents tutoriels du grand internet, les notions de « variables globales » et « variables locales ». C’est à peu près la même chose, mais je n’aime pas trop ces termes, car ça donne l’impression qu’il n’y a que deux contextes, alors qu’il peut y en avoir bien plus.

Je vais pas trop t’embrouiller avec des choses que t’as pas encore vues. Un module possède lui aussi un contexte. D’autre part, tu peux déclarer une fonction dans une fonction, ce qui crée un sous-sous-contexte, et une fonction dans une fonction dans une fonction. Et en plus ça s’appelle pas des contextes mais des « espaces de nommage ». Oublions tout ce batacouac.

Y’a des fois, c’est justifié d’accéder à une variable du contexte englobant, mais là non, c’est pourri.

Déjà, parce que ça oblige à écrire trois lignes de code pour dessiner un diamant où on veut : deux lignes pour pos_x, pos_y, et la dernière pour la fonction. Et ensuite ça fait bizarre, car le comportement de la fonction dépend de choses extérieures à elle. C’est inhabituel, alambiqué, complexe et source de bugs.

Alors on va ajouter deux paramètres à la fonction. Devine comment on va les appeler ? pos_x et pos_y. Hu hu hu.

Il faut ajouter ces paramètres dans la définition de la fonction (la ligne de code avec le mot-clé « def »), ainsi qu’à chaque exécution de la fonction.

Tu n’as plus besoin des lignes de code définissant les variables pos_x et pos_y. Tu peux mettre les coordonnées directement dans les paramètres d’appel à la fonction. Tiens voilà un exemple issu de la même doc que tout à l’heure . Ne t’attardes pas sur le corps de la fonction, osef. Regarde juste comment elle est déclarée, comment elle est appelée, et tu fais le même genre de chose avec ta fonction à toi.

Tu peux faire un petit test pour bien te rendre compte que les paramètres pos_x et pos_y existent dans l’espace de la fonction, mais plus en dehors. Ajoute « print(pos_x) » à la fin de ta fonction. Ça va fonctionner. Ajoute la même ligne tout à la fin de ton programme, ça va merdoyer.

C’est ce qu’on veut, lecteurtrice. Chaque variable et chaque paramètre doit être présent uniquement là où on en a besoin, et ne pas être accessible ailleurs. Sinon ça embrouille, on se demande ce que ça fout là, et on passe pour une baltringue ou un baltringuet (Wesh ! Écriture inclusive !).

Pour finir ce chapitre sur quelque chose d’over-classe, tu mets une boucle de 20 itérations dans laquelle tu exécutes ta fonction. Pour ses deux paramètres, indique directement le compteur de la boucle.

Ça va faire un truc comme ça :

Lien vers le code si t’as vomi ton cerveau.

On taille les diamants

Maintenant que tu as compris le truc avec les paramètres de fonctions, profitons-en pour en rajouter un troisième, permettant de choisir la taille du diamant.

C’est à peu près comme au chapitre précédent :

  • Ajoute un paramètre dans la définition de la fonction, après pos_x et pos_y. On l’appellera « taille ».
  • Utilise ce paramètre dans le corps de la fonction. Ça va se passer dans la ligne de code « turtle.circle(100, 90) »
  • Ajoute le paramètre lors de l’exécution de la fonction. Dans un premier temps, tu peux indiquer une valeur fixe. Le plus simple est de remettre 100.

Avec ça, tu auras la même image que précédemment, mais ton programme sera plus souple, comme lui :

Modifie la boucle affichant les 20 diamants, en faisant varier leur taille, de 0 pixels (inclus) à 100 pixels (exclus), en avançant par pas de 5 pixels.

Et plop :

Lien vers la réponse si t’es pas de taille.

Recentrons-nous

Hé, j’ai une idée géniale. On pourrait afficher des diamants de taille différente, mais tous en coordonnées (0, 0). Ça ferait un truc trop joli, comme une espèce de porte des étoiles magiques en forme de vagin de l’espace.

Sans plus attendre, re-re-modifie la boucle exécutant la fonction, et indique 0 dans les deux premiers paramètres.

Et paf, c’est moche.

Qu’est-ce à dire que ceci ?

La fonction positionne la tortue aux coordonnées (pos_x, pos_y), puis commence tout de suite à dessiner.

Donc ces coordonnées ne correspondent pas au centre du diamant, mais à la pointe de gauche.

Avant de dessiner, il faut se décaler vers la gauche, d’une distance égale à la taille du diamant.

Y’a deux manières de le faire :

Soit tu te positionnes dès le départ où il faut, en changeant le premier paramètre de l’instruction turtle.setpos. Au lieu de « pos_x », tu mets « pos_x – taille ».

Soit tu laisses le setpos comme il est, mais juste après, tu recules de la taille du diamant. La fonction pour reculer, c’est « turtle.backward », elle fonctionne comme le forward.

Je te conseille fortement la deuxième option. Tu en auras besoin au moment de faire tes devoirs. Eh ouais, lecteurtrice, t’auras encore des devoirs. La vie est dure.

Après avoir appliqué le décalage, ça devrait dessiner ça :

Lien vers la réponse, si t’es déconcentré ou déconnecentrée (Wesh, écriture inclusive, t’as vuuuuuu ?)

Diamonds are a girl’s best friend

I have a good filling about this

On va momentanément partir sur autre chose.

Teste-moi ça, dans un autre onglet Trinket :

import turtle
turtle.fillcolor("red")
turtle.begin_fill()

turtle.forward(60)
turtle.left(120)
turtle.forward(60)
turtle.left(120)
turtle.forward(60)

turtle.end_fill()

Ça va dessiner un magnifique triangle rempli de rouge.

Explications :

  • La fonction fillcolor est assez simple : elle définit une couleur de remplissage. Tu peux remplacer « red » par « green », « blue » ou d’autres couleurs en anglais.
  • La fonction begin_fill indique à la tortue qu’on va commencer à tracer un dessin qui sera à remplir.
  • Ensuite, des forward et des left, que tu connais déjà.
  • Finalement, la fonction end_fill indique à la tortue qu’on a fini le dessin et que le remplissage doit être effectué.

Ce n’est pas forcément évident à comprendre. Ces fonctions de fill impliquent beaucoup de traitements réalisés en interne par le python.

Lorsque tu es entre un begin_fill et un end_fill, à chaque fois que tu traces un bout de truc, que ce soit avec un forward, un circle ou autre chose, la tortue enregistre tous les pixels par où elle est passée. Au moment du end_fill, la tortue en déduit l’espace interne de pixel délimité par ton tracé, et elle les colorie. Comme l’outil « pot de peinture » dans les logiciels de dessin, t’as vu ?

Pas besoin de te prendre la tête avec ces traitements compliqués, le python le fait tout seul (plus exactement, c’est la librairie de code turtle qui le fait, osef). Mais du coup, c’est pas évident de comprendre ce que ça fait.

On pourrait presque considérer que tout ce que tu fais entre le begin_fill et le end_fill constitue un sous-bloc de code. D’ailleurs, si ça ne tenait qu’à moi, j’aurais fait un context manager, et ça se serait explicitement écrit comme des sous-blocs de code. Un « context manager », c’est un truc spécial du python que tu peux mentionner quand tu veux montrer à tes lecteurtrices à quel point tu es un over-expert du python.

Et là, lecteurtrice, je me plaît à imaginer que tu t’intéresses à ce que je te raconte jusqu’au plus profond de tes neurones, et que donc tu te poses plein de questions :

  • Si je dessine n’importe quoi et que je ne reviens pas à mon point de départ, est-ce que ça va colorier toute l’image comme dans Paint ?
  • Si je croise des traits, ça va se colorier comment ?
  • Si je fais plusieurs begin_fill et/ou plusieurs end_fill à la suite, ça donne quoi ?

Réponse : t’as qu’à tester. Tiens, je t’ai fait quelques exemples.

Bon, ceci étant expliqué, je veux un diamant de sang ! Yaaahahahhaaarrrr !!

Modifie la fonction de façon à ce qu’elle dessine un diamant coloré en rouge. Il suffit d’ajouter les instructions de fill, aux bons endroits.

Ensuite, les diamants vont se dessiner en se recouvrant l’un après l’autre. À la fin, tu auras ça :

Lien vers la réponse, si tu commences à pleurer du sang.

Ce sera tout pour aujourd’hui

Dans mon article précédent, j’ai dit qu’on ferait ça :

On n’y est pas encore, mais on s’en rapproche. Je m’arrête là pour l’instant. J’ai d’autres trucs à faire que d’écrire des cours de python. Désolé. Promis, le mois prochain, on y arrive.

En attendant, pour pas que tu t’ennuies, BADAM-BING ! LES DEVOIRS !!!

Dessine-moi ça :

Petit indice : depuis le début, on dessine des diamants tout droit, parce que l’orientation initiale de la tortue est droite. Et si tu tournais un peu ta tortue avant de dessiner un diamant ? Pas trop, un ou deux degrés…

Que devient le groupe de musique Lonah ?

C’était il y a quelques années.

Je vous propose de faire mon vieux de la veille et de vous raconter ça comme si c’était une lointaine époque dont je serais le seul survivant à me souvenir. Ça fait toujours super classe.

[Disgression : ça me rappelle une autre époque, pas si lointaine, où, dès que j’utilisais l’expression « ca me rappelle », il se trouvait un petit trou du cul de connard pour se foutre de ma gueule et m’imiter comme si j’étais quelqu’un de très vieux qui se rappelait une ancienne époque. Ce n’était pas uniquement de la moquerie, c’était aussi un acte réducteur de ma personne : le petit trou du cul sous-entendait que j’étais un jeune petit trou du cul qui voulait se donner l’impression qu’il avait une histoire, alors qu’il n’en n’a pas car il est trop jeune. Même à l’age de trois ans, j’avais déjà une histoire, trou du cul. L’histoire de millions d’autres enfants. Mais ce n’est pas le moment de parler de ça.]

En ces temps très très anciens, les licences libres logicielles (GPL, BSD, Apache, …) étaient relativement connues, mais les licences libres artistiques n’en étaient qu’à leurs blablabutiements. Les œuvres apparentées étaient donc assez rares, et souvent d’une qualité et d’un intérêt douteux. Les chantres du Libre devaient donc user d’un peu de mauvaise foi pour les défendre, et lorsqu’ils citaient des exemples, retombaient souvent sur les mêmes :

Je mets les liens grisés ici, car si je les intègre dans la liste, ce sera illisible :

  • https ://orange .blender.org/background/
  • https ://www .youtube.com/user/MastocStudio/videos?sort=dd&view=0&shelf_id=0
  • http ://art9libre .tuxfamily.org/archives/author/eldreammachine
  • http ://www .inlibroveritas.net/
  • http ://tuxracer .sourceforge.net/
  • https ://en .wikipedia.org/wiki/Quake_III_Arena
  • http ://www .xbill.org/
  • http ://web .archive.org/web/20060619144448/http://culturelibre.net:80/article.php3?id_article=330
  • https ://fr .wikipedia.org/wiki/Ehma
  • https ://lacrymosa .tuxfamily.org/
  • http ://www .le-terrier.net/index2.html

Les terres de l’Art Libre étaient encore vierges, il suffisait donc d’y produire une œuvre pas trop dégueu pour avoir un tout petit public conquis dès le départ. C’est à cette occasion que j’ai essayé de devenir riche et célèbre avec mon dessin animé Pru-Pra-Prok. Je vous ai déjà raconté cela.

L’art de la musique était un peu plus avancé que les autres dans la découverte des bouleversements interneto-générés. Un paquet de pop-corn à la main, nous assistions aux échauffourées entre les vilaines maisons de disques soutenues par la méchante Sacem, et les héros robin-des-boisesques qu’étaient Napster et autres eMule. C’est dans ce contexte qu’apparut Jamendo, une plate-forme d’écoute et de téléchargement de musique. Son positionnement par rapport au « Libre » est source de débats et d’analyses diverses (https:// framablog.org/2011/10/04/librologie-jamendo/). De son côté, Mano Solo tentait un truc, se planta, puis mourut un petit peu.

Jamie Lopez n’est pas sur Jamendo, malgré les 3 lettres initiales en commun.

Le groupe de musique Lonah, composé de gens (retrouvez les noms vous-mêmes) était un « early adopter » de Jamendo. Leur premier album « Pièces » est un joli petit concentré patchworkesque de choses belles, étranges, oniriques, volantes, interrogatives, safranées, piscinesques. Je l’aime beaucoup.

J’étais allé les voir en concert, dans un quelconque bar-salle parisien. Le petit dépliant du planning indiquait « Lionah ». Woups, boulette.

Puis ils ont sorti deux autres albums, tout aussi bien. De mon côté, j’étais parti vers d’autres choses. C’est à peu près à cette époque que j’ai commencé ce blog. La suite de cette histoire est dans mes articles.

Récemment, je suis allé traîner sur leur site, le dernier message date de 2012. On y trouve également une photo de chien-loup, à moins que ce soit un choux-lien.

Est-ce qu’ils sont partis en tournée mondiale et n’ont plus le temps de donner de leurs nouvelles ? Est-ce qu’ils se sont séparés ? Est-ce que leur gloire naissante s’est embrasée au contact trop proche d’un soleil trop attirant ? Est-ce que ça leur a finalement semblé mieux et plus jucraciel de devenir trader en cokaïne à Dubaï ? Si vous avez des infos ou si un membre du groupe me lit, ça me ferait très plaisir d’avoir un petit commentaire.

En attendant, j’ai un petit cadeau pour vous. Le groupe avait créé un très beau morceau intitulé « le roi se meurt », inspiré de la pièce de théâtre éponyme de Ionesco. Même que j’avais acheté et lu le texte de la pièce suite à la découverte de cette chanson.

Celle-ci ne semble pas présente sur leur compte Jamendo. Elle est écoutable sur leur blog (http:// www. lonah.net/?q=node/24), mais il faut activer le flash, et c’est difficilement (voire impossiblement) téléchargeable.

Heureusement, j’avais récupéré le mp3 à une époque où il était disponible (je ne sais plus où). Voici donc, chers lecteurtrices/auditeurtrices, un petit trésor : Le roi se meurt en mp3 (https:// www. dropbox.com/s/itnirgtpwhec6xj/12%20Le%20roi%20se%20meurt.mp3?dl=0).