Integrate MO inside str2 and in Tree (doctest are ok)
This commit is contained in:
18
mapytex/calculus/core/MO/__init__.py
Normal file
18
mapytex/calculus/core/MO/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim:fenc=utf-8
|
||||
#
|
||||
# Copyright © 2017 lafrite <lafrite@Poivre>
|
||||
#
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
"""
|
||||
MO: math objects
|
||||
"""
|
||||
|
||||
from .mo import *
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
82
mapytex/calculus/core/MO/fraction.py
Normal file
82
mapytex/calculus/core/MO/fraction.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim:fenc=utf-8
|
||||
#
|
||||
# Copyright © 2017 lafrite <lafrite@Poivre>
|
||||
#
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
from mapytex.calculus.core.tree import Tree
|
||||
from .mo import MO, MOError
|
||||
|
||||
__all__ = ["MOFraction"]
|
||||
|
||||
class MOFraction(MO):
|
||||
|
||||
""" Fraction math object"""
|
||||
|
||||
def __init__(self, numerator, denominator, negative=False):
|
||||
""" Initiate the MOFraction
|
||||
|
||||
It can't be indempotent.
|
||||
|
||||
:param numerator: Numerator of the Fraction
|
||||
:param denominator: Denominator of the Fraction
|
||||
:param negative: Is the fraction negative (not concidering sign of
|
||||
numerator or denominator.
|
||||
|
||||
>>> f = MOFraction(2, 3)
|
||||
>>> f
|
||||
<MOFraction 2 / 3>
|
||||
>>> f = MOFraction(2, 3, negative = True)
|
||||
>>> f
|
||||
<MOFraction - 2 / 3>
|
||||
"""
|
||||
value = Tree("/",
|
||||
MO.factory(numerator),
|
||||
MO.factory(denominator),
|
||||
)
|
||||
MO.__init__(self, value)
|
||||
|
||||
self._numerator = numerator
|
||||
self._denominator = denominator
|
||||
self.negative = negative
|
||||
|
||||
@property
|
||||
def __txt__(self):
|
||||
# TODO: fonctionnement temporaire. Il faudrait utilser un moteur de rendu plus fin. |jeu. mars 8 15:26:49 EAT 2018
|
||||
try:
|
||||
numerator = self._numerator.__txt__
|
||||
except AttributeError:
|
||||
numerator = str(self._numerator)
|
||||
|
||||
try:
|
||||
denominator = self._denominator.__txt__
|
||||
except AttributeError:
|
||||
denominator = str(self._denominator)
|
||||
return "- "*self.negative + f"{numerator} / {denominator}"
|
||||
|
||||
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'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
@@ -6,11 +6,37 @@
|
||||
#
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
from mapytex.calculus.core.tree import Tree
|
||||
from mapytex.calculus.core.coroutine import coroutine, STOOOP
|
||||
from decimal import Decimal
|
||||
|
||||
__all__ = ["moify", "MO", "MOstr"]
|
||||
|
||||
class MOError(Exception):
|
||||
pass
|
||||
|
||||
@coroutine
|
||||
def moify(target):
|
||||
""" Coroutine which try to convert everything into an MO """
|
||||
try:
|
||||
target_ = target()
|
||||
except TypeError:
|
||||
target_ = target
|
||||
|
||||
try:
|
||||
while True:
|
||||
tok = yield
|
||||
try:
|
||||
target_.send(MOnumber(tok))
|
||||
except MOError:
|
||||
try:
|
||||
target_.send(MOstr(tok))
|
||||
except MOError:
|
||||
target_.send(tok)
|
||||
|
||||
except STOOOP as err:
|
||||
yield target_.throw(err)
|
||||
|
||||
|
||||
class MO(object):
|
||||
|
||||
"""MO for math object
|
||||
@@ -117,6 +143,43 @@ class MO(object):
|
||||
<MO -1.2>
|
||||
"""
|
||||
return MO.factory(-self.value)
|
||||
|
||||
class MOnumber(MO):
|
||||
|
||||
""" Base number math object (int or Decimal) """
|
||||
|
||||
def __init__(self, value, negative=False):
|
||||
""" Initiate a number MO
|
||||
|
||||
>>> MOnumber(23)
|
||||
<MOnumber 23>
|
||||
>>> MOnumber(-23)
|
||||
<MOnumber -23>
|
||||
>>> MOnumber(23.3)
|
||||
<MOnumber 23.300000000000000710542735760100185871124267578125>
|
||||
>>> MOnumber(Decimal("23.3"))
|
||||
<MOnumber 23.3>
|
||||
>>> a = MOnumber(23)
|
||||
>>> MOnumber(a)
|
||||
<MOnumber 23>
|
||||
>>> MOnumber("a")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
mapytex.calculus.core.MO.mo.MOError: The value of an MOnumber need to be a int, a float or a Decimal
|
||||
|
||||
"""
|
||||
try:
|
||||
val = value.value
|
||||
except AttributeError:
|
||||
val = value
|
||||
|
||||
if isinstance(val, int) or isinstance(val, Decimal):
|
||||
MO.__init__(self, value)
|
||||
elif isinstance(val, float):
|
||||
MO.__init__(self, Decimal(val))
|
||||
else:
|
||||
raise MOError("The value of an MOnumber need to be a int, a float or a Decimal")
|
||||
|
||||
|
||||
class MOstr(MO):
|
||||
|
||||
@@ -135,14 +198,18 @@ class MOstr(MO):
|
||||
>>> b
|
||||
<MOstr x>
|
||||
|
||||
>>> a = MOstr("+")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
mapytex.calculus.core.MO.mo.MOError: An MOstr should be initiate with a alpha string, got +
|
||||
>>> MOstr("ui")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
mo.MOError: An MOstr should be initiate with a single caracter string
|
||||
mapytex.calculus.core.MO.mo.MOError: An MOstr should be initiate with a single caracter string, got ui
|
||||
>>> MOstr(2)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
mo.MOError: An MOstr should be initiate with a string - the unknown
|
||||
mapytex.calculus.core.MO.mo.MOError: An MOstr should be initiate with a string - the unknown, got 2
|
||||
|
||||
"""
|
||||
try:
|
||||
@@ -151,9 +218,11 @@ class MOstr(MO):
|
||||
val = value
|
||||
|
||||
if not isinstance(val, str):
|
||||
raise MOError("An MOstr should be initiate with a string - the unknown")
|
||||
raise MOError(f"An MOstr should be initiate with a string - the unknown, got {val}")
|
||||
if len(val) != 1:
|
||||
raise MOError("An MOstr should be initiate with a single caracter string")
|
||||
raise MOError(f"An MOstr should be initiate with a single caracter string, got {val}")
|
||||
if not val.isalpha():
|
||||
raise MOError(f"An MOstr should be initiate with a alpha string, got {val}")
|
||||
|
||||
MO.__init__(self, value)
|
||||
self.negative = negative
|
||||
@@ -192,71 +261,6 @@ class MOstr(MO):
|
||||
def __neg__(self):
|
||||
return MO(self.value, not self.negative)
|
||||
|
||||
class MOFraction(MO):
|
||||
|
||||
""" Fraction math object"""
|
||||
|
||||
def __init__(self, numerator, denominator, negative=False):
|
||||
""" Initiate the MOFraction
|
||||
|
||||
It can't be indempotent.
|
||||
|
||||
:param numerator: Numerator of the Fraction
|
||||
:param denominator: Denominator of the Fraction
|
||||
:param negative: Is the fraction negative (not concidering sign of
|
||||
numerator or denominator.
|
||||
|
||||
>>> f = MOFraction(2, 3)
|
||||
>>> f
|
||||
<MOFraction 2 / 3>
|
||||
>>> f = MOFraction(2, 3, negative = True)
|
||||
>>> f
|
||||
<MOFraction - 2 / 3>
|
||||
"""
|
||||
value = Tree("/",
|
||||
MO.factory(numerator),
|
||||
MO.factory(denominator),
|
||||
)
|
||||
MO.__init__(self, value)
|
||||
|
||||
self._numerator = numerator
|
||||
self._denominator = denominator
|
||||
self.negative = negative
|
||||
|
||||
@property
|
||||
def __txt__(self):
|
||||
# TODO: fonctionnement temporaire. Il faudrait utilser un moteur de rendu plus fin. |jeu. mars 8 15:26:49 EAT 2018
|
||||
try:
|
||||
numerator = self._numerator.__txt__
|
||||
except AttributeError:
|
||||
numerator = str(self._numerator)
|
||||
|
||||
try:
|
||||
denominator = self._denominator.__txt__
|
||||
except AttributeError:
|
||||
denominator = str(self._denominator)
|
||||
return "- "*self.negative + f"{numerator} / {denominator}"
|
||||
|
||||
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'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
|
Reference in New Issue
Block a user