
- mise à jour en 5.5de l'applicationSciTools
- mise à jour en 5.5de l'applicationPeriodic
- mise à jour en 5.5de l'applicationPython(TI-83 Premium CE Édition Pythonuniquement)


- time, certes déjà présent mais maintenant listé au menu et donc officiel; il ne risque plus de disparaitre
- , avec diverses possibilités :
- détection des simples pressions de touches clavier (sans validation donc)par l'utilisateur, avec même l'éventuel modificateur actif(, et ça marche aussi avec un clavier
2nde
oualpha
)USB! - affichage dans la console à la ligne que tu veux
- exportation de listes de nombres (entiers, flottants ou complexes)existant dans le contextePythonvers l'environnement de la calculatrice, pour traitement à l'aide d'autres applications
- importation depuis le contexte Pythonde listes ou équation de régression existant dans l'environnement de la calculatrice
- et donc plus généralement un début d'intégration du Pythonà l'environnement mathématique de la calculatrice, enfin l'applicationPythonva pouvoir servir non plus seulement à coder un truc déconnecté dans un coin, mais à traiter des problèmes et tâches complexes dans leur globalité !
- détection des simples pressions de touches clavier
- , une bibliothèque graphique pour tracer dans un repère, conformément aux programmes de Physique-Chimie,SNTetNSI, tout en permettant également nombre d'applications enMathématiques!
- ti_hub, pour les projets d'objects connectés à l'aide de l'interface
- ti_rover, pour les projets de robotique à l'aide du
- ainsi qu'un mystérieux ti_graphicspour sa part non listé au menu, mais justement utilisé par
1) exploration ti_graphics
Go to top- Code: Select all
def getplatform():
id=-1
try:
import sys
try:
if sys.platform=='nspire':id=0
if sys.platform.startswith('TI-Python') or sys.platform=='Atmel SAMD21':id=4
except:id=3
except:
try:
import kandinsky
id=1
except:
try:
if chr(256)==chr(0):id=5+(not ("HP" in version()))
except:
id=2
return id
platform=getplatform()
#lines shown on screen
#plines=[29,12, 7, 9,11,0,0]
plines=[29,16, 7, 9,11,0,0]
#max chars per line
#(error or CR if exceeded)
pcols =[53,99,509,32,32,0,0]
nlines=plines[platform]
ncols=pcols[platform]
curline=0
def mprint(*ls):
global curline
st=""
for s in ls:
if not(isinstance(s,str)):
s=str(s)
st=st+s
stlines=1+int(len(st)/ncols)
if curline+stlines>=nlines:
input("Input to continue:")
curline=0
print(st)
curline+=stlines
def sstr(obj):
try:
s=obj.__name__
except:
s=str(obj)
a=s.find("'")
b=s.rfind("'")
if a>=0 and b!=a:
s=s[a+1:b]
return s
def isExplorable(obj):
s=str(obj)
return s.startswith("<") and s.find(" ")>=0 and not s.startswith("<module")
def explmod(pitm,pitmsl=[],reset=True):
global curline
if(reset):
curline=0
pitmsl=[sstr(pitm)]
hd="."*(len(pitmsl)-1)
spath=".".join(pitmsl)
c,c2=0,0
spitm=str(pitm)
for itms in sorted(dir(pitm)):
c,c2=c+1,c2+1
try:
itm=eval(spath+"."+itms)
mprint(hd+itms+"="+str(itm))
if isExplorable(itm) and itm!=pitm:
pitmsl2=pitmsl.copy()
pitmsl2.append(itms)
c2=c2+explmod(itm,pitmsl2,False)[1]
except:
mprint(hd+itms)
if c>0 and reset:
mprint(hd+"Total: "+str(c)+" 1st level item(s)")
if c2>0 and c2!=c:
mprint(hd+" "+str(c2)+" item(s)")
return [c,c2]
Pas mal de choses a première vue, nous découvrons déjà 30 éléments accessibles rien qu'au premier niveau, et jusqu'à 45 en comptant les sous-éléments.

Une première lecture des noms de différentes fonctions, comme

Pour te donner un point de repère, nous pouvons donc a priori le rapprocher des modules
Nous allons bien évidemment te tester et documenter tout ça sans tarder, mais en attendant cela nous permet déjà de mettre à jour notre petit classement des

