Étiquette : py2png

Art

Balles et ballons : les ballons du système solaire

Le premier projet de la classe de 1ère NSI est « Regard de géomètre ». Ce projet consiste en la création d’une image basée sur un ou plusieurs thèmes donnés. Pour notre image, on a choisi les thèmes astronomie et balles et ballons. Nous avons voulu représenter le système solaire mais en remplaçant les planètes et le Soleil par des balles et des ballons de différents sports.

Les étapes de création de notre image

Après avoir choisi nos thèmes et décidé de l’illustration que l’on souhaitait faire, nous avons commencé par le fond de notre illustration. Pour cela, on voulait un fond noir avec des étoiles représentées par des points blancs et de tailles différentes placées aléatoirement sur l’image. Cependant, les grosses étoiles à cause de leur couleur blanche, se voyaient trop par rapport aux plus petites. On a alors ajouté une couleur un peu plus grise pour les grosses étoiles mais on a gardé le blanc pour les petites. Pour faire cela, nous avons utilisé une instruction conditionnelle :

import turtle
import random
turtle.speed(0)
for i in range(150):
    turtle.penup()
  turtle.goto(random.randint(-640,640),random.randint(-350,350)) 
    turtle.pencolor("black")
    turtle.pendown()
    a=random.randint(1,5)
    if a<2:
        turtle.begin_fill()
        turtle.fillcolor("white")
        turtle.circle(a)
        turtle.end_fill()
    else:
        turtle.begin_fill()
        turtle.fillcolor("#e1e1df")
        turtle.circle(a)
        turtle.end_fill()

Ce qui donne avec le fond:

Tracé du ciel étoilé

Dans un second temps, nous avons choisi les balles que l’on voulait représenter puis nous les avons tracées chacune séparément pour avoir le rendu le plus fidèle possible. Les balles choisies sont:

  • la balle de tennis
  • le ballon de basket-ball
  • le ballon de rugby
  • la balle de base-ball

A l’origine, on voulait faire le ballon de football plutôt que la balle de base-ball mais le motif de ce ballon est un peu trop complexe à faire et n’apportait que peu d’intérêt pour notre script.

Script pour le tracé du ballon de basket :

import turtle
turtle.bgcolor("black")
turtle.begin_fill()
turtle.fillcolor("coral")
turtle.goto(0,-3)
turtle.circle(98)
turtle.end_fill()
turtle.penup()
turtle.goto(-97,93)
turtle.left(-73)
turtle.pendown()
turtle.pensize(5)
turtle.pencolor("black")
turtle.circle(100,150)
turtle.penup()
turtle.goto(-97,93)
turtle.left(180)
turtle.pendown()
turtle.circle(100,-150)
turtle.penup()
turtle.goto(-97,93)
turtle.right(107)
turtle.pendown()
turtle.forward(186)

Tracé du ballon de basket

Dans la dernière étape de la création de notre image, nous avons regroupé toutes nos créations (fond, balles et ballons) dans un même script et nous avons rajouté certaines fonctionnalités comme les ellipses ou l’effet d’ombre qui vous seront montrés plus loin. Mais, lors de ce regroupement, nous avons fait face à plusieurs problèmes notamment au positionnement des balles et également à leur proportion (un ballon de basket ne peut pas être plus petit qu’une balle de tennis). Pour cela, on a effectué une suite d’essai-erreur jusqu’à ce que le résultat nous plaise.

Rendu final

Les fonctions utilisées dans le script

La première fonction importante de ce script est la fonction « orbite ». Elle consiste en la création d’une « fausse ellipse » à l’aide de 4 arcs de cercles de rayons différents. Cette fonction est plutôt simple mais extrêmement efficace.

def orbite(rayon):
  turtle.seth(-45) 
  for i in range(2):
      turtle.circle(rayon,90)
      turtle.circle(rayon/2,90)
  return()

La deuxième fonction marquante de ce script est la fonction permettant de créer un effet d’ombre sur les balles et ballons ayant une forme circulaire. Pour cela, il faut créer un dégradé de couleur formé à l’aide de cercles de plus en plus petits dont la couleur varie en même temps que le rayon diminue. Cette fonction s’appelle « surface ».

