diff --git a/mapytex/calculus/core/MO/exceptions.py b/mapytex/calculus/core/MO/exceptions.py new file mode 100644 index 0000000..a9b7c1e --- /dev/null +++ b/mapytex/calculus/core/MO/exceptions.py @@ -0,0 +1,17 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +""" +Exceptions for core tools +""" + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/mapytex/calculus/core/MO/fraction.py b/mapytex/calculus/core/MO/fraction.py index 178abd3..fe42a7f 100644 --- a/mapytex/calculus/core/MO/fraction.py +++ b/mapytex/calculus/core/MO/fraction.py @@ -46,25 +46,6 @@ class MOFraction(MO): self._denominator = denominator self.negative = negative - def __add__(self, other): - """ Overload * for MOFraction - - :param other: any other MO - :yields: calculus steps and the final yielded value is a MO. - - - >>> f = MOFraction(1, 2) - >>> g = MOFraction(3, 2) - """ - raise NotImplemented - - def __mul__(self, other): - raise NotImplemented - - def __truediv__(self, other): - raise NotImplemented - - # ----------------------------- # Reglages pour 'vim' diff --git a/mapytex/calculus/core/MO/mo.py b/mapytex/calculus/core/MO/mo.py index 5ab1ad0..91ef514 100644 --- a/mapytex/calculus/core/MO/mo.py +++ b/mapytex/calculus/core/MO/mo.py @@ -71,10 +71,14 @@ class MO(object): @classmethod def factory(cls, value): """ Factory to ensure that a value is a MO before using it """ - if isinstance(value, MO): - return value - elif isinstance(value, str): + if isinstance(value, str): return MOstr(value) + elif isinstance(value, int) \ + or isinstance(value, Decimal) \ + or isinstance(value, float): + return MOnumber(value) + elif isinstance(value, MO): + return value return MO(value) @@ -98,64 +102,6 @@ class MO(object): except AttributeError: return str(self.value) - def __add__(self, other): - """ Overload + for MOs - - >>> from decimal import Decimal - >>> a = MO(4) - >>> b = MO(Decimal("1.2")) - >>> a + b - - >>> b + a - - """ - return MO.factory(self.value + other.value) - - def __mul__(self, other): - """ Overload * for MOs - - >>> from decimal import Decimal - >>> a = MO(4) - >>> b = MO(Decimal("1.2")) - >>> a * b - - >>> b * a - - """ - return MO.factory(self.value * other.value) - - def __truediv__(self, other): - """ Overload / for MOs - - >>> from decimal import Decimal - >>> a = MO(4) - >>> b = MO(Decimal("1.4")) - >>> c = b / a - >>> c - - >>> type(c.value) - - >>> c = a / b - >>> c - - >>> type(c.value) - - """ - return MO.factory(self.value / other.value) - - def __neg__(self): - """ Overload + for MOs - - >>> from decimal import Decimal - >>> a = MO(4) - >>> - a - - >>> b = MO(Decimal("1.2")) - >>> - b - - """ - return MO.factory(-self.value) - class MOnumber(MO): @@ -251,35 +197,6 @@ class MOstr(MO): MO.__init__(self, value) self.is_scalar = False - - def __add__(self, other): - raise NotImplemented - - def __radd__(self, other): - raise NotImplemented - - def __mul__(self, other): - if other.is_scalar: - raise NotImplemented - raise NotImplemented - - def __rmul__(self, other): - if other.is_scalar: - raise NotImplemented - raise NotImplemented - - def __truediv__(self, other): - if other.is_scalar: - raise NotImplemented - raise NotImplemented - - def __rtruediv__(self, other): - if other.is_scalar: - raise NotImplemented - raise NotImplemented - - def __neg__(self): - pass # ----------------------------- # Reglages pour 'vim' diff --git a/mapytex/calculus/core/evaluate.py b/mapytex/calculus/core/compute/__init__.py similarity index 82% rename from mapytex/calculus/core/evaluate.py rename to mapytex/calculus/core/compute/__init__.py index f16f125..ff8e63c 100644 --- a/mapytex/calculus/core/evaluate.py +++ b/mapytex/calculus/core/compute/__init__.py @@ -7,13 +7,11 @@ # Distributed under terms of the MIT license. """ -Evaluating a binary tree +Computing with MO """ -from .operator import OPERATORS - -class ComputeError(Exception): - pass +from ..operator import OPERATORS +from .exceptions import ComputeError def compute(node, left_v, right_v): """ @@ -28,7 +26,7 @@ def compute(node, left_v, right_v): >>> compute("-", 1, 2) Traceback (most recent call last): ... - mapytex.calculus.core.evaluate.ComputeError: left_v need to be None for operator with arity 1 + mapytex.calculus.core.compute.exceptions.ComputeError: left_v need to be None for operator with arity 1 """ op = OPERATORS[node] lv = left_v @@ -45,8 +43,6 @@ def compute(node, left_v, right_v): return op["roperate"](rv)(lv) - - # ----------------------------- # Reglages pour 'vim' # vim:set autoindent expandtab tabstop=4 shiftwidth=4: diff --git a/mapytex/calculus/core/compute/add.py b/mapytex/calculus/core/compute/add.py new file mode 100644 index 0000000..dd9ffe0 --- /dev/null +++ b/mapytex/calculus/core/compute/add.py @@ -0,0 +1,119 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +""" +Adding MO +""" + +from ..tree import Tree +from ..operator import OPERATORS +from ..MO.mo import MO, MOnumber, MOstr +from ..MO.fraction import MOFraction +from .exceptions import AddError + + +def add(left, right): + """ Perform the addition of left and right + + :param left: left MO + :param right: right MO + :returns: Tree or MO + + >>> a = MOnumber(4) + >>> b = MOnumber(6) + >>> add(a, b) + + >>> b = MOnumber(0) + >>> add(a, b) + + + """ + if left.value == 0: + return right + elif right.value == 0: + return left + + return ADDFUNCTIONS[(type(left), type(right))](left, right) + +def monumber_monumber(left, right): + """ Adding 2 monumbers + + :param left: left MOnumber + :param right: right MOnumber + :returns: MONumber + + >>> a = MOnumber(4) + >>> b = MOnumber(6) + >>> monumber_monumber(a, b) + + + """ + return MO.factory(left.value + right.value) + +def monumber_mofraction(left, right): + """ Adding a monumber and a mofraction + + :param left: a monumber + :param right: a mofraction + :returns: Tree with the number converted into a mofraction + + >>> a = MOnumber(4) + >>> b = MOFraction(6, 5) + >>> print(monumber_mofraction(a, b)) + + + > / + | > 4 + | > 1 + > / + | > 6 + | > 5 + + """ + if not isinstance(left, MOnumber) or not isinstance(right, MOFraction): + raise AddError(f"Wrong type for left (got {left.__class__.__name__}) \ + or right (got {right.__class__.__name__})") + left_fraction = MOFraction(left, MOnumber(1)) + return Tree("+", left_fraction, right) + +def mofraction_monumber(left, right): + """ Adding a monumber and a mofraction + + :param left: a mofraction + :param right: a monumber + :returns: Tree with the number converted into a mofraction + + >>> a = MOFraction(6, 5) + >>> b = MOnumber(4) + >>> print(mofraction_monumber(a, b)) + + + > / + | > 6 + | > 5 + > / + | > 4 + | > 1 + """ + + if not isinstance(left, MOFraction) or not isinstance(right, MOnumber): + raise AddError(f"Wrong type for left (got {left.__class__.__name__})" + f"or right (got {right.__class__.__name__})") + + right_fraction = MOFraction(right, MOnumber(1)) + return Tree("+", left, right_fraction) + +# TODO: Faire un décorateur pour un enregistrement automatique |dim. mars 11 18:24:32 EAT 2018 +ADDFUNCTIONS = { + (MOnumber, MOnumber): monumber_monumber, + (MOnumber, MOFraction): monumber_mofraction, + (MOFraction, MOnumber): mofraction_monumber, + } + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/mapytex/calculus/core/compute/exceptions.py b/mapytex/calculus/core/compute/exceptions.py new file mode 100644 index 0000000..a0444f7 --- /dev/null +++ b/mapytex/calculus/core/compute/exceptions.py @@ -0,0 +1,23 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +""" +Exceptions for computing +""" + +class ComputeError(Exception): + pass + +class AddError(ComputeError): + pass + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/mapytex/calculus/core/exceptions.py b/mapytex/calculus/core/exceptions.py new file mode 100644 index 0000000..a9b7c1e --- /dev/null +++ b/mapytex/calculus/core/exceptions.py @@ -0,0 +1,17 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +""" +Exceptions for core tools +""" + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/mapytex/calculus/core/tree.py b/mapytex/calculus/core/tree.py index 685f2dd..7466baa 100644 --- a/mapytex/calculus/core/tree.py +++ b/mapytex/calculus/core/tree.py @@ -319,13 +319,12 @@ class Tree(object): + > 3 * 4 > 2 - >>> from .evaluate import compute - >>> tt = t.apply_on_last_level(compute) + >>> tt = t.apply_on_last_level(lambda n, l, r: eval(str(l) + n + str(r))) >>> print(tt) + > 12 > 2 - >>> ttt = tt.apply_on_last_level(compute) + >>> ttt = tt.apply_on_last_level(lambda n, l, r: eval(str(l) + n + str(r))) >>> print(ttt) 14 """ @@ -372,7 +371,7 @@ class Tree(object): ('+', (('*', (3, 4)), 2)) >>> assert t.apply(to_nested) == nested_par - >>> from .evaluate import compute + >>> from .compute import compute >>> t.apply(compute) 14