Casio Graph 35+E II 90+E | NumWorks | TI-83PCE Ed. Python | ||
builtins array collections cmath gc math matplotlib matplotlib.pyplot micropython os random sys time turtle uerrno | 84-175 . . . . 25 . . . . 8 . . . . | 97-440 3-13 . 13-17 9-13 42-46 . . 10-14 . . 17-63 . . 25-29 | 88-188 . . 12 . 41 3 11 6 . 9 . 3 38 . | 92-189 2-4 2 . 7 28 . . . . 8 15-42 4 . . |
spécifique | casioplot:6 | prime:3-7 | ion:48 kandinsky:6 | ti_graphics:30-45 ti_hub:? ti_plotlib:49-56 ti_system:12 ti_rover:? |
Modules | 4 | 9 | 11 | 13 |
Eléments | 123-214 | 219-642 | 265-365 | 249-397 |
Classement en terme d'éventail de modules :
- 13modules :TI-83 Premium CE Edition Python
- 11modules :NumWorks
- 9modules :HP Prime(version alpha)
- 4modules :Casio Graph 90+E / 35+E II
Classement en terme de richesse des modules :
- 219-642éléments :HP Prime(version alpha)
- 249-397éléments :TI-83 Premium CE Edition Python
- 265-365éléments :NumWorks
- 123-214éléments :Casio Graph 90+E / 35+E II
Casio Graph 35+E II 90+E | MicroPython TI-Nspire | TI-Python | |||
builtins array collections cmath gc math matplotlib matplotlib.pyplot micropython os random sys time turtle uerrno | 84-175 . . . . 25 . . . . 8 . . 69 . | 91-204 2-4 . 12 7 41 . . 6 . 8 12 . . 24 | 93-218 2-4 . 12 7 41 . . 3 . . 15-45 . . . | 92-189 2-4 2 . 7 28 . . . . 8 15-42 4 . . | 93-191 2-4 2 12 7 41 . . 6 15 8 15-45 8-10 . . |
spécifique | casioplot:6 matplotl:25 | nsp:3-10 | board:22 storage:7-21 | ||
Modules | 6 | 9 | 8 | 9 | 13 |
Eléments | 217-308 | 203-318 | 176-340 | 158-284 | 238-384 |
Classement en terme d'éventail de modules :
- 13modules :TI-83 Premium CE + TI-Python(firmware tiers)TI-83 Premium CE Edition Python
- 11modules :NumWorks
- 9modules :HP Prime(version alpha)+Casio Graph 75/85/95 / 35+E/USB / 35+E II / fx-9750GII/GIII / fx-9860G/GII/GIII(appli CasioPython)
- 8modules :TI-Nspire(appli MicroPython)+TI-83 Premium CE + TI-Python
- 6modules :Casio Graph 90+E / 35+E II / fx-CG50 / fx-9750/9860GIII
Classement en terme de richesse des modules :
- 219-642éléments :HP Prime(version alpha)
- 249-397éléments :TI-83 Premium CE Edition Python
- 265-365éléments :NumWorks
- 238-384éléments :TI-83 Premium CE + TI-Python(firmware tiers)
- 217-308éléments :Casio Graph 90+E / 35+E II / fx-CG50 / fx-9750/9860GIII
- 203-318éléments :Casio Graph 75/85/95 / 35+E/USB / 35+E II / fx-9750GII/GIII / fx-9860G/GII/GIII(appli CasioPython)
- 176-340éléments :TI-Nspire(appli MicroPython)
- 158-284éléments :TI-83 Premium CE + TI-Python
2) zone graphique contrôlable
Go to topgetPixel(x, y)
setPixel(x, y, c)

Petite astuce pour la détecter automatiquement sans intervention humaine, on peut remarquer que
Un simple boucle de tests suffit alors, avec un éventuel changement de couleur préalable pour les quelques pixels de l'écran qui seraient déjà noirs.
Mettons à jours notre classe de compatibilité écrans
- Code: Select all
class polyscr:
w, h = 0, 0
# get_pixel(x, y)
# set_pixel(x, y, color(r8, g8, b8))
show_screen = lambda self: None
need_show_screen = False
# color mode :
# 0: (R8, G8, B8)
# 1: int RGB-565
color_mode = 0
def color(self, r, g=0, b=0):
if isinstance(r, tuple) or isinstance(r,list):
r, g, b = r[0], r[1], r[2]
return self.color_mode == 0 and (r,g,b) or r<<11 | g<<5 | b
def __init__(self):
try: # TI-Nspire Ndless
from nsp import Texture as myscr
self.w, self.h = 320, 240
myscr = myscr(self.w, self.h, None)
self.get_pixel = myscr.getPx
self.set_pixel = myscr.setPx
self.show_screen = myscr.display
self.need_show_screen = True
self.color_mode = 1
except:
try: # TI-83/84 CE
import ti_graphics as myscr
self.get_pixel = myscr.getPixel
self.set_pixel = myscr.setPixel
except ImportError:
try: # Casio USB Power Graphic 3
import casioplot as myscr
self.show_screen = myscr.show_screen
self.need_show_screen = True
except ImportError: # NumWorks
import kandinsky as myscr
self.get_pixel = myscr.get_pixel
self.set_pixel = myscr.set_pixel
# detect readable pixel array
if self.w <= 0:
def _can_get_pixel(x, y):
c = self.get_pixel(x, y)
if c == self.color(0, 0, 0):
self.set_pixel(x, y, self.color(255,0,0))
c = self.get_pixel(x, y)
return c is not None and c != self.color(0, 0, 0)
self.w, self.h, dw, dh = 0, 0, 1, 1
while dw or dh:
if not _can_get_pixel(self.w - (dw == 0),self.h - (dh == 0)):
if _can_get_pixel(self.w,self.h-1): dh = 0
elif _can_get_pixel(self.w-1,self.h): dw = 0
else: dw, dh = 0, 0
self.w += dw; self.h += dh

- Code: Select all
scr = polyscr()
print('can get {}x{} pixels at (0,0)'.format(scr.w, scr.h))
Mais c'est fantastique, nous bénéficierions donc apparemment un contrôle plein écran



