Page 1 of 1

KhiCAS NumWorks Nspire CX: Python-turtle encore plus parfait

Unread postPosted: 19 Apr 2022, 11:25
by critor
15120Pour accompagner en douceur la transition du Scratch au Python en Seconde, la plupart des solutions Python sur calculatrices graphiques offrent turtle, une bibliothèque permettant du tracé relatif comme en Scratch. On peut citer :
  • la NumWorks dont l'application Python intègre directement turtle
  • les Casio Graph 35+E II et Graph 90+E dont l'application Python intègre directement turtle
  • les TI-Nspire CX II sur lesquelles on peut rajouter la bibliothèque officielle turtle (anciennement ce_turtl) à l'environnement Python
  • les TI-83 Premium CE Edition Python (France), TI-84 Plus CE-T Python Edition (Europe) et TI-84 Plus CE Python (Amérique du Nord), sur lesquelles on peut rajouter une bibliothèque turtle officielle
  • et KhiCAS

11302Aujourd'hui penchons-nous à nouveau sur le turtle de KhiCAS. Conçu par Bernard Parisse, enseignant-chercheur à l'Université de Grenoble, KhiCAS est la déclinaison sur calculatrices du logiciel de Mathématiques intégré Xcas. Disponible pour calculatrices NumWorks N0110, TI-Nspire CX, Casio Graph 35+E II et Graph 90+E, KhiCAS te donne donc accès à une interface unifiée ainsi qu'à des fonctionnalités haut de gamme peu importe la marque ou le modèle de ta calculatrice ! :bj:

12024Ce formidable environnement de Mathématiques et de sciences t'apporte bien des choses. Nous pouvons citer dans tous les cas :
  • la reprise du moteur de calcul formel GIAC développé pour Xcas par le même auteur.
  • la possibilité de programmer dans 2 langages :
    • le langage Xcas historique
    • le langage Xcas avec une couche de compatibilité syntaxique Python

Dans ses éditions pour TI-Nspire CX et NumWorks N0110, KhiCAS apporte pas mal de compléments :
  • possibilité de composer et convertir ses unités
  • une bibliothèque de constantes physiques
  • plusieurs applications elles-même intégrées, dont entre autres :
    • tableur / feuille de calcul
    • tableau périodique des éléments
    • calcul financier
  • 2 langages de programmation supplémentaires :
    • Python via un interpréteur Micropython
    • Javascript via un interpréteur QuickJS

L'environnement Python sur ces modèles est extrêmement riche, bien davantage que les solutions Python intégrées par les constructeurs. On peut citer nombre de bibliothèques :
  • cas et xcas pour appeler le moteur de calcul formel GIAC directement depuis tes scripts Python
  • cmath pour traiter directement tes calculs sur les nombres complexes en Python
  • linalg pour l'algèbre linéaire
  • arit pour l'arithmétique
  • ulab.scipy pour le calcul scientifique
  • ulab.numpy pour le calcul matriciel et vectoriel
  • plusieurs bibliothèque de tracés :
    • turtle pour les tracés relatifs à la Scratch
    • matplotlib pour les tracés dans un repère
    • graphic pour les tracés par pixels, accompagnée de casioplot pour la compatibilité avec les scripts graphiques Casio et kandinsky pour la compatibilité avec les scripts graphiques NumWorks
  • et bien d'autres : gc, math, micropython, nsp, pylab, random, sys, time, ubinascii, ucollections, uctypes, uerrno, uhashlib, uheapq, uio, ujson, ure, ustruct, uzlib

Un fantastique avantage du turtle KhiCAS, exclusif à ce jour, c'est qu'une fois que ton script Python-turtle a terminé de s'exécuter, il t'est possible d'en faire défiler l'affichage avec les flèches du clavier ! :bj:

La dernière mise à jour alpha de KhiCAS améliore encore plus la fiabilité de la bibliothèque turtle. Elle est disponible à ce jour :
  • uniquement en version alpha pour TI-Nspire CX
  • uniquement en version alpha pour NumWorks N0110
Découvrons ensemble les nouveautés.








A) Tests de conformité comparatifs (toutes solutions turtle)

Go to top

Tentons pour le moment un autodiagnostic plus général des différences entres les ancienne et nouvelle bibliothèques turtle de KhiCAS, c'est-à-dire la vérification de tout ce qui peut différer du standard.

Voici des scripts en ce sens, une amélioration majeure de ceux développés dans le code de notre test de rentrée QCC 2021 :
Code: Select all
_turtle_errors = 0

def _turtle_error(k):
  global _turtle_errors
  _turtle_errors |= 1 << k

# import turtle
try:
  import turtle
  if not "forward" in dir(turtle):
    turtle = turtle.Turtle()
except ImportError: #TI-83 Premium CE
  from ce_turtl import turtle
  _turtle_error(0)
try:
  turtle.clear()
except:
  turtle.reset()

# can turtle be patched ?
_fix_turtle = True
try:
  def _fixcolor(c): return c
  turtle._fixcolor = _fixcolor
except:
  _fix_turtle = False

# test color() + pencolor() + fillcolor()
if not "pencolor" in dir(turtle):
  pencolor = turtle.color
  _turtle_error(1)
else:
  pencolor = turtle.pencolor
if not "color" in dir(turtle):
  _turtle_error(2)
if not "fillcolor" in dir(turtle):
  _turtle_error(12)

if not "clear" in dir(turtle):
  _turtle_error(13)