def surface(couleur,rayon,posx,posy):
    r=couleur[0]
    g=couleur[1]
    b=couleur[2]
    turtle.pensize(5)
    for i in range(51):
        turtle.home()
        turtle.goto(posx,posy)
        turtle.pendown()
        if ((r-i*1.5)>=0) and ((g-i*1.5)>=0) and ((b-i*1.5)>=0):
            r1=r-i*1.5; g1=g-i*1.5; b1=b-i*1.5;
        elif ((r-i*1.5)<0): r1=r
        elif ((g-i*1.5)<0): g1=g
        else: b1=b
        turtle.pencolor((r1/255,g1/255,b1/255))
        turtle.circle((100-2*i)*rayon)
        turtle.penup()

Enfin, la dernière fonction est la fonction étoile, elle permet comme son nom l’indique de tracer des étoiles de taille et avec un nombre de branches variables. Elle a pour paramètres le nombre de branches et la longueur des branches.

def etoiles(branches, longueur):
    turtle.begin_fill()
    turtle.fillcolor("white")
    for i in range(branches):
        turtle.forward(longueur)
        turtle.right(180+180/branches)
        turtle.forward(longueur)
        turtle.left(180-180/branches)
    turtle.end_fill()

Malheureusement, cette fonction a un défaut que l’on n’a pas su régler. Lorsque l’on choisit un nombre pair de branches, le nombre n’est pas respecté.

Exemple: lorsque l’on exécute etoiles(6,100). Le nombre de branches n’est pas correct.

Alors que lorsqu’on veut faire une étoile avec un nombre de branches impair, le nombre de branches est respecté.

Exemple: lorsque l’on exécute etoiles(9,100). Le nombre de branches est correct.

Problèmes rencontrés

Lors de la création de notre script, nous avons rencontré plusieurs problèmes comme le positionnement des balles ou encore la proportion des ballons mais également des problèmes qui survenaient lorsqu’on voulait créer une image. Ce problème venait de la commande bgcolor(). Cette fonction consiste à colorier le fond de la toile par la couleur de son choix. Cependant, sur le script nous permettant de créer nos images, le fond n’apparaissait pas. Pour résoudre ce problème, nous avons rajouté au script une boucle faisant des allers-retours sur la toile à l’aide d’un stylo épais permettant de créer manuellement ce fond.

turtle.goto(-760,400)
turtle.pensize(10)
turtle.right(90)
for i in range(75):
    turtle.forward(420*2)
    turtle.left(90)
    turtle.forward(10)
    turtle.left(90)
    turtle.forward(420*2)
    turtle.right(90)
    turtle.forward(10)
    turtle.right(90)

Conclusion sur notre premier projet en NSI

Ce premier projet nous a permis d’approfondir nos connaissances en turtle et de créer notre premier « gros script » de cette année en python en faisant appel à toutes les fonctions vues en cours. Nous aurions pu essayer d’apporter des améliorations avec un peu plus de temps en ajoutant par exemple d’autres balles plus complexes comme la balle de golf.

Télécharger le .py

L’image finale

Art

Jardins : Forêt enneigée

Ce script génère une image aléatoire de forêt enneigée en utilisant deux fractales très connues : l’Arbre de Pythagore et le Flocon de Koch.

Les fractales

Le Flocon de Koch

Le Flocon de Koch utilise une courbe fractale. Une courbe fractale est un dessin composé de segment dont la forme de base va être reproduite à l’infini.

Dans le cas de la courbe de Koch, sur chaque segment, un triangle va être dessiné, et pour chaque niveau, on va rajouter un triangle sur les nouveaux segments.

Pour créer cette courbe, on va utilisé le principe de récursivité, c’est à dire qu’on va appeler dans une fonction python la fonction elle-même.

def cote(longueur,niveau):
    if niveau==0:
        forward(longueur)
    else:
        cote(longueur/3,niveau-1)
        left(60)
        cote(longueur/3,niveau-1)
        right(120)
        cote(longueur/3,niveau-1)
        left(60)
        cote(longueur/3,niveau-1)

On exécute la fonction cotée en définissant la longueur et le niveau de répétition souhaité. Ligne 2, on vérifie que le niveau est égal à 0. S’il ne l’est pas, ligne 5, on rappelle la fonction et cette fois-ci la longueur est divisée par 3 et on enlève 1 au niveau. Ainsi, on répète tant que le niveau n’est pas égal à 0, et quand le niveau est égale à 0, on avance de « longueur ».

En répétant cela plusieurs fois, on obtient la courbe de Koch.

Pour obtenir un flocon, on répète cette courbe trois fois.

def flocon(longueur,niveau,x,y):
    width(1)
    penup()
    goto(x,y)
    pendown()
    for i in range(3):
        cote(longueur,niveau)
        right(120)

