solve bug with some poly evaluation!!

This commit is contained in:
lafrite 2015-06-21 20:43:38 +02:00
parent 2e8cd9dd48
commit ab0862e10a
5 changed files with 91 additions and 39 deletions

View File

@ -21,6 +21,7 @@ def report(fn):
)) ))
print( "Call %s%s called [#%s]" print( "Call %s%s called [#%s]"
% (indent, fc, call)) % (indent, fc, call))
__report_indent[0] += 1 __report_indent[0] += 1
ret = fn(*params,**kwargs) ret = fn(*params,**kwargs)
@ -29,7 +30,10 @@ def report(fn):
print(' '*(__report_indent[0]+4), "ret.steps -> ", len(ret.steps)) print(' '*(__report_indent[0]+4), "ret.steps -> ", len(ret.steps))
except AttributeError: except AttributeError:
print(' '*(__report_indent[0]+4), ret, " has no steps") print(' '*(__report_indent[0]+4), ret, " has no steps")
print( "End %s%s returned %s [#%s]" print( "End %s%s returned %s [#%s]"
#% (indent, fc, repr(ret), call))
#% (indent, fc, [i for i in ret.postfix_tokens], call))
% (indent, fc, repr(ret), call)) % (indent, fc, repr(ret), call))
return ret return ret

View File

@ -86,21 +86,30 @@ class Expression(Explicable):
""" """
expression = object.__new__(cls) expression = object.__new__(cls)
if type(exp) == str: if type(exp) == str:
expression.postfix_tokens = str2tokens(exp) expression.postfix_tokens = str2tokens(exp)
elif type(exp) == list: elif type(exp) == list:
# Ici on ne peut convertir les "+" en opérateur que s'ils sont d'arité 2. # Ici on ne peut convertir les "+" en opérateur que s'ils sont d'arité 2.
exp_mod_op = [op.get_op(i) if op.can_be_operator(i) else i for i in exp] exp_mod_op = [op.get_op(i) if op.can_be_operator(i) else i for i in exp]
expression.postfix_tokens = flatten_list([tok.postfix_tokens if Expression.isExpression(tok) else tok for tok in exp_mod_op]) expression.postfix_tokens = flatten_list([tok.postfix_tokens if Expression.isExpression(tok) else tok for tok in exp_mod_op])
elif type(exp) == Expression: elif type(exp) == Expression:
return exp return exp
elif isNumerand(exp):
expression.postfix_tokens = [exp]
else: else:
raise ValueError("Can't build Expression with {} object".format(type(exp))) raise ValueError("Can't build Expression with {} object".format(type(exp)))
if len(expression.postfix_tokens) == 1: if len(expression.postfix_tokens) == 1:
token = expression.postfix_tokens[0] token = expression.postfix_tokens[0]
if type(token) == Fake_int or type(token) == int: if type(token) == Fake_int or type(token) == int:
return Fake_int(token) return Fake_int(token)
elif hasattr(token, 'simplify') and hasattr(token, 'explain'): elif hasattr(token, 'simplify') and hasattr(token, 'explain'):
ans = expression.postfix_tokens[0] ans = expression.postfix_tokens[0]
return ans return ans
@ -113,8 +122,9 @@ class Expression(Explicable):
methods_attr = {'simplify':simplify, '_isPolynom': is_polynom, 'postfix_tokens': [token]} methods_attr = {'simplify':simplify, '_isPolynom': is_polynom, 'postfix_tokens': [token]}
fake_token = type('fake_str', (str,Explicable, ), methods_attr)(token) fake_token = type('fake_str', (str,Explicable, ), methods_attr)(token)
return fake_token return fake_token
else: else:
raise ValueError("Unknow type in Expression: {}".format(type(token))) raise ValueError("Unknow token type in Expression: {}".format(type(token)))
else: else:
expression._isExpression = 1 expression._isExpression = 1

View File