if not "reset" in dir(turtle):
  _turtle_error(14)
if not "heading" in dir(turtle):
  _turtle_error(11)

# test color argument types
_color_types = 0
try:
  pencolor([0, 0, 0])
  _color_types |= 1 << 0
except: _turtle_error(4)
try:
  pencolor((0, 0, 0))
  _color_types |= 1 << 1
except: _turtle_error(5)
try:
  pencolor(0, 0, 0)
  _color_types |= 1 << 2
except: _turtle_error(6)
try:
  pencolor("black")
  _color_types |= 1 << 3
except: _turtle_error(7)

# test colormode()
if not "colormode" in dir(turtle):
  _turtle_error(3)

# test color strings
_colors_fix={
  "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),
  "black":(0,0,0),
}
for c in tuple(_colors_fix.keys()):
  try:
    pencolor(c)
    _colors_fix.pop(c)
  except: pass
if len(_colors_fix):
  if _color_types & 1 << 3:
    _turtle_error(8)

# test circle(,)
try: turtle.circle(0,0)
except:
  _turtle_error(9)

#test towards
try: turtle.towards
except:
  _turtle_error(15)

# test for unfixable missing functions
_missing_fct=["write","pensize","dot"]
for f in tuple(_missing_fct):
  try:
    eval("turtle."+f)
    _missing_fct.remove(f)
  except: pass
if len(_missing_fct):
    _turtle_error(16)

_missing_alias=[
  ["backward","back","bk"],
  ["forward","fd"],
  ["right","rt"],
  ["left","lt"],
  ["position","pos"],
  ["goto","setpos","setposition"],
  ["setheading","seth"],
  ["pendown","pd","down"],
  ["penup","pu","up"],
  ["pensize","width"],
  ["showturtle","st"],
  ["hideturtle","ht"],
]
for aliases in tuple(_missing_alias):
  validf = None
  for f in tuple(aliases):
    try:
      eval("turtle."+f)
      validf = f
      aliases.remove(f)
      break
    except: pass
  for f in tuple(aliases):
    try:
      eval("turtle."+f)
      aliases.remove(f)
    except: pass
  if not len(aliases):
    _missing_alias.remove(aliases)
  else:
    aliases.insert(0, validf)
if len(_missing_alias):
    _turtle_error(17)

try:
  turtle.position()
except:
  try:
    turtle.pos()
  except:
    _turtle_error(10)
Code: Select all
from ttl_chk import *
from ttl_chk import _fix_turtle, _turtle_errors, _colors_fix, _missing_fct, _missing_alias

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()",
    "No color as list",
    "No color as tuple",
    "No color as args",
    "No color as string",
    "Missing colors strings: ",
    "No circle(,angle)",
    "Can't get position()",
    "No heading()",
    "No fill",
    "No clear()",
    "No reset()",
    "No towards()",
    "Other missing: ",
    "Missing aliases: ",
  )
  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 == 8:
        msg += str(len(_colors_fix)) + " " + str(tuple(_colors_fix.keys()))
      if k == 16:
        msg += str(len(_missing_fct)) + " " + " ".join(_missing_fct)
      if k == 17:
        l = []
        for v in _missing_alias:
          l.extend(v[1:])
        msg += str(len(l)) + " " + " ".join(l)
      print(msg)
  print(str(errors) + " error" + ((errors > 1) and "s" or ""))

turtle_diags()


Voici ce que nous racontent les scripts sur les différentes solutions turtle :

TI-83PCE/84+CE
turtle


TI-Nspire CX II
turtle

Casio
Graph 90E


KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl


NumWorks
Casio
Graph 35+E II



Aucune erreur n'est détectée automatiquement autmatiquement par nos scripts avec KhiCAS, chose exceptionnelle si l'on compare aux solutions officielles, et signe d'un soin absolument minutieux ! :bj:

Mais ça, c'est pour les problèmes détectables par des vérifications automatisées. Voyons maintenant d'éventuels écarts visuels sur quelques exemples de scripts.

Afin de pouvoir comparer équitablement avec les solutions officielles visiblement parfois bien moins conformes au standard turtle tout en conservant une unique version de chaque script utilisable sur l'ensemble des solutions, voici un script qu'il suffira d'importer à la place de chaque bibliothèque turtle et qui, lorsque celle-ci sera modifiable, corrigera la plupart des erreurs détectées : :bj:
Code: Select all
from ttl_chk import *
from ttl_chk import _color_types, _turtle_errors, _colors_fix, _missing_fct, _missing_alias

_fix_turtle = True

def nop(*argv): return None
idty = lambda c: c

try: # can turtle be patched ?
  turtle._fixcolorlist = idty
  turtle._fixcolorval = idty
  turtle._fixcolorstring = idty
  turtle._fixcolorargs = idty
  turtle._fixcolor = lambda c: turtle._fixcolorlist(turtle._fixcolorval(turtle._fixcolorstring(turtle._fixcolorargs(c))))
except:
  _fix_turtle = False

