Feat(API): Allow to init tokens from builtin types

This commit is contained in:
Bertrand Benjamin 2018-12-13 10:44:52 +01:00
parent 780772ec2d
commit c9fe2ede7d
4 changed files with 101 additions and 23 deletions

View File

@ -60,16 +60,16 @@ def factory(exp, name="", ancestor=None):
if isinstance(mo, MOnumber): if isinstance(mo, MOnumber):
if isinstance(mo.value, int): if isinstance(mo.value, int):
return Integer(mo, name, ancestor) return Integer.from_mo(mo, name, ancestor)
elif isinstance(mo.value, _Decimal): elif isinstance(mo.value, _Decimal):
return Decimal(mo, name, ancestor) return Decimal.from_mo(mo, name, ancestor)
raise TypeError(f"Can't build from MOnumber ({mo}) neither int nor decimal") raise TypeError(f"Can't build from MOnumber ({mo}) neither int nor decimal")
elif isinstance(mo, MOFraction): elif isinstance(mo, MOFraction):
if isinstance(mo._denominator, MOnumber) and \ if isinstance(mo._denominator, MOnumber) and \
isinstance(mo._numerator, MOnumber): isinstance(mo._numerator, MOnumber):
return Fraction(mo, name, ancestor) return Fraction.from_mo(mo, name, ancestor)
raise TypeError(f"Can't build from MOFraction ({mo}) numerator and denominator are not MOnumber") raise TypeError(f"Can't build from MOFraction ({mo}) numerator and denominator are not MOnumber")
@ -79,13 +79,13 @@ def factory(exp, name="", ancestor=None):
if isinstance(mo, MOstr) or \ if isinstance(mo, MOstr) or \
(isinstance(mo, MOMonomial) and mo.power.value == 1) or \ (isinstance(mo, MOMonomial) and mo.power.value == 1) or \
(isinstance(mo, MOpolynomial) and mo.power.value == 1): (isinstance(mo, MOpolynomial) and mo.power.value == 1):
return Linear(mo, name, ancestor) return Linear.from_mo(mo, name, ancestor)
elif (isinstance(mo, MOstrPower) and mo.power.value == 2) or \ elif (isinstance(mo, MOstrPower) and mo.power.value == 2) or \
(isinstance(mo, MOMonomial) and mo.power.value == 2) or \ (isinstance(mo, MOMonomial) and mo.power.value == 2) or \
(isinstance(mo, MOpolynomial) and mo.power.value == 2): (isinstance(mo, MOpolynomial) and mo.power.value == 2):
return Quadratic(mo, name, ancestor) return Quadratic.from_mo(mo, name, ancestor)
else: else:
return Polynomial(mo, name, ancestor) return Polynomial.from_mo(mo, name, ancestor)
else: else:
raise TypeError(f"{type(mo)} is unknown MathObject") raise TypeError(f"{type(mo)} is unknown MathObject")

View File