On se rend vite compte que même si
- Code: Select all
from ti_system import *
import ti_graphics as scr
for k in range(240):
sct.setPixel(k, k, (0, 0, 0))
disp_wait()
Complétons donc l'initialisation de notre classe
- Code: Select all
class polyscr:
w, h, w0, h0, x0, y0 = 0, 0, 0, 0, 0, 0
# get_pixel(x, y)
# set_pixel(x, y, color(r8, g8, b8))
show_screen = lambda self: None
need_show_screen = False
# color mode :
# 0: (R8, G8, B8)
# 1: int RGB-565
color_mode = 0
def color(self, r, g=0, b=0):
if isinstance(r, tuple) or isinstance(r,list):
r, g, b = r[0], r[1], r[2]
return self.color_mode == 0 and (r,g,b) or r<<11 | g<<5 | b
def __init__(self):
try: # TI-Nspire Ndless
from nsp import Texture as myscr
self.w, self.h = 320, 240
myscr = myscr(self.w, self.h, None)
self.get_pixel = myscr.getPx
self.set_pixel = myscr.setPx
self.show_screen = myscr.display
self.need_show_screen = True
self.color_mode = 1
except:
try: # TI-83/84 CE
import ti_graphics as myscr
self.get_pixel = myscr.getPixel
self.set_pixel = myscr.setPixel
except ImportError:
try: # Casio USB Power Graphic 3
import casioplot as myscr
self.show_screen = myscr.show_screen
self.need_show_screen = True
except ImportError: # NumWorks
import kandinsky as myscr
self.get_pixel = myscr.get_pixel
self.set_pixel = myscr.set_pixel
# detect readable pixel array
if self.w <= 0:
def _can_get_pixel(x, y):
c = self.get_pixel(x, y)
if c == self.color(0, 0, 0):
self.set_pixel(x, y, self.color(255,0,0))
c = self.get_pixel(x, y)
return c is not None and c != self.color(0, 0, 0)
self.w, self.h, dw, dh = 0, 0, 1, 1
while dw or dh:
if not _can_get_pixel(self.w - (dw == 0),self.h - (dh == 0)):
if _can_get_pixel(self.w,self.h-1): dh = 0
elif _can_get_pixel(self.w-1,self.h): dw = 0
else: dw, dh = 0, 0
self.w += dw; self.h += dh
# detect writable pixel array
# remove top status bar
def _can_set_pixel(x, y):
def _invert_color(r, g=0, b=0):
if isinstance(r, tuple) or isinstance(r,list):
r, g, b = r[0], r[1], r[2]
return self.color(~r & 0xFF, ~g & 0xFF, ~b & 0xFF)
c = self.get_pixel(x, y)
self.set_pixel(x, y, _invert_color(c))
return c != self.get_pixel(x, y)
self.w0, self.h0 = self.w, self.h
while not _can_set_pixel(0, self.y0):
self.y0 += 1; self.h0 -= 1

- Code: Select all
scr = polyscr()
print('can get {}x{} pixels at (0,0)'.format(scr.w, scr.h))
print('can set {}x{} pixels at ({},{})'.format(scr.w0, scr.h0, scr.x0, scr.y0))
Voilà, nous bénéficions en réalité d'un accès total à seulement
A noter que l'origine restant tout en haut à gauche de l'écran, les valeurs de paramètres
Puisque notre classe

prime.pixon(x, y, c)
pour allumer les pixels.Mais à la différence, rien pour tester l'état d'un pixel.
Procédons donc autrement en tentant de tracer un rectangle aussi grand que possible à l'aide du code suivant :
- Code: Select all
import prime as scr
def rect(x, y, w, h, c=(0,0,0)):
for k in range(w):
scr.pixon(x+k, y, c)
scr.pixon(x+k, y+h-1, c)
for k in range(h):
scr.pixon(x, y+k, c)
scr.pixon(x+w-1, y+k, c)

rect(0, 0, 320, 240, 255<<16)
nous affiche bien un rectangle au complet et nous confirme donc que nous contrôlons ici la totalité des 320×240 pixels de l'écran.D'où le classement en terme de zones graphiques dédiées au
- 320×240 = 76800pixels :HP Prime
- 384×192 = 73728pixels :Casio Graph 90+E
- 320×222 = 71040pixels :NumWorks
- 320×210 = 67200pixels :TI-83 Premium CE Edition Python
- 128×64 = 8192pixels :Casio Graph 35+E II
- 320×240 = 76800pixels :HP Prime+TI-Nspire(appli MicroPython)
- 384×192 = 73728pixels :Casio Graph 90+E / fx-CG50
- 320×222 = 71040pixels :NumWorks
- 320×210 = 67200pixels :TI-83 Premium CE Edition Python
- 128×64 = 8192pixels :Casio Graph 35+E II / fx-9750/9860GIII
3) profondeur de couleurs
Go to top
Mais couleurs spécifiées et affichées sont deux choses différentes. Pour mieux t'illustrer les possibilités

