Create real class Operator and include it into expression (need to fix
render now)
This commit is contained in:
parent
4630d0de74
commit
6e99dadd39
@ -1,7 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from .generic import Stack, flatten_list, expand_list, Operator
|
||||
from .generic import Stack, flatten_list, expand_list
|
||||
from .operator import Operator
|
||||
from .fraction import Fraction
|
||||
from .renders import txt, post2in_fix, tex
|
||||
|
||||
@ -81,20 +82,36 @@ class Expression(object):
|
||||
tmpTokenList = []
|
||||
|
||||
while len(tokenList) > 2:
|
||||
# on va chercher les motifs du genre A B + pour les calculer
|
||||
if self.isNumber(tokenList[0]) and self.isNumber(tokenList[1]) and self.isOperator(tokenList[2]):
|
||||
# on va chercher les motifs du genre A B +, quad l'operateur est d'arité 2, pour les calculer
|
||||
if self.isNumber(tokenList[0]) and self.isNumber(tokenList[1]) \
|
||||
and type(tokenList[2]) == Operator and tokenList[2].arity == 2 :
|
||||
|
||||
# S'il y a une opération à faire
|
||||
op1 = tokenList[0]
|
||||
op2 = tokenList[1]
|
||||
token = tokenList[2]
|
||||
operator = tokenList[2]
|
||||
|
||||
res = self.doMath(token, op1, op2)
|
||||
res = operator(op1, op2)
|
||||
|
||||
tmpTokenList.append(res)
|
||||
|
||||
# Comme on vient de faire le calcul, on peut détruire aussi les deux prochains termes
|
||||
del tokenList[0:3]
|
||||
|
||||
elif self.isNumber(tokenList[0]) \
|
||||
and type(tokenList[1]) == Operator and tokenList[1].arity == 1 :
|
||||
|
||||
# S'il y a une opération à faire
|
||||
op1 = tokenList[0]
|
||||
operator = tokenList[1]
|
||||
|
||||
res = operator(op1)
|
||||
|
||||
tmpTokenList.append(res)
|
||||
|
||||
# Comme on vient de faire le calcul, on peut détruire aussi les deux prochains termes
|
||||
del tokenList[0:2]
|
||||
|
||||
else:
|
||||
tmpTokenList.append(tokenList[0])
|
||||
|
||||
@ -106,7 +123,9 @@ class Expression(object):
|
||||
if len(steps[:-1]) > 0:
|
||||
self.steps += [flatten_list(s) for s in steps[:-1]]
|
||||
|
||||
print("self.steps -> ", self.steps)
|
||||
self.child = Expression(steps[-1])
|
||||
print("self.child -> ", self.child)
|
||||
|
||||
## ---------------------
|
||||
## String parsing
|
||||
@ -281,7 +300,6 @@ class Expression(object):
|
||||
arity_Stack.push(arity + 1)
|
||||
|
||||
elif cls.isOperator(token):
|
||||
# On doit ajouter la condition == str sinon python ne veut pas tester l'appartenance à la chaine de caractère.
|
||||
while (not opStack.isEmpty()) and (cls.PRIORITY[opStack.peek()] >= cls.PRIORITY[token]):
|
||||
op = opStack.pop()
|
||||
postfix_tokens.append(op)
|
||||
@ -308,32 +326,6 @@ class Expression(object):
|
||||
|
||||
return postfix_tokens
|
||||
|
||||
## ---------------------
|
||||
## Computing the expression
|
||||
|
||||
@staticmethod
|
||||
def doMath(op, op1, op2):
|
||||
"""Compute "op1 op op2" or create a fraction
|
||||
|
||||
:param op: operator
|
||||
:param op1: first operande
|
||||
:param op2: second operande
|
||||
:returns: string representing the result
|
||||
|
||||
"""
|
||||
if op == "/":
|
||||
ans = [Fraction(op1, op2)]
|
||||
ans += ans[0].simplify()
|
||||
return ans
|
||||
else:
|
||||
if type(op2) != int:
|
||||
operations = {"+": "__radd__", "-": "__rsub__", "*": "__rmul__"}
|
||||
return getattr(op2,operations[op])(op1)
|
||||
else:
|
||||
operations = {"+": "__add__", "-": "__sub__", "*": "__mul__", "^": "__pow__"}
|
||||
return getattr(op1,operations[op])(op2)
|
||||
|
||||
|
||||
## ---------------------
|
||||
## Recognize numbers and operators
|
||||
|
||||
@ -367,12 +359,13 @@ def test(exp):
|
||||
print("\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
Expression.STR_RENDER = txt
|
||||
#exp = "2 ^ 3 * 5"
|
||||
#test(exp)
|
||||
#Expression.STR_RENDER = txt
|
||||
Expression.STR_RENDER = lambda x: str(x)
|
||||
exp = "2 ^ 3 * 5"
|
||||
test(exp)
|
||||
|
||||
#exp = "1 + 3 * 5"
|
||||
#test(exp)
|
||||
exp = "1 + 3 * 5"
|
||||
test(exp)
|
||||
|
||||
#exp = "2 * 3 * 3 * 5"
|
||||
#test(exp)
|
||||
|
@ -57,17 +57,6 @@ class Stack(object):
|
||||
def __add__(self, addList):
|
||||
return self.items + addList
|
||||
|
||||
class Operator(str):
|
||||
|
||||
"""The operator class, is a string (representation of the operator) with its arity (?!? - arrite)"""
|
||||
|
||||
def __new__(cls, operator, arity = 2):
|
||||
op = str.__new__(cls, operator)
|
||||
op.arity = arity
|
||||
return op
|
||||
|
||||
|
||||
|
||||
def flatten_list(a, result=None):
|
||||
"""Flattens a nested list.
|
||||
|
||||
|
50
pymath/operator.py
Normal file
50
pymath/operator.py
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
class Operator(str):
|
||||
|
||||
"""The operator class, is a string (representation of the operator) with its arity"""
|
||||
|
||||
OPERATORS = { \
|
||||
"+": ["", "", ("__add__","__radd__")],\
|
||||
"-": ["", "__neg__", ("__sub__", "__rsub__")], \
|
||||
"*": ["", "", ("__mul__", "__rmul__")], \
|
||||
"/": ["", "", ("__div__","__rdiv__")], \
|
||||
"^": ["", "", ("__pow__", "")] \
|
||||
}
|
||||
|
||||
def __new__(cls, operator, arity = 2):
|
||||
op = str.__new__(cls, operator)
|
||||
op.arity = arity
|
||||
|
||||
op.actions = cls.OPERATORS[operator][arity]
|
||||
|
||||
return op
|
||||
|
||||
def __call__(self, *args):
|
||||
""" Calling this operator performs the rigth calculus """
|
||||
if self.arity == 1:
|
||||
return getattr(args[0], self.actions)()
|
||||
|
||||
elif self.arity == 2:
|
||||
# C'est moche mais je veux que ça marche...
|
||||
if str(self) == "/":
|
||||
ans = [Fraction(op1, op2)]
|
||||
ans += ans[0].simplify()
|
||||
return ans
|
||||
else:
|
||||
if type(args[1]) == int:
|
||||
return getattr(args[0], self.actions[0])(args[1])
|
||||
else:
|
||||
return getattr(args[1], self.actions[1])(args[0])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
Loading…
Reference in New Issue
Block a user