@ -11,6 +11,7 @@ Tokens representing interger and decimal
""" """
from .token import Token from .token import Token
from ...core.MO import MO
from ...core.MO.mo import MOnumber from ...core.MO.mo import MOnumber
from ...core.MO.fraction import MOFraction from ...core.MO.fraction import MOFraction
from decimal import Decimal as _Decimal from decimal import Decimal as _Decimal
@ -19,17 +20,37 @@ __all__ = ["Integer", "Decimal"]
class Integer(Token): class Integer(Token):
""" Token representing a integer """ """ Token representing a integer
:example:
>>> Integer(4)
<Integer 4>
>>> a = MOnumber(4)
>>> Integer.from_mo(a)
<Integer 4>
"""
def __init__(self, mo, name="", ancestor=None): def __init__(self, a, name="", ancestor=None):
if not isinstance(mo, MOnumber): if not isinstance(a, MO):
raise TypeError if not isinstance(a, int):
if not isinstance(mo.value, int): raise TypeError
raise TypeError mo = MOnumber(a)
else:
mo = a
Token.__init__(self, mo, name, ancestor) Token.__init__(self, mo, name, ancestor)
self._mathtype = 'entier' self._mathtype = 'entier'
@classmethod
def from_mo(cls, mo, name="", ancestor=None):
if not isinstance(mo, MOnumber):
raise TypeError
if not isinstance(mo.value, int):
raise TypeError
return cls(mo, name, ancestor)
@classmethod @classmethod
def random(cls): def random(cls):
raise NotImplemented raise NotImplemented
@ -38,14 +59,26 @@ class Decimal(Token):
""" Token representing a decimal """ """ Token representing a decimal """
def __init__(self, mo, name="", ancestor=None): def __init__(self, a, name="", ancestor=None):
if not isinstance(a, MO):
if isinstance(a, (str, float)):
mo = MOnumber(Decimal(a))
else:
raise TypeError
else:
mo = a
self._mathtype = 'décimal'
Token.__init__(self, mo, name, ancestor)
@classmethod
def from_mo(cls, mo, name="", ancestor=None):
if not isinstance(mo, MOnumber): if not isinstance(mo, MOnumber):
raise TypeError raise TypeError
if not isinstance(mo.value, _Decimal): if not isinstance(mo.value, _Decimal):
raise TypeError raise TypeError
Token.__init__(self, mo, name, ancestor) return cls(mo, name, ancestor)
self._mathtype = 'décimal'
@classmethod @classmethod
def random(cls): def random(cls):
@ -55,7 +88,21 @@ class Fraction(Token):
""" Token representing a fraction """ """ Token representing a fraction """
def __init__(self, mo, name="", ancestor=None): def __init__(self, a, name="", ancestor=None):
if not isinstance(a, MO):
if isinstance(a, str):
num, denom = a.split('/')
mo = MOFraction(num, denom)
else:
raise TypeError
else:
mo = a
self._mathtype = 'fraction'
Token.__init__(self, mo, name, ancestor)
@classmethod
def from_mo(cls, mo, name="", ancestor=None):
if not isinstance(mo, MOFraction): if not isinstance(mo, MOFraction):
raise TypeError raise TypeError
if not isinstance(mo._numerator, MOnumber): if not isinstance(mo._numerator, MOnumber):
@ -63,8 +110,7 @@ class Fraction(Token):
if not isinstance(mo._denominator, MOnumber): if not isinstance(mo._denominator, MOnumber):
raise TypeError raise TypeError
Token.__init__(self, mo, name, ancestor) return cls(mo, name, ancestor)
self._mathtype = 'fraction'
@classmethod @classmethod
def random(cls): def random(cls):

View File

@ -11,6 +11,7 @@ Tokens representing polynomials functions
""" """
from .token import Token from .token import Token
from ...core.MO import MO
__all__ = ["Polynomial", "Quadratic", "Linear"] __all__ = ["Polynomial", "Quadratic", "Linear"]
@ -18,11 +19,23 @@ class Polynomial(Token):
""" Token representing a polynomial """ """ Token representing a polynomial """
def __init__(self, mo, name="", ancestor=None): def __init__(self, a, name="", ancestor=None):
if not isinstance(a, MO):
if isinstance(a, str):
raise TypeError
else:
raise TypeError
else:
mo = a
Token.__init__(self, mo, name, ancestor) Token.__init__(self, mo, name, ancestor)
self._mathtype = 'polynome' self._mathtype = 'polynome'
@classmethod
def from_mo(cls, mo, name="", ancestor=None):
return cls(mo, name, ancestor)
@classmethod @classmethod
def random(cls): def random(cls):
raise NotImplemented raise NotImplemented
@ -39,26 +52,26 @@ class Polynomial(Token):
""" Call a Polynomial to evaluate itself on value """ """ Call a Polynomial to evaluate itself on value """
pass pass
class Linear(Token): class Linear(Polynomial):
""" Token representing a linear """ """ Token representing a linear """
def __init__(self, mo, name="", ancestor=None): def __init__(self, mo, name="", ancestor=None):
Token.__init__(self, mo, name, ancestor) Polynomial.__init__(self, mo, name, ancestor)
self._mathtype = 'affine' self._mathtype = 'affine'
@classmethod @classmethod
def random(cls): def random(cls):
raise NotImplemented raise NotImplemented
class Quadratic(Token): class Quadratic(Polynomial):
""" Token representing a quadratic """ """ Token representing a quadratic """
def __init__(self, mo, name="", ancestor=None): def __init__(self, mo, name="", ancestor=None):
Token.__init__(self, mo, name, ancestor) Polynomial.__init__(self, mo, name, ancestor)
self._mathtype = 'polynome du 2nd degré' self._mathtype = 'polynome du 2nd degré'
@classmethod @classmethod

View File

@ -63,6 +63,25 @@ class Token(object):
def __tex__(self): def __tex__(self):
return self._mo.__tex__ return self._mo.__tex__
def __add__(self, other):
""" Adding 2 Tokens or a Token and a Expression
:example:
>>> from .number import Integer
>>> a = Integer(3)
"""
from ..expression import Expression
from ...core import Tree
from . import factory
if not isinstance(other, Token):
_other = factory(other)
else:
_other = other
tree = Tree('+', self.mo, _other.mo)
ans = Expression(tree).simplify()
return ans