Ce code provient de https://www.numworks.com/fr/professeurs/activites-pedagogiques/premiere/flocon/

L’arbre de Pythagore

L’arbre de Pythagore fonctionne de la même manière : la fonction s’appelle elle-même.

def arbre(n,longueur,w,r1,g1,b1,r2,g2,b2):
  if n==0 :
    pencolor(r1,g1,b1)
    forward(longueur)
    backward(longueur)
    pencolor(r2,g2,b2)
  else:
    width(w) 
    forward(longueur/3)
    left(50) 
    arbre(n-1,longueur*2/3,w/1.2,r1,g1,b1,r2,g2,b2)
    right(2*50)
    arbre(n-1,longueur*2/3,w/1.2,r1,g1,b1,r2,g2,b2)
    left(50)
    backward(longueur/3)

Cette fonction prend plusieurs paramètres :

  • le niveau n de répétition
  • la longueur du tronc
  • la largeur w : afin que les arbres éloignés soient plus fins que les arbres au premier plan, on définit la largeur. Plutôt que d’utiliser w-1 (sinon après un certain niveau de répétition la valeur deviendrait négative), on utilise w/1.2 ce qui permet de réduire la valeur sans changer son signe.
  • r1,g1,b1 : qui définissent en RGB la couleur des feuilles.
  • r2,g2,b2 : qui définissent en RGB la couleur du tronc.

Ce code provient de https://my.numworks.com/python/cent20/arbre

Le fond

L’exécution du fond et des montagnes

A chaque exécution le fond va être d’une couleur aléatoire.

color(randint(10,250),255,255)
begin_fill()
goto(-640,700)
pendown()
goto(640,700)
goto(640,-700)
goto(-640,-700)
end_fill()

A chaque fois que nous exécutons le script, le résultat est unique, les montagnes ayant une forme définie auront une couleur aléatoire.

Script d’une des montagnes :

for i in range (10):
    for i in range (5):
        forward(20)
        right(2)
    for i in range (5):
        forward(10)
        left(2)

Cette boucle crée des fragments de cercles collés, qui forment une ondulation.

Les trois montagnes donnent cette image, avec des couleurs uniques à chaque fois.

L’exécution des arbres

On dessine 7 arbres en tout : 2 sur la montagne du fond, 2 sur la montagne du milieu et trois sur la montagne du devant. Chaque arbre a un secteur donné sur sa montagne et il est dessiné dans ce secteur, de façon unique à chaque fois.

Les arbres sur la montagne la plus éloignée sont plus petits, plus fins et plus sombres, cependant chaque arbre est d’une couleur, d’une taille et d’une largeur différentes à chaque exécution.

Voici par exemple l’exécution d’un arbre sur la montagne du fond

penup()
goto(randint(-550,-450),randint(120,160))
pendown()
setheading(90)
color(75,randint(40,50),randint(0,20))
arbre(9,randint(50,90),randint(4,7),randint(130,180),randint(160,180),180,75,randint(40,50),randint(0,20))

L’exécution des flocons

Ensuite on exécute les flocons:

for i in range (randint(30,45)):
    setheading(randint(0,360))
    color(randint(0, 220),randint(110, 240),255)
    begin_fill()
    flocon(randint(20,50),randint(3,5),randint(-639,639),randint(-310,310))
    end_fill()

A chaque exécution, le nombre de flocons est différent. Chaque flocon est orienté différemment , à une couleur, une taille, un niveau de répétition, et un emplacement différent.

L’image finale

Télécharger le .py

Si vous voulez l’essayer, vous trouverez le script ci-dessous, cependant faites attention, chaque arbre prend relativement longtemps à s’exécuter, ajouté aux flocons, le script prend environ 1h30 à s’exécuter.

Art

Pendules : Une horloge analogique

Une horloge analogique… Qu’est-ce cela peut bien être… Eh bien, c’est tout simplement une horloge avec des aiguilles ! Ainsi, ce programme vous permettra, grâce à Turtle, d’afficher une horloge analogique…

Introduction

La spécificité de cette horloge, est que celle-ci est dynamique. C’est-à-dire que les aiguilles bougent en fonction de l’heure réel. Sinon cela serait trop facile, il suffirait seulement de dessiner un cercle pour le cadran, et des segments pour les aiguilles, et c’est fini. Heureusement, ce n’est pas le cas.

Quelques fonctions

