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
|
2 + 12
|
||||||
14
|
14
|
||||||
|
|
||||||
|
|
||||||
>>> e = Expression.from_str("2+3/2")
|
>>> e = Expression.from_str("2+3/2")
|
||||||
>>> e_simplified = e.simplify()
|
>>> e_simplified = e.simplify()
|
||||||
>>> print(e_simplified)
|
>>> print(e_simplified)
|
||||||
@ -34,6 +35,20 @@ Generate and compute like a student!
|
|||||||
(4 + 3) / 2
|
(4 + 3) / 2
|
||||||
7 / 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 = Expression.from_str("(2/3)^4")
|
||||||
>>> e_simplified = e.simplify()
|
>>> e_simplified = e.simplify()
|
||||||
>>> print(e_simplified)
|
>>> print(e_simplified)
|
||||||
@ -54,10 +69,28 @@ x^2 * x * x^4
|
|||||||
x^3 * x^4
|
x^3 * x^4
|
||||||
x^(3 + 4)
|
x^(3 + 4)
|
||||||
x^7
|
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
|
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'
|
# Reglages pour 'vim'
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
Expression
|
Expression
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from ..core import AssocialTree, Tree, compute, typing
|
from ..core import AssocialTree, Tree, compute, typing, TypingError
|
||||||
from .renders import renders
|
from .renders import renders
|
||||||
|
|
||||||
class Expression(object):
|
class Expression(object):
|
||||||
@ -104,19 +104,30 @@ class Expression(object):
|
|||||||
>>> f._ancestor
|
>>> f._ancestor
|
||||||
<Exp: 2 + 12>
|
<Exp: 2 + 12>
|
||||||
"""
|
"""
|
||||||
|
t = self._tree
|
||||||
if optimize:
|
if optimize:
|
||||||
try:
|
try:
|
||||||
# TODO: need to test exclude_nodes |ven. oct. 5 08:51:02 CEST 2018
|
# TODO: need to test exclude_nodes |ven. oct. 5 08:51:02 CEST 2018
|
||||||
self._tree = self._tree.balance(
|
t = t.balance(
|
||||||
exclude_nodes=["\\", "**"]
|
exclude_nodes=["\\", "**"]
|
||||||
)
|
)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
more_typing = 1
|
||||||
|
while more_typing:
|
||||||
try:
|
try:
|
||||||
t = self._tree.apply_on_last_level(compute, typing)
|
t = t.apply_on_last_level(typing)
|
||||||
except AttributeError:
|
except TypingError:
|
||||||
return self
|
more_typing = 0
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
|
more_typing = 0
|
||||||
|
except AttributeError:
|
||||||
|
more_typing = 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
t = t.apply_on_last_level(compute)
|
||||||
|
except AttributeError:
|
||||||
return self
|
return self
|
||||||
else:
|
else:
|
||||||
e = Expression(t, ancestor=self)
|
e = Expression(t, ancestor=self)
|
||||||
|
@ -18,7 +18,7 @@ Abstracts tools for calculs manipulations
|
|||||||
> *
|
> *
|
||||||
| > 3
|
| > 3
|
||||||
| > 4
|
| > 4
|
||||||
>>> print(t.apply_on_last_level(compute, typing))
|
>>> print(t.apply_on_last_level(compute))
|
||||||
+
|
+
|
||||||
> 2
|
> 2
|
||||||
> 12
|
> 12
|
||||||
@ -34,7 +34,12 @@ Abstracts tools for calculs manipulations
|
|||||||
> /
|
> /
|
||||||
| > 3
|
| > 3
|
||||||
| > 4
|
| > 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
|
| > 2
|
||||||
@ -42,7 +47,12 @@ Abstracts tools for calculs manipulations
|
|||||||
> /
|
> /
|
||||||
| > 3
|
| > 3
|
||||||
| > 4
|
| > 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")
|
>>> t = Tree.from_str("2+3x")
|
||||||
>>> print(t)
|
>>> print(t)
|
||||||
@ -56,7 +66,7 @@ Abstracts tools for calculs manipulations
|
|||||||
|
|
||||||
from .tree import Tree, AssocialTree
|
from .tree import Tree, AssocialTree
|
||||||
from .compute import compute
|
from .compute import compute
|
||||||
from .typing import typing
|
from .typing import typing, TypingError
|
||||||
from .renders import tree2txt, tree2tex
|
from .renders import tree2txt, tree2tex
|
||||||
|
|
||||||
|
|
||||||
|
@ -294,13 +294,10 @@ class Tree(object):
|
|||||||
|
|
||||||
return Tree(self.node, left_applied, right_applied)
|
return Tree(self.node, left_applied, right_applied)
|
||||||
|
|
||||||
def apply_on_last_level(self,
|
def apply_on_last_level(self, function):
|
||||||
function,
|
|
||||||
fallback = lambda n,l,r: Tree(n,l,r)):
|
|
||||||
""" Apply the function on last level of the tree before leaf
|
""" Apply the function on last level of the tree before leaf
|
||||||
|
|
||||||
:param function: (op, a, a) -> b function to apply on last level
|
: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
|
:returns: b if it is a 1 level Tree, Tree otherwise
|
||||||
|
|
||||||
|
|
||||||
@ -330,30 +327,17 @@ class Tree(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
left_is_leaf = 0
|
left_is_leaf = 0
|
||||||
right_is_leaf = 0
|
|
||||||
try:
|
try:
|
||||||
left_applied = self.left_value.\
|
left_applied = self.left_value.\
|
||||||
apply_on_last_level(function, fallback)
|
apply_on_last_level(function)
|
||||||
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)
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
left_applied = self.left_value
|
left_applied = self.left_value
|
||||||
left_is_leaf = 1
|
left_is_leaf = 1
|
||||||
|
|
||||||
|
right_is_leaf = 0
|
||||||
try:
|
try:
|
||||||
right_applied = self.right_value.\
|
right_applied = self.right_value.\
|
||||||
apply_on_last_level(function, fallback)
|
apply_on_last_level(function)
|
||||||
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)
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
right_applied = self.right_value
|
right_applied = self.right_value
|
||||||
right_is_leaf = 1
|
right_is_leaf = 1
|
||||||
|
Loading…
Reference in New Issue
Block a user