Quelle Calculatrice Choisir 2021 édition Universelle
Épisode 10 - Python turtle + compatibilité

TI-Planet
en cette rentrée 2021, nous te publions la base de données intégrale de nos classements de rentrée QCC
organisés depuis la rentrée 2015.Nous en profitons de plus pour te réaliser le travail titanesque d'étendre les tests aux modèles plus anciens :
- toutes les calculatrices graphiques Texas Instruments(depuis la premièreTI-81de 1990)
- les calculatrices graphiques Casiode la générationIcon Menu Power Graphic(depuis 1996)
163
modèles différents testés sous toutes leurs coutures, 10 ans de tests et découvertes à portée de clic ! 
Python
et parlons turtle
. Il y a justement du nouveau à ce sujet, puisque Texas Instruments
vient tout juste de sortir un module turtle
additionnel pour ses TI-Nspire CX II
.Mais qu'est-ce que c'est que
turtle
? Les interpréteurs Python
sur nos calculatrices peuvent offrir usuellement jusqu'à 3 types de modules de tracé :- tracé par pixels, habituellement propriétaire au constructeur
- tracé dans un repère, plus ou moins proche du standard matplotlib.pyplot
- et tracé relatif à la tortue, plus ou moins proche du standard , le plus proche de ce qui a été pratiqué au collège avec le langageturtleScratch
Nous allons profiter de l'occasion pour faire d'une pierre deux coup. Nous allons à la fois découvrir ensemble le nouveau
turtle
des TI-Nspire CX II
, et directement le comparer à ce qui existe déjà chez la concurrence, à savoir :- turtlepourTI-Nspire CX II
- turtlesurCasio Graph 35+E IIetGraph 90+E
- turtlesurNumWorks
- turtleviaKhiCASsurNumWorksetTI-Nspire CX
- ce_turtlsurTI-83 Premium CE Edition Python,TI-84 Plus CE-T Python EditionetTI-84 Plus CE Python
Nous allons donc exécuter quelques scripts
turtle
et comparer leurs affichages à ce que donne le turtle Python
standard sur ordinateur, et donc la plus ou moins grande facilité que tu auras à exécuter des scripts Python turtle
conçus pour d'autres plateformes. ce_turtl
était particulièrement mauvais sur ce dernier point ; nous allons donc voir si Texas Instruments
a apporté davantage de soin à son module turtle
pour TI-Nspire CX II
.Commençons déjà par détecter quelques problèmes bloquants avant l'exécution, et peut-être même les corriger. Voici notre tout nouveau
Turtle Doctor