Pour afficher l’heure réel, il faut d’abord récupérer l’heure réel… Pour cela, j’utilise la fonction time.strftime(), à partir du module time, je récupère une donnée de la date actuelle, en l’occurrence j’ai besoin de 3 données : l’heure, la minute, et la seconde. Voici donc une fonction que j’ai codé qui m’a permis de récupérer une de ces 3 données :

def get_time(u):
    match u:
        case "h":
            return int(strftime("%I"))
        case "m":
            return int(strftime("%M"))
        case "s":
            return int(strftime("%S"))

Ici, j’ai utilisé la déclaration match, qui permet, entre autres, de comparer la valeur d’une variable, ici la variable u (pour unité). Par exemple, en appelant la fonction suivante get_time("h"), elle me renvoi la valeur de l’heure actuelle, à l’heure où j’écris cet article, il est exactement 01:44 donc en appelant la fonction maintenant, elle me renverrait la valeur 1.
À savoir qu’utiliser la déclaration match n’est absolument pas obligatoire, j’aurais très bien pu utiliser une structure conditionnelle traditionnelle avec les déclarations if, elif, et else.

Désormais, j’ai besoin d’afficher le cadran de l’horloge, pour cela, rien de plus simple :

def draw_clock(x, y, rayon):
    travel(x, y-rayon)
    pencolor((0,)*3)
    fillcolor((255,)*3)
    begin_fill()
    circle(rayon)
    end_fill()
    travel(x, y-rayon+10)
    fillcolor(7, 24, 31)
    begin_fill()
    circle(rayon-10)
    end_fill()
    travel(x, y-5)
    fillcolor(85, 91, 92)
    begin_fill()
    circle(5)
    end_fill()
    penup()
    goto(x, y)
    setheading(90)
    pencolor((255,)*3)
    for i in range(60):
        forward(rayon-(25 if i%5 == 0 else 15))
        pendown()
        forward(25 if i%5 == 0 else 15)
        penup()
        goto(x, y)
        right(6)

C’est une fonction plutôt simple, bien qu’elle soit assez lourde. On dessine des cercles, et on fait les marquages des minutes et des heures. J’ai dans cette fonction, utilisé une autre fonction qui ne vient pas des modules importés, la fonction travel() (pour voyager). J’aime beaucoup cette fonction car elle est extrêmement simple, et permet d’économiser quelques lignes :

def travel(x, y):
    penup()
    goto(x, y)
    pendown()

En fait, c’est tout simplement l’équivalent d’un goto(), mais sans laisser les traces du pinceau ! Voici donc le cadran, il est fixe :

J’ai également voulu ajouter dans le fond un mur en briques. Pour ne pas laisser le fond vide, la fonction fait seulement 7 lignes :

def wall_brick(x, y, width_bricks, height_bricks):
    for i in range(height_bricks):
        for j in range(width_bricks):
            if i % 2 == 0:
                fill_rect(x+65*j, y+35*i, 60, 30, (161, 84, 68))
            else:
                fill_rect(x+30+65*j, y+35*i, 60, 30, (161, 84, 68))

Les paramètres sont simples, la position du mur (le bas à gauche du mur) via x et y, et le nombre de briques en longueurs, ainsi que le nombre de briques en hauteur. fill_rect() est une fonction maison inspiré de kandinsky.fill_rect(), elle permet de dessiner des rectangles :

def fill_rect(x, y, w, h, c=(0, 0, 0)):
    travel(x, y)
    pencolor(c)
    fillcolor(c)
    begin_fill()
    for i in range(4):
        forward(w if i % 2 == 0 else h)
        right(90)
    end_fill()

Ci-dessous donc, le mur en briques, contruit par la fonction wall_brick(-668, -330, 21, 21) :

Difficultés rencontrées

Il ne reste donc plus qu’à dessiner les aiguilles et les faire pivoter au fur et à mesure. Voici donc la fonction qui occupe cette lourde tâche, et qui m’a bien cassé la tête :

def clock_hands(colors_hands, size_hands):
    s, m, h, k = get_time("s"), get_time("m"), get_time("h"), 0
    update_hours(h, colors_hands[0], size_hands[0])
    update_minutes(m, colors_hands[1], size_hands[1])
    while True:
        update_seconds(s, colors_hands[2], size_hands[2])
        sleep(.6 if k < 90 else .5 if k < 180 else .3 if k < 240 else 0)
        s += 1
        if s == m+2:
            update_minutes(m, colors_hands[1], size_hands[1])
        if s+1 == (h+1)*5:
            update_hours(h, colors_hands[0], size_hands[0])
        if s == 60:
            s, m, h = get_time("s"), get_time("m"), get_time("h")
            update_minutes(m, colors_hands[1], size_hands[1])
            update_hours(h, colors_hands[0], size_hands[0])
            update_seconds(s, colors_hands[2], size_hands[2], 1)
        k += 1

