diff --git a/mapytex/calculus/API/__init__.py b/mapytex/calculus/API/__init__.py index 8d74ae3..5db61aa 100644 --- a/mapytex/calculus/API/__init__.py +++ b/mapytex/calculus/API/__init__.py @@ -84,15 +84,14 @@ x^7 >>> e = Expression.from_str("1+2x^2+3x+4+5x") >>> e_simplified = e.simplify() >>> print(e_simplified) -2x^2 + 5 + 8x +5 + 2x^2 + 8x >>> for s in e_simplified.explain(): ... print(s) 1 + 2x^2 + 3x + 4 + 5x -2x^2 + 3x + 1 + 4 + 5x -3x + 5 + 2x^2 + 5x -2x^2 + 3x + 5x + 5 -2x^2 + (3 + 5) * x + 5 -2x^2 + 5 + 8x +1 + 2x^2 + 3x + 4 + 5x +1 + 4 + 2x^2 + 3x + 5x +5 + 2x^2 + (3 + 5) * x +5 + 2x^2 + 8x """ @@ -100,9 +99,19 @@ x^7 from .expression import Expression if __name__ == "__main__": - e = Expression.from_str("2+3/4") - e_simplified = e.simplify() - print(e_simplified) + e = Expression.from_str("1+2/3/4/5") + et = e._typing() + print("typing") + print(e._tree) + e = et._order() + print("order") + print(e._tree) + e = e._optimize() + print("then optimize") + print(e._tree) + e = et._optimize() + print("optimize without order") + print(e._tree) # ----------------------------- # Reglages pour 'vim' diff --git a/mapytex/calculus/API/expression.py b/mapytex/calculus/API/expression.py index 660ec91..d06a608 100644 --- a/mapytex/calculus/API/expression.py +++ b/mapytex/calculus/API/expression.py @@ -88,7 +88,45 @@ class Expression(object): def __repr__(self): return f"" - def _optimize(self, exclude_nodes=["\\", "**"]): + def _order(self, exclude_nodes=["*", "/", "**"]): + """ Order the expression base on types + + :example: + + >>> e = Expression.from_str("1 + 2x + 3 + 4x") + >>> print(e) + 1 + 2x + 3 + 4x + >>> #print(e._order()) + 1 + 3 + 2x + 4x + >>> e = Expression.from_str("x + 6x^3 + 1 + 2x^2 + 3 + 4x^2 + 5x") + >>> print(e._order()) + x + 5x + 6x^3 + 2x^2 + 4x^2 + 1 + 3 + """ + def signature(leaf): + try: + leaf.node + except AttributeError: + try: + return leaf.signature + except AttributeError: + return type(leaf) + else: + try: + typed_leaf = typing(leaf.node, leaf.left_value, leaf.right_value) + return typed_leaf.signature + except (AttributeError, NotImplementedError, TypingError): + return type(leaf) + + try: + self._tree.node + except AttributeError: + return self + + organised = AssocialTree.from_any_tree(self._tree).\ + organise_by(signature, recursive=True, exclude_nodes=exclude_nodes) + return Expression(organised) + + def _optimize(self, exclude_nodes=["/", "**"]): """ Return a copy of self with an optimize tree :example: @@ -199,7 +237,8 @@ class Expression(object): typed_exp = self._typing() if optimize: - opt_exp = typed_exp._optimize() + organized_exp = typed_exp._order() + opt_exp = organized_exp._optimize() else: opt_exp = typed_exp @@ -228,9 +267,9 @@ class Expression(object): >>> for s in f.explain(): ... print(s) 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 - 3 + 3 + 9 + 6 + 7 + 17 - 6 + 9 + 6 + 24 - 15 + 30 + 3 + 7 + 11 + 7 + 17 + 10 + 11 + 24 + 10 + 35 45 >>> e = Expression.from_str("1+2+3+4+5+6+7+8+9") >>> f_no_balance = e.simplify(optimize=False) @@ -250,10 +289,11 @@ class Expression(object): >>> for s in f.explain(): ... print(s) 1 + 2 + 3 + 4 + 5 * 6 * 7 * 8 * 9 - 3 + 3 + 4 + 30 * 7 * 72 - 6 + 4 + 210 * 72 + 3 + 7 + 30 * 7 * 72 + 10 + 210 * 72 10 + 15120 15130 + >>> e = Expression.from_str("1+2+3+4+5*6*7*8*9") >>> f_no_balance = e.simplify(optimize=False) >>> for s in f_no_balance.explain():