Warning: Undefined array key "DOKU_PREFS" in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/common.php on line 2082
mini_calculatrice_cgi [Les recettes Python de Tyrtamos]

Outils pour utilisateurs

Outils du site


mini_calculatrice_cgi

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
Dernière révision Les deux révisions suivantes
mini_calculatrice_cgi [2008/04/07 09:38]
tyrtamos
mini_calculatrice_cgi [2008/04/11 10:15]
tyrtamos
Ligne 63: Ligne 63:
 A titre d'application concrête du serveur ci-dessus, je vous propose une calculatrice en ligne au sein de votre réseau local. A titre d'application concrête du serveur ci-dessus, je vous propose une calculatrice en ligne au sein de votre réseau local.
  
-Cependantsi vous avez un hébergeur de site web qui accepte les scripts CGI Python, vous pourriez le mettre sur ce site, et donc en libre service pour tout le web!+Vous l'appelezpar exemple, calculcgi.py, vous la placez dans le répertoire cgi-bin de votre serveur.  
 + 
 +Sous linux, il y a 2 particularités: 
 + 
 +  * le code doit avoir des fins de ligne de type "UNIX" (\n), 
 + 
 +  * le fichier calculcgi.py doit être exécutable. 
 + 
 +Si vous avez un hébergeur de site web qui accepte les scripts CGI Python, vous pourriez le mettre sur ce site, et donc en libre service pour tout le web!
  
 Quelques particularités de cette calculatrice CGI: Quelques particularités de cette calculatrice CGI:
