Calculatrice ligne de commande - calcul exact

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 956 fois - Téléchargée 16 fois

Contenu du snippet

Voici une calculatrice en ligne de commande (pour calculer 21+2/8+45*5 par exemple) qui utilise le CALCUL EXACT pour donner des solutions sous formes de fractions à des calculs.

Elle utilise beaucoup la récursivité, par exemple pour 2+2*5 elle va calculer la somme du produit de 2 et 2 avec 5.

Elle ne gère pas encore les parenthèses ni les fonctions telles que racine carrée.

De nombreuses améliorations sont à venir.

N'hésitez pas à postez des COMMENTAIRES, critiques, questions.

Source / Exemple :


from fractions import *
import sys

sys.setrecursionlimit(5000) # profondeur maximal des recusions

def gestion_nb_virgule(chaine):
 chaine_finale = ""
 num = ""
 denum = ""
 for elem in chaine:
  if elem == ".":
   num = denum
   denum = ""
  elif elem in ("+","-","/","*"):
   if num and denum:
    if chaine_finale:
     if chaine_finale[-1] == "/":
      chaine_finale = chaine_finale[:-1]+"*"
      chaine_finale += str(1/Fraction(num+"."+denum))+elem
      denum = num = ""
    else:
     chaine_finale += str(Fraction(num+"."+denum))+elem
     denum = num = ""
   else:
    chaine_finale += denum + elem
    denum = num = ""
  else:
   denum += elem
 if num and denum:
  if chaine_finale:
   if chaine_finale[-1] == "/":
    chaine_finale = chaine_finale[:-1]+"*"
    chaine_finale += str(1/Fraction(num+"."+denum))
    denum = num = ""
   else:
    chaine_finale += str(Fraction(num+"."+denum))
    denum = num = ""
  else:
   chaine_finale += str(Fraction(num+"."+denum))
   denum = num = ""
 else:
  chaine_finale += denum
  denum = num = ""
 return chaine_finale

# Le programme utilise la recursivite pour calculer

def exacalc(chaine):

 if "+" in chaine: # ADDITION OU SOUSTRACTION OU MULTIPLICATIONS OU DIVISIONS
  for rang, operation in enumerate(chaine.split("+")):
   if rang == 0: # 1ER NOMBRE
    if ("-" in operation) and (operation[0]!="-") :
     resultat = exacalc(operation)
    if "*" in operation:
     resultat = exacalc(operation)
    if "/" in operation:
     resultat = exacalc(operation)
    else:
     resultat = operation
   else:
    if "-" in operation:
     operation = exacalc(operation)
    if "*" in operation:
     operation = exacalc(operation)
    if "/" in operation:
     operation = exacalc(operation)

    if "/" not in resultat:
     resultat += "/1"
    if "/" not in operation:
     operation += "/1"
    resultat = resultat.split("/") 
    operation = operation.split("/")
    resultat = str(Fraction(int(resultat[0]),int(resultat[1]))+Fraction(int(operation[0]),int(operation[1])))

 elif ("-" in chaine) and (chaine[0]!="-") : # SOUSTRACTION OU MULTIPLICATIONS OU DIVISIONS
  for rang, operation in enumerate(chaine.split("-")):
   if rang == 0: # 1ER NOMBRE
    if "*" in operation:
     resultat = exacalc(operation)
    if "/" in operation:
     resultat = exacalc(operation)
    else:
     resultat = operation
   else:
    if "*" in operation:
     operation = exacalc(operation)
    if "/" in operation:
     operation = exacalc(operation)

    if "/" not in resultat:
     resultat += "/1"
    if "/" not in operation:
     operation += "/1"
    resultat = resultat.split("/") 
    operation = operation.split("/")
    resultat = str(Fraction(int(resultat[0]),int(resultat[1]))-Fraction(int(operation[0]),int(operation[1])))
    if( resultat[0]=="0") and ("/" in resultat):
     resultat = 0

 elif "*" in chaine: # MULTIPLICATIONS OU DIVISIONS
  for rang, operation in enumerate(chaine.split("*")):
   if rang == 0: # 1ER NOMBRE
    if "/" in operation: # DIVISION
     resultat = exacalc(operation)
    else:
     resultat = operation
   else:
    if "/" not in resultat:
     resultat += "/1"
    if "/" not in operation:
     operation += "/1"
    resultat = resultat.split("/") 
    operation = operation.split("/")
    resultat = str(Fraction(int(resultat[0]),int(resultat[1]))*Fraction(int(operation[0]),int(operation[1])))
	  
 elif "/" in chaine: # QUE DES DIVISIONS
  for rang, operation in enumerate(chaine.split("/")):
   if rang == 0:
    resultat = operation
   elif rang == 1:
    resultat += "/"+operation
   else: # divisions suivantes
    resultat = resultat.split("/")
    resultat = str(Fraction(int(resultat[0]),int(resultat[1]))/Fraction(int(operation),1))

 if "/" in resultat:
  resultat = resultat.split("/")
  return str(Fraction(int(resultat[0]),int(resultat[1])))
 
 else:
  return resultat

while 1:
 saisie = raw_input("\nexacalc : ")
 saisie = saisie.replace(" ","")
 saisie = saisie.replace("++","+")
 saisie = saisie.replace("--","+")
 saisie = saisie.replace("+-","-")
 saisie = saisie.replace("-+","-")
 saisie = saisie.replace("**","*")
 saisie = saisie.replace("\\","/") # attention "\\" correspond a "\"
 saisie = saisie.replace("//","/")
 saisie = saisie.replace(",",".")
 
 # ICI DEBUG
 # if saisie and ("+" in saisie)or("-" in saisie)or("*" in saisie)or("/" in saisie):
  # print " ", exacalc(gestion_nb_virgule(saisie))
 
 # ICI ANTI-ERREUR
 if saisie and ("+" in saisie)or("-" in saisie)or("*" in saisie)or("/" in saisie):
  try:
   saisie = gestion_nb_virgule(saisie)
   resultat = exacalc(saisie)
   print " ", resultat
   if "/" in resultat:
    print " ", float(resultat.split("/")[0])/float(resultat.split("/")[1])
  except:
   print "erreur de syntaxe"

A voir également

Ajouter un commentaire Commentaire
Messages postés
45
Date d'inscription
samedi 3 mai 2003
Statut
Membre
Dernière intervention
25 janvier 2011

Ce dont tu parles c'est plutôt du calcul formel, en tout cas c'est plutôt bon esprit ! :-)

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.