QCC 2021 Universel épisode 6: Python et zone graphique utile
Posted: 17 Aug 2021, 20:15
Quelle Calculatrice Choisir 2021 édition Universelle
Épisode 6 - Python zone graphique utile
Épisode 6 - Python zone graphique utile
Pour fêter les 10 ans de 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 :
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ère TI-81 de 1990)
- toutes les calculatrices graphiques Casio à technologie Flash (depuis 2003)
Dans un épisode précédent, nous t'avons révélé les dimensions de la zone graphique utile de chaque modèle, c'est-à-dire la zone dont l'utilisateur peut librement allumer les pixels :
- par tracé de graphes
- par exécution de programmes en langage constructeur/historique (très souvent un langage Basic)
Comment donc faire maintenant pour tester la taille de la zone graphique, rien qu'en lisant / écrivant des pixels ? Et bien c'est très simple, tu ne vas pas être dépaysé(e).
Nous allons procéder comme avec une tortue (langage Scratch ou module Python turtle). Nous allons parcourir l'écran, en diagonale, en tentant de lire et modifier chaque pixel rencontré.
Pour savoir si un pixel est accessible en écriture, nous tenterons d'inverser sa couleur :
Pour savoir si un pixel que l'on arrive à lire correspond bien à un pixel visible de l'écran, nous prendrons comme référence la mauvaise valeur de pixel retournée par une lecture clairement hors écran, coordonnées
Dans le seul cas où l'on rencontre cette valeur qui peut très bien être justifiée, nous tenterons ici encore de l'inverser.
Voici donc les fonctions principales utilisant tout ça :
Il suffit donc d'appeler
Nous allons procéder comme avec une tortue (langage Scratch ou module Python turtle). Nous allons parcourir l'écran, en diagonale, en tentant de lire et modifier chaque pixel rencontré.
Pour savoir si un pixel est accessible en écriture, nous tenterons d'inverser sa couleur :
- Code: Select all
def invert_color(c):
try:
ci = [0, 0, 0]
for k in range(3):
ci[k] = 255 - c[k]
except:
ci = ~(c&0xffffff) & 0xffffff
return ci
def is_pixel_writable(x, y, bad_pixel):
if is_pixel_readable(x, y, bad_pixel):
c0 = get_pixel(x, y)
set_pixel(x, y, invert_color(c0))
c = get_pixel(x, y)
return c != c0
Pour savoir si un pixel que l'on arrive à lire correspond bien à un pixel visible de l'écran, nous prendrons comme référence la mauvaise valeur de pixel retournée par une lecture clairement hors écran, coordonnées
(-2, -2)
.Dans le seul cas où l'on rencontre cette valeur qui peut très bien être justifiée, nous tenterons ici encore de l'inverser.
- Code: Select all
def is_pixel_readable(x, y, bad_pixel):
c = None
try:
c = get_pixel(x, y)
except:
pass
if c != None:
if c == bad_pixel:
set_pixel(x, y, invert_color(c))
c = get_pixel(x, y)
return c != bad_pixel
Voici donc les fonctions principales utilisant tout ça :
- Code: Select all
def scr_test(x0, y0, dx0, dy0, test):
bad_pixel = None
try:
bad_pixel = get_pixel(-2, -2)
except:
pass
x, y, dx, dy = x0, y0, dx0, dy0
while not test(x, y, bad_pixel):
x += dx
y += dy
if test(x, y - dy, bad_pixel): y = y0
elif test(x - dx, y, bad_pixel): x = x0
x0, y0 = x, y
x += dx
y += dy
while(dx or dy):
if not test(x - ((dx == 0) and dx0),y - ((dy == 0) and dy0), bad_pixel):
if test(x - ((dx == 0) and dx0), y - ((dy == 0) and dy0) - dy0, bad_pixel): dy = 0
elif test(x - ((dx == 0) and dx0) - dx0, y - ((dy == 0) and dy0), bad_pixel): dx = 0
else: dx, dy = 0, 0
x += dx
y += dy
return x0, y0, (x - x0) // dx0, (y - y0) // dy0
def scr_size():
xrd0, yrd0, xrd, yrd = scr_test(0, 0, -1, -1, is_pixel_readable)
xra0, yra0, xra, yra = scr_test(1, 1, 1, 1, is_pixel_readable)
xr0, yr0 = xrd0 - xrd + 1, yrd0 - yrd + 1
xr, yr = xra + xrd, yra + yrd
xw0, yw0, xw, yw = scr_test(xr0, yr0, 1, 1, is_pixel_writable)
print("at (" + str(xr0) + "," + str(yr0) + "): " + str(xr) + "x" + str(yr) + " readable pixels")
print("at (" + str(xw0) + "," + str(yw0) + "): " + str(xw) + "x" + str(yw) + " writable pixels")
return xr0, yr0, xr, yr, xw0, yw0, xw, yw
Il suffit donc d'appeler
scr_size()
, et tu vas vite comprendre avec notre premier exemple. Les TI-83 Premium CE Edition Python et TI-84 Plus CE-T Python Edition t'offrent donc un écran 320×240 pixels, et une zone utile pour graphes et programmes de 265×165 pixels (56,93%).
En Python, les fonctions relatives aux pixels sont
Après donc parcours de l'écran en diagonale par notre tortue virtuelle, cette dernière nous reporte :
Si le fonctionnement est simple, plusieurs bizarreries dans le résultat sont toutefois à traiter ici.
Déjà sur les deux zones différentes qui nous sont retournées :
Ensuite, selon notre tortue nous aurions donc un écran de 321×241 pixels, soit plus que les 320×240 pixels précédemment annoncés, avec :
Or une tentative d'écriture donc sur cette dernière colonne ne donne visiblement rien à l'écran.
Soit il y a un bug dans notre code expliquant ce résultat différent de la réalité, et tu verras bien ci-dessous si la même anomalie est présente sur d'autres modèles ou pas avec exactement le même code.
Soit la chose vient de Texas Instruments. Nous aurions donc un écran de 320×240 pixels, mais avec en mémoire un buffer associé de 321×241 pixels. Ou bien c'est un bug, ou bien il y a une raison technique que nous ignorons à ce jour pour disposer en mémoire d'1 ligne et d'1 colonne supplémentaires de pixels sans aucune existence physique.
Pour notre classement, nous retiendrons donc ici une zone graphique correspondant à la réalité, c'est-à-dire de 320×210, soit 87,50% de la définition de l'écran, c'est déjà bien mieux qu'avec le langage historique !
En Python, les fonctions relatives aux pixels sont
ti_graphic.getPixel(x, y)
et ti_graphic.setPixel(x, y, couleur)
.Après donc parcours de l'écran en diagonale par notre tortue virtuelle, cette dernière nous reporte :
- 321×241= 77361 pixels pouvant être lus à partir des coordonnées
(-1, -1)
- 321×210= 67410 pixels pouvant être écrits à partir des coordonnées
(-1, 30)
Si le fonctionnement est simple, plusieurs bizarreries dans le résultat sont toutefois à traiter ici.
Déjà sur les deux zones différentes qui nous sont retournées :
- la première signifie que l'on peut lire l'intégralité des pixels de l'écran
- la deuxième ne retient donc plus que les pixels pouvant être modifiés, ici situés en-dessous de la barre d'état de 30 pixels de hauteur, et c'est celle-ci qui correspond à la zone graphique, la seule zone où la tortue a réussi à tracer son chemin comme tu vois ci-contre
Ensuite, selon notre tortue nous aurions donc un écran de 321×241 pixels, soit plus que les 320×240 pixels précédemment annoncés, avec :
- une ligne de pixels d'ordonnée -1 pouvant être lus
- une colonne de pixels d'abscisse -1 pouvant être lus, et également écrits à partir de l'ordonnée 30 marque le début de la zone graphique précédente
Or une tentative d'écriture donc sur cette dernière colonne ne donne visiblement rien à l'écran.
Soit il y a un bug dans notre code expliquant ce résultat différent de la réalité, et tu verras bien ci-dessous si la même anomalie est présente sur d'autres modèles ou pas avec exactement le même code.
Soit la chose vient de Texas Instruments. Nous aurions donc un écran de 320×240 pixels, mais avec en mémoire un buffer associé de 321×241 pixels. Ou bien c'est un bug, ou bien il y a une raison technique que nous ignorons à ce jour pour disposer en mémoire d'1 ligne et d'1 colonne supplémentaires de pixels sans aucune existence physique.
Pour notre classement, nous retiendrons donc ici une zone graphique correspondant à la réalité, c'est-à-dire de 320×210, soit 87,50% de la définition de l'écran, c'est déjà bien mieux qu'avec le langage historique !
La Casio Graph 90+E t'offre un écran de 396×224 pixels, avec une zone utile pour graphes et programmes de 379×187 pixels (79,90%).
En Python, les fonctions relatives aux pixels sont
Mais voyons maintenant ce que cela donne dans l'application Python.
Et c'est fantastique, Casio ici aussi a fait un effort, ce sont pas moins de 384×192 pixels qui sont contrôlables en Python, soit 83,12% de l'écran !
En Python, les fonctions relatives aux pixels sont
casioplot.get_pixel(x, y)
et casioplot.set_pixel(x, y, couleur)
.Mais voyons maintenant ce que cela donne dans l'application Python.
Et c'est fantastique, Casio ici aussi a fait un effort, ce sont pas moins de 384×192 pixels qui sont contrôlables en Python, soit 83,12% de l'écran !
Sur les modèles précédents Casio fx-CG10 et fx-CG20, pas de mise à jour avec Python.
Toutefois tu as également la possibilité d'installer l'application KhiCAS, une adaptation pour ta calculatrice du logiciel de mathématiques intégré Xcas par Bernard Parisse, enseignant-chercheur à l'Université de Grenoble.
L'environnement est également programmable avec une syntaxe proche du Python. Pas de fonctions pour contrôler individuellement les pixels ici, mais par contre nous y disposons d'une tortue dont on peut spécifier les déplacements en pixels. Tentons de tracer un rectangle le plus grand possible à l'aide du code suivant :
C'est l'appel
Toutefois tu as également la possibilité d'installer l'application KhiCAS, une adaptation pour ta calculatrice du logiciel de mathématiques intégré Xcas par Bernard Parisse, enseignant-chercheur à l'Université de Grenoble.
L'environnement est également programmable avec une syntaxe proche du Python. Pas de fonctions pour contrôler individuellement les pixels ici, mais par contre nous y disposons d'une tortue dont on peut spécifier les déplacements en pixels. Tentons de tracer un rectangle le plus grand possible à l'aide du code suivant :
- Code: Select all
def scrtest(w, h):
efface
leve_crayon
tourne_gauche 180
avance w // 3
tourne_gauche 90
avance h // 2
baisse_crayon
for k in range(2):
tourne_gauche 90
avance w
tourne_gauche 90
avance h
C'est l'appel
scrtest(383, 191)
qui nous permet de rentrer le plus grand rectangle possible dans l'écran. Comme les paramètres concernent ici des déplacements de la tortue cela correspond à une zone graphique de 384×192 (83,12%), soit exactement comme avec l'application Python officielle.La Casio Graph 35+E II dispose d'un écran de 128×64 pixels, avec une zone utile pour graphes et programmes de 127×63 pixels (97,67%).
En Python, les fonctions relatives aux pixels sont ici encore
Et en Python c'est donc superbe, nous contrôlons apparemment 128×64 pixels soit 100% de l'écran.
En Python, les fonctions relatives aux pixels sont ici encore
casioplot.get_pixel(x, y)
et casioplot.set_pixel(x, y, couleur)
.Et en Python c'est donc superbe, nous contrôlons apparemment 128×64 pixels soit 100% de l'écran.
Les TI-Nspire CX II utilisent un écran 320×240 pixels, avec une zone utile pour graphes et programmes de 318×212 pixels (87,78%).
Le module Python de tracé par pixels est ti_draw. Il ne dispose pas de fonction permettant d'allumer un pixel isolé comme un set_pixel(). On pourrait certainement remplacer cela par un appel
En fait, get_pixel() et set_pixel() sont offertes dans le cadre d'une autre module ti_image, permettant de travailler sur un calque avant de l'afficher. Mais comme il faut définir les dimensions du calque en question, un test basé là-dessus ne serait pas pertinent.
Toutefois, ti_draw fournit une fonction get_screen_dim() nous permettant de récupérer les dimensions de la zone graphique utilisable, sans surprise ici les mêmes 318×212 pixels.
Le module Python de tracé par pixels est ti_draw. Il ne dispose pas de fonction permettant d'allumer un pixel isolé comme un set_pixel(). On pourrait certainement remplacer cela par un appel
draw_rect(x, y, 0, 0)
pour tracer un rectangle d'1 pixel de surface. Mais surtout, ti_draw ne dispose pas de fonction get_pixel().En fait, get_pixel() et set_pixel() sont offertes dans le cadre d'une autre module ti_image, permettant de travailler sur un calque avant de l'afficher. Mais comme il faut définir les dimensions du calque en question, un test basé là-dessus ne serait pas pertinent.
Toutefois, ti_draw fournit une fonction get_screen_dim() nous permettant de récupérer les dimensions de la zone graphique utilisable, sans surprise ici les mêmes 318×212 pixels.
Sur les anciennes TI-Nspire CX, pas de mise à jour avec Python.
Toutefois, si ta calculatrice n'a pas été mise à jour avec la dernière version 4.5.5, tu peux installer Ndless et ensuite l'application KhiCAS.
KhiCAS intègre un interpréteur Python et surtout un mode examen compatible avec celui de Texas Instruments. Si tu actives le mode examen depuis les menus de KhiCAS, ce dernier restera disponible en mode examen !
Les fonctions get_pixel() et set_pixel() sont ici offertes via le module graphic. Ce module est également accessible via les alias casioplot et kandinsky, ce qui permet une compatibilité directe avec les scripts conçus pour Casio et NumWorks !
Notre script de test détecte ici 320×222 pixels pouvant à la fois être lus et écrits, soit 92,5%.
Toutefois, si ta calculatrice n'a pas été mise à jour avec la dernière version 4.5.5, tu peux installer Ndless et ensuite l'application KhiCAS.
KhiCAS intègre un interpréteur Python et surtout un mode examen compatible avec celui de Texas Instruments. Si tu actives le mode examen depuis les menus de KhiCAS, ce dernier restera disponible en mode examen !
Les fonctions get_pixel() et set_pixel() sont ici offertes via le module graphic. Ce module est également accessible via les alias casioplot et kandinsky, ce qui permet une compatibilité directe avec les scripts conçus pour Casio et NumWorks !
Notre script de test détecte ici 320×222 pixels pouvant à la fois être lus et écrits, soit 92,5%.
Sur les TI-Nspire CM et TI-Nspire monochromes, nous n'avons pas que 32 Mio de SDRAM au lieu de 64 Mio. Ce n'est pas suffisant pour lancer KhiCAS.
Tu peux ici installer Ndless puis ensuite l'application MicroPython.
On y contrôle alors 320×240 pixels soit 100% de l'écran !
Attention toutefois, l'activation du mode examen t'interdira l'usage de cette application.
Tu peux ici installer Ndless puis ensuite l'application MicroPython.
On y contrôle alors 320×240 pixels soit 100% de l'écran !
Attention toutefois, l'activation du mode examen t'interdira l'usage de cette application.
La NumWorks t'apporte un écran de 320×240 pixels, dont comme nous avons vu 320×204 pixels pour les graphes (85%).
En Python, les fonctions qui nous intéressent ici sont
Nous avons donc accès ici à une zone graphique de 320×222 pixels, soit 92,5% !
En Python, les fonctions qui nous intéressent ici sont
kandinsky.get_pixel(x, y)
et kandinsky.set_pixel(x, y, couleur)
.Nous avons donc accès ici à une zone graphique de 320×222 pixels, soit 92,5% !
La HP Prime t'offre un écran de 320×240 pixels, intégralement utilisables par les graphes et programmes en langage constructeur (HPPPL).
Le module Python hpprime nous offre de quoi écrire un pixel :
Il ne fournit pas directement de quoi lire un pixel, mais par contre une fonction eval() permettant de faire appel au langage constructeur HPPPL où cette fonction existe. On peut alors se redéfinir une fonction get_pixel() en Python :
Sans surprise ici aussi, nous contrôlons les mêmes 320×240 pixels soit 100% de l'écran !
Le module Python hpprime nous offre de quoi écrire un pixel :
pixon(numero_calque, x, y, couleur)
.Il ne fournit pas directement de quoi lire un pixel, mais par contre une fonction eval() permettant de faire appel au langage constructeur HPPPL où cette fonction existe. On peut alors se redéfinir une fonction get_pixel() en Python :
- Code: Select all
def get_pixel(x, y):
return int(eval("get_pixel(" + str(x) + "," + str(y) + ")"))
Sans surprise ici aussi, nous contrôlons les mêmes 320×240 pixels soit 100% de l'écran !
Les mesures sont toutes disponibles et facilement comparables sur le lien ci-dessous :