Pour cela nous travaillerons en coordonnées HSV/TSV
- teintequi sera ici codée par un nombre flottant de 0 à 2 est en gros ce que tu appelles naturellement couleur.
- saturation, un flottant de 0 à 1 indique de façon inverse la quantité de blanc.
- valeur, ici encore un flottant de 0 à 1 indique de façon inverse la quantité de noir.
Bricolons-nous donc quelques petites fonctions pour ça :
- Code: Select all
from polyscr import *
scr = polyscr()
def hsv2c(h,s,v):
c=v*s
x,m,k=c*(1-abs((h%(2/3))*3-1)),v-c,(h*3)//1
return (round(255*(m+x*(k%3==1)+c*(k%5==0))),round(255*(m+c*(k==1 or k==2)+x*(k%3==0))),round(255*(m+x*(k%3==2)+c*(k==3 or k==4))))
def grad(x,y,w,h):
for i in range(w):
for j in range(h):
c=hsv2c(2*j/(h-1),i>=w//2 and 1 or i/(w//2-1),i<w//2 and 1 or (w-1-i)/((w-w//2)-1))
scr.set_pixel(x+i,y+j,c)

- Code: Select all
grad(scr.x0, scr.y0, scr.w0, scr.h0)
Fantastique, non ? Quand tu penses que dans le langage


timer(grad, scr.x0, scr.y0, scr.w0, scr.h0)
nous renvoie alors - Code: Select all
from time import monotonic
def timer(f, *par):
start=monotonic()
f(*par)
return monotonic()-start


Ce qui veut dire que tu n'as pas à t'embêter à la coder et peux donc ainsi économiser de la mémoire, et qu'elle est peut-être déjà optimisée.

Empressons-nous de tester. Modifions déjà notre bibliothèque de compatibilité pour permettre l'accès à ce genre de fonction spécifique :
- Code: Select all
class polyscr:
w, h, w0, h0, x0, y0 = 0, 0, 0, 0, 0, 0
myscr = None
# get_pixel(x, y)
# set_pixel(x, y, color(r8, g8, b8))
show_screen = lambda self: None
need_show_screen = False
# color mode :
# 0: (R8, G8, B8)
# 1: int RGB-565
color_mode = 0
def color(self, r, g=0, b=0):
if isinstance(r, tuple) or isinstance(r,list):
r, g, b = r[0], r[1], r[2]
return self.color_mode == 0 and (r,g,b) or r<<11 | g<<5 | b
def __init__(self):
try: # TI-Nspire Ndless
from nsp import Texture as myscr
self.w, self.h = 320, 240
myscr = myscr(self.w, self.h, None)
self.get_pixel = myscr.getPx
self.set_pixel = myscr.setPx
self.show_screen = myscr.display
self.need_show_screen = True
self.color_mode = 1
except:
try: # TI-83/84 CE
import ti_graphics as myscr
self.get_pixel = myscr.getPixel
self.set_pixel = myscr.setPixel
except ImportError:
try: # Casio USB Power Graphic 3
import casioplot as myscr
self.show_screen = myscr.show_screen
self.need_show_screen = True
except ImportError: # NumWorks
import kandinsky as myscr
self.get_pixel = myscr.get_pixel
self.set_pixel = myscr.set_pixel
self.myscr = myscr
# detect readable pixel array
if self.w <= 0:
def _can_get_pixel(x, y):
c = self.get_pixel(x, y)
if c == self.color(0, 0, 0):
self.set_pixel(x, y, self.color(255,0,0))
c = self.get_pixel(x, y)
return c is not None and c != self.color(0, 0, 0)
self.w, self.h, dw, dh = 0, 0, 1, 1
while dw or dh:
if not _can_get_pixel(self.w - (dw == 0),self.h - (dh == 0)):
if _can_get_pixel(self.w,self.h-1): dh = 0
elif _can_get_pixel(self.w-1,self.h): dw = 0
else: dw, dh = 0, 0
self.w += dw; self.h += dh
# detect writable pixel array
# remove top status bar
def _can_set_pixel(x, y):
def _invert_color(r, g=0, b=0):
if isinstance(r, tuple) or isinstance(r,list):
r, g, b = r[0], r[1], r[2]
return self.color(~r & 0xFF, ~g & 0xFF, ~b & 0xFF)
c = self.get_pixel(x, y)
self.set_pixel(x, y, _invert_color(c))
return c != self.get_pixel(x, y)
self.w0, self.h0 = self.w, self.h
while not _can_set_pixel(0, self.y0):
self.y0 += 1; self.h0 -= 1
Modifions maintenant le script de tracer du dégradé :
- Code: Select all
from polyscr import *
scr = polyscr()
def grad(x,y,w,h):
for i in range(w):
for j in range(h):
c=scr.myscr.hsv_to_rgb(360*j/(h-1),i>=w//2 and 1 or i/(w//2-1),i<w//2 and 1 or (w-1-i)/((w-w//2)-1))
scr.set_pixel(x+i,y+j,c)

timer(grad, scr.x0, scr.y0, scr.w0, scr.h0)
ne mesure plus que 

C'est-à-dire que même si les coordonnées sont spécifiées en RGB-888, le matériel utilise pour sa part du RGB-565 :
- 25=32 teintes de rouge
- 26=64 teintes de vert
- 25=32 teintes de bleu
Passons maintenant à la
- Code: Select all
import prime as scr
def grad(x,y,w,h):
for i in range(w):
for j in range(h):
_h = 2*j/(h-1)
_s = i>=w//2 and 1 or i/(w//2-1)
_v = i<w//2 and 1 or (w-1-i)/((w-w//2)-1)
_c=_v*_s
_x,_m,_k=_c*(1-abs((_h%(2/3))*3-1)),_v-_c,(_h*3)//1
scr.pixon(x+i,y+j,round(255*(_m+_x*(_k%3==1)+_c*(_k%5==0)))*2**16 + round(255*(_m+_c*(_k==1 or _k==2)+_x*(_k%3==0)))*2**8 + round(255*(_m+_x*(_k%3==2)+_c*(_k==3 or _k==4))))

En réalité, c'est le protocole utilisé pour les captures d'écran qui fait perdre des informations couleur, et il faut donc se référer à la photo ci-contre.
Sur la photo donc aucune saccade mais un dégradé des plus lisses, c'est ici du RGB-888 :
- 28=256 teintes de rouge
- 28=256 teintes de vert
- 28=256 teintes de bleu

Et bien c'est possible si on se rend compte que les valeurs effectivement réglées pour les pixels diffèrent parfois de celles spécifiées.

Modifions encore une fois notre classe
- Code: Select all
class polyscr:
w, h, w0, h0, x0, y0 = 0, 0, 0, 0, 0, 0
col_bits = [8, 8, 8]
myscr = None
# get_pixel(x, y)
# set_pixel(x, y, color(r8, g8, b8))
show_screen = lambda self: None
need_show_screen = False
# color mode :
# 0: (R8, G8, B8)
# 1: int RGB-565
color_mode = 0
has_color = True
def color(self, r, g=0, b=0):
if isinstance(r, tuple) or isinstance(r,list):
r, g, b = r[0], r[1], r[2]
return self.color_mode == 0 and (r,g,b) or r<<(self.col_bits[0]+self.col_bits[1]) | g<<self.col_bits[0] | b
def __init__(self):
try: # TI-Nspire Ndless
from nsp import Texture as myscr
self.w, self.h = 320, 240
myscr = myscr(self.w, self.h, None)
self.get_pixel = myscr.getPx
self.set_pixel = myscr.setPx
self.show_screen = myscr.display
self.need_show_screen = True
self.color_mode = 1
self.col_bits = (5, 6, 5)
except:
try: # TI-83/84 CE
import ti_graphics as myscr
self.get_pixel = myscr.getPixel
self.set_pixel = myscr.setPixel
except ImportError:
try: # Casio USB Power Graphic 3
import casioplot as myscr
self.show_screen = myscr.show_screen
self.need_show_screen = True
except ImportError: # NumWorks
import kandinsky as myscr
self.get_pixel = myscr.get_pixel
self.set_pixel = myscr.set_pixel
self.myscr = myscr
# detect readable pixel array
if self.w <= 0:
def _can_get_pixel(x, y):
c = self.get_pixel(x, y)
if c == self.color(0, 0, 0):
self.set_pixel(x, y, self.color(255,0,0))
c = self.get_pixel(x, y)
return c is not None and c != self.color(0, 0, 0)
self.w, self.h, dw, dh = 0, 0, 1, 1
while dw or dh:
if not _can_get_pixel(self.w - (dw == 0),self.h - (dh == 0)):
if _can_get_pixel(self.w,self.h-1): dh = 0
elif _can_get_pixel(self.w-1,self.h): dw = 0
else: dw, dh = 0, 0
self.w += dw; self.h += dh
# detect writable pixel array
# remove top status bar
def _can_set_pixel(x, y):
def _invert_color(r, g=0, b=0):
if isinstance(r, tuple) or isinstance(r,list):
r, g, b = r[0], r[1], r[2]
return self.color(~r & 0xFF, ~g & 0xFF, ~b & 0xFF)
c = self.get_pixel(x, y)
self.set_pixel(x, y, _invert_color(c))
return c != self.get_pixel(x, y)
self.w0, self.h0 = self.w, self.h
while not _can_set_pixel(0, self.y0):
self.y0 += 1; self.h0 -= 1
if not self.color_mode:
# test color screen
self.set_pixel(self.x0, self.y0, (0, 127, 255))
col = self.get_pixel(self.x0, self.y0)
self.has_color = col[0] != col[1] or col[1] != col[2]
# detect color channel bits
self.set_pixel(self.x0, self.y0, (255, 255, 255))
col = list(self.get_pixel(self.x0, self.y0))
for k in range(3):
while col[k]<255:
col[k] += 2 ** (8 - self.col_bits[k])
self.col_bits[k] -= 1

- Code: Select all
scr = polyscr()
print('can get {}x{} pixels at (0,0)'.format(scr.w, scr.h))
print('can set {}x{} pixels at ({},{})'.format(scr.w0, scr.h0, scr.x0, scr.y0))
print(scr.has_color and 'color' or 'monochrome')
if scr.has_color: print('internal : RGB{}{}{}'.format(scr.col_bits[0], scr.col_bits[1], scr.col_bits[2]))
Voilà, nous obtenons bien comme prévu du
Testons également la concurrence en lançant le même code :
Au classement selon les meilleurs rendus de couleurs, nous avons donc :
- 24bits /16777216couleurs:HP Prime(version alpha)
- +16bits /65536couleurs:TI-83 Premium CE Edition PythonCasio Graph 90+E+NumWorks
- 1bit /2couleurs:Casio Graph 35+E II
- 24bits /16777216couleurs:HP Prime(version alpha)
- +16bits /65536couleurs:TI-83 Premium CE Edition PythonCasio Graph 90+E / fx-CG50+NumWorks+TI-Nspire CX
- 1bit /2couleurs:Casio Graph 35+E II / fx-9750/9860GIII+TI-Nspire
4) allumage de pixels et performances
Go to topReprenons déjà le script permettant de chronométrer l'exécution d'une fonction :
- Code: Select all
from time import monotonic
def timer(f, *par):
start=monotonic()
f(*par)
return monotonic()-start
Faisons maintenant un script allumant un par un tous les pixels de l'écran, et afin de mieux pouvoir mesurer et comparer les performances graphiques nous minimiserons les calculs en ne faisant pas appel à notre classe de compatibilité, mais en appelant directement les fonctions graphiques :
- Code: Select all
from ti_graphics import *
def rectf(x, y, w, h, c=(0, 0, 0)):
for i in range(h):
for k in range(w):
setPixel(x+j, y+i, c)

timer(rectf, 0, 30, 320, 210, (255, 0, 0)))
nous retourne Voici maintenant la version
- Code: Select all
from kandinsky import *
def rectf(x, y, w, h, c=(0, 0, 0)):
for i in range(h):
for k in range(w):
set_pixel(x+j, y+i, c)
L'appel
timer(rectf, 0, 30, 320, 222, (255, 0, 0)))
pour chronométrer l'allumage de - 1.541s sur munie duNumWorks N0110firmware officielEpsilon
- 1.145s sur munie duNumWorks N0110
- 1.605s sur munie duNumWorks N0100firmware officielEpsilon
- 1.623s sur munie duNumWorks N0100
Passons maintenant sur
- Code: Select all
from casioplot import *
def rectf(x, y, w, h, c=(0, 0, 0)):
for i in range(h):
for k in range(w):
set_pixel(x+j, y+i, c)
show_screen()
- 1.64s pour l'appel
rectf(0, 0, 128, 64, (0, 0, 0)
surGraph 35+E II - 9.93s pour l'appel
rectf(0, 0, 384, 192, (255, 0, 0)
surGraph 90+E
De façon similaire pour
- Code: Select all
import nsp.Texture as scr
scr = scr(320, 240, None)
def rectf(x, y, w, h, c=0):
for i in range(h):
for k in range(w):
scr.setPx(x+j, y+i, c)
scr.display()
Nous n'avons malheureusement pas de montre

- 10min36.74s pour l'appel
rectf(0, 0, 320, 240, 31)
surTI-Nspire CX CR4+ - 21min15.42s pour l'appel
rectf(0, 0, 320, 240, 31)
surTI-Nspire CX CR3- - 4min49.5s pour l'appel
rectf(0, 0, 320, 240, 0)
surTI-Nspire
Enfin sur
- Code: Select all
from prime import *
def rectf(x, y, w, h, c=0):
for i in range(h):
for k in range(w):
pixon(x+j, y+i, c)
La machine nous remplit tout l'écran en seulement 0.49s !

Bien évidemment, tous ces écrans ont des définitions différentes. Pour le classement ramenons cela en terme de vitesse d'affichage :
- 156735pixels/s:HP Prime G1(version alpha)
- 62044pixels/s:NumWorks N0110
- 46100pixels/s:NumWorks N0110
- 44262pixels/s:NumWorks N0100
- 43771pixels/s:NumWorks N0100
- 7425pixels/s :Casio Graph 90+E
- 4995pixels/s :Casio Graph 35+E II
- 48pixels/s :TI-83 Premium CE Edition Python
- 156735pixels/s:HP Prime G1(version alpha)
- 62044pixels/s:NumWorks N0110
- 46100pixels/s:NumWorks N0110
- 44262pixels/s:NumWorks N0100
- 43771pixels/s:NumWorks N0100
- 7425pixels/s :Casio Graph 90+E / fx-CG50
- 4995pixels/s :Casio Graph 35+E II / fx-9750/9860GIII
- 265pixels/s:TI-Nspire
- 121pixels/s:TI-Nspire CX CR4+
- 60pixels/s:TI-Nspire CX CR3-
- 48pixels/s :TI-83 Premium CE Edition Python
En terme de boucle d'allumages individuels de pixels, la
Mais attends un petit peu avant de partir, nous sommes très loin d'avoir dit notre dernier mot, nous allons approfondir cela de suite dans les deux prochaines parties.
5) écriture texte et performances
Go to top
- impossibilité de positionner le texte comme on voulait verticalement, nous ne pouvions que choisir une des 11 à 12 bandes horizontales de 17 pixels de hauteur, numérotées de haut en bas, même dans le contexte de ti_plotlibpourtant censé travailler dans un repère
- impossibilité de positionner le texte comme on voulait horizontalement, nous ne pouvion que choisir entre l'aligner à gauche, au centre ou à droite
- et en prime effet de bord sur l'affichage avec effacement de la partie droite non utilisée de la bande ou même de toute la bande
drawString('texte', x, y)
.

Si si, tu pourras bien afficher tes textes en toute liberté !

- Code: Select all
from ti_system import *
import ti_graphics as scr
tw = 10
s = 'Thank you TI'
xmin, xmax, ymin, ymax = 0, 319, 30, 239
x, y, dx, dy = xmin, ymin, 1, 9
scr.cls()
while x <= xmax - tw*len(s):
scr.drawString(s, x, y)
y += dy
x += dx
dx += 1
disp_wait()
C'est le cas de le dire,


Que se passe-t-il donc ? Sans doute que c'est ici qu'il faut tenir comtpe de l'architecture matérielle très spéciale de la
- un cœur secondaire Atmel SAMD21E18A-Uintégrant unARM Cortex-M0+cadencé à48 MHz, coprocesseur 32-bits dédié à l'exécution des scriptsPython
- un cœur principal eZ80qui à la différence dispose d'un accès direct à l'ensemble des autres composantes matérielles(Flash, contrôleur écran, cœur secondaire...)
Alors qu'ici chaque appel à
Un comparatif s'appuyant sur une boucle d'allumage de pixels n'est donc pas représentatif des performances graphiques moyennes de la
6) fonctions de tracé de formes géométriques
Go to top

