# χ\chiCAS pour Numworks N0110, N0115, N0120 ### Bernard.Parisse@univ-grenoble-alpes.fr ### Novembre 2022, avril 2024

English version

Du calcul formel pour tous!
Le calcul formel est autorisé aux examens en France. Un élève équipé d’une calculatrice haut de gamme (TI Nspire CX2 CAS, HP Prime, Casio Classpad) peut s’en servir par exemple au bac. En mai 2025, KhiCAS a été rendu compatible avec le mode examen des calculatrices graphiques milieu de gamme TI83 et Casio Graph (90e et 35eii), mais ce n’est techniquement pas possible sur les Numworks récentes sans l’intervention de Numworks. Les constructeurs de calculatrices empêchent l’exécution de KhiCAS en mode examen pour diverses raisons : soit parce que cela fait concurrence à leur modèle haut de gamme qui rapporte plus, soit parce qu’ils craignent (ou prétextent craindre) être interdits aux examens dans certains pays. C’est pour rendre accessible les mêmes fonctionnalités aux élèves modestes qu’à ceux plus fortunés qui peuvent se payer une calculatrice haut de gamme que KhiCAS a été rendu compatible avec les TI83 et Casio 90/35. Numworks pourrait très bien authentifier KhiCAS et le laisser accessible en mode examen en France, de la même manière que nous l’avons fait sur les Casio. J’ai contacté à plusieurs reprises Numworks à ce sujet mais sans rien obtenir. Chers lecteurs, vous êtes nombreux à consulter ce document (environ 10 000 consultations par an), alors si vous vous mobilisez pour que cela change, nous pouvons être entendus. Contactez Numworks et demandez-leur de rendre KhiCAS utilisable en mode examen en France! Faites-le maintenant!

## Table des matières

## 1 Introduction

Ce document explique comment prendre en main et utiliser efficacement sur calculatrices Numworks N0110, N0115 et N0120 le système de calcul formel χ\chiCAS, une version adaptée du logiciel Xcas pour cette calculatrice. χ\chiCAS permet de transformer votre calculatrice graphique en calculatrice graphique formelle (CAS) pour faire du calcul littéral (développer, factoriser, calculer une limite, une dérivée, une primitive, résoudre des équations, faire du calcul matriciel exact ou approché, ...) et ajoute aussi des fonctionnalités pour les élèves qui envisagent une poursuite d’études en sciences ou en maths : grande varitété de représentations graphiques (champ de tangentes et solution d’une équation différentielle, lignes de niveau, graphes 3d cf. l’appendice 17), géométrie analytique (2d et 3d), arithmétique et cryptographie (corps finis premiers et extensions, polynômes, etc.), algèbre, algèbre linéaire, analyse numérique, calcul flottant multi-précision et certifié (arithmétique d’intervalle), etc.

χ\chiCAS propose aussi une application tableur et une application de géométrie interactive (2d/3d), qui permet de combler l’absence de ces fonctionnalités dans le système Epsilon fourni par Numworks. Enfin, un interpréteur MicroPython est maintenant inclus dans χ\chiCAS pour les programmes qui nécessitent une compatibilité stricte avec Python que le mode de compatibilité de Xcas n’apporte pas. Ce MicroPython est plus complet que celui de Numworks, il comprend un module permettant de faire du calcul formel, un module d’arithmétique (test de primalité, PGCD, identité de Bézout), deux modules pour faire du calcul vectoriel et matriciel et trouver des racines de polynome et un module graphique plus complet (polygones, cercles, formes remplies).

Toutes les fonctionnalités de χ\chiCAS sont intégrées, on peut représenter sur un même graphique un histogramme et un graphe de fonction et une droite, on peut écrire un programme pour faire une simulation et représenter les résultats graphiquement, ou utiliser les fonctions mathématiques dans un programme en syntaxe Python ou utiliser un programme en syntaxe Python dans le tableur.

La philosophie de χ\chiCAS est très éloignée de celle du système Epsilon de la Numworks qui a des applications ciblées, faciles à utiliser, mais aux fonctionnalités mathématiques plus limitées et qui communiquent peu entre elles. Ici, on passera un peu de temps à apprendre comment utiliser le shell et les outils d’édition pour ensuite les faire travailler harmonieusement ensemble, sans autres limites que la mémoire (malheureusement vite remplie) et la vitesse de la Numworks (tout à fait raisonnable pour une calculatrice). Il est donc fortement recommandé de lire cette documentation pour une utilisation optimale de χ\chicas, à l’exception des sections 19 et 20 qui s’adressent uniquement aux programmeurs qui souhaitent programmer leur calculatrice en C ou C++.

N.B. : Ce document est interactif, vous pouvez modifier les commandes et voir le résultat de l’exécution des commandes proposées en exemple en cliquant sur le bouton exe (ou en validant avec la touche Entrée).

## 2 Installation

### 2.1 Installation de KhiCAS sur la calculatrice

Il faut savoir qu’il existe deux versions de KhiCAS, une pour les Numworks N0110 d’avant 2021 et qui n’ont pas été mises à jour (avec Epsilon 15.5 au plus, Omega, Upsilon ou Khi), ce sont les N0110 non verrouillées (ou déverrouillées), et une version de KhiCAS pour les autres modèles. Le numéro de votre modèle est inscrit à l’arrière de votre calculatrice et le numéro de version d’Epsilon se lit dans l’applications Paramètre, A propos.

En effet, afin de satisfaire certaines réglementations d’examens à l’étranger, depuis 2021, Numworks verrouille ses calculatrices, ce qui rend les applications développées par des auteurs indépendants de Numworks nettement moins intéressantes : elles sont plus difficiles à installer, doivent être réinstallées ou réactivées après un crash/RESET et elles ne sont pas utilisables en mode examen. Donc si vous possédez une Numworks N0110 avec une version d’Epsilon inférieure à 16, pour conserver votre liberté, surtout ne mettez pas à jour votre calculatrice sur le site de Numworks.. Si vous avez mis à jour vers Epsilon en version 16 ou plus ou si votre calculatrice N0110 est déjà en version 16 ou plus, une faille logicielle trouvée par la communauté permet dans certains cas de déverrouiller votre calculatrice (on y trouve aussi un lien expliquant comment déverrouiller matériellement n’importe quelle calculatrice N0110, mais cela demande un peu de matériel et nécessite de démonter et remonter la calculatrice, et cela ne fonctionne pas sur les N0115 et N0120), plus d’infos en section 2.1.2. Si vous achetez une calculatrice Numworks d’occasion, demandez au vendeur s’il s’agit d’une N0110 et si le numéro de version du logiciel est au plus 15.5. Les versions récentes de Upsilon (et dans une certaine mesure de Khi) ajoutent une protection contre une mise à jour non intentionnelle.

#### 2.1.1 Numworks N0110 verrouillée, N0115, N0120

Si votre calculatrice est un modèle récent, vous pouvez installer une version de χ\chiCAS depuis la page Numworks du site de Xcas en utilisant un navigateur webUSB compatible (Chromium, Chrome, Edge...). Il existe deux sous-versions : la version courte occupe presque la moitié de l’espace flash de la calculatrice, la version longue environ les deux tiers, la différence est que la version courte ne contient pas l’aide complète en ligne dans plusieurs langues, mais uniquement l’aide sur les principales commandes en français et en anglais. Attention, cette version de χ\chiCAS n’est pas accessible en mode examen, alors que la réglementation française autorise le calcul formel aux examens et que Numworks propose un mode examen spécifique à la France. Ceci défavorise les élèves qui possèdent une Numworks verrouillée par rapport à leurs camarades qui peuvent se payer une calculatrice CAS constructeur (environ deux fois plus chère), Numworks porte avec les décideurs qui imposent le mode examen l’entière responsabilité de cette inégalité. De plus les applications externes sont désactivées en cas de crash ou de reset, il faut alors réinstaller ou réactiver avec un ordinateur le lanceur de KhiCAS, dans le premier cas cela pourrait engendrer une usure prématurée du secteur correspondant de la mémoire flash (en particulier pour les développeurs d’applications externes pour qui il peut être nécessaire de faire plusieurs dizaines de tests par jour avec crash à la clef avant de localiser et corriger des erreurs). Numworks est au courant de ces problèmes, mais ne donne pour l’instant aucun signe de vouloir les résoudre.

Remarque essentielle
La prise en compte du clavier est un peu différente sur cette version de χ\chiCAS. L’appui sur la touche HOME de la calculatrice fait sortir immédiatement de χ\chiCAS pour revenir au menu principal de la Numworks. Il faut taper sur les touches shift puis EXE pour ouvrir le menu “fichier” de KhiCAS (au lieu de HOME sur les N0110 non verrouillées).

Notez que pour insérer un caractère non présent sur le clavier, vous pouvez taper sur shift puis `*` qui ouvre la table de caractères ASCII. La touche shift suivie de `+` renvoie le caractère de tabulation, qui permet d’indenter dans un programme, ou d’afficher de l’aide.

#### 2.1.2 Installation optimisée sur N0110 verrouillée et sur N0115.

Remarque : si vous possédez une Numworks N0120, cette section ne vous concerne pas, en effet à ma connaissance, il n’y a pas eu de version publique de Epsilon <20&lt;20 avec support des applications externes.

Si vous possédez une Numworks N0110 déverrouillable et arrivez à vous procurer une image binaire signée d’un firmware Epsilon 18.2 ou si vous possédez une N0110 non déverrouillable ou une N0115 et arrivez à vous procurer une image binaire signée d’Epsilon 19.5, je vous conseille de l’utiliser pour installer KhiCAS. En effet, avec Epsilon 18.2, vous pourrez déverrouiller les N0110. Et sinon avec Epsilon 19.5, les applications externes sont automatiquement réactivées en sortie de mode examen et en cas de crash ou reset, on peut réactiver toutes les applications externes simultanément, par exemple en cliquant sur le bouton rendre visibles les apps externes de ma page Numworks. Pour installer le binaire, faire reset+6 sur la calculatrice (maintenir appuyé la touche 6 tout en enfonçant puis relachant la touche reset), allez sur le site webdfu de tiplanet et choisissez Flash Slot A (0x90000000). Si vous arrivez à booter Epsilon 18.2 sur une N0110, rendez-vous ici pour la déverrouiller puis en section 2.1.3.

La suite de cette section est un peu technique, mais je ne vois pas comment l’éviter. Elle explique comment générer un firmware 18.2, pourquoi la fourniture à un tiers d’un firmware Epsilon 19.5 est très probablement légale en vertu des lois sur l’interopérabilité, et comment faire tourner une version plus récente d’Epsilon sur Epsilon 19.5. Pour effectuer les manipulations techniques, on suppose que le lecteur a accès à une machine Linux debian ou ubuntu ou compatible (par exemple dans une machine virtuelle, ou depuis WSL sous Windows).

Sur les versions d’Epsilon ≥\geq 20, à chaque reset/crash ou cycle de mode examen, sous prétexte de sécurité, Epsilon sabote les applications externes installées en mettant à 0 le 1er octet du secteur de flash, sans rien demander à l’utilisateur. Ceci nécessite une réinstallation de l’application externe à chaque fois, ce qui décourage fortement l’utilisation d’applications externes (surtout si on en a plusieurs), et cela risque de diminuer inutilement la durée de vie de la flash de la calculatrice (le nombre de cycles d’effacement et écriture de la flash est limité). Aucun des constructeurs concurrents (TI, Casio) n’agit ainsi. Sans être juriste, je pense qu’il s’agit là d’une mesure technique de protection qu’on peut probablement qualifier de disproportionnée vs le droit à l’interopérabilité, ou/et d’un abus de position dominante au sens de l’article 102(b) TFUE (Numworks est maintenant premier en part de marché sur les calculatrices graphique couleur en France, et de plus la concurrence est faussée, car les élèves acheteurs n’ont très souvent pas le choix du modèle de calculatrice, qui est imposé par le lycée), ainsi qu’une atteinte à la durabilité du bien, au sens de l’article L.217-5 3/ du Code de la consommation.

Dans cette section, on explique comment contourner partiellement cette mesure technique de protection disproportionnée, en utilisant Epsilon 18.2 (si la calculatrice est déverrouillable) ou Epsilon 19.5. Il est essentiel ici de comprendre que l’amorçage de la calculatrice autorise l’exécution d’un firmware en flash externe uniquement s’il est signé par Numworks. La version 18.2 d’Epsilon est la dernière version pour laquelle le code source complet du firmware exécuté en flash externe est disponible. On peut reproduire un firmware non signé identique de la manière suivante sur un système Linux

      apt-get install build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config python3 python3-pip dfu-util bsdiff
      pip3 install lz4 pypng stringcase
      cd ~/Downloads
      wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
      cd /usr/local
      sudo tar xfa ~/Downloads/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
      export PATH=/usr/local/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH
      cd
      git clone https://github.com/parisseb/epsilon
      mv epsilon epsilon18
      cd epsilon18
      git checkout 6f231d531fa74574e00f6b266ed4d9c86a9d5ab3
      make kernel.A.bin
      make userland.onboarding.A.bin

Il suffit de concaténer le kernel et l’userland

      cp output/release/device/n0110/kernel/kernel.A.bin kernel18.bin
      truncate -s 65536 kernel18.bin
      cp output/release/device/n0110/userland/userland.onboarding.A.bin userland18.bin
      cat kernel18.bin userland18.bin > epsilon18.bin

et d’ajouter la signature pour obtenir un firmware signé 18.2, par exemple avec hexedit :
`hexedit epsilon18.bin`
Cette signature n’est pas soumise au copyright, car obtenue par un procédé algorithmique complètement déterministe, ce n’est donc pas une oeuvre originale de l’esprit, elle n’a de plus jamais été secrète (puisque le firmware 18.2 a été diffusé publiquement par Numworks pendant plusieurs mois en 2022), il s’agit d’une information au sens de l’article L122-6-1 IV pour permettre le déverrouillage des calculatrices qui ont été verrouillées avant la sortie d’Epsilon 19 et l’utilisation de tous les logiciels rendus incompatibles avec Epsilon 16 (Omega, Upsilon, Khi...), sa diffusion est donc légale. Elle se décompose en deux parties

- au début du kernel, les 4 premiers octets doivent être mis à 0. Il s’agit d’un niveau de sécurité permettant à Numworks dans le futur de refuser de faire tourner un kernel signé si le niveau de sécurité inscrit en flash interne de la calculatrice est supérieur strict au niveau de sécurité du kernel (donc ici dès que le niveau de sécurité en flash interne est non nul)
- les 4 octets suivants indiquent l’offset de la signature à partir de l’offset 8. Sur les 18.2, il faut indiquer 70 24 12 00, donc l’offset de la signature est 0x122478.
- En 0x122478, la signature elle-même sur les 64 derniers octets.

      00122470                             C4 C8 E4 EE  3B E9 5F 8F  E...........;._.
      00122480   4E 28 2A D9  F7 2A F2 D6  C7 D4 96 CD  40 BE E1 B3  N(*..*......@...
      00122490   2D C6 29 0F  41 D0 8A 5D  8B AE 42 BC  5F B5 AD 29  -.).A..]..B._..)
      001224A0   55 0E 70 35  20 91 A9 F3  C4 F4 3D 8E  30 9F BD 64  U.p5 .....=.0..d
      001224B0   12 C5 79 48  3A 8A 87 0D

Sur certaines calculatrices verrouillées, vous pourrez installer ce firmware en maintenant appuyé la touche 6 tout en appuyant sur la touche reset au dos de la calculatrice, puis relâchez reset puis 6. Vous pouvez maintenant flasher la calculatrice :
`dfu-util -i 0 -a 0 -s 0x90000000 -D epsilon18.bin`
Après reset, si le firmware démarre, félicitations, vous pouvez maintenant déverrouiller votre calculatrice avec le jailbreak Phi, puis installer le bootlodaer d’Upsilon ou de Khi ou Omega et passer à la section 2.1.3. Mais il n’est pas possible d’utiliser Epsilon 18.2 directement sur la plupart des machines verrouillées, car Numworks interdit le downgrade vers cette version qui est vulnérable au jailbreak Phi. Techniquement parlant, Numworks a ajouté une 2ème signature, distincte de la précédente, et qui couvre également les 8 premiers octets du noyau, et le bootloader utilise cette signature si il a été installé après le printemps 2022. Les firmwares à partir de la version 19 contiennent les deux signatures, permettant l’utilisation sur les deux versions de bootloader.

Le point critique est donc de se procurer une version signée du firmware 19.5 pour N0110 ou N0115. Le plus simple est évidemment d’en obtenir une copie depuis une calculatrice qui est encore installée avec Epsilon 19.5.

Remarque : une grosse partie du source de ce firmware (l’userland, un peu plus de 1M) est disponible sur github, et peut donc être recompilé à l’identique.

      git clone -b version-19 https://github.com/parisseb/epsilon
      mv epsilon epsilon19
      cd epsilon19
      make userland.onboarding.A.bin

Une petite partie, le kernel (32K environ), n’est plus disponible en code source depuis la version 18.2, elle est soumise au copyright de Numworks qui empêche sa rediffusion sans autorisation. Ce noyau n’apporte aucune fonctionnalité originale par rapport au noyau de la version 18.2, il a pour seule fonction d’interfacer avec le matériel physique de la calculatrice. Sans protection au démarrage, on pourrait interfacer le kernel 18.2 et l’userland 19.5. Mais ici il est indispensable d’avoir un kernel 19.5 avec l’userland 19.5, car ils sont combinés dans la signature. Sans être juriste, je pense donc que la rediffusion du kernel 19.5 est conforme à l’esprit de l’article L122-6-1 du code de la propriété intellectuelle, pour assurer l’interopérabilité des applications externes de manière normale (sans usure prématurée de la flash, et avec réactivation des applications externes simultanément).

Muni du kernel et du userland, il faut rajouter la signature pour pouvoir booter ce firmware.

Pour installer Epsilon 19.5, faire reset+6 sur la calculatrice puis envoyer le firmware, par exemple avec une commande du type
`dfu-util -i 0 -a 0 -s 0x90000000 -D epsilon19.5.bin`
Une fois Epsilon 19.5 installé, vous pouvez ajouter des applications externes, en cas de cycle d’activation/désactivation du mode examen, elles seront automatiquement réactivées, en cas de crash/reset, il suffit de rendre visible les applications externes depuis Epsilon 19.5, avec la commande
`dfu-util -i 0 -a 0 -s 0x90200000:leave`
ou depuis le bouton rendre visible les apps externes de ma page Numworks

Si vous avez besoin de fonctionnalités des versions plus récentes de Epsilon, il est possible d’installer un lanceur de firmware en tant qu’application externe, et de recompiler un firmware 23.2.3 à partir du source disponible sur github et de modifications pour

- empêcher le sabotage du secteur de lancement des applications externes
- faire fonctionner ce firmware à la suite d’Epsilon 19.5 et de l’application lanceur de firmware, dans la première partie de la flash (slot A), pour laisser assez de place contigüe pour KhiCAS (dans la seconde partie, slot B).

Modifications à apporter à ion/src/device/include/n0110/config/board.h pour “shifter” l’userland de 0x160000 octets :

    69c69
    < constexpr uint32_t SlotAOffset = 0x00160000;
    ---
    > constexpr uint32_t SlotAOffset = 0;
    75c75
    < constexpr uint32_t PersistingBytesVirtualOrigin = ExternalFlashOrigin + ExternalFlashLength / 2 - PersistingBytesLength - SlotAOffset;
    ---
    > constexpr uint32_t PersistingBytesVirtualOrigin = ExternalFlashOrigin + ExternalFlashLength / 2 - PersistingBytesLength;
    88c88
    < constexpr uint32_t UserlandLength = 0x280000; // ExternalFlashLength / 2 - KernelLength - ExtraDataLength - PersistingBytesLength;
    ---
    > constexpr uint32_t UserlandLength = ExternalFlashLength / 2 - KernelLength - ExtraDataLength - PersistingBytesLength;

Modification pour éviter le sabotage, fichier ion/src/device/userland/drivers/external_apps.cpp

    97d96
    <   return; // do not erase magic code