- Code: Select all
_turtle_errors = 0
def _turtle_error(k):
global _turtle_errors
_turtle_errors |= 1 << k
# import turtle
try: #TI-83 Premium CE
from ce_turtl import turtle
turtle.clear()
_turtle_error(0)
except ImportError:
import turtle
if not "forward" in dir(turtle):
turtle = turtle.Turtle()
# can turtle be patched ?
_fix_turtle = True
try:
def _fixcolorlist(c): return c
def _fixcolorval(c): return c
def _fixcolorstring(c): return c
def _fixcolor(c): return turtle._fixcolorlist(turtle._fixcolorval(turtle._fixcolorstring(c)))
turtle._fixcolorlist = _fixcolorlist
turtle._fixcolorval = _fixcolorval
turtle._fixcolorstring = _fixcolorstring
turtle._fixcolor = _fixcolor
except:
_fix_turtle = False
# test/fix color() + pencolor()
if not "pencolor" in dir(turtle):
_turtle_error(1)
if _fix_turtle: turtle.pencolor = turtle.color
if not "color" in dir(turtle):
_turtle_error(2)
if _fix_turtle: turtle.color = turtle.pencolor
# test color argument types
_color_types = 0
try:
turtle.pencolor([0, 0, 0])
_color_types |= 1 << 0
except: _turtle_error(4)
try:
turtle.pencolor((0, 0, 0))
_color_types |= 1 << 1
except: _turtle_error(5)
try:
turtle.pencolor(0, 0, 0)
_color_types |= 1 << 2
except: pass
try:
turtle.pencolor("black")
_color_types |= 1 << 3
except: _turtle_error(6)
_fix_color = not _color_types & 1 << 0 or not _color_types & 1 << 1 or not "colormode" in dir(turtle)
# fix list/tuple color argument
if _fix_turtle:
if not _color_types & 1 << 0 and _color_types & 1 << 1:
def _fixcolorlist(c): return type(c) is list and tuple(c) or c
turtle._fixcolorlist = _fixcolorlist
if not _color_types & 1 << 1 and _color_types & 1 << 0:
def _fixcolorlist(c): return type(c) is list and list(c) or c
turtle._fixcolorlist = _fixcolorlist
# fix color() + pencolor()
if _fix_turtle and _fix_color:
turtle._color = turtle.color
turtle._pencolor = turtle.pencolor
if _color_types & 1 << 0 or _color_types & 1 << 1:
def _color(*argv):
if not(len(argv)): return turtle._color()
turtle._color(turtle._fixcolor(argv[0]))
def _pencolor(*argv):
if not(len(argv)): return turtle._pencolor()
turtle._pencolor(turtle._fixcolor(argv[0]))
else:
def _color(*argv):
if not(len(argv)): return turtle._color()
c = turtle._fixcolor(argv[0])
turtle._color(c[0], c[1], c[2])
def _pencolor(*argv):
if not(len(argv)): return turtle._pencolor()
c = turtle._fixcolor(argv[0])
turtle._pencolor(c[0], c[1], c[2])
turtle.color = _color
turtle.pencolor = _pencolor
# test/fix colormode()
_color_mode = 0
if not "colormode" in dir(turtle):
_turtle_error(3)
# test color mode
try:
turtle.pencolor([255, 0, 0])
_color_mode = 255
except: _color_mode = 1.0
if _fix_turtle:
turtle._color_mode = _color_mode
def _colormode(*argv):
if not(len(argv)): return turtle._color_mode
if int(argv[0]) in (1, 255):
turtle._color_mode = int(argv[0]) == 255 and 255 or 1.0
turtle.colormode = _colormode
if _color_mode == 255:
def _fixcolorval(c): return int(turtle._color_mode) == 1 and type(c) in (list, tuple) and [int(c[k] * 255) for k in range(3)] or c
else:
def _fixcolorval(c):
return turtle._color_mode == 255 and type(c) in (list, tuple) and [int(c[k] / 255) for k in range(3)] or c
turtle._fixcolorval = _fixcolorval
# test/fix color strings
_colors_fix={"black":(0,0,0),"blue":(0,0,1),"green":(0,1,0),"red":(1,0,0),"cyan":(0,1,1),"yellow":(1,1,0),"magenta":(1,0,1),"white":(1,1,1),"orange":(1,0.65,0),"purple":(0.66,0,0.66),"brown":(0.75,0.25,0.25),"pink":(1,0.75,0.8),"grey":(0.66,0.66,0.66)}
for c in list(_colors_fix.keys()):
try:
turtle.pencolor(c)
_colors_fix.pop(c)
except: pass
turtle.pencolor((0, 0, 0))
if len(_colors_fix):
if _color_types & 1 << 3:
_turtle_error(7)
if _fix_turtle:
def _fixcolorstring(c):
if type(c) is str and c in _colors_fix:
c = _colors_fix[c]
if turtle.colormode() == 255:
c = [int(c[k] * 255) for k in range(3)]
return c
turtle._fixcolorstring = _fixcolorstring
# test/fix circle(,)
try: turtle.circle(0,0)
except:
_turtle_error(8)
if _fix_turtle:
turtle._circle = turtle.circle
def _circle(r, a=360): turtle._circle(r)
turtle.circle = _circle
if not "write" in dir(turtle):
_turtle_error(9)
if _fix_turtle:
def _write(s): pass
turtle.write = _write
if not "pensize" in dir(turtle):
_turtle_error(10)
if _fix_turtle:
def _pensize(s): pass
turtle.pensize = _pensize
def turtle_diags():
print("Type: " + str(type(turtle)))
print("Patchable: " + (_fix_turtle and "yes" or "no"))
errors_msg = (
"No <import turtle>",
"No pencolor()",
"No color()",
"No colormode(): " + str(_color_mode),
"No color as list",
"No color as tuple",
"No color as string",
"Missing colors strings: ",
"No circle(,angle)",
"No write()",
"No pensize()",
)
errors = 0
for k in range(len(errors_msg)):
if _turtle_errors & 1 << k:
errors += 1
msg = "Err " + str(k) + ": " + errors_msg[k]
if k == 7:
msg += str(len(_colors_fix)) + " " + str(tuple(_colors_fix.keys()))
print(msg)
print(str(errors) + " error" + ((errors > 1) and "s" or ""))


Turtle Doctor
Par exemple,
Turtle Doctor
NumWorks

Aucun problème non plus avec
KhiCAS
pour NumWorks
et TI-Nspire CX
! 

Casio Graph 35+E II
et Graph 90+E
, quelques détails :- absence de la méthode .color()
- absence de la méthode .colormode()
Turtle Doctor
turtle
est modifiable : on peut le patcher
à chaud (à chaque exécution)
afin de corriger. 
Le but des corrections n'est pour le moment pas d'obtenir quelque chose d'identique au standard, mais juste de permettre l'exécution des scripts qui vont suivre :
- Nous choisissons de créer une méthode .color()synonyme de.pencolor()
- Et pour .colormode(), outre la création de la méthode, il nous faut détecter le format de coordonnées de couleurs attendu par le module, afin de convertir le cas échéant. La méthode.colormode()lorsque présente permet de basculer entre les 2 systèmes de coordonnées suivants :
- mode 255: couleursRGBavec chaque composante prenant une valeur entière de0à255
- mode 1.0: couleursRGBavec chaque composante prenant une valeur flottante de0à1
turtletravaille en fait en format1.0, mode qu'il est donc impossible de modifier ici. - mode