Les modules équivalents chez la concurrence sont assez minimalistes, te fournissant juste de quoi choisir la couleur, allumer/éteindre des pixels, et afficher du texte. Tu devais te fabriquer tes autres fonctions graphiques
Et bien ici tu es gâté,


Commençons déjà par de la configuration. Déjà, on eut effacer l'écran à l'aide de la fonction


cursor(c=1)
permet d'activer ou désactiver l'affichage du curseur de texte, comme le permettait déjà la fonction ti_system.cursor(c)
.A la différence ici que les effets des valeurs sont inversés :
- 0: curseur affiché
- 1: curseur masqué

On peut maintenant choisir la couleur du stylo avec
setColor(r, g, b)
, appel équivalent à ti_plotlib.color(r, g, b)
.D'ailleurs si l'on importe les deux modules
On peut également régler la plume du stylo, avec
setPen(taille, type)
, un appel donc similaire à ti_plotlib.pen('taille', 'type')
.A la différence près que
- Code: Select all
def setPen(taille, type):
_strtest(taille)
_strtest(type)
if taille == 'thin': taille = 0
elif taille == 'medium': taille = 1
elif taille == 'thick': taille = 2
else: _excpt('Invalid pen size.')
if type == 'solid': type = 0
elif type == 'dot': type = 1
elif type == 'dash': type = 2
else: _excpt('Invalid pen style.')
gr.pen(taille, type)
Mais ici, pas d'erreur avec des paramètres supérieurs à 2...
Nous allons voir de suite ce que ça donne. Commençons par la fonction
drawLine(x1, y1, x2, y2)
:- Code: Select all
from ti_system import *
import ti_graphics as scr
tw, th = 8, 15
xmin, xmax, ymin, ymax = tw, 319, 30+th, 239
nta, nty = 4, 4
lx = [xmin + k*(xmax-xmin)/(2*nta+1) for k in range(1, 2*nta+1)]
ly = [ymin + k*(ymax-ymin)/(2*nty+1) for k in range(1, 2*nty+1)]
l = (xmax-xmin+1) / (2*nta+1)
scr.cls()
for i in range(nty):
scr.drawString(str(i), xmin-tw, ly[i*2])
for j in range(nta):
scr.drawString(str(j), lx[j*2], ymin-th)
scr.setPen(j, i)
scr.drawLine(lx[j*2], ly[i*2], lx[j*2 + 1], ly[i*2])
disp_wait()