Ligne 76: Ligne 84:
  
   * cette calculatrice est facile à étendre par des modules supplémentaires, et un module est fourni à titre d'exemple: calculsup.py qui contient le calcul de la factoriel de n (fonction fact(n))   * cette calculatrice est facile à étendre par des modules supplémentaires, et un module est fourni à titre d'exemple: calculsup.py qui contient le calcul de la factoriel de n (fonction fact(n))
 +
 +Vous n'avez pas beaucoup d'adaptation à faire:
 +
 +  * l'adresse de votre calculatrice (ici, adresse="%%http://192.168.0.99:8000/cgi-bin/calculcgi.py%%")
 +
 +  * le temps maxi de calcul en secondes au delà duquel la calculatrice s'arrêtera toute seule avec un message d'erreur (ici, dureemaxcalcul=10)
 +
 +Le code est copieusement auto-documenté:
 +
 +<code python>
 +#!/usr/bin/python
 +# -*- coding: utf-8 -*-
 +
 +# importation nécessaire pour les divisions entières aient un résultat décimal
 +from __future__ import division
 +
 +# indispensable pour l'exécution en tant que script cgi
 +print "Content-type: text/html\n\n"
 +# pour Linux: il faut que les fins de ligne de cette page soient "UNIX" ('\n')
 +
 +# importations "système" nécessaires
 +import cgi
 +from sys import path, exc_info, settrace
 +import threading
 +import time
 +
 +# importations seulement nécessaires aux calculs
 +from math import *
 +
 +# importations optionnelles de modules de calcul supplémentaires
 +path.append('./')
 +from calculsup import *
 +
 +##############################################################################
 +# déclaration des variables globales
 +
 +# Nécessaire pour limiter la longueur des calculs (ici, 10 secondes)
 +dureemaxcalcul=10
 +
 +# adresse de la calculatrice à adapter à votre contexte
 +adresse="http://192.168.0.99:8000/cgi-bin/calculcgi.py"
 +
 +# partie html pour présentation des résultats dans un navigateur web
 +codehtml1 = """
 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//FR" "http://www.w3.org/TR/html4/loose.dtd">
 +<html>
 +<head>
 +<title>Calculatrice scientifique en ligne</title>
 +<meta name="description" content="Calculatrice scientifique en ligne" />
 +<meta name="keywords" content="calcul, calculatrice, scientifique" />
 +<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
 +<meta name="author" lang="fr" content="Tyrtamos" />
 +<meta name="language" content="French" />
 +</head>
 +<body>
 +<p><font size="6">Calculatrice scientifique en ligne</font></p>
 +<form name="form1" method="post" action="
 +"""
 +
 +codehtml2 = """
 +">
 +    <p><b>Nouvelle expression :</b></p>
 +    <p><input type="text" name="saisie" id="saisie" size="88"> &nbsp;&nbsp;<input type="submit" name="bouton" id="bouton" value="Calculer"></p>
 +</form>
 +<p>&nbsp;</p>
 +<p><b>Expression calcul&eacute;e = </b>
 +"""
 +
 +codehtml3 = """
 +</p>
 +<p><b>R&eacute;sultat = &nbsp;</b><span style="background-color:yellow;">
 +"""
 +
 +codehtml4 = """
 +</span></p>
 +</body>
 +</html>
 +"""
 +
 +##############################################################################
 +# Définition de la classe "Calcul" dans un thread (=processus "leger")
 +#
 +class Calcul(threading.Thread):
 +    """Thread de calcul permettant le calcul de l'expression en tâche de fond"""
 +
 +    def __init__(self,expr):
 +        """Initialise le thread ainsi que les variables de l'instance"""
 +        threading.Thread.__init__(self)
 +        # stocke l'expression à calculer dans une variable d'instance
 +        self.expression = expr
 +        # créé la variable d'instance qui pourra porter l'ordre d'arrêter le calcul
 +        self.arretcalcul = False
 +        # créé la variable d'instance qui portera le résultat du calcul
 +        self.resultat = ""
 +
 +    def run(self):
 +        """Lance le calcul en tâche de fond et sauvegarde le résultat"""
 +        try:
 +            # lance le traçage pour permettre l'arrêt anticipée du calcul
 +            settrace(self.tracecalcul)
 +            # calcul de l'expression
 +            self.resultat = "%s" % eval(self.expression)
 +            # arrêt du traçage
 +            settrace(None)
 +        except:
 +            # arrêt du traçage en cas d'exception déclenchée
 +            settrace(None)
 +            # enregistrement de l'erreur de calcul détectée s'il y en a une
 +            self.resultat = "erreur: %s" % exc_info()[1]
 +
 +    def tracecalcul(self, frame, event, arg):
 +        """Fonction de trace nécessaire pour permettre l'arrêt anticipé d'eval()"""
 +        if event=='line':
 +            if self.arretcalcul:
 +                raise ValueError ("arrêt calcul trop long")
 +        return self.tracecalcul
 +
 +    def stopcalcul(self):
 +        """Fonction déclenchant l'arrêt du calcul en cours"""
 +        self.arretcalcul = True
 +
 +    def donneresultat(self):
 +        return self.resultat
 +
 +##############################################################################
 +# Traitement de la requête reçue par le réseau
 +#
 +if __name__ == "__main__":
 +    # initialisation du temps de départ
 +    debutcalcul=time.time()
 +    # Récupération d'une éventuelle requête transmise (GET ou POST)
 +    recup=cgi.FieldStorage()
 +    if recup.has_key("saisie"):
 +        # =il y a eu effectivement réception d'une requête (GET ou POST)
 +        requete=recup["saisie"].value
 +        if requete=="":
 +            # la requête reçue est vide: on renvoie la page web avec les zones vides
 +            reponse=""
 +            duree=""
 +        else:
 +            # on lance le calcul de la requête en tâche de fond (thread démon)
 +            calc=Calcul(requete)
 +            calc.setDaemon(True)
 +            calc.start()
 +            while calc.isAlive():
 +                # vérif qu'on ne dépasse pas le temps maxi de calcul
 +                if (time.time()-debutcalcul)>dureemaxcalcul:
 +                    # si oui, on demande l'arrêt anticipé du calcul trop long
 +                    calc.stopcalcul()
 +                # tempo pour laisser la priorité au calcul
 +                time.sleep(0.5)
 +            # lecture du résultat du calcul ou de l'erreur ou du dépassement de temps
 +            reponse = calc.donneresultat()
 +    else:
 +        # si rien n'a été transmis, renvoie la page web avec les zones vides pour calcul suivant
 +        requete=""
 +        reponse=""
 +        duree=""
 +    # renvoie au client web la page html donnant le résultat du calcul ou le message d'erreur
 +    print codehtml1 + adresse + codehtml2 + requete + codehtml3 + reponse + codehtml4
 +
 +</code>
 +
 +Et pour le module de calcul supplémentaire calculsup.py:
 +
 +<code python>
 +#!/usr/bin/python
 +# -*- coding: utf-8 -*-
 +
 +# importation nécessaire pour les divisions entières aient un résultat décimal
 +from __future__ import division
 +
 +###############################################################################
 +# Factorielle de n
 +# - version volontairement non récursive (la pile de python est limitée à environ 1000)
 +def fact(n):
 +    """fact(n): calcule la factorielle de n (entier >= 0)"""
 +    # Vérification de la donnée
 +    if not(type(n)==int or type(n)==long) or n<0:
 +        raise ValueError ("erreur fact(n): n doit être un nombre entier positif ou nul")
 +    # Calcul
 +    x=1
 +    for i in xrange(2,n+1):
 +        x*=i
 +    return x
 +</code>
 +
 +Amusez-vous bien!
 +
  
mini_calculatrice_cgi.txt · Dernière modification: 2008/04/12 08:51 de tyrtamos