Doctest and bugs in str2tokens

This commit is contained in:
lafrite 2014-12-02 12:37:23 +01:00
parent e1da8d2453
commit 543af69979
2 changed files with 33 additions and 31 deletions

View File

@ -209,7 +209,7 @@ class op(object):
("*", 2): "mul",\ ("*", 2): "mul",\
("/", 2): "div",\ ("/", 2): "div",\
("^", 2): "pw",\ ("^", 2): "pw",\
(")", 2): "par",\ ("(", 2): "par",\
} }
@classmethod @classmethod
@ -221,6 +221,12 @@ class op(object):
""" """
return getattr(cls, cls._operators[(op, arity)]) return getattr(cls, cls._operators[(op, arity)])
@classmethod
def can_be_operator(cls, symbole):
""" Tell if the symbole can be an operator """
return symbole in [i[0] for i in cls._operators]
@ClassProperty @ClassProperty
@operatorize @operatorize
def add(cls): def add(cls):
@ -393,6 +399,9 @@ if __name__ == '__main__':
print(op.add.__txt__(f.__txt__(),'2')) print(op.add.__txt__(f.__txt__(),'2'))
print(op.add.__tex__(f.__tex__(),'2')) print(op.add.__tex__(f.__tex__(),'2'))
print("\t op.can_be_operator('+') :" + str(op.can_be_operator('+')))
print("\t op.can_be_operator('t') :" + str(op.can_be_operator('t')))
import doctest import doctest
doctest.testmod() doctest.testmod()

View File

@ -1,8 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from .operator import Operator
from .generic import Stack, isOperator, isNumber from .generic import Stack, isOperator, isNumber
from pymath.operator import op
def str2tokens(exp): def str2tokens(exp):
""" Parse the string into tokens then turn it into postfix form """ Parse the string into tokens then turn it into postfix form
@ -51,7 +51,7 @@ def str2in_tokens(exp):
tokens.append(int(character)) tokens.append(int(character))
elif character in "+-*/:^": elif character in "+-*/:^":
tokens.append(Operator(character)) tokens.append(character)
elif character == ")": elif character == ")":
tokens.append(character) tokens.append(character)
@ -60,9 +60,8 @@ def str2in_tokens(exp):
# If "3(", ")(" # If "3(", ")("
if isNumber(tokens[-1]) \ if isNumber(tokens[-1]) \
or tokens[-1] == ")" : or tokens[-1] == ")" :
#tokens.append(Operator("*")) tokens.append("*")
tokens.append(Operator("*")) tokens.append(character)
tokens.append(Operator(character))
elif character == ".": elif character == ".":
raise ValueError("No float number please") raise ValueError("No float number please")
@ -80,15 +79,11 @@ def in2post_fix(infix_tokens):
@param infix_tokens: the infix list of tokens to transform into postfix form. @param infix_tokens: the infix list of tokens to transform into postfix form.
@return: the corresponding postfix list of tokens. @return: the corresponding postfix list of tokens.
>>> a, s, m, d, p = Operator("+"), Operator("-"), Operator("*"), Operator("/"), Operator("^") >>> in2post_fix([op.par, 2, op.add, 5, op.sub, 1, ')', op.div, op.par, 3, op.mul, 4, ')'])
>>> s1 = Operator("-", 1)
>>> par = Operator("(")
>>> in2post_fix([par, 2, a, 5, s, 1, ')', d, par, 3, m, 4, ')'])
[2, 5, '+', 1, '-', 3, 4, '*', '/'] [2, 5, '+', 1, '-', 3, 4, '*', '/']
>>> in2post_fix([s1, par, s1, 2, ')']) >>> in2post_fix([op.sub1, op.par, op.sub1, 2, ')'])
[2, '-', '-'] [2, '-', '-']
>>> in2post_fix([s1, par, s1, 2, a, 3, m, 4, ')']) >>> in2post_fix([op.sub1, op.par, op.sub1, 2, op.add, 3, op.mul, 4, ')'])
[2, '-', 3, 4, '*', '+', '-'] [2, '-', 3, 4, '*', '+', '-']
""" """
# Stack where operator will be stocked # Stack where operator will be stocked
@ -101,13 +96,13 @@ def in2post_fix(infix_tokens):
for (pos_token,token) in enumerate(infix_tokens): for (pos_token,token) in enumerate(infix_tokens):
## Pour voir ce qu'il se passe dans cette procédure # Pour voir ce qu'il se passe dans cette procédure
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack)) #print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
if token == ")": if token == ")":
op = opStack.pop() next_op = opStack.pop()
while op != "(": while next_op != "(":
postfix_tokens.append(op) postfix_tokens.append(next_op)
op = opStack.pop() next_op = opStack.pop()
# Go back to old arity # Go back to old arity
arity_Stack.pop() arity_Stack.pop()
@ -115,23 +110,22 @@ def in2post_fix(infix_tokens):
arity = arity_Stack.pop() arity = arity_Stack.pop()
arity_Stack.push(arity + 1) arity_Stack.push(arity + 1)
elif isOperator(token): elif op.can_be_operator(token):
if token == "(": if token == "(":
opStack.push(token) opStack.push(op.get_op(token))
# Set next arity counter # Set next arity counter
arity_Stack.push(0) arity_Stack.push(0)
else: else:
while (not opStack.isEmpty()) and opStack.peek().priority >= token.priority:
op = opStack.pop()
postfix_tokens.append(op)
arity = arity_Stack.pop() arity = arity_Stack.pop()
token_op = op.get_op(token, arity + 1)
token.arity = arity + 1
opStack.push(token)
# print("--", token, " -> ", str(arity + 1))
# Reset arity to 0 in case there is other operators (the real operation would be "-op.arity + 1") # Reset arity to 0 in case there is other operators (the real operation would be "-op.arity + 1")
arity_Stack.push(0) arity_Stack.push(0)
while (not opStack.isEmpty()) and opStack.peek().priority >= token_op.priority:
next_op = opStack.pop()
postfix_tokens.append(next_op)
opStack.push(token_op)
#print("--", token, " -> ", str(arity + 1))
else: else:
postfix_tokens.append(token) postfix_tokens.append(token)
arity = arity_Stack.pop() arity = arity_Stack.pop()
@ -141,8 +135,8 @@ def in2post_fix(infix_tokens):
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack)) #print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
while not opStack.isEmpty(): while not opStack.isEmpty():
op = opStack.pop() next_op = opStack.pop()
postfix_tokens.append(op) postfix_tokens.append(next_op)
## Pour voir ce qu'il se passe dans cette procédure ## Pour voir ce qu'il se passe dans cette procédure
#print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack)) #print(str(postfix_tokens), " | ", str(opStack), " | ", str(infix_tokens[(pos_token+1):]), " | ", str(arity_Stack))
@ -161,7 +155,6 @@ if __name__ == '__main__':
# #
#print(in2post_fix(in_tokens)) #print(in2post_fix(in_tokens))
from .operator import op
print(in2post_fix([op.par, 2, op.add, 5, op.sub, 1, ')', op.div, op.par, 3, op.mul, 4, ')'])) print(in2post_fix([op.par, 2, op.add, 5, op.sub, 1, ')', op.div, op.par, 3, op.mul, 4, ')']))
print(in2post_fix([op.sub1, op.par, op.sub1, 2, ')'])) print(in2post_fix([op.sub1, op.par, op.sub1, 2, ')']))
print(in2post_fix([op.sub1, op.par, op.sub1, 2, op.add, 3, op.mul, 4, ')'])) print(in2post_fix([op.sub1, op.par, op.sub1, 2, op.add, 3, op.mul, 4, ')']))