@ -190,7 +190,6 @@ class Fraction(Explicable):
ans = exp.simplify() ans = exp.simplify()
ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.add]) ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.add])
ans.steps = [ini_step] + ans.steps ans.steps = [ini_step] + ans.steps
#print("\t\tIn add ans.steps -> ", ans.steps)
return ans return ans
def __radd__(self, other): def __radd__(self, other):

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
#from debug.tools import report
from .generic import flatten_list, isNumber from .generic import flatten_list, isNumber
from functools import wraps from functools import wraps
@ -37,7 +38,8 @@ class Operator(str):
return getattr(args[0], self.actions)() return getattr(args[0], self.actions)()
elif self.arity == 2: elif self.arity == 2:
if type(args[1]) == int: #if type(args[1]) == int:
if issubclass(type(args[1]),int):
return getattr(args[0], self.actions[0])(args[1]) return getattr(args[0], self.actions[0])(args[1])
else: else:
return getattr(args[1], self.actions[1])(args[0]) return getattr(args[1], self.actions[1])(args[0])
@ -245,35 +247,6 @@ class op(object):
("(", 2): "par",\ ("(", 2): "par",\
} }
@classmethod
def get_op(cls, op, arity = 2):
"""Return the corresponding operator
:op: symbole of the op
:arity: the arity
>>> op.get_op('+')
'+'
>>> mul = op.get_op('*')
>>> mul.tex
'{op1} \\\\times {op2}'
>>> mul.txt
'{op1} * {op2}'
"""
try:
return getattr(cls, cls._operators[(op, arity)])
except KeyError:
raise KeyError("{theOp} (arity: {arity}) is not available".format(theOp = op, arity = arity))
@classmethod
def can_be_operator(cls, symbole):
""" Tell if the symbole can be an operator """
if type(symbole) == str:
return symbole in [i[0] for i in cls._operators]
else:
return False
@ClassProperty @ClassProperty
@operatorize @operatorize
def add(cls): def add(cls):
@ -610,6 +583,34 @@ class op(object):
} }
return caract return caract
@classmethod
def get_op(cls, op, arity = 2):
"""Return the corresponding operator
:op: symbole of the op
:arity: the arity
>>> op.get_op('+')
'+'
>>> mul = op.get_op('*')
>>> mul.tex
'{op1} \\\\times {op2}'
>>> mul.txt
'{op1} * {op2}'
"""
try:
return getattr(cls, cls._operators[(op, arity)])
except KeyError:
raise KeyError("{theOp} (arity: {arity}) is not available".format(theOp = op, arity = arity))
@classmethod
def can_be_operator(cls, symbole):
""" Tell if the symbole can be an operator """
if type(symbole) == str:
return symbole in [i[0] for i in cls._operators]
else:
return False
if __name__ == '__main__': if __name__ == '__main__':
#print(op.add.__tex__('1','2')) #print(op.add.__tex__('1','2'))
#print(op.mul.__tex__('1','2')) #print(op.mul.__tex__('1','2'))

View File

@ -138,9 +138,9 @@ class Polynom(AbstractPolynom):
3 h^{ 2 } + 8 h + 6 3 h^{ 2 } + 8 h + 6
>>> R = P(Q) >>> R = P(Q)
""" """
if isNumerand(value) or Expression.isExpression(value): #if isNumerand(value) or Expression.isExpression(value):
postfix_exp = [value if i==self._letter else i for i in self.postfix_tokens] # postfix_exp = [value if i==self._letter else i for i in self.postfix_tokens]
else: #else:
postfix_exp = [Expression(value) if i==self._letter else i for i in self.postfix_tokens] postfix_exp = [Expression(value) if i==self._letter else i for i in self.postfix_tokens]
return Expression(postfix_exp).simplify() return Expression(postfix_exp).simplify()
@ -230,8 +230,46 @@ if __name__ == '__main__':
# print(i) # print(i)
#Polynom.random(degree = 2, conditions=["{b**2-4*a*c}>0"]) # Polynom deg 2 with positive Delta (ax^2 + bx + c) #Polynom.random(degree = 2, conditions=["{b**2-4*a*c}>0"]) # Polynom deg 2 with positive Delta (ax^2 + bx + c)
import doctest #import doctest
doctest.testmod(optionflags=doctest.ELLIPSIS) #doctest.testmod(optionflags=doctest.ELLIPSIS)
# while True:
# P = Polynom.random(degree = 2)
# e = Expression.random("{a}/{b}")
# try:
# P(e)
# except RuntimeError:
# print(" P -> " + str(P))
# print(" e -> " + str(e))
#
# import sys
# sys.setrecursionlimit(100)
from .fraction import Fraction
from itertools import permutations
P = Polynom([-5,6,-4])
f = Fraction(2,5)
P(f)
try:
P(f)
except Exception as e:
print(e)
print("-----------------\n")
f = Fraction(2,15)
print(str(P).replace('x','('+str(f)+')'),"= ", P(f))
print("-----------------\n")
f = Fraction(2,3)
print(P(f))
#coefs_p = [[(i-2),(j-2)] for i,j in permutations(range(20),2)]
#fractions = [Fraction(i,j) for i,j in coefs_p if j!=0]
#for f in fractions:
# try:
# P(f)
# #print("ok f -> " + str(f))
# except RuntimeError:
# print(" f -> " + str(f))
# ----------------------------- # -----------------------------