C’est sans doute la fonction la plus compliquée du programme. Les deux paramètres ne sont qu’esthétique, ils permettent de modifier la couleur de chaque aiguille, ainsi que la largeur de chaque aiguille, on ne donc y s’attarder plus que ça.
L’objectif est simple, avoir l’heure la plus précise possible, mais en gardant un mouvement des aiguilles fluide.
J’ai fait le choix d’appeler la fonction get_time() le moins de fois possible, car elle requiert de faire un nombre extrêmement élevé de requêtes plusieurs fois par secondes. Et faire des requêtes inutiles, ça ralentit le programme… La fonction n’est donc appelée que lors de l’initialisation (avant de rentrer dans la boucle infinie), et lorsque la trotteuse à passe à la soixantième seconde. Nous appelons donc la fonction get_time() environ une fois par minute ; et c’est suffisant. Ensuite, on met à jour la position des aiguilles toutes les secondes… Enfin, c’est un peu plus compliqué que ça. En effet, il faut que le mouvement soit fluide, et donc il faut supprimer toutes les actions inutiles. Sauf que 98% du temps, il n’y a que l’aiguille des secondes qui bouge, celle des minutes et des heures ne bougent beaucoup moins souvent. Donc cela ne sert à rien de mettre à jour ces aiguilles à chaque seconde. On le fait donc à des instants précis.
Malgré toutes les optimisations pour fluidifier le rafraichissement, il n’est malheureusement pas parfait.
Également, il s’avère que plus le programme tourne longtemps, plus il est lent… Il faut donc adapter la pause de la fréquence en fonction de quand le programme a démarré. Voici à quoi sert la variable k, et la fonction time.sleep(), nous perdons donc beaucoup de précisions au fil du temps. Mais en contrepartie, j’ai mis en place un système pour rerégler automatiquement les aiguilles.

L’image finale

À toi de « jouer » ?!

Tu ne pourras malheureusement pas vraiment t’amuser avec ce programme. À moins que tu veuilles fixer une horloge. Néanmoins, si tu veux savoir comment elle fonctionne exactement, et la voir bouger, n’hésite pas à télécharger le script !

Télécharger le .py

Tutoriels

Exporter une image générée par le module turtle sur…

Il est possible de produire des images à l’aide d’un script python, en exploitant par exemple la bibliothèque turtle de python. Nativement, le module turtle propose un export au format .ps de l’image générée. Ce tutoriel vous permettra d’exporter cette image au format .png

Exporter une image au format .ps

Nativement, le module turtle de python est capable d’exporter une image au format .ps (découvrir le .ps) comme dans l’exemple ci-dessous.

from turtle import *

list1 = ["blue","cyan", "pink", "magenta", "purple"]
for i in range(42) :
  color(list1[i%5])
  pensize(42)
  forward(4*i)
  right(42)
  
image = getcanvas()
image.postscript(file="image.ps", colormode='color')

Cette image est crée puis enregistrée dans le même dossier que celui qui contient le script .py au format .ps

Cette image n’est pas affichée par l’explorateur Windows, il ne gère pas nativement ce format.

Il est possible de l’ouvrir et de la modifier modifiée sous GIMP, et éventuellement de l’exporter au format .png depuis ce logiciel libre.

L’image ouverte dans Gimp

Cette solution présente 4 défauts :

  • Chaque exécution du script va écraser l’image précédente,
  • Le nom du fichier est non pertinent,
  • Le format .ps n’est pas directement utilisable.
  • La taille de l’image n’est pas gérée.

Exporter une image au format .ps avec un nom de fichier défini

from turtle import *

# Uniquement des lettres, des chiffres, un tiret. Rien d'autre.
titre = "Spirale - construite avec turtle"

# Définir le titre de la fenêtre de turtle + propagande ^^
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")

list1 = ["blue","cyan", "pink", "magenta", "purple"]
for i in range(42) :
  color(list1[i%5])
  pensize(42)
  forward(4*i)
  right(42)
  
image = getcanvas()
image.postscript(file=titre+".ps", colormode='color')

La fenêtre turtle à désormais un titre :

Ce titre est exploité pour générer un fichier correctement nommé :

On va maintenant ajouter un identifiant, presque unique pour que les images ne s’écrasent pas.

from turtle import *
from datetime import datetime

