From ab0862e10a4347042cfbda8774f48bdec54386e5 Mon Sep 17 00:00:00 2001 From: lafrite Date: Sun, 21 Jun 2015 20:43:38 +0200 Subject: [PATCH] solve bug with some poly evaluation!! --- debug/tools.py | 4 +++ pymath/expression.py | 14 ++++++++-- pymath/fraction.py | 1 - pymath/operator.py | 61 ++++++++++++++++++++++---------------------- pymath/polynom.py | 50 +++++++++++++++++++++++++++++++----- 5 files changed, 91 insertions(+), 39 deletions(-) diff --git a/debug/tools.py b/debug/tools.py index 6b7ef2a..44ddd29 100644 --- a/debug/tools.py +++ b/debug/tools.py @@ -21,6 +21,7 @@ def report(fn): )) print( "Call %s%s called [#%s]" + % (indent, fc, call)) __report_indent[0] += 1 ret = fn(*params,**kwargs) @@ -29,7 +30,10 @@ def report(fn): print(' '*(__report_indent[0]+4), "ret.steps -> ", len(ret.steps)) except AttributeError: print(' '*(__report_indent[0]+4), ret, " has no steps") + 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)) return ret diff --git a/pymath/expression.py b/pymath/expression.py index ed4043f..9860b0b 100644 --- a/pymath/expression.py +++ b/pymath/expression.py @@ -86,35 +86,45 @@ class Expression(Explicable): """ expression = object.__new__(cls) + if type(exp) == str: expression.postfix_tokens = str2tokens(exp) + elif type(exp) == list: # 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] expression.postfix_tokens = flatten_list([tok.postfix_tokens if Expression.isExpression(tok) else tok for tok in exp_mod_op]) + elif type(exp) == Expression: return exp + + elif isNumerand(exp): + expression.postfix_tokens = [exp] + else: raise ValueError("Can't build Expression with {} object".format(type(exp))) if len(expression.postfix_tokens) == 1: token = expression.postfix_tokens[0] + if type(token) == Fake_int or type(token) == int: return Fake_int(token) + elif hasattr(token, 'simplify') and hasattr(token, 'explain'): ans = expression.postfix_tokens[0] return ans elif type(token) == str: # TODO: Pourquoi ne pas créer directement un polynom ici? |jeu. févr. 26 18:59:24 CET 2015 - # On crée un faux str en ajoutant la méthode simplify et simplified et la caractérisique isNumber + # On crée un faux str en ajoutant la méthode simplify et simplified et la caractérisique isNumber simplify = lambda x:[x] is_polynom = True methods_attr = {'simplify':simplify, '_isPolynom': is_polynom, 'postfix_tokens': [token]} fake_token = type('fake_str', (str,Explicable, ), methods_attr)(token) return fake_token + else: - raise ValueError("Unknow type in Expression: {}".format(type(token))) + raise ValueError("Unknow token type in Expression: {}".format(type(token))) else: expression._isExpression = 1 diff --git a/pymath/fraction.py b/pymath/fraction.py index fe72c48..61c2d49 100644 --- a/pymath/fraction.py +++ b/pymath/fraction.py @@ -190,7 +190,6 @@ class Fraction(Explicable): ans = exp.simplify() ini_step = Expression(self.postfix_tokens + number.postfix_tokens + [op.add]) ans.steps = [ini_step] + ans.steps - #print("\t\tIn add ans.steps -> ", ans.steps) return ans def __radd__(self, other): diff --git a/pymath/operator.py b/pymath/operator.py index a211420..b83e2a8 100644 --- a/pymath/operator.py +++ b/pymath/operator.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 +#from debug.tools import report from .generic import flatten_list, isNumber from functools import wraps @@ -37,7 +38,8 @@ class Operator(str): return getattr(args[0], self.actions)() 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]) else: return getattr(args[1], self.actions[1])(args[0]) @@ -245,35 +247,6 @@ class op(object): ("(", 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 @operatorize def add(cls): @@ -610,6 +583,34 @@ class op(object): } 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__': #print(op.add.__tex__('1','2')) #print(op.mul.__tex__('1','2')) diff --git a/pymath/polynom.py b/pymath/polynom.py index cfe70bf..4caa56f 100644 --- a/pymath/polynom.py +++ b/pymath/polynom.py @@ -138,10 +138,10 @@ class Polynom(AbstractPolynom): 3 h^{ 2 } + 8 h + 6 >>> R = P(Q) """ - if isNumerand(value) or Expression.isExpression(value): - postfix_exp = [value if i==self._letter else i for i in self.postfix_tokens] - else: - postfix_exp = [Expression(value) if i==self._letter else i for i in self.postfix_tokens] + #if isNumerand(value) or Expression.isExpression(value): + # postfix_exp = [value if i==self._letter else i for i in self.postfix_tokens] + #else: + postfix_exp = [Expression(value) if i==self._letter else i for i in self.postfix_tokens] return Expression(postfix_exp).simplify() @@ -230,8 +230,46 @@ if __name__ == '__main__': # print(i) #Polynom.random(degree = 2, conditions=["{b**2-4*a*c}>0"]) # Polynom deg 2 with positive Delta (ax^2 + bx + c) - import doctest - doctest.testmod(optionflags=doctest.ELLIPSIS) + #import doctest + #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)) # -----------------------------