La NumWorks était originellement un merveilleux projet de calculatrice graphique ouverte, rompant radicalement avec les usages des constructeurs historiques.
Le développement tiers a pu s'y hisser à un niveau jamais atteint sur la concurrence et permettre l'émergence d'un projet formidable, Omega par Quentin Guidee et ses non moins illustres collaborateurs.
Il s'agissait d'un firmware alternatif pour ta calculatrice NumWorks. Basé sur le code source du firmware officiel Epsilon comme la licence libre l'autorisait à l'époque, Omega avait pour but de regrouper et mettre en avant les meilleures contributions au code d'Epsilon, en incluant cette fois-ci celles laissées de côté par le constructeur.
Difficile de tout citer ici mais voici déjà par exemple quelques-uns des fantastiques ajouts d'Omega. La NumWorks travaille en interne sur des arbres de calcul, mais les bridait donc artificiellement pour n'accepter que des valeurs numériques. Omega ré-autorisait à nouveau ces arbres à utiliser des lettres / inconnues, ce qui nous redonnait ainsi un moteur de calcul littéral. De quoi même dériver, du jamais vu à seulement 80€ ! On peut aussi citer un tableau périodique des éléments, ou encore la possibilité d'avoir une bibliothèque de constantes physiques avec unités bien avant que ce ne soit disponible dans le firmware officiel.
Outre ce qu'il intégrait, Omega offrait également l'avantage de pouvoir installer à chaud des applications, fonctionnalité jusqu'alors absente du firmware officiel Epsilon. Plusieurs applications de très haute facture furent développées, on peut citer entre autres :
KhiCAS, une formidable application intégrée de Mathématiques et de Sciences par Bernard Parisse, enseignant-chercheur à l'Université de Grenoble, qui étendait gratuitement les capacités de ta calculatrice au niveau d'une HP Prime. L'application intégrait le moteur de calcul formel GIAC développé pour le logiciel Xcas du même auteur pour des possibilités en calcul encore plus étendues. Étaient également inclus un tableur ainsi qu'un un tableau périodique des éléments (deux applications faisant toujours à ce jour cruellement défaut au firmware officiel Epsilon), ainsi qu'une bibliothèque de constantes physiques, un convertisseur d'unités, et bien d'autres choses encore. Le tout était en prime programmable en Python, avec une collection de bibliothèques importables bien plus étoffée que celle de l'application du firmware officiel, et surtout ici de façon intégrée, tes scripts Python pouvant même ici faire appel au moteur de calcul formel GIAC par l'intermédiaire de la bibliothèquecas.
Nofrendo, un émulateur de console de jeux Nintendo NES par zardam
Peanut-GB, un émulateur de console de jeux Nintendo GameBoy par M4x1m3
Periodic, un autre tableau périodique des éléments par M4x1m3
Un gros avantage de plus était ici que KhiCAS et l'ensemble des fonctionnalités rajoutées restaient accessibles en mode examen, de façon parfaitement légale et légitime en France, puisque ces fonctionnalités ne sont pas des données et venaient de plus directement intégrées à des modèles concurrents haut de gamme parfaitement autorisés.
Mais voilà, pour la rentrée 2021 la mise à jour 16.3 d'Epsilon, le firmware officiel des calculatrices NumWorks, a introduit un verrouillage des modèles N0110.
Toute N0110 mise à jour ou venant préchargée d'une version 16.3 ou supérieure, comprend un chargeur de démarrage censé être non effaçable, et empêchant entre autres :
l'installation de tout firmware non correctement signé par le constructeur, c'est-à-dire entre autres de tout firmware antérieur à la version 16 ainsi que de tout firmware non officiel dont Omega
l'installation d'applications persistantes en mémoire Flash(logiciel intégré de Mathématiques avec moteur ce calcul formel KhiCAS, émulateurs Nintendo Game Boy et NES, tableau périodique des éléments, ...)
NumWorks a de plus profité de l'occasion pour révoquer sa licence libre, et interdire ainsi la réutilisation de tout code introduit à partir de la version 16 dans des firmwares non officiels ; Omega ne pouvait donc plus intégrer les dernières nouveautés.
La mort dans l'âme, nous t'annoncions donc à la rentrée 2021 l'abandon en conséquence du projet de firmwareOmega. Toutefois 2 forks en ont par la suite émergé successivement, les firmwaresKhi par Bernard Parisse, puis Upsilon.
Les utilisateurs informés qui avaient la chance d'avoir entre leurs mains des calculatrices non encore verrouillées avaient certes le choix mais restaient face à un très cruel dilemme :
soit mettre à jour vers le firmwareEpsilon pour bénéficier de toutes les dernières nouveautés officielles, mais en contrepartie renoncer définitivement aux formidables ajouts des firmwares tiers
soit utiliser un firmware tiers, mais en contrepartie se priver des nouveautés officielles apportées à ce jour avec les versions 16, 17 puis 18
Dans une actualité précédente, nous t'annoncions la sortie de Phi par M4x1m3, un des anciens de l'équipe de développement Omega. Phi est un chargeur de démarrage avec lequel il suffit d'écraser le chargeur officiel, grâce à une faille présente dans les firmwaresEpsilon officiels jusqu'à la version 18.2.0.
Après plus de 6 mois d'attente Phi te permettait donc enfin de déverrouiller ta calculatrice. Mieux que ça, le nouveau chargeur de démarrage Phi était ensuite capable de lancer aussi bien les firmwares officiels Epsilon(à partir de la version 16) que les firmware tiers, à la seule condition que ces derniers aient été mis à jour pour supporter ce nouvel amorçage.
Le projet Omega profita justement de l'occasion pour renaître de ses cendres avec une mise à jour compatible en version 2.
Encore mieux que ça, avec Phi tu n'avais même pas à choisir entre fonctionnalités officielles et tierces, tu peux avoir les deux en même temps ! Phi rajoute un raccourci reset+
4
permet de consulter l'état de la mémoire Flash et de mettre la calculatrice dans un mode de mise à jour protégé car interdisant la réécriture du chargeur de démarrage. Rappelons que depuis le verrouillage la mémoire Flash des N0110 est partitionnée en deux moitiés égales de 4 Mio et pouvant chacune accueillir un firmware. Justement à cet écran Phi présente la mémoire Flash comme découpée en 2 slotsA et B de 4 Mio chacun. Les nouveaux raccourcis reset+
1
et reset+
2
te permettent alors de basculer entre l'amorçage des deux firmwares présents dans chacun de ces 2 slots. Du multiboot sur une calculatrice, c'est absolument sensationnel !
Sauf qu'il y avait deux problèmes majeurs avec Phi et Omega 2.
D'une part, le découpage de la mémoire Flash en 2 slots égaux de 4 Mio faisait qu'il n'était pas possible de profiter à la fois :
de la possibilité d'avoir 2 firmwares entre lesquels basculer au choix
et de la formidable application KhiCAS, cette dernière occupant trop de place et débordant donc sur le 2èmeslot
D'autre part, et là c'était extrêmement grave, Phi n'est pas conforme à la réglementation française du mode examen et est donc strictement interdit d'utilisation à tout examen exigeant l'activation de ce mode en France. Le problème est que les raccourcis reset+
1
et reset+
2
permettant de basculer entre les deux firmwares présents en mémoire désactivent le mode examen. Or c'est strictement interdit par les spécifications officielles du mode examen français ; le mode examen ne doit pas pouvoir être désactivé de façon autonome par les candidats, c'est-à-dire que la désactivation doit nécessiter un outil extérieur non présent sur leur table de composition car interdit en examen (2ème calculatrice, ordinateur, etc.). Un outil interdit étant frauduleux, si tu introduis Phi dans une salle d'examen en France et te fais prendre (parce que tu auras basculé entre deux firmwares pendant l'épreuve et peut-être même oublié de réactiver immédiatement le mode examen), tu risquais l'ensemble des désagréments possiblement dramatiques (non fixé sur ta réussite à l'examen à la veille de l'été comme les camarades et donc rien à fêter avec eux, le jugement nécessitant du temps alors qu'en prime les rectorats sont fermés une bonne partie de l'été risque de perdre ton inscription dans l'enseignement supérieur et donc une année, jusqu'à 5 ans d'interdiction de passer tout examen y compris le permis de conduire de quoi bien te gâcher la vie, ...).
Malgré sa gravité et ses conséquences éventuelles hautement désagréables, ce problème rapidement signalé n'avait malheureusement pas fait l'objet de corrections de la part de l'équipe Omega.
Nous t'annoncions par la suite une première mise à jour du firmwareKhi dédié à KhiCAS par Bernard Parisse, compatible avec le nouveau amorçage via un chargeur de démarrage, et incluant sa propre version de ce dernier.
Bernard avait pris le soin de traiter les deux problèmes précédents :
d'une part, Khi était proposé dans une version allégée intégrant la seul application Paramètres, permettant de faire rentrer KhiCAS dans un unique slot et ainsi de profiter également en même temps d'un multiboot avec le firmware officiel Epsilon
d'autre part, le mode examen était ici conservé lors de la bascule entre deux firmwares, comportement enfin conforme aux textes réglementaires français
Si pour ta part tu préférais le firmwareUpsilon, et bien c'est le grand jour pour toi !
Dernier mais non le moindre, Upsilon vient en effet enfin d'être à son tour mis à jour dans une version avec un bootloader permettant le multiboot !
En prime cette mise à reprend une des améliorations effectuées dans le cadre de la mise à jour de Khi : le mode examen sera conservé lorsque tu changeras de firmware conformément la réglementation française !
Si tu es en France et as installé Phi ou Omega 2 sur ta machine, il est urgent pour toi de migrer vers une solution conforme à la réglementation des examens aussitôt que possible, c'est-à-dire à ce jour uniquement Khi ou Upsilon, et ce même si tu n'as pas d'examens cette année. En effet :
si tu attends à l'année prochaine tu risques d'oublier entre temps
et même si tu n'as pas du tout d'examen, tu pourrais très bien un jour prêter ou vendre ta calculatrice à quelqu'un qui serait concerné
Si tu souhaites installer ou migrer sur Khi, des mini-tutos sont inclus dans l'annonce associée.
Si tu souhaites installer ou migrer sur Upsilon, voici maintenant quelques mini-tutos à adapter selon ta situation. Attention, contrairement à la solution précédente et comme déjà dit, le chargeur de démarrage Upsilon ne te permettra pas de profiter à la fois de l'application KhiCAS et de la possibilité d'avoir un multiboot.
Supposons que tu dispose déjà d'une machine sous Phi avec un multibootOmega 2.0 et Epsilon, voici comment migrer.
Comme le site web d'Omega n'installe ce dernier que dans le slotA, c'est-à-dire que tu as normalement :
Omega 2.0
Epsilon
Pour remplacer Phi par le nouveau bootloader d'Upsilon c'est extrêmement simple. Il te faut :
mettre la machine en mode de récupération autorisant la réécriture du bootloader avec le raccourci reset+
6
(raccourci à ne plus jamais utiliser sur le site officiel si tu ne veux pas te retrouver à nouveau coincé, et peut-être cette fois-ci sans retour possible )
cliquer sur le bouton Recovery pour charger et lancer le logiciel de récupération
rafraîchir la page pour utiliser alors le bouton Connect, suivre les instructions, et lorsque proposé bien effectuer une installation dans le slotA(choix par défaut à ce jour, et le slot B n'est pas proposé)
Si par contre tu pars d'une calculatrice ne disposant pas encore de Phi ou autre bootloader tiers, le plus simple est de commencer par l'installer pour ensuite suivre la procédure précédente de migration vers Upsilon.
Ta calculatrice TI-83 Premium CE ou TI-84 Plus CE dispose d'une application de tableau périodique des éléments appelée Periodic.
Periodic est normalement préinstallé en usine, et est ensuite mis à jour ou réinstallé avec les fichiers de packs de mises à jour diffusés par Texas Instruments chaque année. L'application est alors accessible via la combinaison
2nde
résol
sur TI-83 Premium CE ou via la touche
apps
sur TI-84 Plus CE. Sur TI-83 Premium CE, cette application a même le gros avantage de rester disponible en mode examen, contrairement aux modèles concurrents de chez Casio.
La dernière version de Periodic est la 5.5.0.0038 compilée le 12 mai 2020, et accompagne donc les packs de mises à jour depuis la mise à jour système 5.5 de rentrée 2020.
C'est une très belle application, disposant d'une superbe interface justement en forme de tableau périodique et tirant profit de l'écran couleur pour distinguer différentes familles d'éléments.
Mais c'est loin d'être tout. Pour accéder à un élément ciblé, tu as le choix entre parcourir le tableau périodique évoqué ou bien une liste d'éléments. Pour te faciliter les choses cette liste peut justement être triée aussi bien par numéro atomique que nom ou symbole.
Rajoutons la possibilité d'exporter les valeurs numériques de propriétés d'élément pour les réutiliser hors de l'application, ainsi que celle de construire des diagrammes qui pourront entre autres mettre en évidence le caractère périodique des propriétés chimiques !
Nous en sommes donc à bientôt 2 ans sans mise à jour de l'application Periodic.
Et Texas Instruments ferait peut-être mieux de se méfier car le concurrent français NumWorks a annoncé fin 2021 être en train de travailler sur une application de tableau péridodique pour une future mise à jour, un des plus gros manques de sa calculatrice, et a l'habitude pour chaque nouveauté d'innover grandement sur l'interface...
Frédéric Desautels alias mr womp womp vient donc de sauter sur l'occasion et de te programmer en langage C sa propre vision d'un tableau périodique amélioré pour TI-83 Premium CE et compatibles.
Son programme est bien évidemment loin d'égaler l'application officielle. On peut déplorer :
l'impossibilité d'accéder aux éléments par liste
l'impossibilité d'exporter ou représenter graphiquement les propriétés numériques
la précision décimale inférieure à l'affichage des propriétés numériques
la non prise en compte de la langue de la calculatrice, l'affichage étant ici toujours en Anglais
un tout petit peu moins de propriétés que Texas Instruments, 13 au lieu de 15
Mais ce qui nous intéresse aujourd'hui ce ne sont pas les manques, mais les différences. Frédéric nous offre en effet quelques évolutions sur l'interface qu'il a tout particulièrement soignée, avec :
les symboles des éléments directement affichés sur le tableau périodique et facilitant donc d'une part au plus grand nombre la recherche sur cette interface, et permettant de plus de lister rapidement les éléments appartenant à une même famille ou période
un thème sombre moins agressif pour les yeux
un affichage des propriétés en petite police permettant de tout faire rentrer sur un même écran, au lieu d'avoir à faire défiler sur 3 écrans comme avec Texas Instruments
sur l'affichage des propriétés, possibilité de passer directement à l'élément suivante/précédent avec les touches fléchées sans avoir à repasser par la vue en tableau
Mais bien sûr à la différence de l'application officielle, ce programme ne restera malheureusement pas disponible en mode examen, les réglementation et spécifications associées semblant avoir été conçues de façon trop complaisante avec les constructeurs ; ce genre de programme parfaitement légitime en France n'aurait jamais dû être bloqué par le mode examen en France. Donc pour t'en servir en évaluation, pas d'autre choix qu'attendre que Texas Instruments accepte de faire quelque chose de similaire, ou à défaut un de ses concurrents.
Attention, ce programme rentre dans la catégorie des programmes en langage machine dits ASM.
Or, suite à un acte hautement maladroit d'un enseignant de Mathématiques français avec ses gesticulations certes compréhensibles mais maladroites et à courte vue dans le contexte de la réforme du lycée, Texas Instruments a réagi en supprimant la gestion de tels programmes depuis la mise à jour 5.5.1.
Si tu es sur une des versions ainsi bridées, tu peux quand même jouer sans trop d'efforts. Il te faut :
installer arTIfiCE pour remettre la possibilité de lancer des programmes ASM
ensuite de préférence installer Cesium pour pouvoir lancer les programmes ASM plus facilement, ou même AsmHook pour pouvoir les lancer comme avant
installer les bibliothèques C nécessaires au fonctionnement de certains jeux dont celui-ci (mais rien de compliqué, juste à transférer le fichier et c'est tout)
Elimination est un jeu de type RPG, une création originale par Hot_Dog initialement sortie en novembre 2021 pour calculatriaces TI-82 Plus, TI-83 Plus et TI-84 Plus monochromes, prenant la forme d'une application.
Le gameplay est comparable à ce que tu as peut-être connu avec Final Fantasy, Pokemon, Earthbound ou encore Super Mario RPG. Tu enchaînes des phases d'exploration et de combat au tour par tour.
En 2050, les terriens sont en guerre avec une étrange race extraterreste insectiforme venue de la galaxie Whirlpool(tourbillon). Mais toute ressemblance avec d'autres histoires de science fiction s'arrête là, car les terriens avaient l'avantage.
Notre aventure démarre avec quatre enfants : Ryan, Jamie, Collin et Megan, qui par curiosité s'amusent à monter à bord d'une soucoupe volante écrasée. Malheureusement pendant qu'ils sont encore à bord, la soucoupe est récupérée et ramenée dans la galaxie Whirlpool. Bien évidemment, aucun d'eux ne sachant piloter une soucoupe volante alien, ce moyen de retour est a priori inenvisageable. Sauf qu'une autre race extraterrestre, les Tosonians et leur leaderJaslin, sont prêts à aider nos quatre explorateurs à retrouver le chemin de la voie lactée.
C'est le début d'une formidable aventure sur calculatrices. Pour aider à la construction du vaisseau spatial Tosonian, ton équipe va devoir explorer des planètes, progresser en expérience et niveau, et accumuler des ressources (or, cuivre, lithium, ...).
Aujourd'hui Hot_Dog nous fait l'immense plaisir d'une version couleur d'Elimination pour TI-83 Premium CE et TI-84 Plus CE !
11 niveaux t'attendent sur 8 planètes peuplées de plus de 70 ennemis dont des boss ; mais qu'attends-tu ?
Attention, Elimination rentre dans la catégorie des programmes en langage machine dits ASM.
Or, suite à un acte hautement maladroit d'un enseignant de Mathématiques français avec ses gesticulations certes compréhensibles mais aveugles dans le contexte de la réforme du lycée, Texas Instruments a réagi en supprimant la gestion de tels programmes depuis la mise à jour 5.5.1.
Si tu es sur une des versions ainsi bridées, tu peux quand même jouer sans trop d'efforts. Il te faut :
installer arTIfiCE pour remettre la possibilité de lancer des programmes ASM
ensuite de préférence installer Cesium pour pouvoir lancer les programmes ASM plus facilement, ou même AsmHook pour pouvoir les lancer comme avant
installer les bibliothèques C nécessaires au fonctionnement de certains jeux dont celui-ci (mais rien de compliqué, juste à transférer le fichier et c'est tout)
Pour 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
Aujourd'hui justement approfondissons ce dernier point, parlons du 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 !
Ce 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
La dernière mise à jour de KhiCAS améliore justement les possibilités de la bibliothèque turtle. Elle est disponible à ce jour :
Effectivement il y a bien des nouveauté, nous passons de 66 à 69 éléments. Nous disposons de 3 nouvelles méthodes :
.clear() pour effacer l'affichage sans réinitialiser la position de la tortue
.pos(), un alias court de .position() que l'on avait déjà pour récupérer la position de la tortue
.towards(x, y) pour obtenir l'angle d'orientation permettant d'atteindre les coordonnées fournies
Cela peut certes te paraître peu, bien que .towards() permette déjà d'aborder facilement des scripts bien plus ambitieux comme nous verrons plus bas.
Mais ça c'est juste pour les méthodes rajoutées ; il va rester à voir si il y a eu des améliorations sur le fonctionnement des méthodes déjà présentes.
B) Tests de conformité comparatifs (toutes solutions turtle)
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 :
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 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)
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 :
On confirme donc avec la nouvelle version KhiCAS l'ajout des 3 méthodes jusqu'alors manquantes.
Mais surtout il n'y a donc dans l'état actuel des scripts plus aucune erreur détectée automatiquement, chose exceptionnelle si l'on compare aux solutions officielles, et signe d'un soin minutieux !
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 :
_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
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
C) 17 exemples comparatifs (toutes solutions turtle)
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 heapPython bien plus restreint des TI-83 Premium CE et compatibles.
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 :
KhiCAS ainsi que le turtle officiel de la NumWorks avaient un tracé incorrect ici, car la méthode .towards() était absente de leur implémentation de turtle. Et malheureusement, la bibliothèque turtle n'est dans ces deux cas pas altérable à l'exécution ce qui empêchait notre script de corriger.
Concernant KhiCAS ce manque est maintenant comblé, et visiblement parfaitement fonctionnel !
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)
Sur cet exemple, KhiCAS reste l'une des solutions turtle qui s'en tire hélas le moins bien.
Toutefois on peut remarquer une petite amélioration depuis la dernière fois ; la couleur de remplissage passé en 2ème paramètre de la méthode .color(,) n'est plus ignorée et est maintenant gérée correctement.
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é :
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)
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 :
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: 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)
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 :
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 :
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 :
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)
Bonne nouvelle ici encore, KhiCAS nous peint enfin les vitraux de la bonne couleur !
Par rapport au fond bleu, notons que c'est cette nouvelle version de 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.
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
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 :
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)
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)
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
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)
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.
Certes il y a encore quelques défauts et donc écarts par rapport au tracé obtenu avec la bibliothèque standard sur ordinateur, mais KhiCAS a l'avantage d'être régulièrement maintenu et de bénéficier de plusieurs mises à jour par an.
Les progrès sont déjà très significatifs par rapport à la version précédente, et nul doute qu'ils vont se poursuivre !
Pour 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
Aujourd'hui justement approfondissons ce dernier point, parlons du 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 !
Ce 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
La dernière mise à jour de KhiCAS améliore justement les possibilités de la bibliothèque turtle. Elle est disponible à ce jour :
Effectivement il y a bien des nouveauté, nous passons de 66 à 69 éléments. Nous disposons de 3 nouvelles méthodes :
.clear() pour effacer l'affichage sans réinitialiser la position de la tortue
.pos(), un alias court de .position() que l'on avait déjà pour récupérer la position de la tortue
.towards(x, y) pour obtenir l'angle d'orientation permettant d'atteindre les coordonnées fournies
Cela peut certes te paraître peu, bien que .towards() permette déjà d'aborder facilement des scripts bien plus ambitieux comme nous verrons plus bas.
Mais ça c'est juste pour les méthodes rajoutées ; il va rester à voir si il y a eu des améliorations sur le fonctionnement des méthodes déjà présentes.
B) Tests de conformité comparatifs (toutes solutions turtle)
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 :
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 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)
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 :
On confirme donc avec la nouvelle version KhiCAS l'ajout des 3 méthodes jusqu'alors manquantes.
Mais surtout il n'y a donc dans l'état actuel des scripts plus aucune erreur détectée automatiquement, chose exceptionnelle si l'on compare aux solutions officielles, et signe d'un soin minutieux !
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 :
_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
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
C) 17 exemples comparatifs (toutes solutions turtle)
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 heapPython bien plus restreint des TI-83 Premium CE et compatibles.
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 :
KhiCAS ainsi que le turtle officiel de la NumWorks avaient un tracé incorrect ici, car la méthode .towards() était absente de leur implémentation de turtle. Et malheureusement, la bibliothèque turtle n'est dans ces deux cas pas altérable à l'exécution ce qui empêchait notre script de corriger.
Concernant KhiCAS ce manque est maintenant comblé, et visiblement parfaitement fonctionnel !
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)
Sur cet exemple, KhiCAS reste l'une des solutions turtle qui s'en tire hélas le moins bien.
Toutefois on peut remarquer une petite amélioration depuis la dernière fois ; la couleur de remplissage passé en 2ème paramètre de la méthode .color(,) n'est plus ignorée et est maintenant gérée correctement.
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é :
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)
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 :
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: 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)
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 :
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 :
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 :
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)
Bonne nouvelle ici encore, KhiCAS nous peint enfin les vitraux de la bonne couleur !
Par rapport au fond bleu, notons que c'est cette nouvelle version de 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.
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
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 :
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)
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)
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
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)
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.
Certes il y a encore quelques défauts et donc écarts par rapport au tracé obtenu avec la bibliothèque standard sur ordinateur, mais KhiCAS a l'avantage d'être régulièrement maintenu et de bénéficier de plusieurs mises à jour par an.
Les progrès sont déjà très significatifs par rapport à la version précédente, et nul doute qu'ils vont se poursuivre !