turtle
pour TI-Nspire CX II
.Une fois installé correctement dans le dossier
/PyLib/
comme expliqué, les fonctions offertes par turtle
sont alors rajoutées au menu.Attention toutefois, comme tout module présent dans le dossier
/PyLib/
, turtle
ne sera pas disponible en mode examen. 
Le module s'importe de la façon suivante, qui est bien une des façons standard :
- Code: Select all
from turtle import Turtle
turtle = Turtle()

- absence de la méthode .colormode(), avec un fonctionnement bloqué en mode255
- absence de gestion du 2ème argument de la méthode .circle()pour tracer un arc de cercle
- et pire, pour les paramètres de couleur :
- refus des paramètres de type liste, n'accepte que des tuples - est-ce un bug ?...
- accepte les paramètres de type chaîne de caractères, mais ignore plusieurs codes de couleur usuels : "pink","grey","brown","purple"
- refus des paramètres de type liste, n'accepte que des tuples -
turtle
importé est modifiable à chaud et peut donc être librement modifié et donc corrigé. En approfondissant la chose, la méthode Turtle Doctor

ce_turtl
pour les éditions Python
des TI-83 Premium CE
et TI-84 Plus CE
. Comme annoncé hélas, c'est une véritable catastrophe niveau conformité au standard. Pas moins de 8 erreurs sont anticipées :- déjà, de par son nom il ne s'importe pas de façon standard, c'est-à-dire qu'aucune des 3 méthode suivantes ne fonctionne :
import turtle
,from turtle import *
, ou encore- Code: Select all
from turtle import Turtle
turtle = Turtle()
- absence de la méthode .pencolor(), qui est remplacée ici par.color()
- absence de la méthode .colormode(), avec un fonctionnement bloqué en mode255
- absence de la méthode .write()pour écrire du texte
- absence de gestion du 2ème argument de la méthode .circle()pour tracer un arc de cercle
- et pire, pour les paramètres de couleur, refus de toute les formes standard : aussi bien liste que tuple ou chaîne de caractère. La méthode color()attend non pas 1 mais 3 arguments, soit un argument par composante.
turtle
importé est certes modifiable à chaud et la méthode Turtle Doctor
(heap)
Python
sur ces calculatrices. Nous sommes déjà à peine à quelques lignes de l'erreur de mémoire, aller plus loin dans cette voie n'est pas envisageable sur ces modèles. 
Pour comparer, il y a malgré tout moyen d'avoir du code d'importation fonctionnant à la fois sur l'ensemble de ces plateformes et sur ordinateur. Par exemple :
- Code: Select all
try: # TI-83PCE/84+CE
from ce_turtl import turtle
turtle.clear()
except ImportError:
import turtle # multiplateformes
if not "forward" in dir(turtle): # TI-Nspire CX II
turtle = turtle.Turtle()
turtle
standard, ainsi que la compatibilité entre différentes calculatrices graphiques.Nous allons pour cela prendre plusieurs exemples et lancerons le même code sur différents modèles.
On commence par une petite rosace ; tout possesseur de
Graph 35+E II
sait que Casio adore ça : 
ordi | NumWorks | Graph 90+E Graph 35+E II | TI-Nspire CX II turtle | TI-83PCE/84+CE ce_turtl | |
![]() | ![]() | ![]() ![]() | ![]() | ![]() | ![]() |
|
Petit léger détail, le
turtle.pensize(1)
n'est respecté ni par KhiCAS
ni par ce_turtl
.Ceci mis à part, le code passe ici sans problème.

Poursuivons avec la fractale de Koch :
Pas de nouveau problème ici.
ordi | NumWorks | Graph 90+E Graph 35+E II | TI-Nspire CX II turtle | TI-83PCE/84+CE ce_turtl | |
![]() | ![]() | ![]() ![]() | ![]() | ![]() | ![]() |
|
Pas de nouveau problème ici.

