[Tyrtamos juin 2008 version 1.40]
Nombreuses améliorations par rapport à la version précédente: voir le fichier lisezmoi.txt de l'archive à télécharger.
Pour Windows, ajout d'une version “exe” permettant l'utilisation de la Calculext sans installer l'interpréteur Python.
Modernisation simultanée de la version en ligne accessible sans installation, par un simple navigateur web (http://calculext.jpvweb.com). Son code n'est pas diffusé, mais elle utilise les mêmes modules sans modification et fait pratiquement tout ce que fait la Calculext installée sur PC, avec quelques limites mentionnées dans le manuel d'utilisation (commun avec la Calculext installable).
S'il y a bien quelque chose d'énervant, c'est d'avoir un ordinateur puissant devant soi, et d'être obligé de sortir une calculatrice de poche pour faire des petits calculs.
Oui, je sais que tous les systèmes d'exploitation ont des calculatrices de poche simulées, mais pourquoi cliquer plein de boutons alors qu'on a devant soi un clavier de 104 touches?
Et puis devant une calculatrice de poche, réelle ou simulée, il y a toujours une limite de précision et des fonctions qui manquent qu'on ne peut pas ajouter.
Et j'aimerais bien avoir la même calculatrice sous Windows et sous Linux!
Voilà, mon objectif correspond bien à ces problèmes:
Mais si, c'est possible!
La calculette, a cet aspect:
Sous Windows XP:
Et sous Linux:
L'utilisation est très simple:
Pour la suite: accédez au manuel complet ci-dessous.
Ce manuel d'utilisation accompagne la Calculext téléchargée et pourra être appelé à tout moment pendant son exécution.
Il est aussi le manuel de la version dérivée en ligne sur le web et pourra être appelé par le lien hypertexte sur sa page web.
Il faut peu de choses pour que cette calculatrice fonctionne:
Pour Linux, on trouve tout ça sous forme de paquets déjà prévus (rpm pour la suse et deb pour debian) et souvent déjà pré installés.
Pour Windows, on trouve le programme à installer ici: http://www.python.org/download/windows/
Pour Mac, ça semble aussi fonctionner avec l'interpréteur Python téléchargé ici: http://www.python.org/download/mac/
Pour les versions de Python:
Voir le fichier “lisezmoi” contenu dans l'archive calculext_v1.40.zip.
Vous placez tous les fichiers de la Calculext dans un même répertoire (je l'appelle “/chemin” pour l'exemple).
Ce répertoire peut être n'importe où, et, une fois les fichiers copiés, vous n'avez pas besoin d'avoir le droit d'écrire, sauf, bien sûr, si vous voulez modifier la Calculext.
A partir de cette version 1.40, la Calculext saisit comme répertoire de travail le répertoire d'où elle a été lancée, et c'est dans ce répertoire que vous devez avoir le droit d'écrire pour sauvegarder l'historique et le dernier résultat. Vous pouvez aussi désigner un répertoire de travail dans votre /home (par exemple) si vous créez une icône de lancement sur le bureau. Le grand avantage est que plusieurs utilisateurs peuvent utiliser la Calculext en conservant chacun ses données.
Vous pouvez lancer la calculette en console sous votre login par:
$ python /chemin/calculext.py
Mais comme c'est un programme graphique, je vous suggère plutôt de construire un raccourcis sur votre bureau KDE ou gnome pour faire ça (clic droit → etc…).
Si vous voulez ajouter des fonctions, installez aussi “idle” de python, ou un autre programme de développement python. N'oubliez pas que l'édition du code doit respecter l'encodage unicode “UTF-8”.
Il n'y a pas de programme d'installation, et vous ne risquez pas de “saloper” votre registre… Vous placez simplement tous les fichiers de la Calculext dans un même répertoire. Le chemin complet de ce répertoire ne doit avoir ni espace, ni caractère accentué. Par exemple: c:\calculext. Ceci est valable pour la Calculext modifiable, et aussi pour la version “exe”.
Pour lancer la calculette modifiable:
C:\Python25\pythonw.exe "C:\calculext\calculext.py"
Vous noterez l'utilisation de “pythonw.exe” (et pas python.exe) pour éviter le lancement et l'affichage de la console dos.
calculext.py => calculext.pyw
Avec cette modif, le double-clic sur le nom calculette.pyw appellera le programme pythonw.exe.
C:\Python25\pythonw.exe "C:\calculext\calculext.py"
Pour lancer la calculette dans sa version “exe” (non modifiable):
Si vous voulez ajouter des fonctions, il faudra lancer “idle” de python, en principe livré aussi avec le python de base, ou un autre programme de développement python. N'oubliez pas que l'édition du code doit respecter l'encodage unicode “UTF-8”. Sous Windows,c'est le cas pour “idle” de Python (c'est ce que j'utilise pour le développement), mais aussi du notepad/bloc-notes. J'ai aussi essayé avec succès “easyeclipse pour Python” (http://www.easyeclipse.org/site/distributions/index.html)
La partie graphique de la calculette est entièrement définie dans la classe “Calculext” qui complète et surcharge la classe Frame du module Tkinter.
Une fois lancée, la calculette s'affiche et attend les évènements à prendre en compte: saisie d'une expression, clic de souris, appel du menu, touche F1 pour demande d'aide, etc…
Toutes les fonctions appelées directement par ces évènements sont définies à l'intérieur de cette classe.
Quand le calcul d'une expression est lancé, il est confié à un thread (thread = processus léger qui s'exécute à l'intérieur d'un processus normal) qui fait le calcul en tâche de fond, ce qui fait que la partie graphique reprend tout de suite la main et n'est pas bloquée par un calcul long. Par contre, pendant un calcul long, la saisie d'une nouvelle expression est neutralisée.
Ce thread de calcul est défini dans la classe “Calcul”. Il reçoit l'expression à calculer, se charge du calcul par la fonction Python “eval()”, traite les erreurs par “try: .. except:” et place le résultat ou le message d'erreur dans la ligne graphique de résultat et affiche aussi le temps de calcul.
L'utilisateur qui a lancé un calcul trop long peut demander l'arrêt du calcul en cliquant sur le menu “stopper” ou en tapant F2. Dans ce cas, il est demandé au thread de s'arrêter (appel de la méthode stopcalcul() du thread). Grâce à “settrace”, les fonctions potentiellement longue n'ont plus besoin d'être codées spécialement pour cela. Cependant, quand une fonction longue a un résultat très très long (50000 caractères par exemple), la fonction d'affichage, qui - elle - ne peut pas être interrompue, peut prendre plus de temps que la fonction de calcul.
Le traitement d'erreur traite:
L'affichage passe par une fonction “affiche()” qui permet de formater correctement les nombres réels (à virgule flottante), selon la valeur de la variable globale “nbchiffres”. La fonction “precision(n) avec -15<=n<=+15 permet à l'utilisateur de modifier ce formatage des nombres réels.
Après chaque calcul, est aussi affiché la durée de ce calcul, formatée par la fonction “afficheduree(sd)”, ce qui permet de faciliter l'optimisation des fonctions qu'on ajoute.
Après chaque calcul réussi, l'expression ainsi que le dernier résultat sont empilés dans une pile (pile[]). On peut ainsi rappeler ce dernier résultat ainsi que l'une des expressions précédentes avec la flèche en haut et flèche en bas. Ce qui est rappelé vient dans la ligne de saisie, ce qui permet de ne pas avoir à les retaper. La pile n'est cependant pas conservée lors de l'extinction de la calculatrice, mais vous pouvez cependant la sauvegarder et la recharger plus tard avec les fonctions du menu.
Avec un clic droit dans la zone de saisie, un menu flottant apparait. Les items de ce menu en cascade (2 niveaux) sont définies dans la variable globale “chmenu” sous forme d'une liste de liste. Sa structure est très simple:
chmenu=( (titre1, item1, iten2, item3), (titre2, item1, item2), (titre3, item1, item2, item3, item4) )
Chaque “titre” est un texte du menu 1er niveau, qui affiche un menu 2ème niveau composé des “items” qui suivent.
Le menu lui-même est créé par le constructeur de la classe Calculext (c'est à dire dans __init__). Son codage est tel qu'il s'adaptera automatiquement aux modifications de chmenu, pour autant qu'on en respecte sa structure. Cela veut dire qu'il sera facile de mettre à jour le menu au fur et à mesure des fonctions ajoutés ultérieurement par les utilisateurs!
Le positionnement du menu à l'emplacement de la souris est défini par la fonction menupopup(self, evt). En cas de sélection d'un item du menu 2ème niveau, il y a insertion de l'item à l'emplacement du curseur (celui de la zone de saisie) par la fonction execmenu(self,ch). L'insertion est empêchée si l'item commence par “$”, ce qui permet de mettre des textes d'information dans le menu, comme par exemple un rappel des règles de priorités des opérateurs. Si l'item est vide, cela déclenche l'affichage d'une ligne de séparation non sélectionnable dans le menu.
Si on avait sélectionné du texte avant d'appeler l'insertion d'une fonction avec parenthèses au menu, le texte sélectionné se retrouve à l'intérieur des parenthèses de la fonction insérée.
Le code est trop long pour être affiché ici, mais il est largement auto-documenté et je vous invite à le consulter directement.
Les “modules” additionnels python utilisés par la Calculext sont des fichiers “texte” séparés, importés dans le programme principal (ici “calculext.py”) par une instruction “import”. Ci-dessous les importations actuelles:
# importation des modules additionnels # ajoutez les modules que vous avez créés # et mettez en commentaire ceux que vous n'utilisez pas from bibgene import * from conversions import * from arithmetique import * from combinatoire import * from probabilite import * from credit import * from temps import *
Je vous suggère d'éditer l'un de ces modules pour voir comment il est présenté.
C'est super simple! Prenons un exemple: une fonction qui teste si un nombre entier est pair.
def estpair(n): """estpair(n): dit si un nombre entier est pair (renvoie True ou False)""" return (n % 2)==0
Ajoutez ce code au fichier bibgene.py, enregistrez-le (n'oubliez pas l'encodage UTF-8!), relancez la calculatrice, et essayez:
estpair(42) => True estpair(99) => False
Vous pouvez voir aussi à quoi sert la ligne entourée de triples guillemets. Faites:
aide(estpair) => "estpair(n): dit si un nombre entier est pair (renvoie True ou False)"
Bien entendu, si la fonction nécessite l'importation de modules supplémentaires, il faut ajouter l'importation de ces modules au début du module en question.
Enfin, il est évident que votre fonction doit renvoyer quelque chose (instruction “return”), sinon, aucun résultat ne sera affiché à part “None” (= “rien”). Par contre, ce résultat peut être n'importe quoi qui peut s'écrire sur une seule ligne, y compris une chaine de caractère ou une liste.
Vous pouvez aussi vérifier que le “n” fourni est bien un nombre entier. L'exemple devient:
def estpair(n): """estpair(n): dit si un nombre entier est pair (renvoie True ou False)""" if not ((type(n)==int) or (type(n)==long)): raise ValueError ("erreur estpair(n): n doit être un nombre entier") return (n % 2)==0
Dans ce cas:
estpair(8.123) => 'erreur estpair(n): n doit être un nombre entier'
C'est aussi simple que ça!
La vérification des données est importante au moins pour 2 raisons:
Pour faciliter la vérification des données, vous pouvez utiliser les fonctions prédéfinies suivantes:
estentier(n) estnombre(n) estchaine(t) estliste(L)
L'appel de ces fonctions situées au début du programme principal calculext.py, à partir d'un module additionnel, nécessite le code suivant à mettre au début de ce module additionnel:
from sys import modules pmain = modules['__main__']
Et les fonctions citées devront être préfixées par “pmain”. Par exemple:
def estpair(n): """estpair(n): dit si un nombre entier est pair (renvoie True ou False)""" if not pmain.estentier(n): raise ValueError ("erreur estpair(n): n doit être un nombre entier") return (n % 2)==0
Vous pouvez aussi recopier les fonctions dont vous avez besoin au début du module additionnel.
Conseils supplémentaires:
Si vous voulez que vos nouvelles fonctions apparaissent dans le menu flottant, il faut l'ajouter dans la variable globale chmenu du fichier calculext.py.
Si vous voulez ajouter simplement une fonction “machin(x,y)” à un menu existant:
Situation initiale:
chmenu=( ..... ("titre_n", "item1", "item2", ..., "itemk"), ..... )
Situation finale:
chmenu=( ..... ("titre_n", "item1", "item2", ..., "itemk", "machin(x,y)"), ..... )
Simple, non?
Si vous voulez créer un nouveau titre “hi-fi” au menu 1er niveau, et une fonction “calcul_hp(x,y,z)” au 2ème niveau:
Nouvelle situation finale:
chmenu=( ..... ("titre_n", "item1", "item2", ..., "itemk"), ("hi-fi", "calcul_hp(x,y,z)"), ..... )
Voilà, c'est tout ce qu'il faut connaitre pour ajouter les fonctions dont vous avez besoin à un module additionnel existant.
Pourquoi ajouter un module supplémentaire? En général parce qu'on veut regrouper plusieurs fonctions qui appartiennent à une même famille d'application. Par exemple:
Prenons le 2ème exemple pour la suite.
Pour construire un module supplémentaire, il suffit:
1- de créer le nouveau module par recopie du fichier fourni “modele.py”. Vous l'appelez comme vous voulez. Pour l'exemple, c'est “photos.py”.
2- Editez ce nouveau fichier photos.py avec un éditeur de texte (avec encodage UTF-8), et ajustez les zones à remplir par vous: votre nom, le nom du module, …
3- Vous devez ensuite ajouter dans ce module “photos.py”, l'importation des modules dont vos nouvelles fonctions auront besoin. Par exemple:
from math import *
4- Et vous ajoutez dans calculext.py l'importation de ce module par:
from photos import *
En variante, l'importation pourrait être plus “propre” en important seulement les fonctions que vous voulez rendre disponible:
from photos import fonction1, fonction2, ..., fonctionn
Mais si vous faites ça:
import photos
vos fonctions devront alors être toutes préfixées dans les expressions à calculer, avec le nom du module, par exemple: “photos.fonction1()”
5- Il ne reste plus qu'à ajouter vos nouvelles fonctions dans votre nouveau module photos.py: pour cela, voir le chapitre précédent “Ajouter une fonction supplémentaire dans un module existant”.
Voilà, c'est fait: vous avez votre calculette miniature toujours disponible, et faisant tout ce que vous voulez (et encore plus)!
Vous aurez du mal à trouver une autre calculatrice qui vous fait tout ça!
Les fonctions supplémentaires que je propose représentent un tout petit début de ce que je souhaite faire: surveillez l'arrivée des prochaines versions!
Si vous ajoutez de nouvelles fonctions ou de nouveaux modules, donnez moi l'info (page contact du site)!
J'espère que vous vous amuserez autant que moi!