Ce qui nous permet de terminer la documentation de
setPen(0, 0)
=ti_plotlib.pen('thin', 'solid')
setPen(1, 1)
=ti_plotlib.pen('medium', 'dot')
setPen(2, 2)
=ti_plotlib.pen('thick', 'dash')
setPen(3, 3)
, il permet donc d'accéder à deux réglages secrets non offerts via 
- une taille de stylo encore plus grande que 'thick'
- un tracé en pointillés qui enchaîne non pas des tirets mais des petits points
Testons maintenant de façon similaire les fonctions
drawPolyLine([(x1,y1), (x2,y2), ..., (xn,yn)])
et fillPolyLine([(x1,y1), (x2,y2), ..., (xn,yn)])
:- Code: Select all
from ti_system import *
import ti_graphics as scr
tw, th = 8, 15
xmin, xmax, ymin, ymax = tw, 319, 30+th, 239
nta, nty = 4, 4
lx = [xmin + k*(xmax-xmin)/(2*nta+1) for k in range(1, 2*nta+1)]
ly = [ymin + k*(ymax-ymin)/(2*nty+1) for k in range(1, 2*nty+1)]
l = (xmax-xmin+1) / (2*nta+1)
scr.cls()
for i in range(nty):
scr.drawString(str(i), xmin-tw, ly[i*2])
for j in range(nta):
scr.drawString(str(j), lx[j*2], ymin-th)
scr.setPen(j, i)
scr.setColor((255,0,0))
scr.fillPolygon([(lx[j*2], ly[i*2]), (lx[j*2 + 1], ly[i*2]), (lx[j*2], ly[i*2+1]), (lx[j*2 + 1], ly[i*2+1])])
scr.setColor((0,0,0))
scr.drawPolyLine([(lx[j*2], ly[i*2]), (lx[j*2 + 1], ly[i*2]), (lx[j*2], ly[i*2+1]), (lx[j*2 + 1], ly[i*2+1])])
disp_wait()