# Uniquement des lettres, des chiffres, un tiret. Rien d'autre. https://learn.microsoft.com/fr-fr/windows/win32/fileio/naming-a-file
titre = "Spirale - construite avec turtle"

# Définir le titre de la fenêtre de turtle + propagande ^^
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI") 

list1 = ["blue","cyan", "pink", "magenta", "purple"]
for i in range(42) :
  color(list1[i%5])
  pensize(42)
  forward(4*i)
  right(42)
  
image = getcanvas()
nom_du_fichier=titre+"_"+hex(datetime.now().microsecond)+".ps"
image.postscript(file=nom_du_fichier, colormode='color')

L’image sera générée aura un identifiant presque unique, codée en base 16.
Après réflexion, un nombre aléatoire généré par le module random aurait été préférable et plus simple 🤔

Si les deux dernières lignes sont exécutés trois fois, on obtient 3 images (identiques) mais ayant chacune un identifiant unique.

Remarque : Il est possible, que parfois une une nouvelle image écrase une précédente, mais la probabilité est faible.

Exporter une image au format .png avec une résolution cible

Pour exporter également les images au format .png, on va avoir besoin du module PILLOW de python et de ghostscript.

  1. Installer ghostscript : https://ghostscript.com/releases/gsdnld.html
  2. Installer PIL, sous Thonny
    Outil > Ouvrir la console système> pip install pillow
  3. Redémarrer l’ordinateur.
  4. Redémarrer Thonny. (ceinture + bretelle 😩)
    Outil > Ouvrir la console système > pip show PILLOW
    Vous devriez voir la version de PIL affichée

Le script final spécifie le format de l’image (ici en 720p), génère le fichier au format .ps et le fichier au format .png.

from turtle import *
from random import randint
from PIL import Image

# Uniquement des lettres, des chiffres, un tiret. Rien d'autre. https://learn.microsoft.com/fr-fr/windows/win32/fileio/naming-a-file
titre = "Spirale - construite avec turtle"

# Définir le titre de la fenêtre de turtle + propagande ^^
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")

# definir la taille de la fenêtre en 720p (Largeur, Hauteur, abscisse départ, ordonnée du départ)
setup(1280, 720, 0, 0) 

# ============== MON SCRIPT PYTHON ==============

list1 = ["blue","cyan", "pink", "magenta", "purple"]
for i in range(2*42) :
  color(list1[i%5])
  pensize(42)
  forward(4*i)
  right(42)  

# ============== GENERER DES IMAGES AUTOMATIQUEMENT ==============

image = getcanvas()
nom_du_fichier_sans_extension=titre+"_"+hex(randint(2**30+2**25,2**30+2**25+2**24-1))[2:]

# Génère un fichier .ps
image.postscript(file=nom_du_fichier_sans_extension+".ps", colormode='color')

# Ouvre le fichier .ps et génère le fichier .png
psimage = Image.open(nom_du_fichier_sans_extension+".ps")
psimage.save(nom_du_fichier_sans_extension+".png")

A noter : Pour l’instant l’export ne respecte pas la résolution imposée (720p), l’image générée fait 959 par 540 pixels. Des investigations sont en cours pour comprendre le problème.

Un fichier .py qui gère les erreurs

Les élèves ne lisent pas les tutoriels, ils préfèrent appeler l’enseignant car « cela ne marche pas ».
Le fichier .py ci-dessous gérera ce problème et les deux erreurs classiques probables.
Si l’élève n’a pas suivi le tuto ou qu’il n’a pas réussi à installer les modules requis, l’image .png ne sera pas générée mais le script ne plantera pas.

try, except pour une gestion propre des plantages.

try:
    from PIL import Image
    pillow_installed = True
except:
    print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :")
    print("https://nsi.xyz/py2png")
    pillow_installed = False

Rudiments pour le module turtle

A lire ici : Découvrir le module turtle de python

Support technique

Aucun support technique ne sera assuré concernant ce tutoriel.

En cas de problème, vous pouvez toujours répondre à ce message sur twitter mais sans garantie de réponse 😉

One More Thing

Le code final formate le nom du fichier avec

randint(2**30+2**25,2**30+2**25+2**24-1)

Pourquoi 230+225 ?

Evolution à prévoir en 2023

1. Générer les images à l’aide d’une fonction, afin de pouvoir l’appeler à plusieurs moments, utile pour écrire l’article de présentation.

2. Intégrer ceci :

Tester ceci (aussi dans un mail reçu le 13 nov. 2022 09:50)