if _fix_turtle:

  # fix color() + pencolor()
  if _turtle_errors & 0x1000:
    turtle.fillcolor, turtle.begin_fill, turtle.end_fill = idty, nop, nop
  if _turtle_errors & 2:
    def _pencolor_(*argv):
      if len(argv): turtle.color(argv)
      else: return turtle.color()[0]
    turtle.pencolor = _pencolor_
  if _turtle_errors & 4:
    def _color_(*argv):
      if len(argv) == 2:
        turtle.pencolor(argv[0])
        turtle.fillcolor(argv[1])
      elif len(argv):
        turtle.pencolor(argv)
      else:
        return (turtle.pencolor(), turtle.fillcolor())
    turtle.color = _color_

  _fix_color = _color_types & 0b11 != 0b11 or not "colormode" in dir(turtle)

  # fix list/tuple color argument
  if _color_types & 0b11 == 0b10:
    def _fixcolorlist(c): return type(c) is list and tuple(c) or c
    turtle._fixcolorlist = _fixcolorlist
  if _color_types & 0b11 == 0b01:
    def _fixcolorlist(c): return type(c) is list and list(c) or c
    turtle._fixcolorlist = _fixcolorlist
  if not _color_types & 4:
    def _fixcolorargs(*argv):
      return len(argv) != 1 and argv or argv[0]

  if _fix_color:
    turtle._color = turtle.color
    turtle._pencolor = turtle.pencolor
    turtle._fillcolor = turtle.fillcolor
    if _color_types & 0b11:
      def _color(*argv):
        n = len(argv)
        if not(n): return turtle._color()
        elif n==2: turtle._color(argv[0], argv[1])
        else: turtle._color(n > 1 and argv or argv[0])
      def _pencolor(*argv):
        if not(len(argv)): return turtle._pencolor()
        turtle._pencolor(turtle._fixcolor(len(argv) > 1 and argv or argv[0]))
      def _fillcolor(*argv):
        if not(len(argv)): return turtle._fillcolor()
        turtle._fillcolor(turtle._fixcolor(len(argv) > 1 and argv or argv[0]))
    else:
      def _color(*argv):
        n = len(argv)
        if not(n): return turtle._color()
        c = turtle._fixcolor(n == 3 and argv or argv[0])
        turtle._color(c[0], c[1], c[2])
      def _pencolor(*argv):
        if not(len(argv)): return turtle._pencolor()
        c = turtle._fixcolor(len(argv)>1 and argv or argv[0])
        turtle._pencolor(c[0], c[1], c[2])
      def _fillcolor(*argv):
        if not(len(argv)): return turtle._fillcolor()
        c = turtle._fixcolor(len(argv)>1 and argv or argv[0])
        turtle._fillcolor(c[0], c[1], c[2])
    turtle.color = _color
    turtle.pencolor = _pencolor
    turtle.fillcolor = _fillcolor

  # fix colormode()
  if _turtle_errors & 8:
    # test color mode
    try:
      turtle.pencolor([255, 0, 0])
      _color_mode = 255
    except: _color_mode = 1.0
    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:
      turtle._fixcolorval = lambda c: int(turtle._color_mode) == 1 and type(c) in (list, tuple) and [int(c[k] * 255) for k in range(3)] or c
    else:
      turtle._fixcolorval = lambda c: turtle._color_mode == 255 and type(c) in (list, tuple) and [c[k] / 255 for k in range(3)] or c

  # fix color strings
  if len(_colors_fix):
    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

  # fix circle(,)
  if _turtle_errors & 0x200:
    turtle._circle = turtle.circle
    def _circle(r, a=360): turtle._circle(r)
    turtle.circle = _circle

  if len(_missing_fct):
    for f in _missing_fct:
      exec("turtle."+f+"=nop")

  if len(_missing_alias):
    for aliases in _missing_alias:
      validf = aliases[0]
      for f in aliases[1:]:
        exec(validf and "turtle."+f+"=turtle."+validf or "turtle."+f+"=nop")

  # fix clear()
  if _turtle_errors & 0x2000:
    turtle.clear = turtle.reset

  # fix reset()
  if _turtle_errors & 0x4000:
    turtle.reset = turtle.clear

  # fix towards()
  if _turtle_errors & 0x8000:
    from math import atan2, pi
    def _towards(x, y):
      x0, y0 = turtle.pos()
      return atan2(y - y0, x - x0) * 180 / pi
    turtle.towards = _towards




B) 4 exemples comparatifs améliorés

Go to top

Maintenant que nous avons de quoi faire tourner une unique version de chaque script sur l'ensemble des machines, poursuivons donc l'exploration de l'ensemble des solutions turtle avec quelques exemples de script.

Nous allons en profiter pour nous en donner à cœur joie avec les formidables fonctions de remplissage rajoutées dans l'avant-dernière version de KhiCAS, sur le thème de #LesMathématiquesSontBelles.

C'est donc l'occasion de voir si il y avait d'autres problèmes qui n'ont pas pu être détectés automatiquement, et si ils sont toujours présents dans la dernière version.

Plusieurs des exemples qui vont suivre sont inspirés de publications de Bert Wikkerink pour TI-Nspire CX II et très librement et fortement adaptés pour être fonctionnels dans le contexte du heap Python bien plus restreint des TI-83 Premium CE et compatibles.

Commençons par quelques exemples sur lesquels la dernière version de KhiCAS progresse :

Exemple B1 : Le défilé automobile

Go to top

Nous t'emmenons maintenant au défilé avec les logos de plusieurs grands constructeurs... automobiles :
Code: Select all
from ttl_fix import *

def rpoly(c, n):
  for k in range(n):
    turtle.forward(c)
    turtle.left(360 / n)