- Code: Select all
def drawPolyLine(l):
for k in range(len(l) - 1):
drawLine(l[k][0], l[k][1], l[k+1][0], l[k+1][1])
La fonction
Et comme tu vois c'est remarquable, elle marche même avec des polygones croisés !

Passons maintenant à
drawRect(x, y, w, h)
et fillRect(x, y, w, h)
:- Code: Select all
from ti_system import *
import ti_graphics as scr
tw, th = 8, 15
xmin, xmax, ymin, ymax = tw, 319, 30+th, 239
nta, nty = 4, 4
lx = [xmin + k*(xmax-xmin)/(2*nta+1) for k in range(1, 2*nta+1)]
ly = [ymin + k*(ymax-ymin)/(2*nty+1) for k in range(1, 2*nty+1)]
l = (xmax-xmin+1) / (2*nta+1)
scr.cls()
for i in range(nty):
scr.drawString(str(i), xmin-tw, ly[i*2])
for j in range(nta):
scr.drawString(str(j), lx[j*2], ymin-th)
scr.setPen(j, i)
scr.setColor((255,0,0))
scr.fillRect(lx[j*2], ly[i*2], lx[j*2+1]-lx[j*2], ly[i*2+1]-ly[i*2])
scr.setColor((0,0,0))
scr.drawRect(lx[j*2], ly[i*2], lx[j*2+1]-lx[j*2], ly[i*2+1]-ly[i*2])
disp_wait()

drawRect(x, y, w, h)
permet donc de tracer un rectangle :- de dimensions wethdonnées en pixels
- aux côtés parallèles aux bors de l'écran
- et en utilisant le point de coordonnées (x, y)comme sommet supérieur gauche
Voici maintenant du lourd avec
drawArc(x, y, w, h, t1, t2)
et fillArc(x, y, w, h, t1, t2)
:- Code: Select all
from ti_system import *
import ti_graphics as scr
tw, th = 8, 15
xmin, xmax, ymin, ymax = tw, 319, 30+th, 239
nta, nty = 4, 4
lx = [xmin + k*(xmax-xmin)/(2*nta+1) for k in range(1, 2*nta+1)]
ly = [ymin + k*(ymax-ymin)/(2*nty+1) for k in range(1, 2*nty+1)]
l = (xmax-xmin+1) / (2*nta+1)
scr.cls()
for i in range(nty):
scr.drawString(str(i), xmin-tw, ly[i*2])
for j in range(nta):
scr.drawString(str(j), lx[j*2], ymin-th)
scr.setPen(j, i)
scr.setColor((255,0,0))
scr.fillArc(lx[j*2], ly[i*2], lx[j*2+1]-lx[j*2], ly[i*2+1]-ly[i*2], 0, 3150)
scr.setColor((0,0,0))
scr.drawArc(lx[j*2], ly[i*2], lx[j*2+1]-lx[j*2], ly[i*2+1]-ly[i*2], 0, 3150)
disp_wait()

