remove all str in calculus. Ready to import correctly fractions

This commit is contained in:
Lafrite 2013-10-21 17:52:11 +02:00
parent b2d8991107
commit ec3e4d34d2
2 changed files with 36 additions and 18 deletions

View File

@ -3,6 +3,7 @@
from generic import Stack from generic import Stack
from fraction import Fraction
def str2tokens(exp): def str2tokens(exp):
"""Convert an expression into a list of tokens """Convert an expression into a list of tokens
@ -11,10 +12,18 @@ def str2tokens(exp):
:returns: the list of tokens :returns: the list of tokens
>>> str2tokens("1 + 2") >>> str2tokens("1 + 2")
['1', '+', '2'] [1, '+', 2]
""" """
return exp.split(" ") tokens = exp.split(" ")
for (i,t) in enumerate(tokens):
try:
tokens[i] = int(t)
except ValueError:
pass
return tokens
def infixToPostfix(infixTokens): def infixToPostfix(infixTokens):
"""Transform an infix list of tokens into postfix tokens """Transform an infix list of tokens into postfix tokens
@ -46,7 +55,7 @@ def infixToPostfix(infixTokens):
while topToken != "(": while topToken != "(":
postfixList.append(topToken) postfixList.append(topToken)
topToken = opStack.pop() topToken = opStack.pop()
elif type(token) == str and token in "+-*/": elif isOperation(token):
# On doit ajouter la condition == str sinon python ne veut pas tester l'appartenance à la chaine de caractère. # On doit ajouter la condition == str sinon python ne veut pas tester l'appartenance à la chaine de caractère.
while (not opStack.isEmpty()) and (priority[opStack.peek()] >= priority[token]): while (not opStack.isEmpty()) and (priority[opStack.peek()] >= priority[token]):
postfixList.append(opStack.pop()) postfixList.append(opStack.pop())
@ -73,7 +82,7 @@ def computePostfix(postfixTokens):
#tokenList = postfixExp.split(" ") #tokenList = postfixExp.split(" ")
for (i,token) in enumerate(postfixTokens): for (i,token) in enumerate(postfixTokens):
if token in "+-*/": if isOperation(token):
op2 = operandeStack.pop() op2 = operandeStack.pop()
op1 = operandeStack.pop() op1 = operandeStack.pop()
res = doMath(token, op1, op2) res = doMath(token, op1, op2)
@ -109,7 +118,7 @@ def computePostfixBis(postfixTokens):
tmpTokenList = [] tmpTokenList = []
# on va chercher les motifs du genre A B + pour les calculer # on va chercher les motifs du genre A B + pour les calculer
while len(tokenList) > 2: while len(tokenList) > 2:
if isNumber(tokenList[0]) and isNumber(tokenList[1]) and tokenList[2] in "+-*/": if isNumber(tokenList[0]) and isNumber(tokenList[1]) and isOperation(tokenList[2]):
# S'il y a une opération à faire # S'il y a une opération à faire
op1 = tokenList[0] op1 = tokenList[0]
op2 = tokenList[1] op2 = tokenList[1]
@ -138,11 +147,16 @@ def isNumber(exp):
:returns: True if the expression can be a number and false otherwise :returns: True if the expression can be a number and false otherwise
""" """
tokenList = exp.split(" ") return type(exp) == int
if len(tokenList) != 1:
# si l'expression est trop longue pour être un chiffre def isOperation(exp):
return 0 """Check if the expression is an opération in "+-*/"
return exp.isdigit() or (exp[0] == "-" and exp[1:].isdigit())
:param exp: an expression
:returns: boolean
"""
return (type(exp) == str and exp in "+-*/")
def doMath(op, op1, op2): def doMath(op, op1, op2):
@ -154,7 +168,12 @@ def doMath(op, op1, op2):
:returns: string representing the result :returns: string representing the result
""" """
return str(eval(op1 + op + op2)) operations = {"+": "__add__", "-": "__sub__", "*": "__mul__"}
if op == "/":
return Fraction(op1,op2)
else:
return getattr(op1,operations[op])(op2)
def postfixToInfix(postfixTokens): def postfixToInfix(postfixTokens):
@ -171,13 +190,13 @@ def postfixToInfix(postfixTokens):
#tokenList = postfixExp.split(" ") #tokenList = postfixExp.split(" ")
for (i,token) in enumerate(postfixTokens): for (i,token) in enumerate(postfixTokens):
if token in "+-*/": if isOperation(token):
op2 = operandeStack.pop() op2 = operandeStack.pop()
if needPar(op2, token, "after"): if needPar(op2, token, "after"):
op2 = "( " + op2 + " )" op2 = "( " + str(op2) + " )"
op1 = operandeStack.pop() op1 = operandeStack.pop()
if needPar(op1, token, "before"): if needPar(op1, token, "before"):
op1 = "( " + op1 + " )" op1 = "( " + str(op1) + " )"
res = "{op1} {op} {op2}".format(op1 = op1, op = token, op2 = op2) res = "{op1} {op} {op2}".format(op1 = op1, op = token, op2 = op2)
operandeStack.push(res) operandeStack.push(res)
@ -198,7 +217,7 @@ def needPar(operande, operator, posi = "after"):
priority = {"*" : 3, "/": 3, "+": 2, "-":2} priority = {"*" : 3, "/": 3, "+": 2, "-":2}
if isNumber(operande) and "-" in operande: if isNumber(operande) and operande < 0:
return 1 return 1
elif not isNumber(operande): elif not isNumber(operande):
# Si c'est une grande expression ou un chiffre négatif # Si c'est une grande expression ou un chiffre négatif
@ -236,7 +255,7 @@ def get_main_op(tokens):
parStack.push(token) parStack.push(token)
elif token == ")": elif token == ")":
parStack.pop() parStack.pop()
elif token in "+-*/" and parStack.isEmpty(): elif isOperation(token) and parStack.isEmpty():
main_op.append(token) main_op.append(token)
return min(main_op, key = lambda s: priority[s]) return min(main_op, key = lambda s: priority[s])
@ -329,7 +348,7 @@ if __name__ == '__main__':
exp = "( 2 + 5 ) * ( 3 * 4 )" exp = "( 2 + 5 ) * ( 3 * 4 )"
test(exp) test(exp)
exp = "( 2 + 5 ) / ( 3 * 4 )" exp = "( 2 + 5 - 1 ) / ( 3 * 4 )"
test(exp) test(exp)
#print(expand_list([1,2,['a','b','c'], 3, ['d','e']])) #print(expand_list([1,2,['a','b','c'], 3, ['d','e']]))

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from calculus import isNumber
from arithmetic import gcd from arithmetic import gcd
class Fraction(object): class Fraction(object):