J’ai découvert la calculette NumWorks [1] cet hiver dans le numéro 105 de Linux Pratique de janvier-février 2018 [2]. Son code source fut protégé par une licence pas vraiment libre (CC BY-NC-ND-4.0 [3]), car les membres de NumWorks disent eux-mêmes qu’ils sont opposés à l’usage commercial de leur travail, mais pas à celui d’enseignants ou de bidouilleurs [4]. Il est passé pendant la rédaction de cet article à la licence CC BY-NC-SA 4.0[5] qui autorise la modification et la redistribution (sans changer la licence) donc de travailler en classe avec une version recompilée de l’émulateur, notamment si votre administrateur n’a pas installé Python sur les machines de votre établissement.
Les spécifications techniques sont elles aussi publiques. Vous pouvez la fabriquer vous-même avec les composants et une imprimante 3D.
Nous verrons d’abord comment installer le nécessaire pour que la compilation se passe bien puis quoi modifier dans le code source pour occuper des élèves pendant une heure au moins.
1. Installation
1.1 L’émulateur natif
Commencez par vérifier (avec Debian) que les paquets suivants sont bien installés :
> dpkg -l bison build-essential dfu-util flex gcc-arm-none-eabi git libfltk1.3-dev libfreetype6-dev libpng12-dev
Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
| État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/H=semi-installé/W=attend-traitement-déclenchements
|/ Err?=(aucune)/besoin Réinstallation (État,Err: majuscule=mauvais)
||/ Nom Version Architecture Description
+++-=====================-===============-===============-===============================================
ii bison 2:3.0.4.dfsg-1+ i386 YACC-compatible parser generator
ii build-essential 12.5 i386 Informational list of build-essential packages
ii dfu-util 0.9-1 i386 Device firmware update (DFU) USB programmer
ii flex 2.6.4-6.1 i386 fast lexical analyzer generator
ii gcc-arm-none-eabi 15:6.3.1+svn253 i386 GCC cross compiler for ARM Cortex-A/R/M process
ii git 1:2.17.1-1 i386 fast, scalable, distributed revision control sy
ii libfltk1.3-dev 1.3.4-7 i386 Fast Light Toolkit - development files
ii libfreetype6-dev:i386 2.8.1-2 i386 FreeType 2 font engine, development files
un libpng12-dev <aucune> <aucune> (aucune description n'est disponible)
Installez les paquets manquants avec votre gestionnaire de paquets préféré. Chez moi, ni libpng12-dev ni une autre version de cette bibliothèque de développement ne sont installées, mais ça compile quand même, peut-être parce que libpng est installée.
Si vous utilisez une autre distribution, la liste des prérequis est fournie sur le site [6] : GNU ARM Embedded Toolchain, libpng, Bison, Flex, GNU Make, FreeType, FLTK, dfu-util et OpenOCD.
Une fois que tout est prêt, pour compiler l’émulateur natif, tapez :
git clone https://github.com/numworks/epsilon.git
cd epsilon
make PLATFORM=simulator clean
make PLATFORM=simulator
Ceci crée l’application que vous lancez avec :
./epsilon.elf
Vous obtiendrez la copie d’écran de l’application ci-contre.
Figure 1 : Le binaire natif compilé sous Linux.
Avec make epsilon_flash, vous pouvez modifier le binaire de votre propre calculette si elle est branchée à votre ordinateur, mais je n’ai pas essayé. Oui, oui, le même code source peut se compiler en un émulateur natif, dans votre machine physique ou en un émulateur en JavaScript, voir plus loin. La performance, vu le peu de personnes qui travaillent chez NumWorks, est à saluer.
Le binaire epsilon.elf est autonome, mais il ne fonctionnera pas dans Windows. Le clavier est incomplet (appuyer sur shift ou alpha ne montre pas les modifications du clavier et presque seules les flèches fonctionnent). Par ailleurs, cette version de l’émulateur n’est plus suivie par l’équipe pour les utilisateurs [7] et le compiler pour Windows à partir de Linux… Bref, tentons autre chose.
1.2 L’émulateur en JavaScript
Au contraire, sa version traduite en JavaScript fonctionne partout (enfin, dans un navigateur décent comme Firefox ou Chrome) et est compilée en une archive zip que vous pouvez décompresser où vous voulez, même sur Internet [8].
Un bug fait interpréter deux fois les touches du clavier dans certaines versions de Chrome (probablement plus anciennes) de mon établissement scolaire, mais pas chez moi ; taper « a » affichait « aa ».
Une chose est sûre :
— M’sieur, ça marche pas avec Internet.
— C’est pour ça que la consigne précisait bien qu’il fallait l’ouvrir avec Firefox. Read the fucking consigne, Attila chou.
Tapez ceci :
make simulator.zip PLATFORM=emscripten
Si, comme attendu, cela ne fonctionne pas, n’essayez pas d’utiliser la version du paquet pour Debian, il n’est pas à jour même dans Sid.
> aptitude show emscripten|grep -i version
Version : 1.22.1-1
Et si, comme Debian, votre distribution ne contient pas la dernière version d’Emscripten, allez plutôt sur son site [9] pour télécharger la version 1.37.35 puis installer si nécessaire Python 2.7 (version 2.7.12 minimum) et Node.JS ; CMake et Java sont optionnels, mais ils pourraient bien être déjà installés comme les autres.
Allez dans le répertoire où vous avez lancé git précédemment et tapez :
git clone https://github.com/juj/emsdk.git
cd emsdk-portable
Ensuite :
./emsdk update
./emsdk install latest
./emsdk activate latest
Les cinq lignes précédentes sont à taper une seule fois pour qu’Emscripten soit fonctionnel ; pas la suivante, à taper dans chaque terminal où vous en aurez besoin, notamment si vous redémarrez :
source ./emsdk_env.sh
ou si vous êtes dans le répertoire numworks/ :
source ../emsdk-portable/emsdk_env.sh
Tout ceci reste coincé dans votre répertoire personnel, inutile d’aller bidouiller dans /usr/local/ ou /opt/.
Voilà, dans numworks/, vous pouvez retenter :
make simulator.zip PLATFORM=emscripten
En cas d’erreur, lisez le fichier emsdk-portable/README.md, installez les quelques bibliothèques de développement manquantes, tentez un make clean ou venez chercher de l’aide sur Reddit [10].
Il est possible qu’une telle version d’emscripten refuse de compiler l’émulateur [11], essayez-en une autre.
C’est raisonnablement long la première fois, mais au bout de quelques minutes sur mon vieux tromblon, vous obtenez l’archive simulator.zip qui contient trois fichiers :
- background.jpg, l’image de fond ;
- epsilon.js, le code de l’émulateur en JavaScript minifié ;
- simulator.html, la page d’accueil avec, en bas, un lien qui crée les copies d’écran que vous verrez plus loin.
Ouvrez simulator.html dans Firefox ou Chrome pour obtenir une image de la calculette, parfaitement utilisable comme l’originale, mais plus rapide, vous bénéficiez de la pleine puissance de votre machine.
Figure 2 : Copie d’écran de l’émulateur en JS. C’est bô, comme Kroc.
Cette fois, le clavier de votre ordinateur est fonctionnel : au moment où j’écris ce texte, seuls le # et quelques caractères de ce genre ne sont accessibles que via la boîte à outils (la touche en haut à droite qui ressemble à une imprimante). La version de la rentrée, qui devrait être toute chaude au moment où vous lirez ces lignes, devrait corriger ça. En effet, l’équipe de NumWorks est active sur le forum officiel [10], disponible, accessible et ouverte aux demandes qui ne sont pas excessives qu’elle insère dans des mises à jour régulières (deux durant la courte durée d’écriture de cet article plus une mi-juin qui m’a obligé à le retoucher).
1.3 Jouons avec Python
L’émulateur contient déjà quelques scripts en Python qui sont considérés comme des modules dans la console d’exécution, mais qu’on peut lancer seuls :
- factorial contient la fonction factorial qui calcule la factorielle d’un nombre de manière récursive, c’est-à-dire que factorial(5) affiche le résultat de 1×2×3×4×5 donc 120, mais factorial(10) plante, car la limite maximale d’appels récursifs est atteinte ;
- mandelbrot contient la fonction du même nom qui affiche une représentation de l’ensemble de Mandelbrot, ainsi mandelbrot(10) limite le nombre d’itérations à 10 ;
- polynomial contient la fonction roots qui calcule les racines d’un polynôme du second degré si elles existent dans ℝ et roots(1,-5,6) affiche 2.0 et 3.0.
Figure 3 : Les scripts en Python inclus.
Vous pouvez les modifier, les supprimer ou en créer d’autres, mais toute modification sera perdue si vous rechargez la page web.
Il est temps, maintenant, de toucher au code source en C++ en y insérant des codes en Python pour vos élèves.
2. Insérons nos scripts
Puisque ces trois scripts sont dans le code source, vous pouvez les y chercher et donc, ajouter les vôtres.
rgrep -i mandelbrot * indique que le mot mandelbrot est présent dans les fichiers apps/code/script_template.cpp, apps/code/script_template.h et apps/code/script_store.cpp et bien sûr dans quelques fichiers objet si vous avez déjà compilé l’émulateur sans nettoyer derrière.
Vous pouvez voir qu’un quatrième module est présent dans le code, mais pas dans l’émulateur : fibonacci contient deux fonctions fibo et fibo2 qui calculent de deux manières différentes les termes de la fameuse suite (une récursive, une récurrente).
Ajoutons un script qui calcule les termes successifs de la suite de Syracuse dans la calculette.
Dans apps/code/script_template.cpp, ajoutez :
constexpr ScriptTemplate syracuseScriptTemplate("syracuse.py", R"(def syracuse(n=14):
maxi=0
compte=1
while n>1:
print(n, end=" ")
maxi=max(n,maxi)
compte+=1
if n%2==0:
n//=2
else:
n=3*n+1
print(1)
print("Altitude maximum :",maxi)
print("Nombre de valeurs :",compte))");
Inutile d’avoir fait du X pour voir où insérer exactement ce petit bout (de code).
Le code en Python est entre R"( et )");.
Il est possible que votre code en Python entre en conflit avec la syntaxe de C++, notamment s’il contient des parenthèses et des guillemets. Si cela vous arrive, ajoutez une espace ou jouez avec chr.
Et plus bas dans le même fichier :
const ScriptTemplate * ScriptTemplate::Syracuse() {
return &syracuseScriptTemplate;
}
Dans apps/code/script_template.h, class ScriptTemplate :
static const ScriptTemplate * Syracuse();
Et dans apps/code/script_store.cpp, ScriptStore::ScriptStore() :
addScriptFromTemplate(ScriptTemplate::Syracuse());
Si vous voulez vous créer une banque de scripts pour pondre des émulateurs distincts pour plusieurs heures ou classes, il vous suffit de commenter des lignes dans apps/code/script_store.cpp pour ne pas inclure les modules qui correspondent à la compilation, tout le reste étant inchangé.
Recompilez avec :
make simulator.zip PLATFORM=emscripten
Ce qui ne compile que le nécessaire et zou, l’émulateur contient la suite de Syracuse.
Figure 4 : Le code de la suite de Syracuse avec coloration syntaxique et numérotation des lignes.
Figure 5 : La suite de Syracuse en action.
Attention, si vous avez besoin d’insérer plus de huit scripts, vous aurez besoin d’augmenter le nombre maximal de scripts dans apps/code/script_store.h, class ScriptStore :
public MicroPython::ScriptProvider :
static constexpr int k_maxNumberOfScripts = 8;
Et augmentez la limite selon vos besoins.
Plutôt que d’insérer vos codes pour les tester en recompilant, vous pouvez les écrire directement sur le site de NumWorks qui a réservé une page au partage de codes en Python [12]. Une fois testé, vous pouvez coller le code dans apps/code/script_template.cpp parce que, pour le moment, un émulateur ne peut pas communiquer avec un autre émulateur ou une calculette ni sauvegarder son état. Ces codes sont copiables sur votre calculette NumWorks dans la limite de la place disponible (vite atteinte pour un geek qui aura envie de golfer [13], mais ça ne dérangera pas l’élève moyen) et les vôtres peuvent rester privés ou être rendus publics. Pour cela, il faut copier un fichier dans /etc/udev/rules.d/ (pour Linux) ou installer un pilote (pour Windows), tout est expliqué sur le site, mais ne fonctionne qu’avec Chrome ou Chromium. Cela permet aussi de mettre à jour sa calculette sans recompiler.
Conclusion
Vous pouvez maintenant insérer vos petits scripts, complets ou non pour que vos élèves jouent avec et les modifient pour apprendre un peu de programmation en Python, dorénavant conseillée au lycée. La partie technique est résolue, je vous laisse l’aspect pédagogique c’est-à-dire quoi insérer, pour quoi faire, en quelle quantité, dans quel ordre, selon quelle progression sur plusieurs heures ou la notation éventuelle.
Ainsi, après avoir fait travailler ma classe de seconde sur Algobox [14] les deux premiers trimestres, j’ai tenté Python au dernier avec quelques petits scripts plutôt simples qui leur ont fait calculer l’équation réduite d’une droite, la longueur d’un segment, afficher le signe d’une fonction affine ou déterminer la nature d’un quadrilatère en fonction des coordonnées des sommets [15]. Comme les « digital natives » ont souvent du mal à interpréter un code même simple ou à en taper un sans erreur, les travaux demandés sont plutôt faciles. La majeure partie du code est écrite, mais ils doivent corriger quelques lignes légèrement fausses ou expliquer des bouts de code justes.
Je retenterai cette manière de travailler, plus cadrée que si on les fait travailler sur un site distant où ils peuvent exécuter du code Python ou sur un environnement de développement bourré de boutons et de fonctions qui vont les perdre.
Pour aller plus loin
La version de Python est limitée, il s’agit d’un Python bridé (µPython 1.9.4), mais qui suffit pour le moment en classe de lycée sauf pour l’actuelle spécialité ISN. Ainsi, la possibilité d’utiliser une boucle sur plusieurs lignes dans la console ou certaines méthodes spéciales comme __mul__ manquent alors que __add__ fonctionne. Vous pouvez toujours tenter de tripatouiller un Makefile ou le code source pour les y inclure, mais attention, la calculette physique ne dispose que d’un Mo de RAM.
Références
[2] https://www.linux-pratique.com/2017/12/en-kiosque-mettez-en-place-votre-systeme-domotique/
[3] https://creativecommons.org/licenses/by-nc-nd/4.0/
[4] https://github.com/numworks/epsilon/issues/38
[5] https://creativecommons.org/licenses/by-nc-sa/4.0/
[6] https://www.numworks.com/resources/engineering/software/sdk/other/
[7] https://old.reddit.com/r/numworks/comments/81q3lb/compiling_epsilon_for_windows_in_linux/dv6bcp8/
[8] https://www.numworks.com/fr/simulateur/
[9] https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
[10] https://www.reddit.com/r/numworks/
[11] https://old.reddit.com/r/numworks/comments/8m0qwc/%C3%A9mulateur_hors_ligne/e0g2bv2/
[12] https://workshop.numworks.com/python
[13] https://www.codingame.com/multiplayer/codegolf
[14] http://www.xm1math.net/algobox/
[15] http://revue.sesamath.net/ecrire/?exec=article&id_article=1114