drawArc(x, y, dx, dy, t1, t2)
permet donc de tracer un arc d'une ellipse elle-même inscrite dans un rectangle :- de dimensions wethdonnées en pixels
- aux côtés parallèles aux bors de l'écran
- et en utilisant le point de coordonnées (x, y)comme sommet supérieur gauche
Et La fonction

fillCircle(x, y, r)
permettant de préciser des éléments caractéristiques différents plus naturels dans le cas particulier d'un disque. La fonction serait donc équivalente au code suivant :- Code: Select all
def fillCircle(x, y, r):
fillArc(x-r, y-r, 2*r, 2*r, 0, 3600)
Ce qui est curieux ? Et bien qu'il n'y ait apparemment pas de fonction similaire
drawCircle(x, y, r)
pour le tracé d'un cercle, obligeant dans ce cas à utiliser une logique complètement différente.- Code: Select all
from ti_system import *
import ti_graphics as scr
tw, th = 8, 15
xmin, xmax, ymin, ymax = tw, 319, 30+th, 239
nta, nty = 4, 4
lx = [xmin + k*(xmax-xmin)/(2*nta+1) for k in range(1, 2*nta+1)]
ly = [ymin + k*(ymax-ymin)/(2*nty+1) for k in range(1, 2*nty+1)]
l = (xmax-xmin+1) / (2*nta+1)
scr.cls()
for i in range(nty):
scr.drawString(str(i), xmin-tw, ly[i*2])
for j in range(nta):
scr.drawString(str(j), lx[j*2], ymin-th)
scr.setPen(j, i)
scr.setColor((255,0,0))
scr.fillCircle(lx[j*2]+(ly[i*2+1]-ly[i*2])/2, (ly[i*2]+ly[i*2+1])/2, (ly[i*2+1]-ly[i*2])/2)
scr.setColor((0,0,0))
scr.drawArc(lx[j*2], ly[i*2], ly[i*2+1]-ly[i*2], ly[i*2+1]-ly[i*2], 0, 3600)
disp_wait()
7) fonctions dédiées aux images
Go to top

Enorme surprise,

Mais ces fonctions dédiées n'en restent pas moins un formidable avantage sur la concurrence, ces boucles d'allumage n'étant sur la plupart des modèles pas assez rapides pour permettre d'animer ou déplacer un
Comme ces fonctions ne sont pas au menu il nous faut donc arriver à deviner ce qu'elles attendent comme arguments.

pushImage(x, y, w, h)
semble définir une image de dimensions La fonction
Par exemple ci-contre, le résultat du code suivant :
- Code: Select all
from ti_system import *
import ti_graphics as scr
scr.pushImage(50, 50, 269, 170)
scr.popImage()
disp_wait()
drawImage(?, ?, ?)
doit pour sa part servir à dessiner l'image en question avant affichage, mais nous n'avons pas réussi à en comprendre le fonctionnement.Si l'on se réfère à notre test précédent ayant mis en évidence que nous disposions de près de 17.5K de mémoire de tas
Nous avons deux hypothèses :
- Soit la fonction attend une liste ou une chaîne de données compressées par exemple en RLE, et peut-être que TIa prévu un outil générant automatiquement à partir d'une image fournie la liste ou chaîne compressée à coller dans ton script. Mais en tous cas cet outil ne nous as pas été passé.
- Soit la fonction attend le nom d'une ressource image à aller chercher en externe dans les variables du système de la calculatrice. En fouillant l'application Pythonà l'éditeur hexadécimal nous avons effectivement trouvé un indice en ce sens, avec un'imgname'qui est bien présent en clair dans le code même nous n'avons trouvé pour le moment aucun menu l'affichant.
En tous cas, faire appel aux variables images préchargées dans le calculatrice avec par exemple
scr.drawImage('Image1', 50, 50)
semble ne rien donner.On pouvait quand même s'en douter, vu que ces images ont une taille fixe prévue pour un affichage en plein écran :
- 265×165 pixels pour les images 16 couleurs Pic0àPic9
- 133×83 pixels pour les images d'arrière plan Image0àImage9(agrandies d'un facteur 2 pour l'affichage)
Peut-être donc plutôt que
8) ti_graphics et autres fonctions
Go to top
Déjà, il inclut le module
Il inclut également une fonction

_write('')
semble être équivalente avec ti_plotlib._write('')
.Sauf qu'ici elle est accompagnée d'une fonction
_read(n)
. Attention, si on lui demande de lire plus de données qu'il y en a, on ne sait où en passant, la calculatrice rentre dans une boucle d'attente infinie qu'il est apparemment impossible d'interrompre autrement que par un Egalement quelques autres mystères à découvrir et qui peut-être nous permettront des choses bien pratiques :
_grcmd('')
, _grcif('')
et _handshake(?)
.Conclusion
Go to top
Il y a clairement eu un travail très conséquent là-dessus, c'est un module conçu à partir de zéro et taillé sur-mesure pour te donner le meilleur avec le matériel choisi pour ta

Pixels, textes, formes géométriques diverses et images, chaque fonction te permet ici d'exploiter l'intégralité des capacités matérielles.

De quoi initier de formidables créations

