Throw bases for computing (and start tiding exceptions)

This commit is contained in:
Bertrand Benjamin 2018-03-11 18:34:41 +03:00
parent b2239e0e56
commit b10492533e
8 changed files with 190 additions and 121 deletions

View File

@ -0,0 +1,17 @@
#! /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 core tools
"""
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -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'

View File

@ -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
<MO 5.2>
>>> b + a
<MO 5.2>
"""
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
<MO 4.8>
>>> b * a
<MO 4.8>
"""
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
<MO 0.35>
>>> type(c.value)
<class 'decimal.Decimal'>
>>> c = a / b
>>> c
<MO 2.857142857142857142857142857>
>>> type(c.value)
<class 'decimal.Decimal'>
"""
return MO.factory(self.value / other.value)
def __neg__(self):
""" Overload + for MOs
>>> from decimal import Decimal
>>> a = MO(4)
>>> - a
<MO -4>
>>> b = MO(Decimal("1.2"))
>>> - b
<MO -1.2>
"""
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'

View File

@ -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:

View File

@ -0,0 +1,119 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2017 lafrite <lafrite@Poivre>
#
# 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)
<MOnumber 10>
>>> b = MOnumber(0)
>>> add(a, b)
<MOnumber 4>
"""
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)
<MOnumber 10>
"""
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

View File

@ -0,0 +1,23 @@
#! /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 computing
"""
class ComputeError(Exception):
pass
class AddError(ComputeError):
pass
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -0,0 +1,17 @@
#! /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 core tools
"""
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -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