Passons maintenant aux flocons de Koch :
Pour ce que l'on obtient pas de problème de tracé avec le module
On comprend mieux ici le problème du
Mais notons justement par rapport à a visiblement correctement injecté l'interception des paramètres de couleurs passés sous la forme de chaînes de caractères.
ordi | NumWorks | Graph 90+E Graph 35+E II | TI-Nspire CX II turtle | TI-83PCE/84+CE ce_turtl | |
![]() | ![]() | ![]() ![]() | ![]() | ![]() | ![]() |
|
Pour ce que l'on obtient pas de problème de tracé avec le module
turtle
de KhiCAS
, le problème vient d'autre chose. Ce module turtle
a l'air d'être extrêmement gourmand, arrivant à déclencher une erreur de mémoire en cours d'exécution alors que d'autres modèles avec un heap
Python
absolument ridicule en comparaison s'en sortent parfaitement.On comprend mieux ici le problème du
.pensize()
sur ce_turtl
et KhiCAS
. Malgré les réglages différents tous les flocons sont ici trop épais d'1 pixel, il y a visiblement un décalage.Mais notons justement par rapport à
ce_turtl
, que notre script Turtle Doctor
Nous arrivons maintenant à un soleil :
Notons que a réussi à parfaitement corriger les paramètres de couleurs sur 
ordi | NumWorks | Graph 90+E Graph 35+E II | TI-Nspire CX II turtle | TI-83PCE/84+CE ce_turtl | |
![]() | ![]() | ![]() ![]() | ![]() | ![]() | ![]() |
|
Notons que
Turtle Doctor
ce_turtl
, tuples et listes étant maintenant utilisables ! 
Poursuivons avec une coquille d'escargot :

ordi | NumWorks | Graph 90+E Graph 35+E II | TI-Nspire CX II turtle | TI-83PCE/84+CE ce_turtl | |
![]() | ![]() | ![]() ![]() | ![]() | ![]() | ![]() |
|
ce_turtl
nous fait ici une véritable catastrophe. Le problème vient de la méthode .circle()
qui ne respecte pas du tout le standard. Au lieu de tracer un cercle qui passe par la position de la tortue, elle trace un cercle qui prend pour centre la position de la tortue. 
Passons maintenant aux triangles de Sierpiński :
Et mince, c'est justement le piège qui fait trébucher pas mal de modèles.
Ici encore, après avoir commencé un tracé parfait,
ordi | NumWorks | Graph 90+E Graph 35+E II | TI-Nspire CX II turtle | TI-83PCE/84+CE ce_turtl | |
![]() | ![]() | ![]() ![]() | ![]() | ![]() | ![]() |
|
Et mince, c'est justement le piège qui fait trébucher pas mal de modèles.
Ici encore, après avoir commencé un tracé parfait,
KhiCAS
se met à manquer de mémoire.La
Et mince, c'est justement le piège qui fait trébucher pas mal de modèles.
Rapidement, très léger détail sur les
Pour les modules qui ne gèrent pas l'appel
Le cas
Casio Graph 90+E
s'en sort fort honorablement jusqu'à présent, non ? Dédions-lui un tableau :ordi | NumWorks | Graph 90+E Graph 35+E II | TI-Nspire CX II turtle | TI-83PCE/84+CE ce_turtl | |
![]() | ![]() | ![]() ![]() | ![]() | ![]() | ![]() |
|
Et mince, c'est justement le piège qui fait trébucher pas mal de modèles.
Rapidement, très léger détail sur les
Casio Graph 35+E II
et Graph 90+E
. La méthode .write()
prend les coordonnées indiquées comme coin supérieur gauche du texte affiché, alors que le standard est de les prendre comme coin inférieur gauche.Pour les modules qui ne gèrent pas l'appel
.circle(rayon, angle)
les arcs de cercles sont ici remplacés par des cercles, ce qui naturellement perturbe le reste du tracé.Le cas
KhiCAS
est toutefois plus surprenant, cet appel étant bien géré... 
Le nouveau 
Sur la conformité au standard. 
Nous ignorons si
En attendant donc mieux, les différentes solutions
turtle
TI-Nspire CX II
est une superbe réalisation. On apprécie particulièrement la grille et le repère entièrement configurables, une véritable valeur ajoutée ! 
Sur la conformité au standard
turtle
ce n'est certes pas le meilleur, même si cela reste honorable. Il y a bien pire et plus grave que cela. Texas Instruments
a déjà fait un fort bel effort relativement à la catastrophe qu'était ce_turtl

Nous ignorons si
Texas Instruments
poursuivra ses efforts, mais à défaut nous avons quand même une excellente nouvelle. Bien que l'on n'ait pas accès au code source du module turtle
TI-Nspire CX II
celui-ci a le gros avantage de nous présenter des éléments modifiables à chaud. Comme de plus nous bénéficions ici d'un heap
Python
extrêmement généreux, pas moins de 2 Mo
soit l'un des plus larges tous modèles concurrents confondus, une conformité parfaite au standard est bel et bien envisageable, pourvu que quelqu'un se donne le temps de creuser la question. 
En attendant donc mieux, les différentes solutions
Python turtle
disposent désormais dans nos tableaux d'un indice de compatibilité / conformité au standard, basé sur les tests précédents :