et pour autoriser les applications externes depuis 23.2.3, modifications du fichier ion/src/device/userland/Makefile

    11c11
    <   external_apps.cpp: \
    ---
    >   external_apps.cpp:+allow3rdparty \
    15a16,19
    > )
    >
    > ion_device_userland_src += $(addprefix ion/src/shared/dummy/, \
    >   external_apps.cpp:-allow3rdparty \

On compile avec

    make userland.A.bin # V=1
    truncate -s 1572864 output/release/device/n0110/userland/userland.A.bin
    cp output/release/device/n0110/userland/userland.A.bin userland23.bin
    objdump  -C -t output/release/device/n0110/userland/userland.A.elf | sort > dump_t

Puis on envoie ce userland, qui commence en 0x90170000, avec la commande
`dfu-util -i 0 -a 0 -s 0x90170000 -D userland23.bin`
Pour pouvoir accéder à Epsilon 23.2.3 depuis Epsilon 19.5, on envoie le lanceur de firmware avec la commande
`dfu-util -i 0 -a 0 -s 0x90150000 -D run.bin`
Le source de ce lanceur de firmware est disponible ici, il détecte un firmware à lancer sur les secteurs de flash 0x17 à 0x1f.

On peut maintenant profiter de Epsilon 23.2.3 sans les énormes contraintes de réinstallation d’applications externes. En cas de crash/reset, il suffit de rendre visible les applications externes d’Epsilon 19.5, avec la commande
`dfu-util -i 0 -a 0 -s 0x90200000:leave`
ou depuis le bouton rendre visibles les apps externes de ma page Numworks, puis on relance l’application lanceur du firmware 23.2.3.

#### 2.1.3 Numworks N0110 non verrouillée avec Epsilon au plus 15.5

Attention, certains concours ou examens interdisent l’utilisation de calculatrices formelles. Il est de la responsabilité de l’utilisateur de vérifier que les calculatrices formelles sont autorisées avant d’utiliser χ\chi CAS dans un examen ou concours. Les auteurs ne sauraient être tenus pour responsables en cas d’utilisation non autorisée.

Avant d’installer ou mettre à jour χ\chiCAS, pensez à sauvegarder vos données, car elles pourraient être effacées. Si vous faites une mise à jour, il pourra être nécessaire de faire reset+4 sur votre calculatrice pour accéder à la flash (i.e. appuyer sur la touche 4, puis enfoncer une pointe à l’arrière sur reset, relacher la touche 4). Puis choisir une des méthodes :

1. Via Internet avec un navigateur compatible avec webUSB
   Cliquez sur ce lien en utilisant un navigateur supportant web USB tel que Chromium ou Edge ou Google Chrome. Connectez la calculatrice et cliquez sur le bouton Installer ou mettre à jour KhiCAS.
2. Depuis Xcas (Windows et Linux)
   C’est une méthode d’installation locale (une fois Xcas installé) N.B. :sous Linux, vérifiez que dfu-util est bien installé et que le fichier 50-numworks-calculator.rules a été copié dans `/etc/udev/rules.d`.
   Connecter la calculatrice, ouvrez Xcas, puis dans le menu Fich, sous-menu Numworks, sélectionner `Installer KhiCAS sur la calculatrice`. Lorsqu’on vous demande de faire un reset de la calculatrice, appuyez sur le bouton `RESET` à l’arrière de la calculatrice.
3. Depuis le site d’Upsilon ou d’Omega, suivre les instructions de ces sites et installer KhiCAS comme application externe. Notez que le support du clavier depuis KhiCAS est moins bien optimisé qu’avec les autres méthodes d’installation décrites ici. Par contre les bootloader d’Upsilon et Omega ont du support pour lancer des versions plus récentes du système d’exploitation Epsilon de Numworks.
4. Installation manuelle
   Pour installer ou mettre à jour χ\chiCAS sur votre Numworks N0110 : récupérez sur votre ordinateur le fichier khi.zip.
   - Si nécessaire, installez dfu-util
     - sur Mac, installez brew si nécessaire puis depuis un Terminal (dans Utilitaires) faire
       `brew install dfu-util`
     - sous Linux debian compatible, ouvrir un Terminal et faire
       `sudo apt-get install dfu-util`
       Vous pouvez aussi compilez et installer à partir du source.
       Récupérez ce fichier et copiez le dans `/etc/udev/rules.d`. Si vous avez installé un package debian, cela peut se faire par la commande
       `sudo cp /usr/share/giac/doc/50-numworks-calculator.rules /etc/udev/rules.d` Vous pouvez aussi créer un fichier `/etc/udev/rules.d/50-numworks-calculator.rules` de contenu :

           SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="a291", TAG+="uaccess"
           SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", TAG+="uaccess"

     - sous Windows, téléchargez et installez la version 64 bits ou 32 bits (provenance). L’exécutable s’appelle `dfu-util-static.exe`. Si nécessaire éditez le fichier `updaten110.bat` (64 bits) ou `updaten110_32.bat` (32 bits) pour adapter les chemins d’installation. Le fichier actuel suppose que l’on a desarchivé `khi.zip` et `dfu-util-0.9-win64.zip` depuis le même répertoire racine (par exemple `c:\temp`) et qu’on lance `updaten110.bat` (64 bits) ou `updaten110_32.bat` (32 bits) en cliquant sur le fichier dans l’explorateur de fichiers.
   - Tapez la commande `./updaten110` (Linux/Mac) ou exécutez `updaten110.bat` (Windows 64 bits) ou `updaten110_32.bat` (Windows 32 bits). Les commandes `dfu-util` sont les suivantes

         dfu-util -i 0 -a 0 -s 0x08000000 -D bootloader.bin -R
         dfu-util -i 0 -a 0 -s 0x90000000 -D khi.A.bin -R
         dfu-util -i 0 -a 0 -s 0x90180000 -D khi.B.bin -R
         dfu-util -i 0 -a 0 -s 0x90200000:force -D apps.tar

     Vous pouvez ajouter des fichiers scripts Python ou sessions Xcas (ou même des programmes) à l’archive `apps.tar` avec la commande `tar rvf apps.tar <filenames>`. Ils seront alors visibles depuis χ\chiCAS hors mode examen (et l’ajout est compatible avec la certification du firmware disponible depuis le kit de connexion Numworks).

Après installation, redémarrez la calculatrice par appui sur le bouton RESET si nécessaire.

Multi-boot
Si vous avez installé une version récente de χ\chiCAS, votre calculatrice peut dorénavant lancer deux firmwares :

- une version du logiciel du constructeur Numworks, dérivée de la version 15.5 d’Epsilon (c’est la dernière version dont la licence permet les modifications et redistribution, qui date de mai 2021). C’est le firmware du slot 1. Il est techniquement possible d’installer Epsilon 18 dans ce slot 1, mais ce n’est pas recommandé, car l’utilisation de χ\chiCAS n’est pas possible depuis Epsilon 18, il faut alors rebooter pour le lancer depuis le slot 2. Vous pouvez consulter la section B pour trouver l’équivalent dans χ\chiCAS des fonctionnalités mathématiques qui ont été ajoutées dans Epsilon par rapport à la version 15.5.
- un mini-firmware lanceur. Il n’affiche aucune des applications du constructeur à part les paramètres, mais permet de lancer χ\chiCAS (et d’autres applications externes) avec plus de mémoire disponible. C’est le firmware du slot 2.

Pour vérifier l’état des slots de votre calculatrice, maintenez la touche 4 enfoncée et en appuyant sur le bouton RESET à l’arrière, puis relachez la touche 4. Cela lance le multi-boot et affiche le contenu des slots. Notez que le slot 3 est incompatible avec χ\chiCAS (il s’agit du slot B du multi-boot φ\varphi).

Pour passer du slot 1 au slot 2, appuyez sur la touche 1 ou 2, faites simultanément RESET à l’arrière, puis relachez la touche 1 ou 2.

Protection contre des sites potentiellement malveillants
Si vous ne l’avez pas déjà fait, mettez à jour χ\chi et χ\chiCAS afin de bénéficier d’un minimum de protection si vous naviguez sur Internet avec votre calculatrice branchée. Une fois cela fait, en fonctionnement normal, il est impossible à un site d’écrire dans la flash de la calculatrice. Vous ne pourrez modifier la flash qu’en activant le multi-boot (par reset+4) ou le mode de récupération (reset+6). Soyez particulièrement vigilants avant de faire reset+4 ou reset+6. En particulier, si vous voulez conserver le controle de votre calculatrice (éviter un verrouillage) et la compatibilité avec χ\chiCAS, ne faites jamais reset+4 ou reset+6 depuis les sites de Numowrks même si on vous le demande. Si votre calculatrice est bloquée ou pour échanger des scripts, rendez-vous sur mon kit de connexion Numworks.

Mode examen
L’installation de χ\chiCAS et χ\chi dans les slots 1 et 2 est conforme à la réglementation française du mode examen. Un surveillant d’examen qui souhaite s’assurer qu’une calculatrice Numworks n’a pas subi de modifications pour frauder peut le certifier depuis mon kit de connexion Numworks.

Lancement de χ\chi CAS
Tapez sur la touche Back puis Entree pour lancer χ\chiCAS.

Licences d’utilisation :
la licence choisie par Numworks pour son système d’exploitation rend impossible la publication d’un firmware binaire unique contenant également un logiciel libre. Le logiciel est donc décomposé en deux parties, `khi.*`, sous licence Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International Public License et `apps.tar` sous licence GPL2.

### 2.2 Simulateur de Numworks avec KhiCAS

Pour des questions de licences logicielles, il est actuellement nécessaire de compiler le simulateur si on veut utiliser Epsilon 22 dont la license est maintenant "All rights reserved". Si c’est plutôt Xcas (ou Python) qui vous intéresse, vous pouvez utiliser le simulateur d’Upsilon, basé sur Epsilon 15.5, avec Xcas

1. Version sans installation, utilisable depuis un navigateur compatible (Firefox, Chrome,...).
   Pour lancer Xcas depuis le menu principal de la Numworks simulée, appuyez/cliquez sur la touche Back de la calculatrice simulée.
   Cette version permet de partager facilement une session de calculs Xcas éventuellement accompagné d’un programme, en affichant un QR-code qu’on peut flasher avec un smartphone ou une tablette. Pour afficher le QR-code de la session, tapez sur la touche Power du simulateur. Sur une calculatrice, il suffit de sauvegarder la session : taper shift EXE, puis choisir 2 ou 3. Appuyez sur la touche Back pour revenir au shell.
   Si vous êtes enseignant, vous pouvez préparer une session avec le simulateur ou avec Xcas et vidéo-projeter le QR-code, vos élèves peuvent alors le flasher avec un smartphone ou une tablette.
   Les versions à jour de Xcas pour calculatrices Numworks et Casio permettent également d’afficher un QR-code pour partager une session. Mais les calculatrices n’ont pas de lecteur de QR-code donc ne permettent pas de charger une session de cette manière.
2. PC avec Windows : téléchargez upsilon.zip, ouvrez l’archive et exécutez upsilon.exe
3. Mac version stable (testé avec OS 14.4 et 12.7.1) : téléchargez Upsilon.dmg, ouvrir l’image disque Upsilon.dmg et installez.
   Remerciements à Adrien Bertrand qui m’a aidé pour ce portage et a signé ce package.
4. Linux ou compilation depuis le source :

       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/upsilon.tar.bz2
       tar xfj upsilon.tar.bz2
       cd Upsilon
       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
       tar xfj ext.tar.bz2
       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/upsilon_cas_full.tgz
       tar xfz upsilon_cas_full.tgz

   puis exécuter `mksimu` (Linux) ou `mkmac` (Mac) ou `mkwin` (Windows). La compilation de la version javascript fonctionne avec emscripten 1.40 et le script `mkw`, elle nécessite des versions des librairies GMP, MPFR et MPFI compilées avec `-fPIC`, ces libraries se trouvent dans l’archive emgiac3, ce répertoire contient aussi une copie de emscripten 1.40.1 installée sous Ubuntu 20 pour architecture `x86_64`.

Voici maintenant une procédure de compilation semi-automatisée pour Epsilon 22+Xcas (si vous souhaitez savoir ce qui se passe sous le capot, rendez-vous à la section 19.1.2)

1. PC avec Windows
   1. Installez msys2/mingw64
   2. Ouvrir un terminal mingw64 depuis le menu principal de toutes les applications windows, msys2. Dans le menu Options de la fenêtre mingw64 (coin en haut à gauche), sélectionner Keys, puis cocher Ctrl-shift-letter shortcut, ceci vous permettra de coller avec Ctrl-shift-V.
   3. copiez-collez dans le terminal (Ctrl-C puis Ctrl-shift-V)
      `pacman -S wget`
      `wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwwin`
      `./nwwin`
      Patientez, le temps que le compilateur fasse le travail. Si tout va bien le simulateur `epsilon.exe` va s’ouvrir. L’exécutable du simulateur est `c:\msys64\home\username\epsilon\epsilon.exe` où `username` est votre nom d’utilisateur. Vous pouvez le recopier dans un autre répertoire ou sur un autre PC.
      Attention, les licences ne permettent pas la publication de cet exécutable.
2. Mac :
   1. Depuis le launchpad, tapez Terminal dans le champ de recherche, ceci vous permet d’ouvrir un Terminal
   2. Téléchargez le fichier nwmac, vérifiez qu’il se trouve dans votre répertoire Téléchargements (Downloads)
   3. Copiez-collez (command-c et command-v) la commande
      `~/Downloads/nwmac`
      Patientez, le temps que le compilateur fasse le travail. Si tout va bien le simulateur va s’ouvrir. Il a été automatiquement recopié dans le répertoire `/Applications` et peut donc se lancer comme n’importe quelle autre application.
   4. Optionnel : si vous souhaitez faire une installation sur un autre Mac dans un cadre d’utilisation privée
      Un package `Khicasnw.pkg` a été créé dans le répertoire Téléchargements. Vous pouvez faire une image disque en lançant l’utilitaire de disque Mac puis menu Fichier, nouvelle image. Recopiez le package dans l’image disque, éjectez l’image disque du Finder puis recopiez l’image disque vers l’autre Mac (par le réseau ou avec une clef USB), et ouvrez-là avec le Finder de l’autre Mac puis cliquez sur le package en maintenant la touche Control enfoncée.
      Attention, les licences ne permettent pas la publication de cette image disque.
3. Linux : cf. la section 19.1.2

Pour lancer le simulateur, tapez `./simu` (Linux) ou cliquez sur `upsilon.exe` (windows) ou ouvrir `upsilon.app` dans `Applications` (mac) (ou `epsilon.app` depuis le répertoire `epsilon` si vous compilez la version Epsilon 22). Ensuite pour lancer KhiCAS, vous pouvez utiliser le raccourci Esc depuis le menu principal de la Numworks simulée. Attention, la touche shift du clavier ne simule pas la touche shift de la calculatrice, afin de pouvoir composer les caractères tels que 1 à 9 ou 0 sur un clavier français. Il faut taper la touche Alt gauche du PC ou Opt gauche du Mac pour simuler un appui sur shift. Pour faire une copie d’écran du simulateur, tapez Ctrl-P, sous Linux la copie est sauvegardée sous le nom `/tmp/epsilon.png`, pensez à le renommer avant une nouvelle capture écran. Le source du simulateur prévoit de pouvoir faire shift-Ctrl-P pour copier dans le presse-papier, mais ce n’est pas encore fonctionnel avec Linux/Windows, seulement sur Mac.

Le simulateur simule la flash utilisateur avec un fichier nommé `scripts.tar`. Vous pouvez le créer avec l’utilitaire d’achivage `tar` en y mettant des sessions Xcas (sauvegardées dans Xcas depuis le menu Fichier, Exporter comme, HP/Casio) et des scripts Python. Vous pouvez utiliser comme exemple le fichier khi92.tar dont l’installation est proposée en même temps que KhiCAS sur les calculatrices, il suffit de le renommer `scripts.tar` et de le copier dans le répertoire `Documents` sur Mac ou dans le répertoire courant sur Linux/Windows.

## 3 Premiers pas

N.B. : vous pouvez aussi consulter ce Tutoriel par fmOOmf et Yaya.Cout.

Depuis le menu principal de la Numworks, tapez la touche Back ou déplacez le curseur jusqu’à l’icone KhiCAS puis tapez EXE. Ceci ouvre un “shell” dans lequel vous pouvez taper la plupart des commandes de calcul formel de Xcas. Au premier lancement, vous avez le choix de l’évaluateur entre Xcas et MicroPython, on suppose ici que vous choisissez Xcas en tapant OK ou EXE. Si vous avez choisi MicroPython, lisez la section correspondante 13. Pour passer à Xcas (respectivement Python), depuis une ligne de commande vide, taper les touches `shift ) 8 OK`. Attention sur les Numworks N0115/N0120/N0110 verrouillées (section 2.1.1), il faut taper les touches `shift` et `)` en même temps.

Pour revenir au menu principal de la Numworks, il faut taper HOME, plusieurs fois sur les N0110 non verrouillées (2 fois depuis le shell). Sur les Numworks N0115/N0120/N0110 verrouillées (section 2.1.1), la touche HOME renvoie directement au menu principal de la Numworks, pour simuler l’action de HOME des N0110 non verrouillées, il faut taper les touches shift puis EXE.

Par exemple, tapez `1/2+1/6` puis EXE, vous devriez voir le résultat `2/3` s’afficher sur la ligne du dessous.

Vous pouvez recopier dans la ligne de commande une commande de l’historique en utilisant le curseur vers le haut ou vers le bas puis EXE, puis vous pouvez modifier la commande et l’exécuter. Par exemple, taper sur la touche curseur vers le haut, EXE et remplacez `1/6` par `1/3`.

Vous pouvez utiliser le résultat de la dernière commande avec la touche `Ans` de la calculatrice. Il vaut en général mieux définir une variable comme résultat d’une commande si on souhaite la réutiliser. Pour cela, on utilise une des deux instructions d’affectation :

- l’affectation vers la droite `=>` s’obtient avec la touche `sto`→\rightarrow de la calculatrice, par exemple `2=>a` met 2 dans la variable a. Vous pouvez ensuite utiliser `a` dans un calcul, sa valeur sera remplacée par 2.
- l’affectation vers la gauche `=`. Par exemple `a=2` fait la même chose que `2=>a`.

Pour vous aider à saisir les commandes Xcas les plus utiles, χ\chiCAS dispose d’un catalogue d’une centaine de commandes, avec une courte description et le plus souvent un exemple d’exécution facile à recopier. Appuyez sur la touche Toolbox, choisissez une catégorie avec le curseur, par exemple `Algebre`, tapez EXE, puis choisissez une commande avec le curseur, par exemple `factor`. Un deuxième appui sur la touche Toolbox vous affiche une courte description de la commande, en général avec un exemple. En tapant sur Ans (ou EXE), vous recopiez l’exemple en ligne de commande. Vous pouvez alors valider (EXE) ou modifier la commande et valider (EXE) pour factoriser un autre polynôme que celui donné en exemple. Essayez avec `factor` (touche Toolbox, puis `Algebre`).

Parmi ces commandes, celles qui sont le plus utilisées sont accessibles par des menus rapides activés par la touche shift suivi d’un chiffre, de `.`, de 10^x, de `(` ou de `)`, comme le rappelle la ligne en bas de l’écran, par exemple shift suivi de 1 affiche un menu d’algèbre où on retrouve la commande `factor`.

Lorsqu’une commande est entrée sans arguments, un “tooltip” (petit rectangle sur fonds jaune) affiche une courte description de ce que fait la commande et la syntaxe, pour voir en entier l’aide sur la commande il suffit de taper sur la touche flèche vers le bas (ou sur la touche var). Taper sur Ans pour entrer les arguments du premier exemple de l’aide. Taper sur la touche Back (à droite de OK) pour effacer le tooltip.

Lorsque vous exécutez une commande et qu’elle renvoie une expression, celle-ci est affichée en écriture naturelle (affichage 2-d). Vous pouvez faire défiler l’affichage avec les touches du curseur lorsque l’expression est grande. Tapez sur Back (à droite de OK) pour revenir au shell.

Maintenant essayez de taper la commande `plot(sin(x))`. Indication: tapez Toolboox, puis sélectionner `Courbes`, ou utilisez le menu rapide shift 3.

Lorsqu’une commande renvoie un graphe, celui-ci est affiché. Vous pouvez modifier la fenêtre graphique d’affichage avec les touches `+` ou `-` (zoom in ou out), les touches du curseur, orthonormaliser le repère (touche `/`) ou faire une recherche automatique de l’échelle (autoscale touche `*`). Pour enlever ou remettre les axes et graduations, tapez sur var. Tapez sur Back pour revenir au shell.

Vous pouvez effacer l’historique des calculs et les variables pour commencer un nouvel exercice : ouvrez le menu principal taper shift puis EXE (calculatrices récentes verrouillées) ou HOME, sélectionnez `9 Effacer historique`. Vous avez ensuite le choix entre effacer l’écran en conservant les variables (OK) ou en les effaçant (Back). Vous pouvez visualiser la place occupée par les variables en tapant sur la touche `var`. Pour effacer une variable pour faire de la place en mémoire, sélectionnez la commande `purge` dans ce menu, puis taper le nom de variable à effacer (ou sélectionnez la variable depuis le menu `var`).

Pour quitter χ\chiCAS depuis le shell, appuyez sur la touche HOME une ou 2 fois. Lorsque vous lancez une autre application, les variables et l’historique des calculs sont sauvegardés, ils seront restaurés lorsque vous reviendrez dans χ\chiCAS.

Remarques :

- Depuis le shell de calcul, les touches 1 à 9, 0, `.` et `x10` x^x, `(`, `)` précédées de shift (ou en maintenant shift enfoncé selon la version de KhICAS) font apparaitre un petit menu pour saisir rapidement certaines commandes.
- Lorsque le curseur est sur la ligne de commande juste après un nom de commande, l’appui sur la touche curseur vers le bas permet de voir l’aide sur la commande (si l’aide existe) et de saisir un exemple.
- Exemple : tapez shift-2, puis 3 (integrate), flèche vers le bas, puis Ans ou EXE
  Modifiez l’expression à intégrer selon vos besoin puis tapez EXE
- Lorsqu’il reste peu de mémoire (affichage en haut lorsqu’on tape sur la touche var), on peut essayer de restaurer de la place en effaçant des variables avec la commande `purge` (accessible depuis la touche `var`). On peut aussi quitter KhiCAS et le relancer pour repartir d’une situation où la mémoire n’est pas fragmentée.

## 4 Sauvegarde et échange de données.

Remarque : Si votre session n’est pas trop grande, vous pouvez l’afficher sous forme de QR code sur la calculatrice. Depuis le shell, ouvrir le menu Fichier (touches shift EXE ou touche HOME selon la version de KhiCAS), choisir Enregistrer session, mettre le cas échéant un nom de session. Le QR code s’affiche, vous pouvez le scanner avec un smartphone et obtenir un clone de votre session sur votre smartphone. Le QR code s’affiche également si vous quittez KhiCAS depuis le menu principal (shift EXE ou HOME deux fois de uite).

Si vous disposez du cable adéquat, vous pouvez connecter le smartphone à une autre Numworks et y recopier la session (cf. section suivante). Si vous n’avez pas de cable adéquat, vous pouvez appuyer avec le doigt sur l’icone d’enveloppe en haut et envoyer la session par email, puis depuis un PC vous pourrez recopier la session sur une autre calculatrice.

### 4.1 Depuis un navigateur webusb (Chromium ou Chrome ...)

- Le kit de connexion Numworks utilisée avec un navigateur compatible webusb, par exemple Chrome ou Chromium ou Edge, permet d’échanger des données avec la calculatrice Numworks : des scripts Python ou des backups. On peut aussi installer χ\chiCAS, personnaliser le contenu de la mémoire flash de la calculatrice. Pour les N0110 non verrouillées, on peut porter assistance à une calculatrice bloquée et certifier que le firmware installé sur une calculatrice est conforme à la réglementation française.
- La version web de Xcas permet d’échanger des données avec la calculatrice Numworks. Cliquez sur le bouton Détecter à gauche du bouton Numworks→\rightarrow pour détecter la calculatrice, ensuite en cliquant sur le bouton Numworks→\rightarrow, on peut importer un script de la calculatrice vers la feuille de calcul du navigateur, le modifier, puis le renvoyer vers la calculatrice avec le bouton →\rightarrowNumworks.
  N.B. : pour afficher un graphique sur la version web, taper sur une ligne vide `,` ou `.` ou `;` selon le type de graphique

### 4.2 Depuis Xcas pour Windows, Linux

Vérifiez que Xcas. est en version 1.7.0-31 ou ultérieure, si nécessaire installez ou mettez à jour.

Sous Linux, vérifiez que dfu-util est bien installé et que le fichier 50-numworks-calculator.rules a été copié dans `/etc/udev/rules.d`. Si vous avez installé un package debian, cela peut se faire par la commande
`sudo cp /usr/share/giac/doc/50-numworks-calculator.rules /etc/udev/rules.d`

Les outils pour se connecter avec la Numworks se trouvent dans le menu `Fich`, sous-menu `Numworks`. Vous pouvez :

- ouvrir un programme de la calculatrice dans la session actuelle Xcas ou ouvrir une session χ\chiCAS Numworks de la calculatrice dans un nouvel onglet de Xcas,
- envoyer la session actuelle Xcas comme une session χ\chiCAS sur votre calculatrice,
- envoyer le programme de l’éditeur de programme courant sur votre calculatrice
- créer une nouvelle session Xcas contenant tous les programmes de votre calculatrice
- effacer les programmes de votre calculatrice et les remplacer par tous les programmes de la session Xcas actuelle
- faire une sauvegarde de votre calculatrice
- restaurer votre calculatrice à partir d’une sauvegarde
- installer χ\chiCAS sur une calculatrice (il suffit de le faire une fois pour toutes)
- débloquer une calculatrice N0110. Ceci fonctionnera sur toute calculatrice N0110 qui n’est pas verrouillée par une mise à jour faite sur le site de Numworks après septembre 2021. Cela utilise le bootloader du fabricant du microprocesseur (ST) que l’on lance en maintenant la touche 6 de la calculatrice enfoncée en appuyant sur RESET à l’arrière de la calculatrice en même temps. Ce sous-menu envoie un bootloader “rescue mode” dans la RAM de la calculatrice et l’exécute, on peut ensuite installer Khi+χ\chiCAS (ou toute autre version dérivée d’Epsilon ≤15\leq 15).
- certifier que la version de Khi+χ\chiCAS de la calculatrice N0110 non verrouillée d’un élève est identique à celle fournie avec Xcas (et n’a donc pas été modifiée et recompilée en y ajoutant des données personnelles).

Sur Mac, il est recommandé d’utiliser le kit de connectivité web Numworks de la section précédente.

### 4.3 Gestion de la mémoire flash sur la calculatrice

Depuis la version du 14 octobre 2021, vous pouvez lancer un mini-gestionnaire de fichiers en flash depuis le menu Applications de KhiCAS (touches shift Ans puis valider puis avant-avant-dernier item). Ce gestionnaire permet

- de lister les fichiers installés en flash et d’afficher des informations (dont la date de création)
- de copier un script depuis la RAM vers la flash (ce qui la préserve d’un effacement par un reset ou un crash de la calculatrice). Notez qu’un script en flash peut être importé depuis KhiCAS sans être recopié dans le scriptstore RAM de la Numworks.
- de modifier la visibilité d’un fichier ou de le renommer. Dans ce sous-menu, on valide les changements par OK ou EXE, on les annule avec la touche Back.
- d’effacer réellement les fichiers marqués comme non visibles pour faire de la place (Vider la corbeille).

Attention, si vous faites des modifications, cela écrit en flash, or on ne peut pas écrire indéfiniment sur le même secteur en flash (pour la flash externe, Numworks a assigne une taille de 64K aux secteurs). Pour augmenter la durée de vie de la mémoire flash, il est conseillé de ne vider la corbeille que lorsqu’il est vraiment nécessaire de faire de la place. En effet, si on ne vide pas la corbeille, les nouveaux fichiers ajoutés en flash vont progressivement être écrits dans de nouveaux secteurs, ce qui répartira mieux l’usure de la flash. (Un “vrai” système de fichiers fait normalement cela automatiquement). Si vous n’avez pas besoin de beaucoup de place pour stocker des fichiers par rapport à la place disponible (6*64K à 1M selon la version de KhiCAS), vous pouvez aussi ajouter un gros fichier inerte de taille un multiple de 64K vers le début de l’archive (à partir du fichier d’indice 10 si vous voulez conserver la certification sur les N0110 non verrouillées), que vous changez de temps en temps.

Par ailleurs, lorsque vous lancez le mode examen sur les N0110 non verrouillées utilisant Khi, l’état de la calculatrice est automatiquement sauvegardé dans le dernier secteur de la mémoire flash (sauf s’il n’y a aucun script Python). Plus tard, lorsque vous avez quitté le mode examen (en branchant la calculatrice), vous pouvez restaurer l’état de la calculatrice depuis le menu HOME, Configuration/mode examen.

## 5 Commandes usuelles de calcul formel

### 5.1 Développer et factoriser

Depuis le catalogue, sélectionner le sous-menu `Algebre` (2) ou le menu rapide shift-1

- `factor` : factorisation. Raccourci clavier shift-* (préfixé) ou `=>*` (infixé touche sto puis *), par exemple
  x^4-1=>*
  . Utiliser `cfactor` pour factoriser sur C\C.
- `partfrac` : développement d’un polynôme ou décomposition en éléments simples pour une fraction. Raccourci clavier `=>+` (touche sto puis +), par exemple
  (x+1)^4=>+
  ou
  1/(x^4-1)=>+
  .
- `simplify` : essai de simplifier une expression. Raccourci clavier `=>/` (touche →\rightarrow puis /), par exemple
  sin(3x)/sin(x)=>/
  Attention, cette commande est gourmande en mémoire, et la Numworks en a peu, le risque de reset existe.
- `ratnormal` : développer une expression, écrire une fraction sous forme irréductible.

### 5.2 Analyse

Depuis le catalogue (Toolbox), sélectionner le sous-menu `Analyse` (4) ou le menu rapide shift-2

- `diff` : dérivation. On peut aussi utiliser la notation `'` (alpha-shift-") pour dériver par rapport à x x, ainsi
  diff(sin(x),x)
  et
  sin(x)'
  sont équivalents. Pour dériver plusieurs fois, ajouter le nombre de dérivations par exemple
  diff(sin(x^2),x,3)
  .
- `integrate` : primitive si 1 ou 2 arguments, par exemple
  integrate(sin(x))
  ou
  integrate(1/(t^4-1),t)
  pour ∫1 t 4−1 d t\int \frac{1}{t^4-1} \ dt
  Calcul d’intégrale définie si 4 arguments, par exemple
  integrate(sin(x)^4,x,0,pi)
  pour ∫ 0 π sin(x) 4 d x\int_0^\pi \sin(x)^4 \ dx. Mettre une des bornes d’intégration sous forme approchée si on souhaite un calcul approché d’intégrale définie, par exemple
  integrate(sin(x)^4,x,0.0,pi)
- `limit` : limite d’une expression. Exemple
  limit((cos(x)-1)/x^2,x=0)
- `tabvar` : tableau de variations d’une expression. Par exemple
  tabvar(x^3-7x+5)
  on peut vérifier avec le graphe plot(x^3-7x+5,x,-4,4)
- `taylor` et `series` : développement de Taylor (ou développement limité ou asymptotique). Par exemple taylor(sin(x),x=0,5)
- `sum` : somme discrète. Par exemple
  sum(k^2,k,1,n)
  calcule ∑ k=1 n k 2\sum_{k=1}^n k^2,
  sum(k^2,k,1,n)=>*
  calcule la somme et l’écrit sous forme factorisée.

### 5.3 Résoudre

Depuis le catalogue, sélectionner le sous-menu `Resoudre` (Toolbox puis touche ln)

- `solve` permet de résoudre de manière exacte une équation (se ramenant à une équation polynomiale). Il faut préciser la variable si ce n’est pas `x` par exemple
  solve(t^2-1=0,t)
  .
  Si la recheche exacte échoue, la commande `fsolve` permet de faire une résolution approchée, soit par une méthode itérative en partant d’une valeur initiale
  fsolve(cos(x)=x,x=0.0)
  , soit par dichotomie
  fsolve(cos(x)=x,x=0..1)
  .
  Pour avoir des solutions complexes, utiliser `csolve`.
  On peut faire des hypothèses sur la variable que l’on cherche, par exemple
  assume(m>1)
  puis
  solve(m^2-4=0,m)
  .
- `solve` permet aussi de résoudre des systèmes polynomiaux simples, on donne en 1er argument la liste des équations, en 2ème argument la liste des variables. Par exemple intersection d’un cercle et d’une droite
  solve([x^2+y^2+2y=3,x+y=1],[x,y])
- `linsolve` permet de résoudre des systèmes linéaires. On lui passe la liste des équations et la liste des variables (par convention une expression équivaut à l’équation expression=0). Par exemple
  linsolve([x+2y=3,x-y=7],[x,y])
  `linsolve` renvoie la solution générale du système (y compris si la solution n’est pas unique).
- `desolve` permet de résoudre de manière exacte certaines équations différentielles, par exemple pour résoudre y′=2 y y'=2y, on tape `desolve(y'=2y)`.
  Un exemple où on indique une condition initiale, la variable indépendante et la fonction inconnue :
  `desolve([y'=2y,y(0)=1],x,y)` Utiliser `odesolve` pour une résolution approchée et `plotode` pour une représentation graphique de solution calculée de manière approchée.
- `rsolve` permet de résoudre de manière exacte certaines relations de récurrences u n+1=f(u n,...)u_{n+1}=f(u_n,...), par exemple les suites arithmético-géométriques, par exemple u n+1=2 u n+3,u 0=1 u_{n+1}=2u_n+3, u_0=1
  rsolve(u(n+1)=2*u(n)+3,u(n),u(0)=1)

### 5.4 Arithmétique

Lorsque cela est nécessaire, on distingue l’arithmétique des entiers de celle des polynômes par l’existence du préfixe `i` (comme `integer`) dans un nom de commande, par exemple `ifactor` factorise un entier (pas trop grand) alors que `factor` factorise un polynôme (et `cfactor` factorise un polynôme sur les complexes). Certaines commandes fonctionnent à la fois pour les entiers et les polynômes, par exemple `gcd` et `lcm`.

#### 5.4.1 Entiers

Depuis le catalogue, sélectionner le sous-menu `Arithmetic, Crypto` (Toolbox 5)

- `iquo(a,b)`, `irem(a,b)` quotient et reste de la division euclidienne de deux entiers.
  iquo(23,13),irem(23,13)
- `isprime(n)` teste si n n est un nombre premier. Le test est probabiliste pour de grandes valeurs de n n.
  isprime(2^64+1)
- `ifactor(n)` factorise un entier pas trop grand (les algorithmes utilisés se limitent à la division et Pollard-ρ\rho, il n’y avait pas de place pour le crible quadratique). Par exemple
  ifactor(2^64+1)
  Raccourci clavier touches →\rightarrow puis * (`=>*`)
- `gcd(a,b)`, `lcm(a,b)` PGCD et PPCM de deux entiers ou de deux polnômes
  gcd(25,15),lcm(25,15)
  gcd(x^3-1,x^2-1),lcm(x^3-1,x^2-1)
- `iegcd(a,b)` renvoie 3 entiers u,v,d u,v,d tels que a u+b v=d au+bv=d où d d est le PGCD de a a et b b, avec |u|<|b||u|&lt;|b| et |v|<|a||v|&lt;|a|.
  u,v,d:=iegcd(23,13); 23u+13v
- `ichinrem([a,m],[b,n])` lorsque cela est possible, renvoie c c tel que c=a(mod m)c=a \pmod m et c=b(mod n)c=b \pmod n (si m m et n n sont premiers entre eux, c c existe).
  c,n:=ichinrem([1,23],[2,13]); irem(c,23); irem(c,13)
- `powmod(a,n,m)` calcule a n(mod m)a^n \pmod m par l’algorithme de la puissance rapide modulaire.
  powmod(7,22,23)

Les commandes `asc` et `char` permettent de convertir une chaine de caractères en liste d’entiers (entre 0 et 255) et réciproquement, ce qui permet de faire facilement de la cryptographie avec des messages sous forme de chaines de caractères.

#### 5.4.2 Polynômes

Depuis le catalogue, sélectionner le sous-menu `Polynomes` (8). La variable est par défaut x x, sinon il faut la spécifier en général en dernier argument, par exemple `degree(x^2*y)` ou `degree(x^2*y,x)` renvoient 2, alors que `degree(x^2*y,y)` renvoie 1

- `coeff(P,n)` coefficient de x n x^n dans P P, `lcoeff(P)` coefficient dominant de P P, par exemple
  P:=x^3+3x; coeff(P,1); lcoeff(P)
- `degre(P)` degré du polynôme P P. degree(x^3)
- `quo(P,Q)`, `rem(P,Q)` quotient et reste de la division euclidienne de `P` par `Q`
  P:=x^3+7x-5; Q:=x^2+x; quo(P,Q); rem(P,Q)
- `proot(P)` : racines approchées de P P (réelles et complexes)
  proot(x^5+x+1)
  Représentation graphique :
  point(proot(x^5+x+1))
- `interp(X,Y)` : pour deux listes de même taille, polynôme d’interpolation passant par les points (X i,Y i)(X_i,Y_i).
  X,Y:=[0,1,2,3],[1,-3,-2,0]; P:=interp(X,Y)=>+
  Représentation graphique
  scatterplot(X,Y); plot(P,x,-1,4)
- `resultant(P,Q)` : résultant des polynômes P P et Q Q P:=x^3+7x-5; Q:=x^2+x; resultant(P,Q)
- `hermite(x,n)` : n-ième polynôme de Hermite, orthogonal pour la densité e −x 2 d x e^{-x^2}dx sur R\R
- `laguerre(x,n,a)` : n-ième polynôme de Laguerre,
- `legendre(x,n)` : n-ième polynôme de Legendre, orthogonal pour la densité d x dx sur [−1,1][-1,1]
- `tchebyshev1(n)` et `tchebyshev2(n)` polynômes de Tchebyshev de 1ère et 2ème espèce définis par : T n(cos(x))=cos(n x),U n(cos(x))sin(x)=sin((n+1)x)T_n(\cos(x))=\cos(nx), \quad U_n(\cos(x))\sin(x)=\sin((n+1)x)

#### 5.4.3 ℤ/n ℤ\mathbb{Z}/n\mathbb{Z} et corps finis

Pour travailler avec des classes modulo n n, utiliser la notation `a mod n`, par exemple `sqrt(2 mod 7)`. Ceci s’applique aussi pour travailler sur des corps finis premiers ℤ/p ℤ\mathbb{Z}/p\mathbb{Z}. Pour travailler sur des corps finis non premiers, il faut d’abord définir le corps avec `GF`, puis on utilise un polynôme en le générateur du corps.

### 5.5 Algèbre linéaire, vecteurs, matrices

Xcas ne fait pas de différence entre vecteur et liste. Par exemple pour faire le produit scalaire de deux vecteurs, on peut saisir :

    v:=[1,2]; w:=[3,4]

onload
dot(v,w)

Pour saisir une matrice élément par élément, taper sur shift-7 (touche M comme matrice) puis `matrix(` ou selon le modèle `shift EXE i` ou `HOME i` (editer matrice). Vous pouvez ensuite créer une nouvelle matrice ou éditer une matrice existante parmi la liste de variables proposées. Pour de petites matrices, vous pouvez aussi entrer en ligne de commandes une liste de listes de même taille. Par exemple pour définir la matrice A=(1 2 3 4)A=\left(\begin{array}{cc} 1 & 2 \\ 3 & 4 \end{array}\right) on tape

    A:=[[1,2],[3,4]]

onload
ou
[[1,2],[3,4]]=>A

Il est fortement conseillé de stocker les matrices dans des variables pour éviter de les saisir plusieurs fois.

Pour entrer une matrice dont les coefficients sont donnés par une formule, on peut utiliser la commande `matrix`, par exemple
matrix(2,2,(j,k)->1/(j+k+1))
renvoie la matrice dont le coefficient ligne j j et colonne k k vaut 1 j+k+1\frac{1}{j+k+1} (attention les indices commencent à 0).

La matrice identité de taille n n est renvoyée par la commande `idn(n)`, alors que `ranm(n,m,loi,[parametres])` renvoie une matrice à coefficients aléatoires de taille n,m n,m. Par exemple
U:=ranm(4,4,uniformd,0,1)
N:=ranm(4,4,normald,0,1)

Pour exécuter une commande sur des matrices, s’il s’agit d’arithmétique de base (`+,-,*` inverse), on utilise les opérations au clavier. Pour les autres commandes. depuis le catalogue, sélectionner le sous-menu `Matrices` (Toolbox sin)

- eigenvals(A)
  eigenvects(A)
  renvoient les valeurs propres et vecteurs propres d’une matrice carrée A A.
- P,D:=jordan(A)
  calcule la forme normale de Jordan d’une matrice A A (à coefficients exacts) et renvoie les matrices P P et D D telles que P −1 A P=D P^{-1}AP=D, avec D D triangulaire supérieure (diagonale si A A est diagonalisable)
- Ak:=matpow(A,k)
  calcule la puissance k k-ième d’une matrice A A avec k k une variable formelle.
- `rref` effectue la réduction sous forme échelonnée d’une matrice A A (pivot de Gauss)
- `lu` calcule la décomposition L U LU d’une matrice A A et renvoie une permutation de matrice P P et deux matrices L L triangulaire inférieure et U U triangulaire supérieure telles que P A=L U PA=LU. Le résultat de la commande P,L,U:=lu(A)
  peut être passé en argument à la commande linsolve(P,L,U,v)
  pour résoudre un système A x=b Ax=b de matrice A A en résolvant deux systèmes triangulaires (calcul en O(n 2)O(n^2) au lieu de O(n 3)O(n^3)).
- `qr` calcule la décomposition Q R QR d’une matrice A A et renvoie deux matrices Q Q orthogonale et R R triangulaire supérieure telles que A=Q R A=QR.
- `svd(A)` calcule la factorisation en valeurs singulières d’une matrice A A, et renvoie U U orthogonale, S S vecteur des valeurs singulières, Q Q orthogonale tels que `A=U*diag(S)*tran(Q)`. Le rapport de la plus grande valeur singulière de S S sur la plus petite donne le nombre de condition de A A relativement à la norme euclidienne, plus ce nombre est grand, plus on perd en précision en résolvant un système A x=b Ax=b lorsque b b n’est pas connu exactement.

## 6 Probabilités et statistiques

### 6.1 Tirages aléatoires

Depuis le catalogue, sélectionner le sous-menu `Probabilites` (Toolbox 9) puis sélectionnez rand()
(réel selon la loi uniforme dans [0,1][0,1]) ou n:=6:; randint(n)
(entier entre 1 et n n). De nombreuses autres fonctions aléatoires existent, avec comme préfixe `rand`, suivi par le nom de la loi, par exemple `randbinomial(n,p)` renvoie un entier aléatoire selon la loi binomiale de paramètres n,p n,p. Pour créer un vecteur ou une matrice aléatoire, utiliser la commande `ranv` ou `ranm` (menu `Alglin, Matrice`), par exemple pour un vecteur de 10 composantes selon la loi normale centrée réduite
ranv(10,normald,0,1)

### 6.2 Lois de probabilités

Depuis le catalogue, sélectionner le sous-menu `Probabilites` (9). Les lois proposées dans le catalogue sont la loi binomiale, la loi normale, la loi exponentielle et la loi uniforme. D’autres lois sont disponibles depuis `Tout` : `chisquared`, `geometric`, `multinomial` `studentd`, `fisherd`, `poisson`.

Pour obtenir la distribution cumulée d’une loi, on saisit le nom de la loi et le suffixe `_cdf` (sélectionner `cdf` dans le catalogue sous-menu Probabilités et taper Ans). Pour obtenir la distribution cumulée inverse, on saisit le nom de la loi et le suffixe `_icdf` (sélectionner `cdf` dans le catalogue sous-menu Probabilités et taper EXE).

Exemple : calcul de l’intervalle centré I I pour la loi normale de moyenne 5000 et d’écart-type 200 tel que la probabilité d’être en-dehors de I I soit de 5% : M:=5000; S:=200; normald_icdf(M,S,0.025);normald_icdf(M,S,0.975)

### 6.3 Statistiques descriptives 1-d

Ces fonctions agissent sur des listes par exemple

    l:=[9,11,6,13,17,10]

onload
Depuis le catalogue, sélectionner le sous-menu `Statistiques` (Toolbox log)

- mean(l)
  : moyenne arithmétique d’une liste
- stddev(l)
  : écart-type d’une liste
  Utiliser stddevp(l)
  pour avoir un estimateur non biaisé de l’écart-type d’une population dont `l` est un échantillon
- median(l)
  , quartile1(l)
  , quartile3(l)
  renvoient respectivement la médiane, le 1er et 3ème quartiles d’une liste

Pour les statistiques 1-d de listes avec effectifs, on remplace `l` par deux listes de même longueur, la 1ère liste est la liste des valeurs de la série statistique, la 2ème liste est la liste des effectifs. Voir aussi les commandes du menu `shift-3` `histogram` et `barplot`.

### 6.4 Statistiques descriptives 2-d, régressions.

Voir aussi la section 15 expliquant le tableur.

Entrez les deux listes de données dans deux variables, par exemple `X:=[1,2,3,4,5]` et `Y:=[3,5,6,8,11]`, ou dans une variable matrice ayant 2 colonnes, depuis le shell avec le menu `shift-6` `8 matrix(`.
Depuis le catalogue, sélectionner le sous-menu `Statistiques` (touches `Toolbox log`), pour les régressions, depuis le shell, tapez `shift-6`.

- `correlation(X,Y)` calcule la corrélation entre 2 listes de même taille.
- `covariance(X,Y)` calcule la covariance entre 2 listes de même taille.
- les commandes de suffixe `_regression(X,Y)` calculent des ajustements par régression au sens des moindres carrés, les commandes de suffixe `_regression_plot` tracent la courbe représentative de la régression (Ces commandes affichent de plus le coefficient R 2 R^2 qui permet de quantifier la qualité de l’ajustement (plus R 2 R^2 est proche de 1, meilleur est l’ajustement). Khicas a des commandes pour faire des régressions linéaires, exponentielles, logarithmiques, puissance, polynomiales et logistique.
- Par exemple `linear_regression(X,Y)` renvoie les coefficients m,p m,p de la droite de régression linéaire y=m x+p y=mx+p.
  `linear_regression_plot(X,Y)` trace la droite d’ajustement des données contenues dans les listes `X,Y` de même taille.
- voir aussi les commandes `scatterplot`, `polygonplot` et `polygonscatterplot` pour afficher les données sur un graphique. On peut superposer plusieurs courbes de régression sur le même graphe en les séparant par un `;` en ligne de commande.

Ainsi pour afficher la droite de régression linéaire correspondant aux données `X=[1,2,3,4,5]` et `Y=[3,5,6,8,11]`, tapez les deux commandes ci-dessus ou éditez une matrice ayant 2 colonnes avec le raccourci `shift-6 8`. Puis `shift-6 EXE` (ou `Toolbox log` puis sélectionnez la commande `linear_regression_plot(`) complétez la commande par `X,Y)` ou par le nom de variable de la matrice puis EXE.

Remarque : si vos données sont dans une matrice `m` ayant 2 lignes au lieu de 2 colonnes, vous pouvez utiliser `m^*` pour transposer (en fait cela transconjugue, ce qui est identique pour des données réelles).

## 7 Courbes et autres représentations graphiques.

Pour obtenir une représentation graphique, on saisit une commande de tracé (ou plusieurs commandes séparées par `;`). Depuis le catalogue, sélectionner le sous-menu `Courbes` (accès rapide par Toolbox 7, ou shift-3 depuis le shell).

- `plot(f(x),x=a..b)` trace le graphe de f(x)f(x) pour x∈[a,b]x\in [a,b]. On peut spécifier un pas de discrétisation avec `xstep=`, par exemple plot(x^2,x=-4..4,xstep=1)
- `plot(x+y>0 and 2x+y<4 and x+2y<5)` : représentation graphique des solutions de ce système d’inéquations. Les inéquations polynomiales du premier et deuxième degré (délimités par des droites et des coniques) bénéficient d’un support amélioré, les bords de la zone solution sont calculés sous forme d’une ligne polygonale exacte (si tout est de degré 1) ou approchée. Sinon, une discrétisation est calculée et la zone représentée est une suite de petits rectangles, ce qui donne un aspect pixelisé au graphe, surtout sur la Numworks où la mémoire disponible et le temps nécessaire au calcul ne permet pas un graphe très précis.
  Si vous voulez aussi tracer les droites sur cet exemple, tapez la commande
  `plot(x+y>0 and 2x+y<4 and x+2y<5);line(x+y=0);line(2x+y=4); line(x+2y=5)`
- `LineTan(f(x),x,x0)` trace la tangente au graphe de f(x)f(x) en x=x 0 x=x_0.
- `plotarea(f(x),x=a..b,n,methode)` trace le graphe de f(x)f(x) pour x∈[a,b]x\in [a,b], et noircit une portion du plan qui approche l’aire sous la courbe, on peut préciser une méthode d’intégration avec `n` subdivisions parmi `rectangle_droit`, `rectangle_gauche`, `trapezes`, `simpson` (aller dans Toolbox , Options puis taper le début du nom de la méthode pour la saisir plus rapidement)
- `plotseq(f(x),x=[u0,a,b])` graphe “en toile d’araignée” de la suite récurrente u n+1=f(u n)u_{n+1}=f(u_n) de premier terme u 0 u_0 donné. Par exemple si u n+1=2+u n,u 0=6 u_{n+1}=\sqrt{2+u_n}, u_0=6 avec une représentation sur [0,7][0,7] plotseq(sqrt(2+x),x=[6,0,7])
- `plotparam([x(t),y(t)],t=tm..tM)` courbe en paramétriques (x(t),y(t))(x(t),y(t)) pour t∈[t m,t M]t\in [t_m,t_M]. On peut spécifier un pas de discrétisation avec `tstep=` par exemple plotparam([sin(2t),cos(3t)],t,0,2*pi)
- `plotpolar(r(theta),theta=a..b)` courbe en polaires r(θ)r(\theta) pour θ∈[a,b]\theta \in [a,b], par exemple plotpolar(sin(3*theta),theta,0,2*pi)
- `plotlist(l)` pour une liste `l`, trace la ligne polygonale reliant les points de coordonnées (i,l i)(i,l_i) (indice i i commençant à 0).
  `plotlist([X1,Y1],[X2,Y2],...)` trace la ligne polygonale reliant les points de coordonnées (X i,Y i)(X_i,Y_i)
- `scatterplot(X,Y)`, `polygonscatterplot(X,Y)` pour 2 listes `X,Y` de même taille, trace un nuage de points ou une ligne polygonale reliant les points de coordonnées (X i,Y i)(X_i,Y_i)
- `histogram(l,class_min,class_size)` trace l’histogramme des données de la liste `l` avec comme largeur de classe `class_size` en commençant à `class_min`. Par exemple, on peut tester la qualité du générateur aléatoire avec l:=ranv(500,normald,0,1); histogram(l,-4,0.25); plot(normald(x),x,-4,4)
- `plotcontour(f(x,y),[x=xmin..xmax,y=ymin..ymax],[l0,l1,...])` trace les courbes de niveaux f(x,y)=l 0,f(x,y)=l 1,...f(x,y)=l_0, f(x,y)=l_1, ....
- `plotdensity(f(x,y),[x=xmin..xmax,y=ymin..ymax])` représentation par niveaux de couleurs de la fonction de 2 variables `x` et `y` dans le rectangle spécifié (par défaut entre -4 et 4).
- `plotfield(f(t,y),[t=tmin..tmax,y=ymin..ymax])` trace le champ des tangentes à l’équation différentielle y′=f(t,y)y'=f(t,y). On peut ajouter en dernier paramètre optionnel `,plotode=[t0,y0]` pour tracer simultanément la solution passant par la condition initiale y(t 0)=y 0 y(t_0)=y_0. Exemple y′=sin(t y)y'=\sin(ty) sur l’intervalle [−3,3][-3,3] en temps et [−2,2][-2,2] en y y
  plotfield(sin(t*y),[t=-3..3,y=-3..3],plotode=[0,1])
  On peut aussi utiliser la commande `plotode` en-dehors d’une commande `plotfield`. pour tracer simultanément plusieurs graphiques, il suffit de séparer les commandes de tracé par `;`

Lorsqu’un graphique comporte des tracés de courbes (graphes de fonction, courbes en paramétriques ou en polaires), le mode “trace” est activé par défaut. Dans ce mode, l’appui sur la touche curseur vers la droite ou la gauche permet de déplacer un pointeur sur la courbe active, en affichant les coordonnées du pointeur (et du paramètre pour une courbe en paramétriques) et d’un vecteur tangent. S’il y a plusieurs arcs de courbe, les touches de curseur haut et bas permettent de changer l’arc d’étude. L’appui sur shift-2 permet d’afficher les informations sur la courbe courante, si on confirme par OK ou EXE on accède à un tableau de valeurs.

Le menu Toolbox item 2 étude de courbes (raccourci touche x,n,t) permet d’ajouter un vecteur normal pointant vers le centre de courbure (raccourci shift-4), ou/et le cercle osculateur (shift-5) et le rayon de courbure. On peut aussi à partir de ce menu déplacer le pointeur vers une position déterminée, ou vers un point remarquable: racine, tangente horizontale ou verticale, point d’inflexion, intersection avec un autre arc de courbe. On peut enfin calculer une longueur d’arc ou l’aire sous la courbe entre le pointeur et la marque.

Lorsque vous faites une étude de courbe, les variables `x0,x1,x2,y0,y1,y2` sont automatiquement affectées avec l’expression de la position, vitesse et accélération sur la courbe étudiée. Lors de la recherche d’une racine, tangente horizontale, inflexion, longueur d’arc, aire sous la courbe, des variables contenant la dernière recherche sont crées.

Le menu `Options` (Toolbox ,) vous permet de spécifier certaines options graphiques :

- pour les couleurs, on utilise `display=couleur`, par exemple plot(sin(x),display=red)
- Pour changer l’épaisseur des segments (y compris les lignes polygonales utilisées pour tracer une courbe), utiliser `display=line_width_2` à `display=line_width_8`. Pour changer à la fois la couleur et l’épaisseur, additionnez les attributs, par exemple : `display=red+line_width_2`
- Les cercles ainsi que les rectangles dont les bords sont parallèles aux axes peuvent être remplis avec l’attribut `display=filled` (qui peut s’additionner à d’autres attributs).
- Pour remplacer la fenêtre graphique calculée automatiquement par des valeurs prédéfinies, saisir `gl_x` ou/et `gl_y` et indiquer l’intervalle en x x ou en y y souhaité, la commande doit précder une commande de tracé. Par exemple gl_x=-2..2;gl_y=-1..4;plot(exp(x))
- Pour enlever les axes, sélectionner `axes` (`axes=0`). La commande doit précéder une commande de tracé.

Les versions récentes de χ\chiCAS permettent de représenter en 3d ou 4d des fonctions de 2 variables à valeur réelle ou complexe, par exemple `plot(x^2-y^2)` pour représenter la fonction de ℝ 2→mahtbb R\mathbb{R}^2 \rightarrow \mahtbb{R} ou `plot((x+i*y)^2-9)` pour représenter la fonction de ℂ→mahtbb C\mathbb{C} \rightarrow \mahtbb{C} qui à z z associe z 2−9 z^2-9. Dans ce dernier cas, le module est représenté selon l’axe O z Oz et l’argument par une couleur de l’arc en ciel, de −π-\pi en bleu violet à 0 en vert (en passant par jaune et orange) et de 0 à π\pi en passant par cyan.

Pour préciser des options en 3d/4d, il faut utiliser la commande `plotfunc`, par exemple
`plotfunc((x+i*y)^3-1,[x=-2..2,y=-2..2],nstep=500)`
pour tracer z→z 3−1 z \rightarrow z^3-1 depuis le carré du plan complexe centré en l’origine de coté 4, avec une discrétisation utilisant 500 petits rectangles.

## 8 Géométrie analytique.

L’application de géométrie permet de construire des figures dans le plan ou dans l’espace, et de faire bouger un point et tout ce qui en dépend pour illustrer certaines propriétés (géométrie dynamique). On peut faire des constructions de géométrie euclidienne pure, mais aussi avec des graphes de fonction, des coniques, etc. L’application possède deux “vues”: la vue graphique et la vue symbolique qui contient les commandes Xcas permettant de créer la figure (la philosophie de cette application est proche de celle du logiciel Geogebra, avec les commandes de Xcas).

### 8.1 Modes, vue graphique et symbolique.

Taper shift-Ans pour afficher la liste des applications additionnelles, puis OK puis sélectionnez soit une nouvelle figure 2d ou 3d soit une figure existante. Vous pouvez aussi ouvrir l’application de géométrie depuis un graphe (par exemple après avoir tapé `plot(sin(x))`) en tapant shift EXE ou Home selon le modèle puis Sauvegarder figure.

Au lancement on est dans la vue graphique en mode repère, les touches de curseur permettent de changer de point de vue. Pour changer le mode, utiliser la touche Toolbox, pour passer en vue symbolique et vice-versa taper OK. Par exemple tapez Toolbox 3 pour passer en mode point qui permet de construire des points en déplaçant le pointeur et en tapant OK ou tapez Toolbox 5 pour passer en mode triangle qui permet de construire un triangle à partir de ses 3 sommets, on déplace le pointeur et on tape OK trois fois. Pour déplacer le pointeur, utiliser les touches de déplacement, pour se déplacer plus rapidement, faire shift touche de curseur. Si on est proche d’un point existant, son nom apparait en bas. Pour déplacer le pointeur vers un point existant, vous pouvez aussi taper le nom du point (par exemple touche alpha A).

Le mode pointeur permet de sélectionner un point et de le déplacer pour observer comment la construction varie, ce qui permet de mettre en évidence des propriétés de la figure, par exemple concurrence de 3 droites.

Si vous tapez sur la touche Back depuis la vue graphique de l’application, vous revenez au mode repère ou si vous y étiez vous passez en vue symbolique. Vous pouvez ajouter des objets à la construction depuis cette vue, en mettant une commande par ligne. Tapez EXE pour passer à la ligne. Tapez OK pour revenir à la vue graphique. Dans la vue symbolique, vous pouvez sauvegarder la construction géométrique au format texte (avec une extension `.py`, même s’il ne s’agit pas d’un script Python). Tapez Back pour quitter l’application de géométrie.

Lorsque vous quittez l’application de géométrie, la figure est automatiquement sauvegardée dans une variable Xcas qui a le même nom que celui du nom de fichier affiché dans la vue symbolique. Vous pouvez purger la variable Xcas si vous voulez effacer la figure de la session.

### 8.2 Exemples

#### 8.2.1 Exemple 2d : cercle circonscrit.

Depuis le shell, taper shift-Ans sélectionner nouvelle figure 2d et valider OK. Puis Toolbox 5 Triangle, OK pour créer le premier sommet du triangle puis déplacer le pointeur avec les touches de déplacement, OK pour créer le 2ème sommet du triangle, déplacer le pointeur à nouveau et OK pour créer le triangle.

Version longue en construisant le centre : Taper Toolbox 7, sélectionner 8 Mediatrice, déplacer le pointeur de sorte que seul un segment du triangle soit sélectionné (affichage en bas à droite `perpen_bisector D5,D`), taper OK pour créer la médiatrice du segment, déplacer le curseur sur une autre arête du triangle et OK pour créer la 2ème médiatrice, optionnellement sur le 3ème segment pour avoir les 3 médiatrices. Puis Toolbox 6 et 4 Intersection unique. Déplacer le curseur vers une des médiatrices, taper OK puis vers une autre médiatrice, taper OK, ceci crée le centre du cercle circonscrit. Pour tracer le cercle, taper Toolbox 4, déplacer le curseur au centre du cercle (vous pouvez utiliser les touches de déplacement ou juste taper alpha H ou la bonne lettre si le centre du cercle s’appelle autrement), puis OK puis sur un des sommets et OK.

Version courte avec la commande `circonscrit` : taper Toolbox 9 puis circonscrit puis sélectionner chaque sommet avec OK (alpha A OK alpha B OK alpha C OK, remplacez A, B, C par les lettres du sommet du triangle).

Version en vue symbolique : taper Back puis en fin de script sur une ligne vide (taper EXE s’il faut en créer une), taper
`c:=circonscrit(A,B,C)` OK

#### 8.2.2 Exemple 3d: bac septembre 2019

On considère un cube A B C D E F G H ABCDEFGH et on vérifie que le segment D E DE est perpendiculaire au plan A B G ABG
Taper shift Ans pour lancer l’application de géométrie puis nouvelle figure 3d.

- Taper Puis Back ou OK pour passer en vue symbolique. Puis alpha c shift = puis Toolbox flèche haut deux fois pour sélectionner 3D puis OK puis 5 pour cube puis Toolbox (aide), qui explique que les 2 premiers arguments de cube sont les sommets d’une arête, le troisième est un point d’un plan d’une face. Le premier exemple nous convient ici exactement, on tape Ans et on obtient `c=cube([0,0,0],[1,0,0],[0,1,0])` On tape EXE pour voir le cube puis + plusieurs fois pour zoomer et EXE pour revenir à la vue symbolique.
- Vous pouvez sauvegarder à tout moment la construction au format texte depuis le menu (touche shift-EXE ou Home selon le modèle).
- On passe à la ligne en tapant EXE. Puis on définit les sommets du cube en tapant `A,B,C,D,E,F,G,H:=` (taper alpha shift A , alpha shift B etc.), puis Toolbox et flèche vers le haut 3 fois pour sélectionner Géometrie puis flèche vers le haut 4 fois pour sélectionner `sommets` OK et mettre c en argument `sommets(c)`. Taper OK pour visualiser puis OK à nouveau pour revenir en vue symbolique.
- Passer à la ligne avec EXE puis créer le plan ABG en tapant alpha shift P = puis shift-2 pour ouvrir le menu rapide lines et 8 pour saisir plane. La commande plan prend en arguments 3 points pour définir le plan (on peut aussi donner une équation cartésienne), ici A,B,G, `P=plan(A,B,G,` on va lui ajouter une couleur avec le menu rapide shift 4 disp `display=filled+green`, vérifier en visualisant avec OK OK.
- On passe à la ligne (EXE) et on crée le segment DE alpha S = shift 2 sélectionner la commande segment avec OK puis D,E et shift 4 pour lui donner une couleur `S=segment(D,E,color=cyan)` (on pouvait aussi créer le segment depuis la vue graphique en mode Lignes mais déplacer le pointeur est un peu lent).

La construction est donc la suivante:

    c=cube([0,0,0],[1,0,0],[0,1,0])
    A,B,C,D,E,F,G,H=sommets(c)
    P=plan(A,B,G,display=filled+green)
    S=segment(D,E,display=cyan)

Vous pouvez taper OK pour la visualiser et utiliser les flèches de déplacement pour changer de point de vue. Taper OK ou Back pour revenir en vue symbolique. Pour quitter l’application taper Back. Taper OK pour sauvegarder la figure si nécessaire.

Vous pouvez depuis le shell de KhiCAS accéder à de nombreuses informations de géométrie analytique, par exemple `equation(P)` (menu Toolbox Géométrie) vous donnera l’équation cartésienne du plan P P ou `is_orthogonal(P,S)` (à saisir depuis le catalogue complet Toolbox OK) vous confirmera que le plan P P est orthogonal au segment S S.

## 9 Unités et constantes physiques.

Le menu Toolbox permet d’ouvrir un sous-menu constantes physiques (raccourci `Toolbox pi`) et unités physiques (raccourci `Toolbox sqrt`) avec

- des commandes de gestion d’unité
  `mksa` pour convertir vers les unités fondementales du système international
  `usimplify` pour simplifier en utilisant une seule unité lorsque c’est possible, ou un produit de deux.
  `ufactor` pour forcer l’écriture d’une unité en fonction d’une autre
  `=>` (raccourci touche sto) pour convertir entre deux unités compatibles
- une liste non exhaustive d’unités physiques
- une liste de constantes physiques fondementales.

Exemples de commandes :
`60_(km/h) => _(m/s)`
`mksa(_hbar_)`
`usimplify(1_W*1_s)`
`ufactor(1_W,1_J)`

## 10 L’éditeur d’expressions

Lorsqu’un calcul renvoie une expression, elle est affichée en plein écran dans l’éditeur d’expression 2d. Depuis l’historique des calculs, si le niveau sélectionné est une expression, l’appui sur shift-5 (2d) affiche l’expression dans l’éditeur 2d. En ligne de commande, l’appui sur shift-5 ouvre aussi l’éditeur 2d, soit avec 0 si la ligne de commande était vide, ou avec le contenu de la ligne de commande si celle-ci est syntaxiquement correcte.

Lorsque l’éditeur 2d est ouvert, l’expression est affichée en plein écran et une partie de l’expression est sélectionnée. On peut alors agir sur la sélection en exécutant des commandes saisies via les menus ou le clavier, on peut aussi éditer la sélection (en mode de saisie 1d). Ceci permet de retravailler des sous-expressions ou d’éditer une expression en écriture naturelle.

Vous pouvez annuler la dernière modification effectuée en tapant sur shift-3 (undo).

Taper OK pour quitter l’éditeur 2d et copier l’expression en ligne de commande, taper Back pour quitter sans recopier l’expression.

Exemple 1 : nous allons saisir lim x→0 sin(x)x\lim_{x \rightarrow 0} \frac{\sin(x)}{x} Depuis une ligne de commande vide, taper shift-5 (2d), vous devez voir 0 sélectionné. Tapez sur la touche x et EXE, maintenant c’est x qui est en surbrillance. Tapez sur la touche sin, c’est sin(x)\sin(x) qui est en surbrillance. Tapez sur la touche de division (au-dessus de -), vous devez voir sin(x)0\frac{\sin(x)}{0} avec 0 en surbrillance, tapez x puis EXE, vous devez voir sin(x)x\frac{\sin(x)}{x} avec x au dénominateur en surbrillance. Tapez sur le curseur flèche vers le haut pour mettre sin(x)x\frac{\sin(x)}{x} en surbrillance, puis shift-2 4 (pour limit). L’expression est correcte, vous pouvez taper OK pour la recopier en ligne de commande et OK à nouveau pour exécuter le calcul. Si on avait voulu une limite en +∞+\infty, il aurait fallu déplacer la sélection avec curseur vers la droite, puis faire shift-1 7 (oo) OK.

Exemple 2 : nous allons saisir ∫ 0 +∞1 x 4+1 d x\int_0^{+\infty} \frac{1}{x^4+1} \ dx Depuis une ligne de commande vide, taper shift-5 (2d), puis shift-2 3 (integrate), vous devez voir ∫ 0 1 0 d x\int_0^1 0 \ dx avec x x sélectionné. Il faut donc changer le 1 de la borne supérieure et le 0 à intégrer. Pour modifier le 0, curseur vers la gauche pour le sélectionner puis `1/(x^4+1)` EXE, puis curseur vers la gauche shift-1 7 EXE. Taper sur OK pour recopier vers la ligne de commande puis OK pour effectuer le calcul, le résultat s’affiche dans l’éditeur 2d, OK quitte l’éditeur avec dans l’historique l’intégrale et sa valeur (en syntaxe algébrique 1d).

Exemple 3 : nous allons calculer et simplifier ∫1 x 4+1 d x\int \frac{1}{x^4+1} \ dx Depuis une ligne de commande vide, taper shift-5 (2d), puis shift-2 3 (integrate), vous devez voir ∫ 0 1 0 d x\int_0^1 0 \ dx Déplacez le curseur sur le 0 de la borne inférieure de l’intégrale et tapez sur la touche DEL, vous devez voir ∫0 d x\int 0 \ dx avec le tout sélectionné. Utilisez le curseur vers le bas pour sélectionner 0 et tapez `1/(x^4+1)` EXE puis OK pour recopier en ligne de commande puis OK pour exécuter le calcul, le résultat s’affiche maintenant dans l’éditeur 2d.
On peut alors sélectionner avec les touches du curseur par exemple l’argument d’un des arctangentes et exécuter shift-1 EXE (simplify) pour effectuer une simplification partielle du résultat, puis recommencer avec l’autre arctangente.
On peut simplifier encore plus, en rassemblant les logarithmes. Pour cela il faut d’abord échanger deux des arguments de la somme. Sélectionnez un des logarithmes avec des déplacements du curseur, puis tapez shift-curseur droit ou gauche, cela échange l’argument sélectionné avec son frère de droite ou de gauche. Tapez ensuite alpha curseur vers la droite ou vers la gauche, ceci augmente la sélection en ajoutant le frère de droite ou de gauche. Une fois les deux logarithmes sélectionnés, menu shift-1 2 EXE (factor), puis descendez la sélection sur la somme ou différence de logarithmes, allez dans le menu Toolbox puis EXE (Tout), tapez les lettres l, n, c ce qui déplace à la première commande commençant par `lnc`, sélectionnez `lncollect`, validez et tapez enfin sur EXE (eval).

## 11 Sessions de calculs

### 11.1 Edition de l’historique.

En utilisant la touche curseur vers le haut/bas, on se déplace dans l’historique des calculs, le niveau courant est en surbrillance.

Pour modifier l’ordre des niveaux dans l’historique des calculs, tapez alpha-curseur vers le haut ou vers le bas. Pour effacer un niveau, appuyez sur la touche DEL (le niveau est recopié dans le presse-papiers).

Pour modifier un niveau existant, on tape sur shift-5 ou sur shift-4. Dans le premier cas, c’est l’éditeur 2d qui est appelé si le niveau est une expression, dans le deuxième cas, c’est l’éditeur texte qui est appelé. Taper Back pour annuler les modifications ou EXE pour valider. Si les modifications sont validées, les lignes de commande situées en-dessous de la ligne modifiée seront automatiquement calculées, tenant compte des modifications, par exemple si vous modifiez un niveau comme `A:=1`, les lignes situées en-dessous dépendant de `A` seront actualisées.

Ce processus peut être automatisé en utilisant un curseur, que l’on peut créer avec un assistant, depuis le menu principal (shift EXE ou HOME), Parameter. Une fois créé, vous pouvez modifier un curseur en tapant sur les touches + ou - lorsque le niveau contenant la commande `assume` ou `parameter` est sélectionné (tapez * ou / pour une modification plus rapide).

### 11.2 Variables

En appuyant sur la touche `var` vous affichez la liste des variables qui ont une valeur, ainsi que des commandes de gestion de variables. Déplacez le curseur vers une variable puis EXE pour la recopier en ligne de commande, DEL copie en ligne de commande la commande d’effacement de la variable (confirmez ensuite avec EXE). La commande `restart` permet d’effacer toutes les variables. La commande `assume` permet de faire une hypothèse sur une variable, par exemple `assume(x>5)` (`>` se trouve dans le menu shift-PRGM).

## 12 Programmation

L’environnement de programmation de χ\chicas est assez complet: un éditeur, l’interpréteur de Xcas avec toutes ses commandes (compatibilité partielle avec les modules Python math, cmath, random, turtle, numpy, scipy, giacpy, matplotlib et un sur-ensemble du module kandinsky), avec un outil de mise au point permttant l’exécution en pas à pas.

Vous pouvez programmer en utilisant les structures de commande en français de Xcas ou en utilisant la compatibilité de syntaxe Python. Les programmes très courts (en une ligne) peuvent être saisis directement en ligne de commande. Les programmes plus longs ou que l’on souhaite sauvegarder seront saisis dans l’éditeur de programmes sur la calculatrice, ou bien transférés depuis un PC ou une autre calculatrice.

Plusieurs programmes sont installés après un reset de la calculatrice (des polygones avec la tortue, la fractale de Mandelbrot, le calcul des racines d’un polynôme de degré 2). Vous pouvez les visualiser depuis le shell en tapant shift-EXE ou Home selon le modèle de calculatrice, puis Ouvrir script, les interpréter avec la touche OK et les exécuter depuis le shell (Back puis var pour sélectionner la fonction).

### 12.1 Prise en main (programmation)

Un premier exemple en ligne de commande :
une fonction définie par une expression algébrique. On saisit `nom_fonction(parametres):=expression` Par exemple, pour définir le périmètre d’un cercle de rayon r r, on peut taper peri(r):=2*pi*r
puis on peut calculer peri(1)
.

Autre exemple, pour calculer l’intervalle de confiance de seconde connaissant une fréquence p p et un effectif n n, on tape
F(P,N):=[P-1/sqrt(N),P+1/sqrt(N)]
puis on teste F(0.4,30)

Autre exemple : avec la tortue de Xcas
La tortue de Xcas est un petit robot qui se déplace selon des ordres qui lui sont donnés en laissant une trace de son passage. Les commandes de la tortue sont accessibles depuis le dernier item du menu Toolbox, par le raccourci Toolbox x 2 x^2. Saisir la commande avance dans ce menu puis valider, vous devez voir la tortue (symbolisée par un triangle) avancer de 10 pixels. Taper Back pour revenir en ligne de commande. Saisir la commande `tourne_gauche` et valider, la tortue a tourné de 90 degrés. Répéter 3 fois ces deux commandes pour afficher un carré.
Pour effacer le dessin et ramener la tortue à l’origine, saisir la commande efface. Pour faire des dessins tortue, il est conseillé d’utiliser l’éditeur de programmes (cf. ci-dessous).

Autre exemple : une boucle “oneliner” en syntaxe Xcas.
Ouvrez le menu Programmes (Toolbox cos), puis sélectionnez l’exemple de `pour` (curseur sur pour puis Ans)
pour j de 1 jusque 10 faire print(j,j^2); fpour;
tapez sur EXE, vous devez voir les carrés des entiers de 1 à 10.

Exercice : faire faire un carré à la tortue en utilisant une boucle.

Utilisation de l’éditeur
Modifions cet exemple pour faire afficher les carrés de 1 à n n en utilisant la syntaxe compatible Python et l’éditeur de programmes. Tapez sur Back pour passer du shell à l’éditeur de programmes. Si on vous demande programme ou Tortue faites OK. Ceci ouvre l’éditeur avec une maquette de fonction `def f(x):` Vérifiez que la syntaxe Python est activée (menu principal shift EXE ou HOME), sinon activez-la (8). Remplacez `x` par `n`, puis déplacez le curseur en fin de ligne et passez à la ligne (EXE). Tapez Shift-2 puis EXE (`for`), placez un `j` entre `for` et `in range(` puis un `n` entre les parenthèses de `range()`. À la ligne suivante, tapez shift-3 7 (`print`) et validez (EXE), puis tapez `j,j^2)`. Vous devriez avoir le programme suivant :

    def f(n):
      for j in range(1,n+1):
        print(j,j^2)
      return x

Remplacez `x` par `n` dans `return` (ou effacez la ligne). N.B.: pour la puissance, on peut utiliser `^` ou `**` dans KhiCAS (il faut utiliser `**` en Python).

Maintenant, tapez OK. Si tout va bien, vous devez voir `Success` dans la ligne d’état. Sinon, le numéro de ligne de la première erreur est indiqué ainsi que le mot qui a provoqué l’erreur. Le curseur est positionné sur la ligne où l’erreur a été détectée (il peut arriver que l’erreur soit située avant mais détectée un peu plus loin seulement). Si vous utilisez la syntaxe en Python, notez que les structures de programmation sont traduites en langage Xcas, les erreurs affichées le sont par rapport à cette traduction (donc des mots-clefs de fin de structure comme `end` peuvent avoir été ajoutées).

Si le programme est syntaxiquement correct, vous pouvez le sauvegarder depuis le menu principal (shift EXE ou HOME). Pour l’exécuter, revenez à la ligne de commande en tapant la touche Back, tapez par exemple `f(10)`, vous devriez voir s’afficher les carrés de 1 à 10.

3ième exemple : Calcul de l’intervalle de confiance de terminale S
En syntaxe Xcas. On peut le saisir en ligne de commande F(P,N):=[P-1.96*sqrt(P*(1-P)/N),P+1.96*sqrt(P*(1-P)/N)]
On peut éviter les calculs redondants en utilisant une variable locale (utiliser Toolbox Programmes pour saisir fonction, local, return et ffonction)

    fonction F(P,N)
      local D;
      D:=1.96*sqrt(P*(1-P)/N);
      return [P-D,P+D];
    ffonction;

Exercice Créez un fichier `carre.py` contenant un script pour afficher un carré avec la tortue. Créez un fichier `carren.py` pour afficher un carré de n n pixels, en utilisant une fonction d’argument n n et l’instruction `repete`.

Solution Depuis l’éditeur de script, faire shift EXE ou HOME puis 5 (Effacer). Puis shift-4 `efface`. Ajouter 4 fois `avance; tourne_gauche;`. Appuyer sur OK pour tester. Sauvegardez (shift EXE ou HOME puis 3 Sauvegarder comme).

Effacer à nouveau (shift EXE ou HOME 5 effacer) Puis shift-4 `efface`. Ajouter avant la ligne `efface`

    def f(n):
      for j in range(4):
        avance(n)
        tourne_gauche

puis après la ligne `efface;` tapez par exemple `f(40)` puis OK. Ensuite faire shift EXE ou HOME 3 (Sauvegardez comme).

Un exemple de fonction non algébrique : le calcul du PGCD de 2 entiers.
Utiliser EXE pour passer à la ligne. En syntaxe Xcas

    fonction pgcd(a,b)
      tantque b!=0 faire
        a,b:=b,irem(a,b);
      ftantque;
      return a;
    ffonction

Le même en syntaxe Python

    def pgcd(a,b):
      while b!=0:
        a,b=b,a % b
      return a

On vérifie pgcd(12345,3425)

Mise au point
La commande `debug` permet d’exécuter une fonction en mode pas-à-pas, i.e. visualiser l’évolution des variables instruction par instruction, par exemple
`debug(pgcd(12345,3425))`

### 12.2 Quelques exemples

Le répertoire `prog` de l’archive khicasio.zip contient quelques exemples de TP pour classes de seconde de l’IREM de Grenoble :

- utilisation de la tortue pour introduire la programmation textuelle et la notion de fonction (PDF+corrections fichiers py)
- longueur approchée d’un arc de courbe (PDF+correction fichier py)
- tableau de valeurs, recherche de minimum (enonce et morceaux de programmes, fichier tabval.py)

ainsi que quelques autres programmes (avec fréquemment une représentation graphique) :

- fréquence dans un échantillon, intervalle de fluctuations (freq.py)
- le paradoxe du duc de Toscane (toscane.py)
- résolution d’équation du second degré (deg2.py)
- dichotomie (dicho.py)
- méthode des rectangles (integr.py),
- fractale de Mandelbrot (mandel.py)
- un benchmark utilisé par tiplanet pour mesurer la vitesse de l’interpréteur (qcc.py)

### 12.3 Commandes utilisables

Contrairement aux adaptations de MicroPython proposées par les constructeurs (dont celui de la Numworks N0110), la programmation en (simili-)Python dans KhiCAS n’est pas une application indépendante. Vous pouvez donc utiliser tous les types de Xcas (par exemple les rationnels) et appliquer toutes les commandes de Xcas dans vos programmes. Ceci correspond plus ou moins à un environnement Python avec les modules `math`, `cmath`, `random` (plus complet que le module `urandom` fourni par les constructeurs), `scipy`, `numpy`, un petit module de graphiques pixelisé (`set_pixel(x,y,c)`, `set_pixel()` pour synchroniser l’affichage, `clear()`, `draw_line(x1,y1,x2,y2,c)`, `draw_polygon([[x1,y1],[x2,y2],...],c)`, `draw_rectangle(x,y,w,h,c)`, `draw_circle(x,y,r,c)`, la couleur+epaisseur+remplissage `c` est un paramètre optionnel, `draw_arc(x,y,rx,ry,t1,t2,c)` permet de tracer un arc d’ellipse). et pour remplacer `matplotlib` on peut utiliser les commande graphiques dans un repère de χ\chiCAS (`point`, `line`, `segment`, `circle`, `barplot`, `histogram` et les commandes `plot...`). De plus, vous pouvez travailler avec des expressions et faire du calcul formel dessus. Pour la liste complète des commandes et une présentation détaillée, on renvoie à la documentation de Xcas.

## 13 Interpréteur MicroPython intégré

χ\chiCAS est maintenant fourni avec son propre interpréteur MicroPython (qui n’est pas identique à celui fourni par Numworks). Pour passer dans χ\chiCAS de l’interpréteur Xcas à MicroPython et réciproquement vous pouvez taper la commande `python` ou `xcas` dans le shell sur une ligne vide. Ces commandes sont accessibles dans le menu rapide shift ).

Attention, si vous lancez MicroPython après avoir travaillé avec Xcas ou/et avec le tableur, il peut ne pas y avoir assez de mémoire pour le tas MicroPython, dans ce cas vous risquez de perdre votre session de travail, pensez à la sauvegarder. Par défaut, 40K sont réservés pour MicroPython. Vous pouvez modifier cette valeur jusqu’à 64K dans la configuration (shift EXE ou Home puis touche ln). Si vous choisissez une valeur haute, il peut être nécessaire de quitter χ\chiCAS et de le réouvrir pour que le tas puisse être alloué dans une zone mémoire contiguë (problème de fragmentation du tas sinon).

Remarque : lorsque l’interpréteur Xcas est actif, si vous passez en argument à la commande `xcas` ou `python` le nom de variable d’une fonction que vous avez programmée, cela affiche son texte source sous forme d’une chaine de caractères en syntaxe Xcas ou Python. Vous pouvez donc programmer en syntaxe Xcas et traduire ensuite en Python si vous devez vous conformer à des règles qui imposent ce langage.

### 13.1 Les modules math, cmath, random

Ce sont les modules natifs fournis par MicroPython (`urandom` a été renommé `random`), et qui sont conforme au standard. D’autres modules MicroPython standard qui ne sont pas destinés à faire des maths sont disponibles.

### 13.2 Le module graphic

Il s’agit d’un module natif MicroPython qui exporte de Xcas des fonctions de tracé pixelisés. Une partie des commandes est accessible depuis le menu rapide shift 0. Ce module a des synonymes, `kandinsky` et `casioplot` afin de faciliter l’utilisation de scripts Python pour calculatrices Numworks (Epsilon) et Casio.

### 13.3 Le module matplotl

Il s’agit d’un module natif MicroPython qui exporte de Xcas des fonctions de tracé repéré et vise à une certaine compatibilité avec le module `matplotlib` (ou un de ses sous-modules) sur PC. Une partie des commandes est accessible depuis le menu rapide shift `.`

### 13.4 Le module arit

C’est un module natif qui exporte de Xcas des fonctions d’arithmétique entière : test de primalité et prochain nombre premier (par Miller-Rabin), factorisation d’entiers pas trop gros (détection par Pollard-rho du plus petit facteur premier, donc jusqu’à environ 9 chiffres), pgcd et identité de Bèzout, indicatrice d’Euler (si on sait factoriser). J’y ai aussi inclus deux fonctions de conversion liste vers chaine de caractères pour faciliter l’enseignement d’un peu de cryptographie.

### 13.5 Le module linalg

Il permet de manipuler les listes comme des vecteurs et les listes de listes comme des matrices. Contrairement à Xcas, Python n’est pas un langage spécifiquement adapté aux maths, il faut utiliser des commandes préfixées `add, sub, mul` pour effectuer les opérations arithmétiques de base `+ - *` sur les vecteurs et matrices représentés par des listes.

Le module `linalg` est un module natif, qui utilise Xcas pour effectuer la quasi-totalité des calculs.

### 13.6 Le module numpy

C’est une surcouche du module `linalg` qui définit une classe `array` pour représenter les vecteurs et les matrices. On peut alors utiliser `+ - *` pour faire les opérations de base sur vecteurs et matrices.

Le module `numpy` n’est pas un module natif, c’est un texte source écrit en Python. Son importation consomme donc de la mémoire RAM. Vous pouvez écrire votre propre version de `numpy.py` et la stocker dans le scriptstore, elle prendra alors la précédence sur la version utilisée par défaut. Cette dernière vise à assurer un minimum de compatibilité avec le module du même nom sur PC. Bien que non natif, ce module est disponible en mode examen (le texte source par défaut est intégré au code source de l’interpréteur MicroPython).

    import linalg
    import math
    class array:
        def __init__(self, a):
            self.a = a

        def __add__(self, other):
            return array(linalg.add(self.a , other.a))

        def __sub__(self, other):
            return array(linalg.sub(self.a , other.a))

        def __mul__(self, other):
            if type(self)==array:
                if type(other)==array:
                    return array(linalg.mul(self.a , other.a))
                return array(linalg.mul(self.a,other))
            return array(linalg.mul(self,other.a))

        def __rmul__(self, other):
            if type(self)==array:
                if type(other)==array:
                    return array(linalg.mul(self.a , other.a))
                return array(linalg.mul(self.a,other))
            return array(linalg.mul(self,other.a))

        def __matmul__(self, other):
            return __mul(self,other)

        def __getitem__(self,key):
            r=(self.a)[key]
            if type(r)==list or type(r)==tuple:
                return array(r)
            return r

        def __setitem__(self, key, value):
            if (type(value)==array):
                (self.a)[key]=value.a
            else:
                (self.a)[key]=value
            return None

        def __len__(self):
            return len(self.a)

        def __str__(self):
            return 'array('+str(self.a)+')'

        def __repr__(self):
            return 'array('+str(self.a)+')'

        def __neg__(self):
            return array(-self.a)

        def __pos__(self):
            return self

        def __abs__(self):
            return array(linalg.abs(self.a))

        def __round__(self):
            return array(linalg.apply(round,self.a,linalg.matrix))

        def __trunc__(self):
            return array(linalg.apply(trunc,self.a,linalg.matrix))

        def __floor__(self):
            return array(linalg.apply(floor,self.a,linalg.matrix))

        def __ceil__(self):
            return array(linalg.apply(ceil,self.a,linalg.matrix))

        def T(self):
            return array(linalg.transpose(self.a))

    def real(x):
        if type(x)==array:
            return array(linalg.re(x.a))
        return x.real

    def imag(x):
        if type(x)==array:
            return array(linalg.im(x.a))
        return x.imag

    def conj(x):
        if type(x)==array:
            return array(linalg.conj(x.a))
        return linalg.conj(x)

    def sin(x):
        if type(x)==array:
            return array(linalg.apply(math.sin,x.a,linalg.matrix))
        return math.sin(x)

    def cos(x):
        if type(x)==array:
            return array(linalg.apply(math.cos,x.a,linalg.matrix))
        return math.cos(x)

    def tan(x):
        if type(x)==array:
            return array(linalg.apply(math.tan,x.a,linalg.matrix))
        return math.tan(x)

    def asin(x):
        if type(x)==array:
            return array(linalg.apply(math.asin,x.a,linalg.matrix))
        return math.asin(x)

    def acos(x):
        if type(x)==array:
            return array(linalg.apply(math.acos,x.a,linalg.matrix))
        return math.acos(x)

    def atan(x):
        if type(x)==array:
            return array(linalg.apply(math.atan,x.a,linalg.matrix))
        return math.atan(x)

    def sinh(x):
        if type(x)==array:
            return array(linalg.apply(math.sinh,x.a,linalg.matrix))
        return math.sinh(x)

    def cosh(x):
        if type(x)==array:
            return array(linalg.apply(math.cosh,x.a,linalg.matrix))
        return math.cosh(x)

    def tanh(x):
        if type(x)==array:
            return array(linalg.apply(math.tanh,x.a,linalg.matrix))
        return math.tanh(x)

    def exp(x):
        if type(x)==array:
            return array(linalg.apply(math.exp,x.a,linalg.matrix))
        return math.exp(x)

    def log(x):
        if type(x)==array:
            return array(linalg.apply(math.log,x.a,linalg.matrix))
        return math.log(x)

    def size(x):
        if type(x)==array:
            return linalg.size(x.a)
        return linalg.size(x)

    def shape(x):
        if type(x)==array:
            return linalg.shape(x.a)

    def dot(a,b):
        return a*b

    def transpose(a):
        if type(x)==array:
            return array(linalg.transpose(x.a))

    def trn(a):
        if type(x)==array:
            return array(linalg.conj(linalg.transpose(x.a)))
        return linalg.conj(linalg.transpose(x.a))

    def zeros(n,m=0):
        return array(linalg.zeros(n,m))

    def ones(n,m=0):
        return array(linalg.ones(n,m))

    def eye(n):
        return array(linalg.eye(n))

    def det(x):
        if type(x)==array:
            return linalg.det(x.a)
        return linalg.det(x)

    def inv(x):
        if type(x)==array:
            return array(linalg.inv(x.a))
        return linalg.inv(x)

    def solve(a,b):
        if type(a)==array:
            if type(b)==array:
                return array(linalg.solve(a.a,b.a))
            return array(linalg.solve(a.a,b))
        if type(b)==array:
            return array(linalg.solve(a,b.a))
        return linalg.solve(a,b)

    def eig(a):
        if type(a)==array:
            r=linalg.eig(a.a)
            return array(r[0]),array(r[1])
        return linalg.eig(a)

    def linspace(a,b,c):
        return array(linalg.linspace(a,b,c))

    def arange(a,b,c=1):
        return array(linalg.arange(a,b,c))

    def reshape(a,n,m=0):
        if type(n)==tuple:
            m=n[1]
            n=n[0]
        if type(a)==array:
            return array(linalg.matrix(n,m,a.a))
        return linalg.matrix(n,m,a)

## 14 Applications additionnelles

Les applications additionnelles sont accessibles en tapant shift Ans. Il y a actuellement un tableur, le tableau périodique des éléments (d’après Maxime Friess), et trois exemples d’addin qui peuvent servir de modèle aux programmeurs : la suite de Syracuse (très simple), la fractale de Mandelbrot et les bassins d’attraction de la méthode de Newton, et un jeu de mastermind (qui peut aussi servir de passe-temps).

## 15 Le tableur

Au lancement, vous avez un tableau de 14 lignes et 4 colonnes remplies de 0. Vous pouvez changer la dimension depuis la configuration du tableur (shift EXE ou Home puis configuration), mais attention, chaque cellule utilise de la mémoire, un peu moins de 100 octets pour une cellule remplie d’un nombre, plusieurs centaines d’octets si elle est remplie par une formule, et la mémoire de la Numworks est très limitée, s’il n’y a pas assez de mémoire lors d’une allocation, vous perdrez votre session de travail. Pensez à faire une sauvegarde de votre session de temps en temps!

La syntaxe pour créer une formule est identique à celle d’un tableur classique, on tape sur shift = puis on entre la formule, avec des références relatives (par exemple `=a1+1`) ou absolues (`=$a$1+1`). Pour saisir une cellule après avoir tapé `=`, on peut déplacer le curseur vers la cellule cible, à condition de commencer par un déplacement de curseur vers le haut ou vers le bas (sinon le déplacement vers la droite ou la gauche déplace dans la ligne de commande, pas dans le tableur). On peut utiliser les commandes de Xcas ainsi que des fonctions qu’on a programmées.

Il y a des assistants de saisie spécifiques au tableur dans les menus rapides shift 1, 2 et 3. Par exemple pour générer des entiers consécutifs, taper shift 3 puis OK ce qui crée une ligne de commande contenant `range(`, il suffit de mettre un entier a a ou deux entiers a a et b b en arguments pour créer la liste des entiers entre 0 et a−1 a-1 ou entre a a et b−1 b-1 et la dispatcher sur la colonne.

Autre exemple, pour avoir un tableau de valeurs de fonctions, se placer au début d’une colonne vide dont la colonne à droite est aussi vide et taper shift 3, sélectionner `tablefunc` puis passer en argument l’expression, par exemple `sin(x)` (ou `f(x)` si vous avez défini une fonction `f`). Vous pouvez ensuite régler la valeur de début et le pas dans le tableur. Pour une suite récurrente, se placer en haut d’une colonne vide et utiliser la commande `tableseq` du menu rapide shift 3.

Pour sélectionner une plage de cellules, taper simultanément sur shift et une touche de direction, vous pouvez ensuite relacher shift et déplacer le curseur en fin de sélection. Tapez OK pour valider (si vous la passez en argument d’une formule saisie dans une cellule du tableur), ou shift copy si vous voulez copier la sélection dans le presse-papier pour par exemple la recopier dans le shell avec shift paste.

Si vous utilisez un des assistants de statistiques 2d, faites la sélection des 2 colonnes avant de choisir la commande. Par exemple, en 1ère ligne, 1ère colonne, tapez shift 3 sélectionnez `range` puis complétez en `range(6)` comme valeurs de X puis en face en 2ème colonne entrez des valeurs et Y. Déplacez le curseur en 1ère ligne et en 1ère colonne, puis shift-curseur vers le base puis déplacements du curseur pour rejoindre l’autre extrémité de la sélection, puis shift 2, puis par exemple `polygonscatterplot`. Pour voir le graphique, tapez shift 6. Pour voir sur le même graphique la droite de régression linéaire correspondante, vous pouvez recommencer la procédure ou bien recopier la cellule contenant la formule de `polygonscatterplot` avec shift-copy shift-copy et la coller avec shift paste en-dessous, puis la modifier (shift 4 OK) en remplaçant `polygonscatterplot` par `linear_regression_plot`

Lorsqu’on utilise une plage de cellule en argument d’une commande, la plage de cellule est aplatie en une seule liste. Si on souhaite utiliser une matrice comme argument d’une commande, il faut reconstruire la matrice à partir de la liste en utilisant la commande `matrix(l,c,liste)` où `l,c` sont les dimensions de la matrice (c’est ce que fait l’assistant `scatterplot` du menu rapide de statistiques 2d (shift 2) si on sélectionne la plage de cellules auparavant).

Dans le menu accessible depuis la touche shift EXE ou HOME, vous pouvez insérer ou effacer une ligne ou une colonne, vous pouvez aussi donner un nom de variable au tableur, la matrice des valeurs sera alors automatiquement sauvegardée dans cette variable, que vous pouvez utiliser ensuite depuis le shell.

Si vous entrez dans une cellule une formule donnant un résultat vecteur ou matrice, celle-ci sera dispatchée par défaut dans plusieurs cellules. On peut modifier cela dans la configuration du tableur.

## 16 Raccourcis claviers.

- shift * (N0110 verrouillées, N0115, N0120): table de caractères
- shift + (N0110 verrouillées, N0115, N0120): indentation ou aide
- La touche d’effacement en mode alphabétique a été modifiée (dans tout l’OS) pour effacer et ne pas renvoyer `%`, car cela rend la correction d’erreur de frappes très pénible. Pour saisir `%`, tapez shift `/` (ce qui est facile à retenir quand on programme un peu).
- on peut taper alpha-shift-`"` pour saisir `'`
- le caractère `\` est accessible via shift-`-`.
- shift-1 à shift-6: selon le mode (Xcas ou Python) voir les légendes
- shift-7 (M) matrice, 8 complexes, 9 arithmétique entière, `(` listes, `)` programmation, `0` probas `.` réels, `x10^` arithmétique polynomiale, Si MicroPython est activé, shift 7 linalg, 8 numpy, 9 arithmétique entière, `(` listes, `)` programmation, `0` matplotl, `.` graphic, `x10^` couleurs
- Si Xcas est actif, `=>` suivi d’une unité physique effectue une conversion d’unité, `=>` suivi d’une fonction permet d’exécuter des actions:
  `=>*` écriture sous forme de produit (pour une unité, écriture en utilisant les unités fondementales du système MKSA),
  `=>+` écriture sous forme de somme (pour une unité, écriture sous forme le plus simple possible),
  `=>/` écriture sous forme de quotient,
  `=>sin`, `=>cos`, `=>tan` conversion vers des sinus, cosinus ou tangentes.
  `=>,` permet de chronométrer une évaluation,
  `16=>=>` écrit les entiers en base 16, `10=>=>` en base 10, `8=>=>` en base 8
- shift-) 8 EXE permet de changer d’interpréteur.

Dans l’éditeur de programmes :

- touches curseur shiftées: déplacement en début/fin de ligne/fichier.
- shift copy ou shift et touche curseur simultanément: début de sélection. Déplacer le curseur à l’autre extrémité puis taper sur DEL pour effacer la sélection et la copier dans le presse-papier ou sur shift copy pour copier la sélection sans l’effacer. Pour coller le presse-papier, taper shift paste.
- EXE: si une recherche/remplacement de mot est active (après avoir fait shift EXE 6 ou Home 6 selon le modèle), recherche l’occurence suivante d’un mot. Sinon, passe à la ligne.
- DEL efface le caractère précédent ou la sélection.
- shift PASTE: copie le presse-papier
- var: bascule entre l’éditeur et la figure tortue
- Back: quitte l’éditeur et revient en ligne de commandes. On peut revenir ensuite à l’éditeur en tapant à nouveau Back.

## 17 Moteur de rendu 3d et géométrie.

La dernière version de KhiCAS pour Numworks fournit un moteur de rendu de graphique 3d, inspiré au départ par le script Python 3d de Eric Schrafstetter.

Ce moteur de rendu apparait si vous créez une figure 3d ou si vous entrez dans le shell ou l’éditeur de programmes une commande renvoyant un graphe dans l’espace, par exemple depuis le menu Toolbox, sous-menu 3d (raccourci `(`) :

- un plan, donné par 3 points ou une équation cartésienne par exemple plan(z=x)
- une surface z=f(x,y)z=f(x,y) avec la commande `plot(f(x,y))` ou la commande `plotfunc(f(x,y),[x,y],nstep=N)`
- une surface paramétrée avec la commande `plotparam`
- un polyèdre, en particulier les polyèdres réguliers (solides de Platon) correspondent à une commande `tetrahedron`, `cube`, `octahedron`, `dodecahedron`, `icosahedron`
- une droite, un segment donnée par 2 points ou par 2 équations cartésiennes (droite uniquement).
- une courbe gauche paramétrée, par exemple plotparam([t,cos(t),sin(t)])

Depuis le moteur, appuyez sur sur shift EXE ou HOME (ou sur Toolbox sauf depuis l’application de géométrie 3d) pour modifier les réglages numériquement et pour voir la liste des raccourcis clavier, dont voici les plus importants :

- les touches du curseur permettent de changer de point de vue. Pendant le changement de point de vue, le calcul/affichage de la scène est effectué avec une précision plus faible et peut être interrompu en appuyant sur la touche Back.
- la touche 5 permet de revenir au point de vue initial
- la touche y x y^x recalcule et affiche la scène 3d en précision maximale, ce qui peut être assez long. Vous pouvez interrompre le calcul précis en appuyant sur la touche Back
- les touches `+` et `-` permettent de zoomer in ou out, les touches `*` et `/` de faire un autoscale ou une orthonormalisation
- les touches 7,9,1,3 permettent de se déplacer dans la scène 3d selon x x et y y.

Il est possible de créer des figures géométriques 2d ou 3d, et de faire des calculs de géométrie analytique. Ouvrez l’éditeur de programmes, effacez si nécessaire le patron `def ...` ou `efface ...`, puis entrez une instruction par ligne. Pour passer à la ligne, utilisez la touche EXE, pour afficher la construction utilisez la touche OK. Les principales commandes de géométrie se trouvent dans le menu Toolbox. Le menu rapide shift `+` affiche les commandes de géométrie les plus fréquentes, le menu shift `*` permet de donner facilement des couleurs aux objets géométriques créés.

## 18 Copyright, licences et remerciements

- OS Epsilon 15.5 de la Numworks, (c) 2021 Numworks. Sous licence Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International Public License
  Modifications par Damien Nicolet et Bernard Parisse, (c) 2019 et 2021 (projets Delta, Khi), sous la même licence. Modifications par l’équipe du projet Omega (c) 2021 sous la même licence.
- Giac et χ\chiCAS, noyau de calcul (c) B. Parisse et R. De Graeve, 2024. Les calculs en entiers sont effectués avec GMP, les flottants multipécision avec MPFR, l’arithmétique d’intervalle avec MPFI
- Certaines parties du code sont sous licence MIT:
  - MicroPython 1.12 (c) Damien P. George
  - QR code generator, project Nayuki
- Interface de χ\chiCAS adaptée par B. Parisse à partir de l’interface utilisateur du code source d’Eigenmath créée par Gabriel Maia et de l’interface utilisateur de Xcas.
  License d’utilisation de χ\chiCAS: GPL2. (voir le détail des conditions dans le fichier LICENSE.GPL2 ou sur la page GPL2 du site de la Free Software Foundation).
- Le code source de χ\chiCAS ainsi que des librairies GMP, MPFR, MPFI et de la version modifiée de l’OS Numworks, sont disponibles pour la version N0110 non verrouillée et pour les autres modèles, qui utilisent aussi un lanceur d’application externe version indépendante (ou version NWA)
- L’archive apps.tar pour N0110 non verrouillée contient d’autres applications, dont les licences sont (sauf erreur involontaire de ma part) :
  - Nofrendo sous licence LGPL2
  - Peanut-GB sous licence MIT
  - Hexedit sous licence BSD2
- Remerciements à Damien Nicolet pour le premier portage de giac sur Numworks N100 (au prix d’une modification matérielle), pour le portage de la newlib (librairie C/C++) sur N110 et la maintenance des sources au format git et la compatibilité avec les sources de Numworks. Sans lui, ce portage n’existerait pas.
  Remerciement à Jean-Baptiste Boric pour tests et conseils, à Maxime Friess pour son squelette d’application hello et à toute l’équipe d’Omega pour les améliorations qu’ils ont apporté à Epsilon.
  Remerciement à l’équipe de tiplanet, en particulier Xavier Andréani, Lionel Debroux et Adrien Bertrand, pour le forum de discussion et tout le travail de mise en valeur de χ\chicas (stockages d’archives, articles, concours).
  Remerciement à Yaya.Cout pour de longues discussions par email et du code pour accéder aux informations des firmwares verrouillés et la rédaction de ce Tutoriel (par fmOOmf et Yaya-Cout).
  Remerciements au (ou à la) mystérieux ScarlettSpell, créateur du site Nwagyu (aujourd’hui abandonné), dont le portage de KhiCAS en application externe Numworks m’a fortement incité à créer la nouvelle version de KhiCAS pour les Numworks récentes verrouillées.
- le tableau périodique des éléments est un portage de l’application de Maxime Friess avec son autorisation de diffusion sous licence GPL.

## 19 Développement en C/C++.

Cette section s’adresse aux utilisateurs avancés qui souhaitent programmer leur calcultrice en exploitant toute sa puissance, donc sans être limité par la faible quantité de mémoire disponible pour des scripts Python et la lenteur relative du langage interprété. Le système non modifié de la Numworks permet de le faire, mais il est difficile de le maitriser, au-delà de modifications simples du code existant (par exemple modifier la valeur de certains paramètres), il faut bien connaitre C++, la programmation orienté objet et se limiter à une librairie standard très spartiate. Cela limite à mon avis le nombre de développeurs et la vitesse de développement sur cette plateforme, encore plus si on est habitué à un environement de développement frugal, personnellement j’utilise `emacs` comme éditeur de texte et un terminal, les arborescences à plusieurs niveaux et les espaces de noms imbriqués d’Epsilon sont un cauchemar. Le temps nécessaire à la compilation d’Epsilon est d’ailleurs un indicateur de cette complexité.

Un autre problème est que modifier Epsilon nécessite d’utiliser la même licence de logiciel, on ne peut donc pas développer du logiciel libre.

Damien Nicolet et moi-même avons développé des modifications autour de Epsilon, qui permettent de lancer un firmware d’extensions à partir de Epsilon. C’est le projet Delta/Khi, qui permet d’utiliser la `newlib`, une implémentation complète de la libc et de la libstdc++, et offre un SDK en langage C et en C– (i.e. avec un paradigme de programmation impératif très proche du C donc beaucoup plus accessible, avec les avantages que procurent la librairie standard C++). Ainsi ajouter une application toute simple comme la suite de Syracuse nécessite une dizaine de lignes de code, programmer la fractale de Mandelbrot et les bassins d’attraction ou le jeu de mastermind font une bonne centaine de lignes (ces trois exemples se trouvent dans le fichier `kadd.cc` du source de `giac`) et l’interface du tableur de χ\chiCAS de l’ordre d’un millier de lignes.

Licences
L’utilisation du SDK de base de l’OS (19.4) vous impose de choisir une licence permettant d’utiliser les services de base d’un OS propriétaire, ce que toute licence de logiciel raisonnable devrait permettre, c’est le cas en particulier de la GPL. L’utilisation des autres fonctions du SDK impose une licence compatible avec la GPL.

### 19.1 Installation de l’environnement de développement.

Je décris l’installation sous Linux debian/ubuntu compatible depuis un terminal avec comme shell `bash`. On peut programmer sur d’autres OS, mais c’est plus facile sous Linux (en tout cas c’est plus facile pour moi d’expliquer comment faire!). Si vous travaillez habituellement sur Mac ou Windows, vous pouvez installer une machine virtuelle, par exemple avec Virtualbox et y mettre une distribution Linux debian-compatible, par exemple xubuntu.

On installe les packages nécessaires pour compiler giac et pour cross-compiler pour le processeur ARM :

    sudo apt-get install wget gdb gcc g++ libgmp-dev libmpfr-dev libmpfi-dev libpari-dev libgsl0-dev libxext-dev libpng-dev libjpeg-dev libreadline-dev libncurses5-dev mesa-common-dev libx11-dev libxt-dev libxft-dev libntl-dev libgl1-mesa-dev libgl-dev libao-dev hevea debhelper libfltk1.3-dev
    sudo apt-get install build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config gcc-arm-none-eabi binutils-arm-none-eabi dfu-util

#### 19.1.1 Epsilon 15.3.1/Khi (calculatrice), 12.3 (simulateur)

Simulateur Delta
Pour récupérar les sources du simulateur, faire

    wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/delta_simu.tar.bz2
    tar xvfj delta_simu.tar.bz2

Pour compiler le simulateur, vous pouvez lancer le script `delta/mksimu` ou vous pouvez exécuter les instructions suivantes

    cd delta/ext/giac-1.6.0/src
    ln -sf config.h.numworks.gmp config.h
    make -f Makefile.numworks.simulator
    /bin/cp simu/libgiac.a ../../simulator/lib
    cd ../../..
    /bin/rm output/simulator/debug/epsilon.elf
    make V=1 DEBUG=1 PLATFORM=simulator
    ln -sf output/simulator/debug/epsilon.elf simu

Essayez mantenant de taper `./simu` puis de lancer Khicas sur le simulateur en tapant `\` ou `$` selon le clavier (cette touche permet de simuler l’appui sur la touche HOME).

Attention, le support de MicroPython et de l’exécution en mode pas à pas n’est pas compatible, à cause du code assembleur de certaines fonctions situées dans les fichiers `delta/python/src/py/nlr*`. En conséquence si vous sélectionnez MicroPython pour évaluer dans KhiCAS, le simulateur plantera dès la première évaluation. Pour contourner ce problème, il faut compiler ces fichiers `nlr*` en mode release puis copier les fichiers objets obtenus dans le répertoire `debug` d’Epsilon/Delta. Pour faire cela, vous pouvez lancer le script `delta/mksimu`, puis le script `delta/cpnlr`. La prochaine exécution de `delta/mksimu` devrait alors donner un exécutable `simu` qui permet d’activer simultanément l’évaluation MicroPython et la mise au point.

Version du source calculatrice avec le multi-boot Khi : faites

    wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/khi2.tgz
    tar xvfz khi2.tgz
    wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/khi18.tgz
    tar xvfz khi18.tgz
    wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/khiext.tgz
    tar xvfz khiext.tgz

khi2 est pour le slot 1, khi18 pour le slot 2 (et contient le bootloader avec slot 2 en 0x90180000 et slot 3 en 0x90400000).

Il y a donc quatre arborescences distinctes, trois pour la calculatrice (`khi18`, `khi2` et `khiext`), une (`delta`) pour avoir un environnement de développement avec possibilité d’exécuter le code pas à pas. Cela pour deux raisons

- le simulateur a changé dans Epsilon 14, et la nouvelle version est inutilisable sur ma machine (affichage flou peu lisible), je travaille donc avec l’ancienne version du simulateur (qui par ailleurs utilise le même toolkit FLTK que Xcas ce qui me facilite le travail pour adapter le simulateur pour debugguer efficacement)
- le shell KhiCAS permet maintenant de choisir MicroPython comme évaluateur. Sur la calculatrice, KhiCAS et Epsilon sont complètement séparés donc chacun peut utiliser son propre MicroPython, mais sur le simulateur, il n’y a qu’une seule application, il faut donc utiliser le même source pour le MicroPython dans Epsilon et dans KhiCAS.

Le répertoire `khi2` contient l’arborescence pour compiler pour l’OS calculatrice, `khiext` pour les extensions. Les librairies nécessaires sont précompilées dans le répertoire `khiext/apps`.

    cd khi2
    make MODEL=bootloader epsilon.A.bin
    cd ../khiext
    make

Si vous voyez des messages tels que `... switch -mcpu=cortex-m7 conflicts...`, c’est que le cross-compilateur ARM de votre distribution Linux est trop ancien. Allez sur le site du ARM SDK, descendez jusqu’à faire apparaitre la version 9 (vous pouvez essayer une version plus récente si votre distribution Linux est récente), téléchargez pour Linux x64 et exécutez la commande
`cd && tar xvfj Downloads/gcc-arm-none-eabi-9-2020-q2-update-linux.tar.bz2`
puis ajoutez dans votre fichier `~/.bashrc` la ligne
`export PATH=~/gcc-arm-none-eabi-9-2020-q2-update/bin:$PATH`
sauvegardez, puis tapez les commandes
`source ~/.bashrc`
`cd chemin_vers_khi2`
`make`
`cd ../khiext`
`make`
`cd ../`
Vous pouvez aussi éditer les scripts `mkarm` des répertoires `khi2` et `khiext` et les exécuter à la place de `make`

Le fichier firmware de la version modifiée de Epsilon, `epsilon.A.bin` est dans le sous-répertoire `output/release/device/bootloader` de `khi2`, le fichier contenant les applications externes est `apps.tar` dans le répertoire `khiext`. Pour les flasher sur la calculatrice, faire reset+4 sur la calculatrice et

    dfu-util -i0 -a0 -s 0x90000000 -D khi2/output/release/device/bootloader/epsilon.A.bin -R
    dfu-util -i0 -a0 -D khiext/apps.tar -s 0x90200000:force

Le premier fichier est le firmware Epsilon avec les modifications des projet Delta/Omega/Khi. Ce projet fournit une interface pour programmer la calculatrice en C et permet d’exécuter du code contenu dans un fichier `apps.tar` qui est stocké dans le deuxième firmware.

Le répertoire `khi18` contient une version allégée de Epsilon pour fournir un firmware de lancement minimal, qui permet d’accéder à plus de mémoire RAM dans KhiCAS. La compilation est quasi-identique à celle dans `khi2`
`make MODEL=bootloader epsilon.B.bin`
ou éditer et exécuter le script `mkarm`.

KhiCAS
Si vous modifiez le source de giac, il faut recompiler la librairie `libgiac.a` et la copier dans `../../lib`, pour cela vous pouvez utiliser le script `mkarm` dans le répertoire `khiext`. N’oubliez pas de répercuter la modification dans le code source du simulateur.

#### 19.1.2 Epsilon 19.5 à 23, compiler KhiCAS pour N0110/N0115/N0120.

1. Sur un Mac, l’installation est un peu compliquée, car il faut construire un binaire pour les deux architectures Intel et ARM64, il y a donc plusieurs shells scripts spécifiques `mkmac, mkarm, mkx86` qui appellent 2 fichiers Makefile, un pour chaque architecture. Pour pouvoir compiler, il faut installer homebrew et les dépendances pour les deux architectures, sur un Mac récent arm64, cela se fait depuis un Terminal (tapez Terminal depuis le launchpad) avec les commandes ci-dessous (taper command-C et command-V pour faire du copier-coller)

       /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
       brew install numworks/tap/epsilon-sdk
       brew install libpng gmp mpfr mpfi
       arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
       arch -x86_64 /usr/local/bin/brew install libpng gmp mpfr mpfi

   Ensuite on tape

       git clone https://github.com/parisseb/epsilon
       cd epsilon
       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
       tar xfj ext.tar.bz2
       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwsimu.tgz
       tar xfz nwsimu.tgz
       ./mkmac
       mv output/release/simulator/macos/epsilon.app /Applications
       open /Applications/epsilon.app

2. Procédure de compilation sous Linux. Pour installer le simulateur avec KhiCAS, vérifiez que vous avez installé l’environnement de développement (gcc, sdl, etc.) pour votre PC. Si ce n’est pas le cas ouvrez un terminal, et copiez-collez les commandes ci-dessous (raccourci shift-Ctrl-V pour copier dans le terminal)

       sudo apt-get install wget build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config python3 python3-pip
       sudo apt-get gcc g++ libgmp-dev libmpfr-dev libmpfi-dev libpari-dev libgsl0-dev libxext-dev libpng-dev libjpeg-dev libreadline-dev libncurses5-dev mesa-common-dev libx11-dev libxt-dev libxft-dev libntl-dev libgl1-mesa-dev libgl-dev libao-dev hevea debhelper libecm1-dev libnauty2-dev libcliquer-dev libresample1-dev libxinerama-dev libsamplerate0-dev libfltk1.3-dev
       pip3 install lz4 pypng stringcase

   puis exécutez toujours depuis un terminal les commandes

       git clone https://github.com/parisseb/epsilon
       cd epsilon
       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
       tar xfj ext.tar.bz2
       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwsimu.tgz
       tar xfz nwsimu.tgz
       ./mk
       ln -sf output/release/simulator/linux/epsilon.bin simu
       ./simu

   Notez que la compilation par le script mk se fait en deux temps, d’abord la compilation normale d’Epsilon mais qui renvoie des erreurs car elle ne linke pas avec les librairies contenant Xcas et ses dépendances, puis une édition de liens avec ce qui est nécessaire, et qui elle ne doit pas renvoyer d’erreurs.
3. Sur un PC Windows
   Première méthode : on peut installer une distribution Linux en utilisant WSL ou dans une machine virtuelle avec un logiciel de virtualisation comme VirtualBox et suivre les indications Linux ci-dessus.
   Deuxième méthode : installer Msys2/mingw64. Ensuite ouvrir depuis le menu principal Windows, dans Msys2 un terminal mingw64. Dans le menu Options de la fenêtre, sélectionner Keys, puis cocher Ctrl-shift-letter shortcut, ceci vous permettra de coller avec Ctrl-shift-V. Copier-coller la commande ci-dessous et exécutez-là :

       pacman -S git wget mingw-w64-x86_64-gcc mingw-w64-x86_64-freetype mingw-w64-x86_64-pkg-config mingw-w64-x86_64-libusb make mingw-w64-x86_64-python3 mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libpng mingw-w64-x86_64-imagemagick mingw-w64-x86_64-librsvg mingw-w64-x86_64-inkscape mingw-w64-x86_64-python3-pip mingw-w64-x86_64-python-lz4 mingw-w64-x86_64-libpng gmp mpfr
       echo "export PATH=/mingw64/bin:$PATH" >> .bashrc
       pip3 install pypng stringcase

   Vérifiez que vous pouvez compiler Epsilon sans KhICAS

       git clone https://github.com/parisseb/epsilon
       cd epsilon
       make PLATFORM=simulator

   Si tout va bien, ajoutez les modifications permettant d’utiliser KhiCAS

       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
       tar xfj ext.tar.bz2
       wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwsimu.tgz
       tar xfz nwsimu.tgz

   Il faut ensuite
   - soit compiler et installer MPFI dans `/usr/lib`, on le désarchive `tar xfj /chemin/vers/mpfi-1.5.4.tar.bz2` on le configure avec `./configure --prefix=/usr` puis `make` puis `make install`,
   - soit enlever `-lmpfi` dans le script `mkwin`
   puis on exécute le script
   `./mkwin`
   (au lieu de `mk`).

Cf. la section 2 pour une rapide description de l’utilisation du simulateur.

Pour pouvoir utiliser le débugger, il faut échanger les `#` lignes 22 et 23 de `build/defaults.mak`. Attention, Python ne fonctionne pas avec la compilation en mode debug (`-g`), il faut compiler les fichiers `nlr*` sans ce flag (par exemple on compile tout en mode debug, puis on change `defaults.mak`, on fait `touch pypthon/port/mpconfigport.h`, et on compile).

Le code source pour la calculatrice physique est disponible dans les deux archives version lanceur indépendante (ou version lanceur NWA) et version de KhiCAS.

1. Normalement il n’y a pas de raison de modifier le lanceur d’application externe. Si nécessaire, il faut lire la section 20 si on utilise le lanceur indépendant ou sinon installer l’EADK de Numworks et compiler avec `make` et génère un fichier `output/khicas.nwa` qui s’installe depuis le site des applications externes de Numworks. Il est lié à l’EADK de Numworks, avec quelques ajouts pour les fonctions manquantes, afin de donner accès à la même API que l’application External des N0110 non verrouillées.

         extern "C" void (* const apiPointers[])(void) = {
           (void (*)(void)) extapp_millis,
           (void (*)(void)) extapp_msleep,
           (void (*)(void)) extapp_scanKeyboard,
           (void (*)(void)) extapp_pushRect,
           (void (*)(void)) extapp_pushRectUniform, // 4
           (void (*)(void)) extapp_pullRect,
           (void (*)(void)) extapp_drawTextLarge,
           (void (*)(void)) extapp_drawTextSmall,
           (void (*)(void)) extapp_waitForVBlank, // 8
           (void (*)(void)) extapp_clipboardStore,
           (void (*)(void)) extapp_clipboardText,
           (void (*)(void)) extapp_fileListWithExtension,
           (void (*)(void)) extapp_fileExists, // 12
           (void (*)(void)) extapp_fileErase,
           (void (*)(void)) extapp_fileRead,
           (void (*)(void)) extapp_fileWrite,
           (void (*)(void)) extapp_lockAlpha, // 16
           (void (*)(void)) extapp_resetKeyboard,
           (void (*)(void)) extapp_getKey,
           (void (*)(void)) extapp_restorebackup,
           (void (*)(void)) extapp_erasesector, // 20
           (void (*)(void)) extapp_writememory,
           (void (*)(void)) extapp_inexammode,
           (void (*)(void)) extapp_isalphaactive,
           (void (*)(void)) extapp_kbdstatus,  // 24
           (void (*)(void)) nullptr,
         };

   L’adresse de ce tableau est ensuite passé en paramètre à la fonction `extapp_start` de `khib/startup.c`
   `uint32_t _extapp_start(const uint32_t api_version, const void * api_base, void * heap, const uint32_t heap_size);`
   qui va copier ces paramètres, en particulier le tableau apiPointers qui sert à faire fonctionner le SDK C dans `khib/api.c`, initialiser la RAM statique, puis appeler `extapp_main` dans `khib/main.c`, qui appelle `ext_main` qui appelle `caseval("*")` ce qui est une convention de la librairie Giac/Xcas pour lancer le shell de KhiCAS.
2. KhiCAS peut se compiler en deux versions: une version allégée sans l’aide complète qui tient dans le 2ème slot Numworks (commençant à 0x90400000) ou en version complète qui génère alors deux fichiers binaires, un commençant en 0x90260000 et finissant en 0x903f0000 (les données read only), le deuxième commençant en 0x90400000, il se présente comme une archive tar à laquelle on peut ajouter des fichiers de données/scripts qui seront accessibles en lecture seule sur la calculatrice. On utilise l’une des commandes `./mkb` ou `./mkab`. On peut envoyer à la calculatrice une autre archive tar en 0x90200000 qui contient des données/scripts accessible en lecture/écriture depuis la calculatrice. Il y a donc 4 versions de fichiers de link (*.ld) selon le modèle de calculatrice cible et la version allégée ou non de KhiCAS: `n01?0.ld, n01?0ab.ld`. On compile par paires, en choisissant comme cible `khi110b.tar khi120b.tar` ou `khi110ab.tar khi120ab.tar` avec comme define en ligne de compilation de g++ `-DNUMWORKS_SLOTB` ou `-DNUMWORKS_SLOTAB`. La RAM statique est située en début de RAM pour les apps externes (236 octets sont utilisés actuellement), et le lanceur crée le tas de KhiCAS par un malloc la RAM disponible pour les apps externes moins 13K pour ne pas toucher la ram statique de KhiCAS
3. Le modèle actuel est donc le suivant:
   - RAM statique du lanceur (qui fait un peu plus de 200 octets) au début de la ram des apps externes
   - le tas du lanceur commence juste après, l’appel à malloc renvoie alors un pointeur vers une zone terminant avant la RAM statique de KhiCAS
   - RAM statique de KhiCAS: `0x2?034000` (12K, actuellement un peu plus de 256 octets sont encore disponibles)
   - flash tar file R/W: `0x90200000` (6*64K disponible)
   - flash `.rodata 0x90260000-0x903f0000`: fichier khia, pour la version longue de KhiCAS
   - flash `.text 0x90400000-0x907f0000` (dont environ 0.5M disponible pour tar file RO en version longue), fichier khi1?0ab.tar, ou fichier khi1?0b.tar (version courte).
4. Les commandes dfu pour flasher sans accès Internet

       dfu-util -i 0 -a 0 -s 0x90400000 -D khi120b.tar
           (version courte) ou (version longue)
       dfu-util -i 0 -a 0 -s 0x90400000 -D khi120ab.tar
       dfu-util -i 0 -a 0 -s 0x90260000 -D khia
           exemples de scripts:
       dfu-util -i 0 -a 0 -s 0x90200000 -D khi92

   Pour reflasher le secteur de lancement de l’application sans accès Internet, commencer par récupérer une fois pour toutes la version du secteur qui correspond à votre firmware/calculatrice depuis ici, sauvegardez-là sous un nom tel que sector puis

       #! /bin/bash
       dfu-util -i 0 -a 0 -s 0x90190000:0x10000:force -U sector

Remarques :

- KhiCAS peut se compiler en version courte en français uniquement en tapant `./mkfr`, cette version occupe environ 4M-90K. On peut alléger plus en supprimant le support de MicroPython (enlever `-DMICROPY_LIB` dans le Makefile).
- La compilation du lanceur pourrait sans doute se faire avec un fichier ld “universel” qui utiliserait un secteur fixe pour la flash (`0x90190000`) et le fonds de la pile (stack) pour la RAM statique (`0x2?380000`) vu que la pile a pas mal de place disponible, il faudrait aussi remplacer les appels à l’EADK par des appels SVC et ajouter le nécessaire (headers) pour être reconnu comme app externe Numworks.

      ion/src/device/userland/drivers/external_apps.cpp
      ion/include/ion/external_apps.h
        /* The ExternalApp start with its info layout as:
         * - 4 bytes: a magic code 0xBABECODE
         * - 4 bytes: the API level of the AppInfo layout
         * - 4 bytes: the address of the app name
         * - 4 bytes: the size of the compressed icon
         * - 4 bytes: the address of the compressed icon data
         * - 4 bytes: the address of the entry point
         * - 4 bytes: the size of the external app including the AppInfo header
         * - 4 bytes: the same magic code 0xBABECODE
         */
      apps/home/controller.cpp: affichage et lancement par switchToExternalApp
      apps/apps_container.cpp:void AppsContainer::switchToExternalApp(Ion::ExternalApps::App app)

### 19.2 Utilisation du débuggueur

Le simulateur peut se lancer avec le débuggueur en tapant `gdb ./simu` ou depuis votre éditeur de texte ou votre environnement de développement. Par exemple si vous utilisez `emacs`, tapez `Esc x gdb`, valider, mettre `simu` comme nom d’exécutable, valider. Voir par exemple ici un guide de prise en main d’utilisation du débuggueur avec emacs. Vous pouvez exécuter la commande
`cp delta/ext/giac-1.6.0/src/.gdbinit delta`
ou télécharger le fichier .gdbinit pour définir la macro `v` de `gdb` qui vous permettra de visualiser les variables de type `giac::gen` de manière plus parlante qu’avec la commande `p`.

Par exemple, si vous faites dans la console `gdb` la commande `b khicas_addins_menu` (breakpoint, i.e. point d’arrêt à cette fonction), puis `r` pour lancer le programme, il s’interrompra dans le menu d’affichage des applications tierces (shift-Ans), vous pouvez alors exécuter ligne après ligne avec la commande `n`, en visualisant le contenu des variables avec la commande `p` ou `v` pour des variables Xcas de type gen.

### 19.3 Intégration avec le shell Khicas

Pour ajouter une application au menu `shift-Ans` des applications ajoutées dans Khicas, il faut modifier la fonction `khicas_addins_menu()` dans `kadd.cc`. Incrémentez `smallmenu.numitems`, définissez `smallmenuitems[j].text` pour la première valeur de `j` disponible, puis dans la boucle `while(1) {...}`, ajoutez la définition de votre fonction ou un appel vers votre fonction avec `if (smallmenu.selection==j+1)`. Pour compiler et tester, cf. la fin de la section 19.1.1.

L’exemple de la suite de Syracuse vous montre comment faire entrer une valeur, afficher un graphique repéré, et entrer quelque chose en ligne de commande. L’exemple de la fractale de Mandelbrot montre comment afficher un graphique pixelisé pixel par pixel. L’exemple du jeu de Mastermind montre comment afficher un graphique pixelisé avec des formes plus complexes et interagir avec l’utilisateur lorsqu’il appuie sur une touche.

Conseils :

- Pour commencer à programmer votre propre version de KhiCAS, vous pouvez modifier un de ces exemples. Par exemple, demander des paramètres pour la fractale. Ou changer le nombre de couleurs disponibles ou le nombre d’essais dans le Mastermind. Puis ajouter une application de votre cru, par exemple faire un écran de saisie puis afficher une courbe.
- Si vous utilisez des données constantes, n’oubliez pas de mettre le modificateur `const` pour économiser la mémoire RAM.
- Pour travailler avec des chaines de caractères sans vous soucier des allocations mémoires, vous pouvez utiliser `string`, pour des tableaux de taille dynamique `vector<>` (voir par exemple le site cplusplus.com pour la description des fonctions de la librairie standard C++)
- Il faut être économe en mémoire, la disponibilité sur le tas est faible (un peu plus de 100 kilo-octets si aucune variable KhiCAS n’est stockée en mémoire, que le tas Micro-Python n’est pas actif et qu’il n’y a pas de tableur).

Les paragraphes qui suivent décrivent brièvement le SDK. Pour plus de détails, il faut ensuite se référer à `k_csdk.h` et `kdisplay.h/kdisplay.cc` pour l’interface et aux fichiers headers de `giac` pour toutes les fonctions de `giac`.

### 19.4 Fonctions de base de l’OS.

Les fonctions de bas niveau de Epsilon sont déclarées dans `k_csdk.h` et sont utilisables depuis un programme C et tout langage qui s’interface avec C (donc quasiment tout langage).

Si vous voulez créer une extension indépendante de KhiCAS, vous pouvez vous inspirer d’une des applications de `final/nw-external-apps`, définissez votre propre fonction `int main()` et linkez avec votre fichier objet à la place de `-lgiac`, dans ce cas vous pouvez choisir n’importe quelle licence de logiciel qui peut se lier avec une licence d’OS propriétaire.

Le clavier :

- `int getkey(int allow_suspend);`
  renvoie un code touche, `allow_suspend` est non nul si on autorise l’utilisateur à éteindre la calculatrice (attention dans ce cas à gérer l’affichage). Les touches sont définies comme suit, la 2ième ligne correspond aux touches Home (jaune) et Power (noire), avec 4 codes de touches inexistantes, les lignes à partir de la 6ième ont un code de touche inexistant sur le clavier.

      const short int translated_keys[]=
        {
         // non shifted
         KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
         KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
         KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_XTT,KEY_CTRL_VARS,KEY_CTRL_CATALOG,KEY_CTRL_DEL,
         KEY_CHAR_EXPN,KEY_CHAR_LN,KEY_CHAR_LOG,KEY_CHAR_IMGNRY,',',KEY_CHAR_POW,
         KEY_CHAR_SIN,KEY_CHAR_COS,KEY_CHAR_TAN,KEY_CHAR_PI,KEY_CHAR_ROOT,KEY_CHAR_SQUARE,
         '7','8','9','(',')',-1,
         '4','5','6','*','/',-1,
         '1','2','3','+','-',-1,
         '0','.',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
         // shifted
         KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
         KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
         KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_CUT,KEY_CTRL_CLIP,KEY_CTRL_PASTE,KEY_CTRL_AC,
         KEY_CHAR_LBRCKT,KEY_CHAR_RBRCKT,KEY_CHAR_LBRACE,KEY_CHAR_RBRACE,'_',KEY_CHAR_STORE,
         KEY_CHAR_ASIN,KEY_CHAR_ACOS,KEY_CHAR_ATAN,'=','<','>',
         KEY_CTRL_F7,KEY_CTRL_F8,KEY_CTRL_F9,KEY_CTRL_F13,KEY_CTRL_F14,-1,
         KEY_CTRL_F4,KEY_CTRL_F5,KEY_CTRL_F6,KEY_CTRL_INS,'%',-1,
         KEY_CTRL_F1,KEY_CTRL_F2,KEY_CTRL_F3,'\t','\\',-1,
         KEY_CTRL_F10,KEY_CTRL_F11,KEY_CTRL_F12,KEY_SHIFT_ANS,KEY_CTRL_EXE,-1,
         // alpha
         KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
         KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
         KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','"',KEY_CTRL_DEL,
         'a','b','c','d','e','f',
         'g','h','i','j','k','l',
         'm','n','o','p','q',-1,
         'r','s','t','u','v',-1,
         'w','x','y','z',' ',-1,
         '?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
         // alpha shifted
         KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
         KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
         KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','\'','%',
         'A','B','C','D','E','F',
         'G','H','I','J','K','L',
         'M','N','O','P','Q',-1,
         'R','S','T','U','V',-1,
         'W','X','Y','Z',' ',-1,
         '?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
        };

- `int getkey_raw(bool allow_suspend);`
  renvoie le scan code de Numworks, de 0 à 53 pour le clavier non shifté, ajouter 54 pour shifté, ajouter 108 pour alpha, 162 pour alpha shifté
- `void GetKey(int * key);`
  renvoie une touche au clavier, en utilisant le même prototype que le SDK pour calculatrices Casio.
- `bool os_set_angle_unit(int mode);` change l’unité d’angle (0 radians, 1 degrés)
- `int os_get_angle_unit();` renvoie l’unité d’angle
- `bool isalphaactive();`
  renvoie vrai si le mode alpha est actif.
- `bool alphawasactive();`
  renvoie vrai si le mode alpha était actif avant la dernière frappe de touche
- `void lock_alpha();`
  verrouille le mode alpha
- `bool back_key_pressed();`
  renvoie vrai en cas d’appui sur la touche Back. Utile pour permettre d’interrompre un programme. Ceci nécessite de tester souvent l’appui sur Back. Attention, pour éviter des problèmes lors de l’initialisation, les 400 premiers appels à cette fonction renvoient faux.
- `bool is_keydown(int key);`
- `void reset_kbd();`
  enlève les modes shift et alpha s’ils étaient actifs.

Les affichages.
Notez que y=0 y=0 correspond à la première ligne en-dessous de la ligne d’état (18 pixels de hauteur), on a donc 0≤y<222 0 \leq y&lt;222 et 0≤x<320 0\leq x &lt;320
Les couleurs utilisent un entier 16 bits au format RGB 565, on peut convertir depuis RGB888 par

    int rgb888to565(int c){
      int r=(c>>16)&0xff,g=(c>>8)&0xff,b=c&0xff;
      return (((r*32)/256)<<11) | (((g*64)/256)<<5) | (b*32/256);
    }

- `void statusline(int mode=0);`
  affiche la ligne d’état standard
- `void statuslinemsg(const char * msg);`
  affiche une chaine de caractères dans la ligne d’état
- `void os_fill_rect(int x,int y,int w,int h,int c);`
  remplit un rectangle avec une couleur de couleur `c` donné en rgb565,
- `void os_set_pixel(int x,int y,int c);`
  affiche un pixel de couleur `c` donné en rgb565
- `int os_get_pixel(int x,int y);`
  renvoie la couleur rgb565 d’un pixel.
- `int os_draw_string(int x,int y,int c,int bg,const char * s,bool fake=false);`
  `int os_draw_string_small(int x,int y,int c,int bg,const char * s,bool fake=false);`
  écrit une chaine de caractère avec la fonte de taille normale ou petite à partir du pixel x,y x,y en couleur `c` (rgb565 ), avec une couleur de fonds `bg`. Renvoie la position finale de x x. Si `fake` est `true`, il n’y a pas décriture, juste le calcul de la position finale de x x.
- `bool waitforvblank()`
  synchronisation écran, à appeler juste avant de faire des opérations de tracé pour éviter le scintillement.
- `void os_redraw();`
  signale à l’OS Numworks qu’il doit retracer l’écran en entier

Le système de fichiers.

- `bool file_exists(const char * filename);`
- `bool erase_file(const char * filename);`
- `const char * read_file(const char * filename);`
- `bool write_file(const char * filename,const char * s,size_t len=0);`
- `int os_filebrowser(const char ** filenames,int maxrecords,const char * extension);`
  Place dans `filenames` la liste des noms de fichiers d’extension `extension`

Gestion du temps

- `void os_wait_1ms(int ms);`
  attend `ms` millisecondes.
- `double millis();`
  renvoie un nombre de millisecondes depuis le dernier démarrage. Attention, l’horloge système ne tourne pas à la bonne vitesse lorsque la calculatrice est éteinte, il n’est donc pas possible de s’en servir pour afficher l’heure.

### 19.5 Commandes graphiques complémentaires

- `void xcas::draw_line(int x1, int y1, int x2, int y2, int color);`
  segment de droite
- `void xcas::draw_rectangle(int x, int y, int width, int height, int color);`
  rectangle rempli
- `void xcas::draw_polygon(std::vector< std::vector<int> > & v1,int color)`
  polygone de sommets dans la matrice de n n lignes `v`, une ligne par sommet, chaque ligne est un vecteur de 2 entiers (coordonnées en pixels).
- `void xcas::draw_filled_polygon(std::vector< std::vector<int> > &L,int xmin,int xmax,int ymin,int ymax,int color);`
  polygone de sommets dans la matrice de n n lignes `v`, une ligne par sommet, chaque ligne est un vecteur de 2 entiers (coordonnées en pixels). Le polygone rempli est tracé avec “clipping” dans le rectangle défini par `x1,y1,x2,y2`.
- `void xcas::draw_circle(int xc,int yc,int r,int color);`
  cercle de centre `(xc,yc)` et rayon `r`
- `void xcas::draw_filled_circle(int xc,int yc,int r,int color);`
  disque de centre `(xc,yc)` et rayon `r`
- `void xcas::draw_arc(int xc,int yc,int rx,int ry,int color,double theta1, double theta2);`
  arc d’ellipse.
- `void xcas::draw_filled_arc(int x,int y,int rx,int ry,int theta1_deg,int theta2_deg,int color,int xmin,int xmax,int ymin,int ymax,bool segment);`
  arc d’ellipse rempli, ou segment de cercle rempli avec clipping.

### 19.6 Interaction avec l’UI Khicas

Certaines fonctions utilisent un pointeur vers le contexte du moteur de calcul (qui contient les variables assignées, le mode radian/degré, etc.), de type `giac::context *`, et dont la valeur est en général stockée dans la variable `contextptr` dans les fonctions d’interface de Khicas de `kdisplay.cc` (on peut aussi passer un pointeur nul).

- `int inputline(const char * msg1,const char * msg2,std::string & s,bool numeric,int ypos=65,const giac::context *contextptr=0);` permet d’entrer une chaine de caractères en affichant le message `msg1` et en préremplissant la chaine à entrer avec `msg2`. Seuls les caractères utilisables pour un nombre sont acceptés si `numeric` est `true`. La position verticale de la ligne de commande est ajustable en changeant la valeur de `ypos`. Renvoie 0 si l’utilisateur a annulé en tapant sur Back.
- `bool inputdouble(const char * msg1,double & d,const giac::context *contextptr)`
  permet d’entrer un nombre flottant en affichant le message `msg1`, renvoir `false` si l’utilisateur a annulé en tapant sur Back. `int select_item(const char ** ptr,const char * title);`
  affiche un menu à choix et renvoie le choix de l’utilisateur.
- `int confirm(const char * msg1,const char * msg2,bool acexit=false,int y=40);`
  affiche une boite de dialogue de type OK/Annuler, avec 2 lignes d’affichage. Si `acexit` est `true`, l’appui sur Back renvoie -1. Sinon, l’appui sur Back renvoie l’entier `KEY_CTRL_F6`. L’appui sur `OK` ou `EXE` renvoie l’entier `KEY_CTRL_F1`.
- `int giac_filebrowser(char * filename,const char * extension,const char * title);`
  affiche un menu de sélection parmi les fichiers dont l’extension est `extension`. Si l’utilisateur sélectionne un fichier, renvoie 1 et met le nom de fichier dans `filename`, qui doit avoir une taille suffisante.
- `void displaygraph(const giac::gen & ge, const giac::context * contextptr);`
  affiche un `gen` de type graphique (si `ge.is_symb_of_sommet(at_pnt)`)
- `void displaylogo();`
  affiche la tortue logo
- `giac::gen eqw(const giac::gen & ge,bool editable,const giac::context * contextptr);`
  affiche une expression dans l’éditeur 2d.
- `void add(textArea *edptr,const std::string & s);`
  écrit la chaine C++ `s` vers le buffer texte pointé par `edptr` (dans `edptr->elements`)
- `int doTextArea(textArea* text,const giac::context * contextptr);`
  ouvre l’éditeur de texte, renvoie 0 si l’utilisateur quitte avec la touche Back, 1 si `text->allowEXE` est à `true` et si l’utilisateur appuie sur `EXE`, 2 si `text->allowF1` est à `true` et l’utilisateur appuie sur F1.
- `std::string merge_area(const std::vector<textElement> & v);`
  renvoie la chaine C++ correspondant à `v`, si `edptr` est un pointeur sur `textArea`, on prendra pour `v` `edptr->elements`.

L’internationalisation est gérée par la commande
`const char * gettext(const char *)`
Pour ajouter une chaine en plusieurs langues, par exemple Hello, mettez dans votre code `gettext("Hello")`, et ajoutez au fichier `numworks_translate.h`, dans l’ordre alphabétique une ligne du type
`{"Hello",0,0/* zt */,"Bonjour" /* fr */,"Guten Tag" /* de */,0 /* es */,0 /* nl */,0 /* pt */,0},`
Attention, l’utilisation du fichier `numworks_translate.h` ne peut se faire qu’avec du code GPL qui est linké avec KhiCAS (mais rien ne vous empêche d’utiliser `gettext` dans un programme compatible avec la GPL avec un autre fichier de traductions en repartant de zéro).

### 19.7 Interaction avec giac

Le type `giac::gen` permet de travailler avec tous les types de Xcas : entier, flottant, fraction, nom de variable, expression, fonction... On peut construire un gen avec les types de base C

    gen g(1.2),h(3);

ou avec l’interpréteur (avec une chaine de caractères), dans ce dernier cas il faut évaluer le gen avec un appel à `eval`, par exemple

    gen g("x^4-1",contextptr);
    g=eval(g,1,contextptr);

En général une fonction de Xcas a un équivalent C++ avec le même nom précédé par `_`, et deux arguments, un de type `giac::gen` et un deuxième qui est un pointeur sur le contexte d’évaluation. Lorsqu’une commande Xcas prend plusieurs arguments, il faut les grouper en un gen de type vecteur, en utilisant une commande `makesequence`. Par exemple `_randNorm(makesequence(0.0,2.0),contextptr)` équivaut à la commande `randNorm(0.0,2.0)` de Xcas. Notez que les fonctions usuelles n’ont pas de préfixe `_`.

### 19.8 Sauvegardes et restauration (N0110 non verrouillée)

Il est possible de sauvegarder l’ensemble des données de votre calculatrice en local sur votre PC, i.e. sans connexion Internet. Xcas le permet depuis le menu Numworks. On peut aussi appeler `dfu-util` directement, cf. la section 2. Il faut ensuite récupérer les informations sur la calculatrice avec la commande
`dfu-util -i0 -a0 -s 0x080001c4:0x20 -U platform.info`
ce qui place dans le fichier binaire `platform.info` (de taille 32 octets) des informations sur la Numworks (cf. `ion/src/shared/platform_info.cpp`)

- offset 0 0xDEC00DF0
- offset 4 la version (8 caractères)
- offset 12 le numéro de patch (8 caractères)
- offset 20 (0x14) l’adresse A de l’espace de stockage de la Numworks
- offset 24 (0x18) la taille T de l’espace de stockage
- offset 28 (0x1C) 0xDEC00DF0

Ensuite en remplaçant A et T par leur valeur dans la commande
`dfu-util -i0 -a0 -s A:T:force -U numworks.storage`
vous pouvez archiver l’ensemble des données de votre calculatrice dans le fichier `numworks.storage`. A devrait valoir `0x20000b60`, et T `0x8014` (dont 4 octets valant `0xEE0BDDBA` puis 32K de data puis à nouveau les 4 octets du début, et 3 pointeurs) ce qui donne la commande
`rm -f numworks.storage &&dfu-util -i0 -a0 -s 0x20000b60:0x8014:force -U numworks.storage`

Vous pourrez ensuite restaurer l’archive par la commande
`dfu-util -i0 -a0 -s A:T:force -D numworks.storage`
avec Khi
`dfu-util -i0 -a0 -s 0x20000b60:0x8014:force -D numworks.storage`

## 20 Développement indépendant sur Numworks verrouillées.

Lors du verrouillage des Numworks en 2021, Numworks en a discuté avec la communauté Numworks, principalement avec les développeurs du firmware tiers Omega, mais en me laissant délibérement à l’écart (j’ai appris le verrouillage sur tiplanet lors de la sortie de la version 16 beta d’Epsilon). Ces discussions n’ont probablement pas servi à grand chose, Numworks semble n’avoir tenu aucun compte des suggestions faites, si on lit les messages du sujet sur tiplanet.

L’environnement de développement sur Numworks est aujourd’hui hostile, comme on a pu le voir à la section 2.1.2. Il y a 8M de flash externe découpé en 2 slots de 4M chacun, un des slots doit commencer par un firmware officiel Numworks, il n’y a pas de système de fichiers, il y a peu de RAM disponible : sur 256K, 36K sont réservés pour le noyau et la pile, 42K pour le scriptstore, il ne reste qu’un peu plus de 128K pour une application externe. La N0120 a même des zones de RAM supplémentaires actuellement inutilisées, mais qui sont rendues inaccessibles par le kernel (à date du 3/11/2025). Ce dernier point semble bien être une conséquence de la politique commerciale de Numworks, il s’agissait de vendre au même moment et au même prix que les N0120 des N0110 ou N0115 moins puissantes sans que cela ne se voit pour ce qui concerne la RAM disponible. On verra si cela évolue prochainement.

On peut soit développer un firmware tiers qui sera placé dans l’autre slot, soit développer une application externe dans le même slot que le firmware officiel.

- Dans le premier cas, un seul firmware tiers est installable, il doit être réactivé par un PC à chaque reset/crash, et s’il est basé sur Epsilon, il est uniquement redistribuable au format source sur github alors qu’avant le verrouillage, on pouvait redistribuer les firmwares tiers au format binaire, beaucoup plus simple à installer pour un utilisateur normal.
  Ces limitations font qu’aucun firmware tiers tel que Upsilon ou Omega n’a jamais été développé, cette méthode ne sert en fait qu’à tester des variations mineures de versions d’Epsilon, pour les personnes qui veulent proposer un PR.
  On pourrait s’en servir pour installer plusieurs applications externes sur le firmware tiers en désactivant le sabotage du 1er octet de chaque application externe, on peut alors réactiver le firmware tiers et toutes ses applications externes. Mais cela diminue considérablement la taille mémoire contigüe libre, ce qui compliquerait inutilement la compilation de KhiCAS.
- Dans le deuxième cas, plusieurs applications externes peuvent être installées simultanément, mais l’interaction avec le firmware qui lance l’application externe dépend de la version du firmware, si l’application externe est linkée normalement, elle ne pourra s’exécuter qu’avec une version précise de firmware.
  Numworks a alors imaginé une méthode d’édition de liens à l’installation sur la calculatrice cible, qui permet de s’affranchir de cette contrainte, mais cela rend le développeur complètement dépendant de Numworks, il faut passer par le site de Numworks pour installer une application externe. Si ce site est inaccessible (par exemple pas de connection Internet), ou si Numworks décide brusquement de supprimer le support des applications externes, tout le travail de développement est perdu, même si on ne fait pas de mise à jour de la calculatrice, y compris pour le développeur lui-même!

Dans cette section, on va voir qu’il est possible de développer, des applications externes sans dépendre du site web de Numworks. Il suffit en effet de créer un fichier d’édition de lien `ram.ld` (inclus par `app.ld`) adapté à la calculatrice cible et au firmware qui y tourne. La compilation et les tests sont alors plus rapides et peuvent se faire sans être connecté à Internet. L’indépendance a toutefois un prix : il faudra une version de l’application externe pour chaque version de firmware ciblée (c’est ce que je fais pour le lanceur de KhiCAS pour une sélection de versions de firmware) ou il faudra la recompiler pour la calculatrice cible.

Les informations nécessaires pour constituer le fichier `ram.ld` sont contenues dans le header du userland :

- offset 0x14 et 0x18 début et fin des apps externes
- offset 0x1c et 0x20 début et fin de la RAM utilisable
- à partir de l’offset 0x20, chercher les 4 octets 0xfe 0xed 0xc0 0xde, par exemple offset 0x2c, ajouter 12, par exemple offset 0x38, on trouve l’adresse du “trampoline” du userland, qui contient pour l’instant une seule adresse de fonction, celle de `eadk_display_draw_string`.

Exemple avec le header du userland 23.2.3 (dernière version dont le source est public au 2/11/2025) pour N0120:

    00020000   FE ED C0 DE  32 33 2E 32  2E 33 00 00  9C 77 00 24  ....23.2.3...w.$
    00020010   00 A8 00 00  00 00 19 90  00 00 3F 90  40 2A 01 24  ..........?.@*.$
    00020020   00 70 03 24  00 00 3F 90  00 04 3F 90  FE ED C0 DE  .p.$..?...?.....
    00020030   F8 EF 03 24  61 6D 08 90  55 96 10 90  00 00 00 00  ...$am..U.......

et le fichier `ram.ld` associé :

    MEMORY {
      FLASH (rx) : ORIGIN = 0x90190000, LENGTH = 0x260000
      RAM (rwx) : ORIGIN = 0x24012a40, LENGTH = 0x245c0
    }

    _userland_trampoline_address = 0x90109655;

Pour la version 22.2.1, on obtient un début de RAM en 0x240129a8, le fichier pour la 23.2.3 conviendrait donc pour la 22.2.1, il est très légèrement sous-optimal d’une centaine d’octets. On peut donc mutualiser les lanceurs, sous réserve que le 1er secteur des applications flash soit identique et qu’on n’utilise pas la variable `_userland_trampoline_address`, mais qu’on code la recherche, ce qui est fait dans le fichier `eadk_userland.c`.

Voici une liste de secteurs, adresse de début de RAM et longueurs :

- N0110/115 :
  - ε\varepsilon19: secteur 15, ORIGIN = 0x20014a9c, LENGTH = 0x22564
  - ε\varepsilon20: secteur 17, ORIGIN = 0x200148b4, LENGTH = 0x2274c
  - ε\varepsilon21 : secteur 18, ORIGIN = 0x20014798, LENGTH = 0x22868
  - ε\varepsilon22 : secteur 18, ORIGIN = 0x200129a8, LENGTH = 0x24658
  - ε\varepsilon23: secteur 19, ORIGIN = 0x20012a40, LENGTH = 0x245c0
  - ε\varepsilon24.5 à 24.8: secteur 17, ORIGIN = 0x20012804, LENGTH = 0x247fc (attention la 24.1 laisse beaucoup moins de place :LENGTH = 0x1fbc8)
- N0120 :
  - ε\varepsilon20: secteur 18, ORIGIN = 0x2401490c, LENGTH = 0x226f4
  - ε\varepsilon21: secteur 19, ORIGIN = 0x24014798, LENGTH = 0x22868
  - ε\varepsilon22: secteur 19, ORIGIN = 0x240129a8, LENGTH = 0x24658
  - ε\varepsilon23: secteur 19, ORIGIN = 0x20012a40, LENGTH = 0x245c0
  - ε\varepsilon24: secteur 17, ORIGIN = 0x24012804, LENGTH = 0x247fc (attention la 24.1 laisse beaucoup moins de place :LENGTH = 0x1fbc8)

Si on n’a pas besoin de toute la mémoire disponible, on peut utiliser une configuration mémoire RAM `ram120.ld` quasi-universelle (jusqu’à présent), et juste changer l’origine :

    MEMORY {
      FLASH (rx) : ORIGIN = 0x90180000, LENGTH = 0x270000
      RAM (rwx) : ORIGIN = 0x2401490c, LENGTH = 0x226f4
    }

et pour les n0110/n0115

    MEMORY {
      FLASH (rx) : ORIGIN = 0x90150000, LENGTH = 0x2a0000
      RAM (rwx) : ORIGIN = 0x20014a9c, LENGTH = 0x22564
    }

On observe au passage que la version 24 économise 2 secteurs de flash par rapport à la version 23, le moteur de calcul a été recodé pour tenir dans la ROM de la Numworks scientifique collège, en gagnant environ 140K de code.

Et pour finir trois exemples :

- L’archive simple contient un exemple d’application externe très simple et deux programmes pour constituer ce fichier `ram.ld`, le premier `addr.cc` s’utilise en connectant la calculatrice cible, le second `binaddr.cc` s’utilise avec une image binaire du firmware en slot A. Utilisez l’un des deux, puis faites `make clean` et `make` pour compiler puis `./sendapp` pour envoyer l’application sur la calculatrice avec dfu-utils.
- L’application externe run permet d’exécuter un firmware tiers dans le même slot que le firmware officiel Numworks, ce qui laisse plus de place contigüe pour un gros programme comme KhiCAS (qui occupe tout le slot B)
- l’application externe lanceur de KhiCAS illustre la possibilité d’utiliser une API compatible avec les applications externes des Numworks déverrouillées. Cette application donne le controle au point d’entrée lu à l’adresse 0x90400200 (début du slot B après le tar header), en passant en paramètres le même tableau de pointeurs, ainsi que l’adresse de début pour le tas mémoire et la taille du tas. Elle montre également la possibilité d’authentifier le slot B en testant une signature RSA 2048 bits, que l’on peut inscrire en filigrane dans le tar header au début du slot B.

## A Opinions

### A.1 Quelques mots sur les calculatrices.

La calculatrice est devenue incontournable dans les enseignements de mathématique au lycée, avec trop souvent une utilisation presse-boutons, alors qu’elle est sous-utilisée dans les études scientifiques, partiellement en réaction. De ce fait, les constructeurs mettent l’accent sur le développement de fonctionnalités pour le lycée, en faisant apprendre des séquences de touches à effectuer pour certaines taches bien précises, plutot qu’une méthode plus générale, un peu moins conviviale pour ces taches, mais plus adaptable. C’est par exemple ce qu’on retrouve dans la philosophie des applications de Numworks, si on veut effectuer une tache pour laquelle elles sont prévues, c’est facile et en général intuitif, mais il devient vite difficile de faire quelque chose qui n’est pas prévu (par exemple simuler des données avec un programme et les utiliser dans une des applis de statistiques, représenter graphiquement une fonction définie par un programme, utiliser dans Calculs ou dans Python certaines fonctions des applications probabilité ou statistiques, ...).

Je pense que ce n’est pas adapté pour les élèves qui doivent pouvoir expérimenter des choses que le constructeur n’a pas implémenté parce que cela ne correspond pas aux programmes (c’est particulièrement vrai pour les bons élèves si on ne veut pas qu’ils s’ennuient!). À court terme, c’est plus facile pour enseigner d’utiliser une application comme Fonctions, mais à long terme, c’est plus formateur pour de futurs étudiants (au moins en sciences et en maths) d’apprendre à utiliser un shell puissant en y tapant des commandes (N.B. : on peut d’ailleurs sérieusement se demander à quoi cela rime d’apprendre un peu de programmation en Python sans avoir au préalable un minimum de maitrise dans l’écriture d’une ligne de commande simple). Bien sur, les deux approches doivent se compléter. Or les élèves sont souvent tributaires du choix de modèle demandé par leur enseignant de seconde, ils n’ont pas encore de recul pour choisir un autre modèle que celui demandé par l’enseignant et comprendre toutes les conséquences du choix, en particulier si la calculatrice ne permet pas d’y installer ou/et utiliser un shell puissant. Il est donc important de pouvoir proposer pour le plus possible de modèles populaires une alternative à la calculatrice officielle, permettant aussi aux bons élèves d’exploiter toutes les possibilités de leur calculatrice et de favoriser leur curiosité. Pour moi, une calculatrice qui fait aimer les maths, c’est une calculatrice qui va donner envie à un élève d’expérimenter sur sa calculatrice des questions en prolongement du programme scolaire. À coté d’applications intuitives, il faut un espace de liberté qui ne soit pas limité aux quelques fonctionnalités d’une interface d’application. C’est le sens de χ\chiCAS, pour Numworks ici, disponible également pour d’autres modèles (Casio Graph 90/35eii, TI Nspire).

Il faut aussi que les enseignants qui conseillent un modèle de calculatrices en seconde prennent bien conscience que le choix ne se limite pas à une utilisation pendant une année ou même pendant les 3 années de lycée mais impacte toutes les années d’études, en particulier pour les élèves bons en sciences et en maths. La Numworks non verrouillée réalise d’une certaine manière un bon équilibre entre la facilité d’utilisation pour tous en seconde (Epsilon 15 ici) et les possibilités ensuite pour les bons élèves qui auront des maths ensuite (χ\chiCAS ici). Mais le passage à une version plus récente d’Espilon casse cet équilibre, un enseignant soucieux de ses bons élèves devrait les mettre en garde pour qu’ils ne mettent pas à jour!

### A.2 Mes relations compliquées avec Numworks.

C’est en mai 2016 que j’ai entendu parler pour la première fois de Numworks. Romain Goyet, qui démarrait son projet, m’a contacté pour me sonder un peu dans le domaine des calculatrices. La recommandation principale que je lui avais faite était la suivante : il ne faut pas chercher à faire des économies sur la mémoire, car on le regrette. Ensuite, je n’ai plus eu aucune nouvelle avant d’apprendre par tiplanet le lancement de la calculatrice en aout 2017, en particulier je n’ai pas participé au programme de beta-tests. Cette attitude a sans doute contribué à ce que j’exprime sans retenue mon scepticisme vis-à-vis de la Numworks dans plusieurs posts sur tiplanet : à propos de la mémoire, des fonctionnalités et de la communication à mon avis trompeuse sur le caractère open-source. Ce qui m’a sans doute valu d’être considéré comme un anti-Numworks par Goyet, alors que l’accueil du reste de la communauté était à l’époque très (trop?) enthousiaste. Mais je ne regrette pas du tout d’avoir exprimé publiquement mes réserves, si tout le monde était resté sans rien dire, il n’y aurait pas eu de changement dans la licence d’Epsilon, et les firmwares Omega, Upsilon, Delta (et Khi leur héritier direct) n’auraient pas pu exister.

Je ne sais pas si ma recommandation de 2016 sur la mémoire a eu un quelconque effet, peut-être que sans elle, les premières Numworks auraient encore eu moins de mémoire. En tout cas, la mémoire disponible était et reste encore vraiment très limitée, même s’il y a eu un progrès pour le stockage en flash avec le passage de 1M à 8M en 2019, probablement parce que Numworks s’est rendu compte que la taille des firmwares successifs atteindrait plus vite que prévu la taille de 1M. Il me semble qu’il y aurait des marges de progression peu onéreuses sur la RAM. Et je continue à penser que Numworks a perdu et perd toujours beaucoup de temps de développement avec la gestion de la très faible quantité de RAM (256K).

Les relations avec Numworks se sont ensuite améliorées en 2018, lors d’une rencontre à l’APMEP de Bordeaux, où je leur avais montré mon module de tortue logo sur les calculatrices Casio (J.B. Boric avait aussi implementé un module turtle pour la Numworks). Numworks comprend alors l’intérêt d’avoir un module officiellement supporté pour faire la transition avec le collège. À cette occasion, ils me donnent une N0100. J’apprécie le geste, même si je n’en ai pas l’usage pour y porter Giac (à cette époque, Damien Nicolet, alias zardam, avait réussi à porter Giac sur sa Numworks N0100 mais en modifiant le hardware ce dont je suis personnellement incapable). En mai 2019, Numworks me contacte pour me proposer de signer un accord de confidentialité, ce que j’interprète comme le signe qu’un nouveau modèle allait sortir permettant de porter Giac (sans modification hardware). Mais certaines clauses de l’accord ne me convenaient pas : je voulais m’assurer que rien n’entrave le développement de Giac/Xcas. Numworks refusant de modifier les clauses en question, je ne signe pas l’accord de confidentialité. Le nouveau modèle de Numworks (N0110) est annoncé deux mois plus tard, et j’en achète un. À la rentrée 2019, avec l’aide de J.B. Boric et Damien Nicolet, j’arrive à faire tourner sur ma N0110 un prototype logiciel qui permet d’utilise le moteur de calcul de Giac dans l’appli Calculs. Se pose alors la question de l’incompatibilité des licences entre Giac sous licence GPL et Epsilon, qui n’est pas un logiciel libre. Mais Numworks est inflexible sur la licence d’Epsilon. Ce qui conduit Damien Nicolet à développer un système permettant de compiler deux firmwares à installer séparément, l’un dérivé d’Epsilon (sous sa licence) et l’autre sous licence GPL (le deuxième sera remplacé plus tard par la gestion des applications externes dans Delta/Omega/Upsilon/Khi). En novembre 2019, nous informons Numworks de ce succès et leur demandons s’ils voient encore des problèmes juridiques. Fin 2019, n’ayant pas reçu de réponse, nous publions alors la première version de Delta/KhiCAS. Je n’ai pas de statistiques du nombre de personnes qui ont installé KhiCAS sur leur Numworks, j’ai par contre le nombre de personnes qui ont consulté la documentation, pour l’année 2020/21 cela dépasse un peu les 5000 et pour 2021/22 on dépasse les 9000, ce qui n’est pas négligeable du tout comparé aux chiffres de ventes estimés. Pour l’année 2023, on est encore un peu au-dessus de 8000, alors qu’il devient de plus en plus difficile de se procurer une Numworks non verrouillée.

En 2017/2018, les ventes de calculatrices Numworks en France ont du être confidentielles : avec une sortie fin aout 2017, ce ne sont pas des scolaires qui ont acheté, uniquement des passionés et des profs (avec le soutien de L. Chéno de l’inspection générale). En 2018/19, quelques profs enthousiastes (en particulier par le module de programmation en Python) ont commencé à recommander la Numworks à leurs élèves, mais les ventes étaient certainement encore faibles (j’estime à quelques milliers d’unités). Le succès en France s’est dessiné à la rentrée 2019 (j’estime qu’ils ont vendu 10 à 15 000 calculatrices en 2019/20) et encore plus en 2020 (probablement le double). À la rentrée 2022, j’estime que Numworks possède environ la moitié du marché des calculatrices couleurs avec de l’ordre de 40 000 calculatrices vendues par an. Je pense que c’est en voyant les ventes décoller à la rentrée 2019, que Numworks a décidé de tourner le dos au calcul formel sur leurs calculatrices, par crainte de ne pas pouvoir se développer à l’étranger, alors qu’en mai 2019, ils envisagaient encore la chose en se disant que cela pouvait aider à booster les ventes en France (sinon ils ne m’auraient pas proposé de signer un accord de confidentialité). Ils ont dû être très désagréablement surpris de la solution technique réalisée par zardam (et qui est sans équivalent de leur coté à ce jour!), alors qu’ils espéraient sans doute pouvoir bloquer la diffusion par des questions de licence. La suite n’a fait que confirmer cette tendance : ils ont commencé par cacher les (maigres) capacités de calcul symbolique d’Epsilon (on peut les retrouver dans Omega et Khi), puis décidé de verrouiller leurs calculatrices et modifié la licence d’Epsilon.

En 2023, les chiffres de vente d’amazon sont disponibles, on peut estimer les ventes (probablement mondiales) à 30 000 unités via ce distributeur. Pas d’estimations aussi précise sur les autres canaux de vente, on sait juste qu’à la rentrée 2023 la TI83 et la Numworks se disputaient la 1ère place à la fnac. Probablement un peu plus de 80 000 unités vendues dans le monde en 2023, dont au moins 4/5èmes en France, et des parts de marché qui continuent à progresser en France, précipitant l’annonce par Casio de nouveaux modèles de calculatrices graphiques pour la rentrée 2024 en France.

L’objectif de Numworks, c’est maintenant le marché américain. On verra si ils réussissent aussi bien qu’en France, où les conditions étaient bien plus favorables : maintenant ils ne peuvent plus communiquer sur l’open-source, le chauvinisme ne va pas dans le bon sens (vis-à-vis de Texas Instruments en particulier) et il n’y a probablement pas d’équivalent à un inspecteur général qui vous soutient parce que vous allez dans le sens de sa réforme Python. Pour le moment, le décollage aux US semble plus lent qu’anticipé par Numworks. C’est un pari pour Numworks, sans compter que TI est sans doute vacciné par ce qui s’est passé en France. Le choix fait par Numworks risque d’être perdant-perdant : malgré sa faible mémoire, la N0110 est (je devrais plutôt dire était) une calculatrice avec un excellent rapport qualité-prix pour installer Khicas (avec Xcas en parallèle), et coté Numworks, KhiCAS ouvrait le marché français des BTS et prépas scientifiques, et aux USA des tests autorisant le calcul formel.

En conclusion, c’est quand même dommage de ne pas chercher une solution qui permette aux élèves français équipés de Numworks de ne pas être défavorisés par rapport à ceux équipés de modèles CAS haut de gamme (TI Nspire CX2, HP Prime ou Casio Classpad), il y a pas mal de possibilités techniques (par exemple avoir deux modèles de calculatrices, avoir plusieurs modes examens, signer KhiCAS pour la France...). Il est d’ailleurs assez symptomatique que Numworks ait discuté du verrouillage pendant plusieurs mois avec beaucoup de monde dans la communauté ... mais jamais avec moi!

### A.3 Développer pour Epsilon/Omega/Upsilon vs Giac/KhiCAS : une querelle ancien-moderne?

Epsilon (et ses dérivés) est écrit en C++ en utilisant des fonctionnalités avancées du langage, il est difficile de naviguer dans le code source avec des éditeurs comme emacs (il y a beaucoup de petits fichiers sources avec des arborescences profondes et des espaces de noms imbriqués) et pour compiler il faut une version récente de gcc (9). Giac est aussi écrit en C++ mais en fait c’est un style très proche du C, impératif, avec des noms de fonction courts, peu de fichiers sources dans un même répertoire et on peut compiler avec des versions anciennes de gcc (4).

Epsilon n’utilise pas les librairies standards (libc, libstdc++) contrairement à Giac. Il n’y a pratiquement pas de mémoire sur le tas pour allouer des structures de données avec malloc ou new. Je pense que ce choix, lié aux faibles capacités mémoire de la calculatrice, a fait et fait perdre pas mal de temps de développement, d’abord parce que dans les premières versions Epsilon utilisait le tas, ils a fallu réécrire ensuite autrement, ensuite parce qu’ils doivent rajouter manuellement des algorithmes standard des librairies standards lorsqu’ils en ont besoin, enfin parce que l’architecture du système est beaucoup plus complexe.

La complexité est parfois nécessaire, mais si on se laisse fasciner, on risque d’oublier l’objectif ou/et coder de manière inefficace ou renoncer devant des objectifs plus difficiles. Et surtout la marche est haute pour commencer à développer : ici il faut s’approprier une architecture complexe et compiler un firmware complet, voir par exemple un tutoriel ici. Très bien fait, mais on est déjà bien fatigué avant d’avoir pu écrire un algorithme un peu original! Pas étonnant finalement qu’il n’y ait que deux applications Omega (RPN et Atomic) qui ne sont pas de Numworks (trois si on y ajoute External qui permet d’utiliser KhiCAS, un éditeur hexa, des jeux), alors que les sources de l’OS sont disponibles depuis 5 ans. Upsilon, un fork du projet Omega, est de mon point de vue un peu meilleur sur cet aspect de développement original, avec une application liseuse de fichiers texte (support partiel de commandes LaTeX) et un support de MicroPython plus récent que celui de Numworks et avec des modules scientifiques complémentaires. On peut aussi observer que ni Epsilon ni ses forks ne proposent de tableur, plus de 5 ans après la sortie de la première version d’Epsilon. (alors qu’il existait plusieurs tableurs développés par la communauté pour les HP48 il y a 25 ans, bien sur, avec une interface plus rudimentaire, mais fonctionnels). Il y a des centaines de programmes disponibles pour les calculatrices concurrentes avec des communautés assez actives, on ne peut pas dire que c’est le cas pour la Numworks, l’activité récente de Omega et Upsilon consiste essentiellement à rester compatible avec les protections des dernières versions d’Epsilon.

On verra s’il y a d’autres développeurs qui se lancent pour créer des applications externes avec ce que propose Epsilon 16 ou supérieur, mais le squelette d’application exemple est aussi relativement complexe, cf. l’exemple, avec 21 fichiers sources pour 773 lignes de code. On peut comparer avec les exemples d’applications additionnelles dans KhiCAS de complexité croissante, allant de la suite de Syracuse (25 lignes) à la fractale de Mandelbrot (29 lignes), au mastermind (132 lignes) ou au tableau périodique (environ 400 lignes) jusqu’au tableur (un peu plus de 1000 lignes), le tout dans un ou deux fichiers source (kadd.cc, kdisplay.cc pour le tableau périodique).

Comme je l’écrivais en titre, c’est peut-être une querelle ancien-moderne. Mais peut-être aussi une question de culture. Le matheux que je suis voit vraiment l’informatique comme un outil pour calculer, et écrire des algorithmes, en général en lien avec les maths. Écrire du code d’interface ne m’intéresse pas, je le fais par obligation. L’inverse est certainement vrai pour beaucoup de passionés d’informatique, en tout cas c’est mon impression quand j’enseigne les maths en parcours informatique ou quand j’échange sur les forums. Lorsque Numworks dit que sa calculatrice va faire aimer les maths, cela n’a absolument pas le même sens pour eux que pour moi. Pour eux, cela veut visiblement dire proposer une belle interface qui donne aux élèves avec le moins d’effort possible les réponses aux problèmes types de maths donnés au lycée. Alors que moi je souhaite rendre les élèves autonomes pour être capable de résoudre des problèmes en-dehors des exercices types de lycée, et donner aux élèves motivés l’envie d’aller au-delà des programmes scolaires en utilisant toute la puissance de calcul à leur disposition sur la calculatrice pour explorer. Malheureusement, j’ai l’impression que de moins en moins de gens sont de mon avis, y compris chez certains profs de maths. La principale raison à mon avis, c’est le déclassement du métier de prof, qui a conduit à une crise de recrutement, et un niveau moyen en maths des étudiants au capes de plus en plus faible. Parallèlement, le mauvais usage des outils de calcul (en presse-boutons) conduit à une contre-réaction hostile parmi les profs de maths qui sont bons dans leur discipline.

Il y a aussi une controverse sur les outils de développement et collaboration. L’outil de synchronisation à la mode aujourd’hui est `git` avec un hébergement sur `github` et les jeunes ne jurent que par Discord. Personnellement, je travaille essentiellement seul et j’ai l’habitude d’utiliser des archives tar pour mes sauvegardes. Pour collaborer, j’ai l’habitude d’utiliser `svn`, que je trouve plus simple pour faire un commit que `git` (une étape et pas deux). Je n’aime pas du tout l’idée d’héberger des projets sur `github`, cela donne trop de controle à l’hébergeur (Microsoft ici) et c’est aussi bien trop centralisé à mon gout (le contraire de ce qui a donné naissance à Internet), sans compter que le cout en ressources doit être gigantesque. Si d’autres développeurs le font, je respecte leur choix, et je consulte ou utilise du code source indépendamment de la façon dont il est produit et publié, ce qui importe c’est le code lui-même. Je n’ai jamais essayé Discord et je n’ai pas l’intention d’essayer, c’est peut-être très convivial en particulier pour de la communication synchrone, mais c’est du logiciel propriétaire sur lequel on n’a aucun controle alors qu’il y a des logiciels libres qui permettent de gérer des forums, où on discute de manière asynchrone ce qui de plus me convient mieux. Bref, je ne vois pas au nom de quoi github+discord devrait être la seule et unique façon de développer et collaborer, surtout que cela pourrait être remplacé par d’autres outils dans quelques années (comme cvs par svn puis git, ou SourceForge). Il y a une forme d’intégrisme dans l’usage de l’outil informatique chez certains (y compris au plus haut niveau de l’éducation nationale avec l’imposition de Python comme unique langage de programmation au lycée), qui devient un peu comme une religion. Il serait souhaitable je pense qu’il y ait plus de tolérance, la diversité est une richesse.

Je travaille depuis 24 ans sur Giac et je programme du calcul formel depuis 30 ans, au début le web n’existait même pas, les échanges se faisaient via des newsgroup et des serveurs ftp. Je ne suis sur aucun réseau social, ni sur des systèmes d’échange synchrones et je n’en vois pas trop l’intérêt, la consultation asynchrone de forums et d’emails me semble bien plus approprié, on est dans sa bulle quand on code et on ne se laisse pas distraire par des notifications. Je ne me précipite pas sur la dernière mise à jour ou la dernière nouveauté, j’ai appris à mes dépens que quand quelque chose marche, il faut y réfléchir à deux fois avant de le modifier (et bien conserver une sauvegarde de ce qui marchait). J’ai aussi appris que le monde est complexe, il m’a fallu parfois plusieurs mois pour porter Giac et ses dépendances sur une calculatrice. Les erreurs de compilation ou d’édition de liens lors d’un nouveau portage sont normales et se comptent souvent par centaines. Si on ne travaille que sur des petits projets ou des projets récents, on risque de prendre des habitudes de confort où tout marche du premier coup et de renoncer à la première difficulté.

## B Équivalents dans χ\chiCAS de fonctionnalités mathématiques d’Epsilon ≥\geq 16.

Dans cette section on explique comment faire avec χ\chiCAS pour retrouver les fonctionnalités mathématiques récemment introduites par Numworks dans Epsilon. En effet χ\chiCAS s’utilise conjointement avec la version 15.5 d’Epsilon et il n’est pas commode ou pas possible d’installer une version plus récente d’Epsilon en parallèle.

- Epsilon 16: Résolution exacte d’équations polynomiales de degré 3.
  Utiliser la commande `solve` (menu rapide shift-2). Par exemple
  solve(x^3-x^2+x-1=0)
  Le solveur de χ\chiCAS détermine les solutions rationnelles pour toutes les équations polynomiales. Il gère aussi certaines autres équations, parfois à l’aide de fonctions spéciales, par exemple
  solve(x-2=ln(x))
- Epsilon 17: Coniques.
  Vous pouvez tracer n’importe quelle conique avec la commande `plot` (menu rapide shift-3), par exemple
  plot(x^2+y^2+x*y=4)
  Pour tracer plusieurs graphes simultanément, séparez les commandes de tracé par `;`. Pour donner une couleur à un tracé, utilisez un argument optionnel en fin de commande, par exemple
  p=plot(x^2+y^2+x*y=4,color=red)
  Pour déterminer le centre, un foyer et un point sur le grand axe de cette ellipse, on peut utiliser la commande `centre` qui se trouve dans le menu principal (touche Toolbox), sous-menu Géométrie (raccourci x 2 x^2)
  centre(p),0
  (le `,0` a été ajouté pour voir les coordonnées des points, sinon les points sont affichés dans un graphique). La commande `rayon` affiche les valeurs des paramètres a,b,c,e a,b,c,e de l’ellipse.
- Epsilon 17, inéquations.
  Pour tracer un graphe d’inéquation, on utilise aussi la commande `plot`, par exemple
  plot(4>x^2+y^2+x*y)
  Il est possible de combiner plusieurs inéquations
  plot(4>x^2+y^2+x*y and x>y)
  On peut bien sur combiner des tracés d’inéquations avec d’autres tracés de graphes (menu Toolbox Courbes) ou géométriques (menu Toolbox Géométrie), il suffit de taper les commandes correspondantes dans une même ligne de commande en les séparant par un `;`.
- Epsilon 17: Pente, équation d’une droite
  Utiliser la commande `slope` ou `equation` ou `parameq`, par exemple
  slope(droite(point(1,2),point(-1,1)))
- Epsilon 17: tests statistiques, intervalles de confiance
  Test du χ 2\chi^2: `chisquaret`. Taper `chi` puis la touche flèche vers le bas, puis sélectionner la commande, vous avez une description et deux exemples.
  Autres tests: Kolmogorov-Smirnov `kolmogorovt` (taper `k` puis flèche vers le bas, etc.), test Z de la loi normale `normalt`, test de Student `studentt`.
  Pour les intervalles de confiance, on peut utiliser les distributions inverses, le nom de commande est le nom de la loi suivi du suffixe `_icdf` par exemple `normald_icdf` pour la loi normale
  normald_icdf(0.975)
- Epsilon 18, finances
  χ\chiCAS dispose d’une application finance, depuis le menu des applications shift Ans

> Ce document a été traduit de LATEX par H E V E A