Fix(steps): Typing steps are bypassed

Useless steps where complex objects were built are not shown. I create
a typing function which is called when compute raise
NotImplementedError.
This commit is contained in:
Bertrand Benjamin 2018-09-24 17:21:50 +02:00
parent 0e479323dd
commit a557fa3981
7 changed files with 149 additions and 13 deletions

View File

@ -10,7 +10,7 @@
Expression Expression
""" """
from ..core import Tree, compute from ..core import Tree, compute, typing
from .renders import renders from .renders import renders
class Expression(object): class Expression(object):
@ -104,9 +104,11 @@ class Expression(object):
<Exp: 2 + 12> <Exp: 2 + 12>
""" """
try: try:
t = self._tree.apply_on_last_level(compute) t = self._tree.apply_on_last_level(compute, typing)
except AttributeError: except AttributeError:
return self return self
except NotImplementedError:
return self
else: else:
e = Expression(t, ancestor=self) e = Expression(t, ancestor=self)
return e.simplify() return e.simplify()

View File

@ -37,10 +37,8 @@ Abstracts tools for calculs manipulations
>>> print(t.apply_on_last_level(compute, typing)) >>> print(t.apply_on_last_level(compute, typing))
+ +
> / > /
| > * | > 2
| | > 2 | > 1
| | > 4
| > 4
> / > /
| > 3 | > 3
| > 4 | > 4

View File

@ -10,6 +10,7 @@
Divide MO Divide MO
""" """
from decimal import Decimal
from multipledispatch import Dispatcher from multipledispatch import Dispatcher
from ..tree import Tree from ..tree import Tree
from ..MO.mo import MO, MOnumber from ..MO.mo import MO, MOnumber
@ -66,12 +67,22 @@ def divide_filter(left, right):
def monumber_monumber(left, right): def monumber_monumber(left, right):
""" Divide 2 monumbers and return a MOFraction """ Divide 2 monumbers and return a MOFraction
>>> a = MOnumber(4)
>>> b = MOnumber(6.2)
>>> monumber_monumber(a, b)
Decimal('0.6451612903225806266768278939')
>>> a = MOnumber(4) >>> a = MOnumber(4)
>>> b = MOnumber(6) >>> b = MOnumber(6)
>>> monumber_monumber(a, b) >>> monumber_monumber(a, b)
<MOFraction 4 / 6> Traceback (most recent call last):
...
NotImplementedError: Can't divide 2 int. Need to create a Fraction instead
""" """
return MOFraction(left, right) if type(left.value) in [float, Decimal] or \
type(right.value) in [float, Decimal]:
return left / right
else:
raise NotImplementedError("Can't divide 2 int. Need to create a Fraction instead")
@divide.register(MOnumber, MOFraction) @divide.register(MOnumber, MOFraction)
@special_case(divide_filter) @special_case(divide_filter)

View File

@ -294,10 +294,13 @@ 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, function): def apply_on_last_level(self,
function,
type_function = 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 :param function: (op, a, a) -> b function to apply on last level
:param type_function: (op, a, a) -> b typing function to apply on subtree which raise a TypeError. 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
@ -325,22 +328,38 @@ class Tree(object):
>>> print(ttt) >>> print(ttt)
14 14
""" """
left_is_leaf = 0 left_is_leaf = 0
right_is_leaf = 0 right_is_leaf = 0
try: try:
left_applied = self.left_value.apply_on_last_level(function) left_applied = self.left_value.\
apply_on_last_level(function, type_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 = type_function(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
try: try:
right_applied = self.right_value.apply_on_last_level(function) right_applied = self.right_value.\
apply_on_last_level(function, type_function)
except NotImplementedError:
right_is_leaf = 1
right_tree = self.right_value
right_applied = type_function(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
if left_is_leaf and right_is_leaf: if left_is_leaf and right_is_leaf:
return function(self.node, self.left_value, self.right_value) return function(self.node, left_applied, right_applied)
else: else:
return Tree(self.node, left_applied, right_applied) return Tree(self.node, left_applied, right_applied)

View File

@ -0,0 +1,44 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2017 lafrite <lafrite@Poivre>
#
# Distributed under terms of the MIT license.
"""
Computing with MO
"""
from .exceptions import TypingError
# from .add import add
# from .minus import minus
# from .multiply import multiply
from .divide import divide
OPERATIONS = {
# "+": add,
# "-": minus,
# "*": multiply,
"/": divide,
}
def typing(node, left_v, right_v):
"""
Typing a try base on his root node
:example:
>>> from ..MO.mo import MOnumber
"""
try:
operation = OPERATIONS[node]
except KeyError:
raise TypingError(f"Unknown operation ({node})")
return operation(left_v, right_v)
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -0,0 +1,43 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2017 lafrite <lafrite@Poivre>
#
# Distributed under terms of the MIT license.
"""
Typing trees with a divide root
"""
from multipledispatch import Dispatcher
from ..MO.mo import MO, MOnumber
from ..MO.fraction import MOFraction
divide_doc = """ Typing trees a divide root
:param left: left MO
:param right: right MO
:returns: Tree or MO
"""
divide = Dispatcher("divide", doc=divide_doc)
@divide.register(MOnumber, MOnumber)
def monumber_monumber(left, right):
""" A divide tree with 2 MOnumbers is a MOFraction
>>> a = MOnumber(4)
>>> b = MOnumber(6)
>>> monumber_monumber(a, b)
<MOFraction 4 / 6>
"""
return MOFraction(left, right)
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -0,0 +1,19 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2017 lafrite <lafrite@Poivre>
#
# Distributed under terms of the MIT license.
"""
Exceptions for typing trees
"""
class TypingError(Exception):
pass
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del