Fix(API): Rewrite tree apply_on_last_level and reorganise simplify
This commit is contained in:
parent
6edf4fe5b4
commit
e37a8a5a2e
@ -21,6 +21,7 @@ Generate and compute like a student!
|
||||
2 + 12
|
||||
14
|
||||
|
||||
|
||||
>>> e = Expression.from_str("2+3/2")
|
||||
>>> e_simplified = e.simplify()
|
||||
>>> print(e_simplified)
|
||||
@ -34,6 +35,20 @@ Generate and compute like a student!
|
||||
(4 + 3) / 2
|
||||
7 / 2
|
||||
|
||||
>>> e = Expression.from_str("(2+3)/2 + 1")
|
||||
>>> e_simplified = e.simplify()
|
||||
>>> print(e_simplified)
|
||||
7 / 2
|
||||
>>> for s in e_simplified.explain():
|
||||
... print(s)
|
||||
(2 + 3) / 2 + 1
|
||||
5 / 2 + 1
|
||||
5 / 2 + 1 / 1
|
||||
5 / 2 + (1 * 2) / (1 * 2)
|
||||
5 / 2 + 2 / 2
|
||||
(5 + 2) / 2
|
||||
7 / 2
|
||||
|
||||
>>> e = Expression.from_str("(2/3)^4")
|
||||
>>> e_simplified = e.simplify()
|
||||
>>> print(e_simplified)
|
||||
@ -54,10 +69,28 @@ x^2 * x * x^4
|
||||
x^3 * x^4
|
||||
x^(3 + 4)
|
||||
x^7
|
||||
|
||||
>>> e = Expression.from_str("2x+2+3x")
|
||||
>>> e_simplified = e.simplify()
|
||||
>>> print(e_simplified)
|
||||
5x + 2
|
||||
>>> for s in e_simplified.explain():
|
||||
... print(s)
|
||||
2x + 2 + 3x
|
||||
2x + 3x + 2
|
||||
(2 + 3) * x + 2
|
||||
5x + 2
|
||||
"""
|
||||
|
||||
from .expression import Expression
|
||||
|
||||
if __name__ == "__main__":
|
||||
e = Expression.from_str("2x+2+3x")
|
||||
print(e)
|
||||
e_simplified = e.simplify()
|
||||
print(e_simplified)
|
||||
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
|
@ -10,7 +10,7 @@
|
||||
Expression
|
||||
|
||||
"""
|
||||
from ..core import AssocialTree, Tree, compute, typing
|
||||
from ..core import AssocialTree, Tree, compute, typing, TypingError
|
||||
from .renders import renders
|
||||
|
||||
class Expression(object):
|
||||
@ -104,19 +104,30 @@ class Expression(object):
|
||||
>>> f._ancestor
|
||||
<Exp: 2 + 12>
|
||||
"""
|
||||
t = self._tree
|
||||
if optimize:
|
||||
try:
|
||||
# TODO: need to test exclude_nodes |ven. oct. 5 08:51:02 CEST 2018
|
||||
self._tree = self._tree.balance(
|
||||
t = t.balance(
|
||||
exclude_nodes=["\\", "**"]
|
||||
)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
more_typing = 1
|
||||
while more_typing:
|
||||
try:
|
||||
t = self._tree.apply_on_last_level(compute, typing)
|
||||
except AttributeError:
|
||||
return self
|
||||
t = t.apply_on_last_level(typing)
|
||||
except TypingError:
|
||||
more_typing = 0
|
||||
except NotImplementedError:
|
||||
more_typing = 0
|
||||
except AttributeError:
|
||||
more_typing = 0
|
||||
|
||||
try:
|
||||
t = t.apply_on_last_level(compute)
|
||||
except AttributeError:
|
||||
return self
|
||||
else:
|
||||
e = Expression(t, ancestor=self)
|
||||
|
@ -18,7 +18,7 @@ Abstracts tools for calculs manipulations
|
||||
> *
|
||||
| > 3
|
||||
| > 4
|
||||
>>> print(t.apply_on_last_level(compute, typing))
|
||||
>>> print(t.apply_on_last_level(compute))
|
||||
+
|
||||
> 2
|
||||
> 12
|
||||
@ -34,7 +34,12 @@ Abstracts tools for calculs manipulations
|
||||
> /
|
||||
| > 3
|
||||
| > 4
|
||||
>>> print(t.apply_on_last_level(compute, typing))
|
||||
>>> print(t.apply_on_last_level(compute))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
NotImplementedError: Can't divide 2 int. Need to create a Fraction instead
|
||||
>>> tt = t.apply_on_last_level(typing)
|
||||
>>> print(tt.apply_on_last_level(compute))
|
||||
+
|
||||
> /
|
||||
| > 2
|
||||
@ -42,7 +47,12 @@ Abstracts tools for calculs manipulations
|
||||
> /
|
||||
| > 3
|
||||
| > 4
|
||||
|
||||
>>> type(t.right_value)
|
||||
<class 'mapytex.calculus.core.tree.Tree'>
|
||||
>>> type(tt.right_value)
|
||||
<class 'mapytex.calculus.core.MO.fraction.MOFraction'>
|
||||
>>> tt.right_value
|
||||
<MOFraction 3 / 4>
|
||||
|
||||
>>> t = Tree.from_str("2+3x")
|
||||
>>> print(t)
|
||||
@ -56,7 +66,7 @@ Abstracts tools for calculs manipulations
|
||||
|
||||
from .tree import Tree, AssocialTree
|
||||
from .compute import compute
|
||||
from .typing import typing
|
||||
from .typing import typing, TypingError
|
||||
from .renders import tree2txt, tree2tex
|
||||
|
||||
|
||||
|
@ -294,13 +294,10 @@ class Tree(object):
|
||||
|
||||
return Tree(self.node, left_applied, right_applied)
|
||||
|
||||
def apply_on_last_level(self,
|
||||
function,
|
||||
fallback = lambda n,l,r: Tree(n,l,r)):
|
||||
def apply_on_last_level(self, function):
|
||||
""" Apply the function on last level of the tree before leaf
|
||||
|
||||
:param function: (op, a, a) -> b function to apply on last level
|
||||
:param fallback: (op, a, a) -> b fallback function to apply on subtree which raise a NotImplementedError. The return value will be concidered as an leaf
|
||||
:returns: b if it is a 1 level Tree, Tree otherwise
|
||||
|
||||
|
||||
@ -330,30 +327,17 @@ class Tree(object):
|
||||
"""
|
||||
|
||||
left_is_leaf = 0
|
||||
right_is_leaf = 0
|
||||
try:
|
||||
left_applied = self.left_value.\
|
||||
apply_on_last_level(function, fallback)
|
||||
except NotImplementedError:
|
||||
# TODO: overload __getitem__ to ease unpacking |dim. sept. 23 19:17:50 CEST 2018
|
||||
left_is_leaf = 1
|
||||
left_tree = self.left_value
|
||||
left_applied = fallback(left_tree.node,
|
||||
left_tree.left_value,
|
||||
left_tree.right_value)
|
||||
apply_on_last_level(function)
|
||||
except AttributeError:
|
||||
left_applied = self.left_value
|
||||
left_is_leaf = 1
|
||||
|
||||
right_is_leaf = 0
|
||||
try:
|
||||
right_applied = self.right_value.\
|
||||
apply_on_last_level(function, fallback)
|
||||
except NotImplementedError:
|
||||
right_is_leaf = 1
|
||||
right_tree = self.right_value
|
||||
right_applied = fallback(right_tree.node,
|
||||
right_tree.left_value,
|
||||
right_tree.right_value)
|
||||
apply_on_last_level(function)
|
||||
except AttributeError:
|
||||
right_applied = self.right_value
|
||||
right_is_leaf = 1
|
||||
|
Loading…
Reference in New Issue
Block a user