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"
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.