def audi(r):
  ir = 2 * r // 13
  turtle.penup()
  turtle.left(90)
  turtle.forward(r//2 - 2*ir)
  turtle.right(90)
  turtle.forward(-ir)
  turtle.pendown()
  turtle.pensize(3)
  for i in range(4):
    turtle.penup()
    turtle.forward(3 * ir)
    turtle.pendown()
    turtle.circle(2 * ir)

def mercedez_benz(r):
  ir = r // 2
  turtle.penup()
  turtle.forward(ir)
  turtle.left(90)
  turtle.forward(ir)
  turtle.pendown()
  turtle.pensize(2)
  x, y = turtle.pos()
  turtle.setheading(210)
  for i in range(3):
    turtle.goto(x,y)
    turtle.forward(ir)
    turtle.left(120)
  turtle.setheading(0)
  turtle.circle(-ir)

def citroen(r):
  x,y=turtle.pos()
  turtle.setheading(0)
  turtle.color((255,0,0), (255,0,0))
  turtle.begin_fill()
  rpoly(r, 4)
  turtle.end_fill()
  turtle.fillcolor((255,255,255))
  for i in range(2):
    turtle.setheading(45)
    turtle.begin_fill()
    for k in range(2):
      turtle.forward(.71 * r)
      turtle.left(k and 172 or -90)
    for k in range(2):
      turtle.forward(5 * r / 6)
      turtle.left(106)
    turtle.end_fill()
    y += r / 3
    turtle.penup()
    turtle.goto(x,y)
    turtle.pendown()

def mitsubichi(r):
  ir = r // 3
  turtle.penup()
  turtle.left(90)
  turtle.forward(ir)
  turtle.right(90)
  turtle.forward(r // 2)
  turtle.pendown()
  for i in range(3):
    turtle.setheading(60 + 120*i)
    turtle.color((255,0,0), (255,0,0))
    turtle.begin_fill()
    for k in range(4):
      turtle.forward(ir)
      turtle.left((k%2) and 120 or 60)
    turtle.end_fill()

def jeep(r):
  a=54
  ir = r/0.47552825814758/4 #sin(radians(a))/cos(radians(a))
  a=ir/0.85
  d=0.93*ir
  turtle.penup()
  turtle.forward(r//2)
  turtle.right(90)
  turtle.forward(ir - r)
  turtle.pendown()
  x, y = turtle.pos()
  turtle.setheading(234)
  turtle.forward(ir)
  turtle.left(126)
  turtle.fillcolor((180,180,180))
  turtle.begin_fill()
  rpoly(a, 5)
  turtle.end_fill()
  for i in range(5):
    col = i < 3 and (0,0,0) or (255,255,255)
    for j in range(2):
      turn =  j and turtle.left or turtle.right
      turtle.goto(x,y)
      turtle.setheading(90 + 72*i)
      turtle.fillcolor(col)
      turtle.begin_fill()
      turtle.forward(d)
      turn(172)
      turtle.forward(0.85*d)
      turn(44)
      turtle.forward(0.2*d)
      turtle.end_fill()
      col = [255 - col[k] for k in range(3)]

turtle.speed(0)
turtle.colormode(255)

r = 92
for iy in range(2):
  for ix in range(3):
    i = iy*3+ix
    if i < 5:
      y, x = (2*iy - 1) * r//2 - 48, (ix - 1)*r - 50
      turtle.penup()
      turtle.goto(x, y)
      turtle.setheading(0)
      turtle.pensize(1)
      turtle.pencolor((0,0,0))
      turtle.pendown()
      (mercedez_benz,jeep,mitsubichi,citroen,audi)[i](r)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

nouveau
KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II

ancien
KhiCAS
NumWorks
TI-Nspire CX II CX


Amélioration fantastique, KhiCAS rattrape le gros retard qu'il avait ici par rapport à la concurrence, et trace maintenant correctement les différents logos des constructeurs ! :bj:

Exemple B2 : Les flocons de Koch

Go to top

Encore une fois si tu es dans le Sud de la France, tu n'a pas dû voir de neige depuis des années... Faison donc neiger dans ta calculatrice maintenant, faisons neiger des flocons de Koch :
Code: Select all
from ttl_fix import *

def rotate_list(l):
  l[1:],l[0] = l[0:-1],l[-1]

def koch(n, l):
  if n<=0:
    turtle.forward(l)
  else:
    koch(n - 1, l / 3)
    turtle.left(60)
    koch(n - 1, l / 3)
    turtle.right(120)
    koch(n - 1, l / 3)
    turtle.left(60)
    koch(n - 1, l / 3)

def flock(n, l):
  koch(n, l)
  turtle.right(120)
  koch(n, l)
  turtle.right(120)
  koch(n, l)

turtle.speed(0)
turtle.colormode(255)

c = [127, 255, 0]
l = 80
for j in range(2):
  for i in range(3):
    n = j and 3 + i or 2 - i
    s = 5 - n
    turtle.penup()
    turtle.goto(i*117-157, j*95-25)
    turtle.pencolor(tuple(c))
    turtle.pensize(s)
    turtle.setheading(0)
    turtle.pendown()
    flock(n, l)
    n += 1
    rotate_list(c)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

nouveau
KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II

ancien
KhiCAS
NumWorks
TI-Nspire CX II CX


Beau progrès ici aussi, le flocon en haut à droite est enfin tracé de la bonne couleur comme chez la concurrence.

Exemple B3 : La linea

Go to top

Code: Select all
try: #TI-83 Premium CE
  from ti_system import disp_clr
  disp_clr()
except: pass
from ttl_fix import *

def spiral(k,a,l):
  x0, y0 = turtle.pos()
  h0 = turtle.heading()
  while True:
    for s in l:
      turtle.forward(s*k)
      turtle.left(180-a)
    x, y = turtle.pos()
    if abs(x - x0) + abs(y - y0) + abs(turtle.heading() - h0) <= 1:
      break

turtle.speed(0)
turtle.pensize(1)
turtle.colormode(255)
turtle.color((0,0,0),(255,255,0))

try:
  for i in range(-1, 2, 2):
    turtle.penup()
    turtle.goto(80*i - ((i > 0) and 40 or 50), 0)
    turtle.pendown()
    try: turtle.begin_fill()
    except: pass
    spiral((i > 0) and 9 or 30, (i > 0) and 90 or 36, (i > 0) and (1,2,3,4,5,6,7,8,9) or (1,2,3))
    try: turtle.end_fill()
    except: pass
except MemoryError as e: print(e)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

nouveau
KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II

ancien
KhiCAS
NumWorks
TI-Nspire CX II CX


Belle amélioration ici aussi, KhiCAS remplit enfin correctement la forme de droite magré sa complexité !

Exemple B4 : Pavage d'une lagogne

Go to top

Partons maintenant à la pêche avec un script très hautement impressionnant par rapport aux contraintes de heap des TI-83 Premium CE et compatibles ; ici nous sommes vraiment sur le fil de la limite des possibilités concernant ces modèles.

Voici donc une lagogne littéralement pavée de poissons :
Code: Select all
from math import sqrt
from ttl_fix import *

turtle.speed(0)
turtle.pensize(1)
turtle.colormode(255)
turtle.pencolor((0,0,0))

a=16

try:
  j = 0
  while -5 < j < 4:
    col = ((0,0,255),(255,0,0),(255,180,0))[j%3]
    i = 0
    while -2 + (j % 2) < i < 2:
      for c in range(3):
        turtle.penup()
        turtle.goto(sqrt(3)*3*a*(i*2-(j%2)), 3*a*j)
        turtle.setheading(-30 + 120*c)
        turtle.pendown()
        turtle.fillcolor(col)
        turtle.begin_fill()
        for k in range(-17, 18):
          l = a*sqrt(7)
          tf = ((1,141.787), (0,l), (1,-100.893), (0,a), (1,120), (0,a/2), [1,-120], [0,-a], [0,a], [1,120], (0,a/2), (1,60), (0,a), (1,-120), (0,a), (1,100.893), (0,l), [1,-40.893])[abs(k)]
          if k==6 or k==9 or k==17: tf[1] -= 180
          elif k==7 or k==8: tf[1] *= -1
          (turtle.forward, turtle.left)[tf[0]](tf[1])
        turtle.end_fill()
        turtle.forward(6*a)
        turtle.backward(5*a)
        turtle.penup()
        turtle.right(90)
        l = a*sqrt(3)/6
        for k in range(2):
          turtle.forward(l)
          turtle.pencolor((255,255,255))
          turtle.dot(a//4)
          turtle.pencolor((0,0,0))
          turtle.dot(a//8)
          turtle.backward(l)
          turtle.left(180)
      i = -i + (i <= 0)
    j = -j - (j >= 0)
except Exception as e: print(e)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

nouveau
KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II

ancien
KhiCAS
NumWorks
TI-Nspire CX II CX


Formidable ici aussi, les poissons se comportent enfin correctement sous KhiCAS pour réaliser la pavage !
Petits détails toutefois non spécifiques à cet exemple, lorsque l'on fait défiler le tracé obtenu :
  • les affichages effectués sur la barre de titre/état en haut d'écran (18 premières lignes de pixels) ne sont pas nettoyés correctement lors des rafraichissements
  • les formes ne sont bizarrement pas remplies correctement dans une bande correspondant aux 42 premières lignes de pixels

Exemple B4 : ♫ Le tournesol, le tournesol, ... ♫

Go to top

15452Terminons enfin avec un exemple absolument bluffant de réalisme pour du turtle, nous allons faire pousser un tournesol devant toi :
Code: Select all
from math import pi, sin, cos, sqrt
from ttl_fix import *

def spiral():
  phi = (1+sqrt(5))/2
  a  =0
  r = 0
  dr = 0.15
  turtle.penup()
  for i in range(300):
    turtle.forward(r)
    turtle.pencolor((0,0,0))
    try: turtle.dot(3)
    except: pass
    turtle.pencolor((205,133,63))
    try: turtle.dot(2)
    except: pass
    turtle.goto(0,0)
    turtle.setheading(0)
    a+=360/phi
    turtle.right(a)
    if a>=360:
      r+=dr
      a-=360   

def feuille(core,a):
    try: turtle.begin_fill()
    except: pass
    turtle.right(a/2)
    turtle.forward(core)
    turtle.left(a)
    turtle.forward(core)
    turtle.left(180-a)
    turtle.forward(core)
    turtle.left(a)
    turtle.forward(core)
    try: turtle.end_fill()
    except: pass

turtle.speed(0)
turtle.colormode(255)
turtle.pencolor((30,144,255))
try: turtle.dot(320)
except: pass

d=25
core=40
turtle.pencolor((160,82,45))
try: turtle.dot(40)
except: pass

c=((255,215,0),(255,255,0))

for i in range(2):
  turtle.color(c[0], c[i])
  for h in range(10*i,370,20):
    r=h * pi / 180
    x=d*cos(r)
    y=d*sin(r)
    turtle.penup()
    turtle.goto(x,y)
    turtle.pendown()
    turtle.setheading(h)
    feuille(core,32)

spiral()

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

nouveau
KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II

ancien
KhiCAS
NumWorks
TI-Nspire CX II CX


Excellent, les graines dans le cœur sont enfin délimitées correctement sous KhiCAS ! :bj:





C) 13 autres exemples comparatifs

Go to top




Exemple C1 : La dalle aux ammonites

Go to top

C'est donc parti pour quelques exemples afin d'approfondir les améliorations de la nouvelle bibliothèque turtle pour TI-83 Premium CE Edition Python et compatibles, ainsi que les points forts et faibles par rapport aux autres modèles de calculatrices.

Précisons que les problèmes récurrents ne seront pas systématiquement réévoqués sur chaque exemple.

Un petit peu au Nord de Digne-les-bains en rive droite de la Bléone se trouve la dalle aux ammonites. Comme il est strictement interdit d'en prélever, voici de quoi en reproduire une sur ta calculatrice :
Code: Select all
from ttl_fix import *
from math import pi

turtle.speed(0)
turtle.pencolor((0,0,0))
turtle.pendown()
turtle.pensize(1)

turtle.goto(0,-8)
x,y = turtle.pos()
turtle.left(115)
for i in range(132):
  turtle.forward(10)
  try:
    h = turtle.towards(x,y)
    turtle.setheading(h)
  except: pass
  d=10*pi
  turtle.forward(d)
  turtle.backward(d)
  turtle.right(90)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C2 : L'escargot de lumière

Go to top

Si tu es dans le Sud de la France tu sais qu'il ne pleut pas souvent (par contre, quand il pleut... il pleut !). Alors voici pour toi un escargot bariolé :
Code: Select all
from math import exp
from ttl_fix import *

turtle.speed(0)
turtle.pensize(1)
turtle.colormode(1.0)

turtle.penup()
turtle.goto(0, -20)
turtle.pendown()
turtle.right(90)
for i in range(20):
  c = [exp(-.5 * ((i - k) / 12)**2) for k in (6, 18, 30)]
  cb = [v/2 for v in c]
  turtle.color(cb, c)
  try: turtle.begin_fill()
  except: pass
  turtle.circle(27 + i)
  try: turtle.end_fill()
  except: pass
  turtle.right(10)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C3 : Le triangle de Penrose

Go to top

Tu n'as jamais touché à un triangle de Penrose ? Et bien voici de quoi en afficher le plan dans ta calculatrice, tu n'auras plus qu'à l'imprimer en 3D, si tu arrives à comprendre où est le devant et l'arrière : ;)
Code: Select all
from math import sqrt
from ttl_fix import *

def hook(a, c):
  turtle.penup()
  turtle.goto(0,-15)
  turtle.setheading(a)
  turtle.forward((l - 4*b) / sqrt(3))
  turtle.right(150)
  turtle.pendown()
  lf = ((turtle.left, 60),[turtle.forward,b],(turtle.left,120),(turtle.forward,l-b),[turtle.right,120],[turtle.forward,l-3*b])
  try:
    turtle.fillcolor(c)
    turtle.begin_fill()
  except: pass
  for k in range(-len(lf) + 1, len(lf)):
    tf = lf[abs(k)]
    if k == 1: tf[1] = l
    elif k == 4: tf[0] = turtle.left
    elif k == 5: tf[1] = b
    tf[0](tf[1])
  try: turtle.end_fill()
  except: pass
 
turtle.speed(0)
turtle.pensize(2)
turtle.colormode(255)

l=180
b=23

for i in range(112):
  turtle.pencolor(232 - int(i * 23 / 11), 249 - int(i * 29 / 55), 255)
  turtle.penup()
  turtle.goto(-192, 111 - 2*i)
  turtle.pendown()
  turtle.forward(384)

turtle.pencolor((0,0,0))
turtle.pensize(1)

hook(330, (255,255,0))
hook(90, (0,0,255))
hook(210, (255,0,0))

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C4 : La courtepointe de Mamie

Go to top

Voici maintenant la courtepointe brodée avec amour et soin par Mamie :
Code: Select all
from ttl_fix import *

def rotate_list(l):
  l[1:],l[0] = l[0:-1],l[-1]

def poly_reg_a(l, a):
  h0 = turtle.heading()
  while True:
    turtle.forward(l)
    turtle.left(a)
    if abs(h0 - turtle.heading()) < .1:
      break

turtle.hideturtle()
turtle.speed(0)
turtle.pensize(1)
turtle.colormode(255)

c = [191, 127, 0]
cf = [127, 255, 0]
i = 0
while i > -3:
  j = 0
  while j > -2:
    turtle.penup()
    turtle.goto((i - 1)*88, (j - 1)*85 + 28)
    turtle.pendown()
    turtle.color(c, cf)
    try: turtle.begin_fill()
    except: pass
    poly_reg_a(80, 140)
    try: turtle.end_fill()
    except: pass
    rotate_list(c)
    rotate_list(cf)
    j = -j + (j <= 0)
  i = -i + (i <= 0)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C5 : Les vitraux rhombiques

Go to top

Voici maintenant une belle rosace rhombique pour décorer le bâtiment de ton choix.

Nous utilisons ici la méthode .dot() permettant de remplir un disque de diamètre donné, afin de générer de quoi avoir une couleur de fond d'écran sur nos calculatrices, suffit-il juste de lui spécifier un diamètre suffisamment grand :
Code: Select all
from ttl_fix import *

turtle.speed(0)
turtle.colormode(255)
turtle.pencolor((0,0,255))
turtle.dot(320)
turtle.pencolor((0,0,0))
turtle.pensize(2)
col = ((255,0,0),(255,255,0),(0,255,0),(255,255,255),(255,0,255))
a=60

for i in range(10):
  c = col[i%5]
  turtle.color(c, c)
  turtle.begin_fill()
  for j in range(5):
    turtle.forward(a)
    turtle.right(72)
  turtle.end_fill()
  turtle.right(36)

for i in range(10):
  c = [v//3 for v in col[i%5]]
  turtle.pencolor(c)
  for j in range(5):
    turtle.forward(a)
    turtle.right(72)
  turtle.right(36)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Par rapport au fond bleu, notons que c'est bel et bien KhiCAS qui adopte le comportement correct. Selon le standard turtle, la méthode .dot() attend en paramètre le diamètre du disque à tracer. Ce sont les modèles Texas Instruments qui le considèrent à tort comme un rayon et remplissent alors tout l'écran.

Exemple C6 : Les roses par 12

Go to top

Voici maintenant une rose, cette fois-ci sur un fond d'écran en dégradé radial. Nous utiliserons pour cela cette fois-ci une boucle de .dot() :
Code: Select all
from math import pi, sin, cos, sqrt
from ttl_fix import *

def rpoly(c, n):
  a=360/n
  for k in range(n):
    turtle.forward(c)
    turtle.left(a)
def carre(c): rpoly(c, 4)

turtle.speed(0)
turtle.colormode(255)
turtle.penup()

r=80
alpha=(15 * pi / 180)

for i in range(320):
  c=int(255/320*i)
  turtle.pencolor(c,c,c)
  try: turtle.dot(320-i)
  except: pass

turtle.goto(20,-76)
turtle.color((255,255,255),(0,0,0))

for i in range(4):
  a=r*sin(alpha)*2
  d=a/sqrt(2)
  turtle.pendown()
  for i in range(12):
    turtle.right(15)
    try: turtle.begin_fill()
    except: pass
    carre(d)
    try: turtle.end_fill()
    except: pass
    turtle.left(45)
    turtle.penup()
    turtle.forward(a)
    turtle.pendown()
  turtle.penup()
  turtle.left(75)
  turtle.forward(d)
  turtle.right(60)
  r=r*cos(alpha)-a/2

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Sur la taille du disque de fond d'écran et comme déjà dit, c'est ici encore KhiCAS qui fait comme il faut.

Exemple C7 : Les triangles de Sierpiński

Go to top

Revenons aux fractales et à la récursivité avec les triangles de Sierpiński. As-tu déjà réussi à les compter ? Et bien voici de quoi commencer sur ta calculatrice :
Code: Select all
from ttl_fix import *

def sierp(n, l):
  if n == 0:
    for i in range (0, 3):
      turtle.forward(l)
      turtle.left(120)
  if n > 0:
    sierp(n - 1, l / 2)
    turtle.forward(l / 2)
    sierp(n - 1, l / 2)
    turtle.backward(l / 2)
    turtle.left(60)
    turtle.forward(l / 2)
    turtle.right(60)
    sierp(n - 1, l / 2)
    turtle.left(60)
    turtle.backward(l / 2)
    turtle.right(60)

turtle.colormode(255)
turtle.speed(0)
turtle.pensize(1)

turtle.penup()
turtle.goto(-110, -95)
turtle.pendown()
turtle.pencolor((255,0,0))
sierp(6, 220)
turtle.penup()
turtle.forward(400)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C8 : Sous le soleil exactement

Go to top

Plaçons-nous maintenant sous le soleil exactement, profitant ainsi de toutes les couleurs de la lumière blanche :
Code: Select all
from math import exp
from ttl_fix import *

def rpoly(c, n):
  a=360/n
  for k in range(n):
    turtle.forward(c)
    turtle.left(a)
def carre(c): rpoly(c, 4)

turtle.speed(0)
turtle.pensize(1)
turtle.colormode(1.0)

n = 36
for i in range(n):
  k=.4 + 4*i/255
  cp = [.7*exp(-.5 * ((n - i - k) / (n / 3))**2) for k in (6, 18, 30)]
  turtle.pencolor(cp)
  try:
    turtle.fillcolor((k,k,0))
    turtle.begin_fill()
  except: pass
  carre(60)
  try: turtle.end_fill()
  except: pass
  turtle.right(360 / n)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C9 : Le labyrinthe du Minotaure

Go to top

Explorons maintenant dans la labyrinthe du Minotaure :
Code: Select all
from ttl_fix import *

turtle.speed(0)
turtle.colormode(255)
turtle.pendown()

turtle.right(48)
turtle.pencolor((0,0,0))
for i in range(98):
  turtle.forward(2*i)
  turtle.left(90.5)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C10 : Le carreau de carreaux

Go to top

Code: Select all
from math import sqrt
from ttl_fix import *

def rotate_list(l):
  l[1:],l[0] = l[0:-1],l[-1]

def reg_poly(l, n):
  for i in range(n):
    turtle.forward(l)
    turtle.left(360/n)

def square(l):
  reg_poly(l, 4)

turtle.colormode(255)
turtle.pencolor(0,0,0)
turtle.speed(0)

turtle.pensize(3)
d=190
c=[0,255,127]
turtle.penup()
turtle.goto(-d/2,-d/2)
turtle.setheading(0)
turtle.pendown()
for i in range(8):
  try:
    turtle.fillcolor(tuple(c))
    turtle.begin_fill()
  except: pass
  square(d)
  try:
    turtle.end_fill()
  except: pass
  turtle.penup()
  turtle.forward(d/2)
  turtle.left(45)
  turtle.pendown()
  d/=sqrt(2)
  rotate_list(c)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Exemple C11 : Les étoiles jumelles

Go to top

Code: Select all
try: # TI-83 Premium CE
  from ti_system import disp_clr
  disp_clr()
except: pass
from ttl_fix import *

def rpoly(c, n):
  a=360/n
  for k in range(n):
    turtle.forward(c)
    turtle.left(a)

def rosace(c, n1, a, n2):
  try: turtle.begin_fill()
  except: pass
  for i in range(n2):
    turtle.left(a)
    rpoly(c, n1)
  try: turtle.end_fill()
  except: pass

turtle.colormode(255)
turtle.pencolor((0,0,0))

try: turtle.dot(320)
except: pass
turtle.color((255,255,255),(255,255,0))
turtle.speed(0)
turtle.pensize(1)
try:
  for i in range(-1, 2, 2):
    turtle.penup()
    turtle.goto(80*i, 0)
    turtle.pendown()
    rosace((i > 0) and 21 or 30, (i > 0) and 12 or 8, 30, 12)
    turtle.pensize(2)
    turtle.pencolor((0,0,255))
except MemoryError as e: print(e)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II


Sur la taille du disque de fond d'écran, c'est à nouveau ici KhiCAS qui a raison et pas TI.

Exemple C12 : La toile de l'araignée

Go to top

Suivons maintenant le fil de l'araignée :
Code: Select all
from ttl_fix import *

def spiral(a,b):
  turtle.pencolor((0,0,0))
  try: turtle.dot(320)
  except: pass
  turtle.pencolor((255,255,0))
  for i in range(189):
    for j in range(6):
      turtle.forward(i/a)
      turtle.left(23)
    turtle.left(b)
    try: turtle.dot(2)
    except: pass
   
turtle.speed(0)
turtle.colormode(255)
turtle.pensize(1)

a=17
b=194

spiral(a,b)

try: turtle.show() #TI-83 Premium CE
except: pass


TI-83PCE/84+CE
turtle

TI-Nspire CX II
turtle

Casio
Graph 90+E

KhiCAS
NumWorks
TI-Nspire CX II CX

TI-83PCE/84+CE
ce_turtl

NumWorks
Casio
Graph 35+E II





Conclusion

Go to top

Selon notre outil de tests, KhiCAS pour TI-Nspire CX et NumWorks N0110 est bien mieux conforme au standard Python-turtle que l'ensemble des solutions turtle officielles, et semble en conséquence bien mieux se comporter en pratique sur une majorité de nos exemples. nous semble offrir à ce jour la meilleure bibliothèque Python turtle toutes solutions confondues.

Les méthodes de remplissage, absentes des implémentations officielles de Casio et NumWorks t'ouvrent la porte à de formidables progrès.

Les progrès témoignent d'un soin minutieux apporté par Bernard Parisse, et vu que tout semble parfait maintenant il va nous falloir tenter d'inventer de nouveaux exemples piégeux... :P




Téléchargements

Go to top


Re: KhiCAS NumWorks Nspire CX: Python-turtle encore plus par

Unread postPosted: 19 Apr 2022, 17:49
by ggauny@live.fr
Bonsoir,
Ayant fait l'erreur de passer en version : 5.4.0.259, bien sûr ma TI-nspire CX II-T CAS refuse tout.

M Parisse a-t-il réalisé une version qui fonctionnerait sur ma calculatrice ?

Merci et bonne soirée.

Re: KhiCAS NumWorks Nspire CX: Python-turtle encore plus par

Unread postPosted: 19 Apr 2022, 17:50
by Hamza.S
non, il faut ndless et ndless est développé par une autre équipe et pour le moment il n'y a pas de ndless pour cette version

Re: KhiCAS NumWorks Nspire CX: Python-turtle encore plus par

Unread postPosted: 19 Apr 2022, 17:53
by ggauny@live.fr
Merci

Re: KhiCAS NumWorks Nspire CX: Python-turtle encore plus par

Unread postPosted: 22 Apr 2022, 20:08
by critor
Les examens approchent. Alors bonne nouvelle, pour la NumWorks l'ensemble des dernières améliorations Khi+KhiCAS dont justement le turtle, viennent tout juste d'être basculées sur la version stable : :)
viewtopic.php?f=97&t=25595&p=267701#p267701

Re: KhiCAS NumWorks Nspire CX: Python-turtle encore plus par

Unread postPosted: 23 Apr 2022, 06:56
by parisse
Les versions TI Nspire CX (utilisable en mode examen) et CX 2 (non utilisable en mode examen) viennent d'etre mises a jour.

Re: KhiCAS NumWorks Nspire CX: Python-turtle encore plus par

Unread postPosted: 23 Apr 2022, 13:07
by critor
Merci beaucoup.

Re: KhiCAS NumWorks Nspire CX: Python-turtle encore plus par

Unread postPosted: 26 Apr 2022, 19:32
by parisse
Mise a jour faite pour les Casio Graph 90 (et FXCG50)
Attention, il faut installer un addin en 2 parties:
Pour les FXCG50, remplacer 90 par 50 dans les liens ci-dessus.