Feat: tokenify for everything!
This commit is contained in:
parent
f471a1efb3
commit
419e5955eb
@ -10,52 +10,84 @@
|
||||
Tokens represents MathObject at API level
|
||||
|
||||
"""
|
||||
from ...core.MO import MO, MOnumber, MOstr
|
||||
from ...core.MO import MO, MOnumber, MOstr, moify
|
||||
from ...core.MO.fraction import MOFraction
|
||||
from ...core.MO.monomial import MOstrPower, MOMonomial
|
||||
from ...core.MO.polynomial import MOpolynomial
|
||||
from decimal import Decimal as _Decimal
|
||||
from .token import Token
|
||||
|
||||
__all__ = ["factory"]
|
||||
|
||||
def tokenify(mo, name="", ancestor=None):
|
||||
""" Transform a MO or a python builtin to the appropriate token
|
||||
|
||||
def factory(exp, name="", ancestor=None):
|
||||
""" Transform a Expression with on MathObject (from core) to a appropriate token (from API)
|
||||
:param mo: the thing to turn into a Token
|
||||
:param name: a virtual name of the toke
|
||||
:param ancestor: its ancestor
|
||||
|
||||
:example:
|
||||
>>> from ..expression import Expression
|
||||
>>> a = Expression(MOnumber(2))
|
||||
>>> factory(a)
|
||||
>>> a = MOnumber(2)
|
||||
>>> tokenify(a)
|
||||
<Integer 2>
|
||||
>>> a = Expression(MOnumber(2.5))
|
||||
>>> factory(a)
|
||||
<Decimal 2.5>
|
||||
>>> a = Expression(MOFraction(2, 5))
|
||||
>>> factory(a)
|
||||
<Fraction 2 / 5>
|
||||
>>> a = Expression(MOstr('x'))
|
||||
>>> factory(a)
|
||||
>>> tokenify(2)
|
||||
<Integer 2>
|
||||
>>> tokenify("x")
|
||||
<Linear x>
|
||||
>>> a = Expression(MOstrPower('x', 2))
|
||||
>>> factory(a)
|
||||
>>> tokenify(_Decimal("2.2"))
|
||||
<Decimal 2.2>
|
||||
>>> tokenify("2.2")
|
||||
<Decimal 2.2>
|
||||
>>> tokenify(2.2)
|
||||
<Decimal 2.20000000000000017763568394002504646778106689453125>
|
||||
|
||||
tokenify is idempotent on "mo" parameter
|
||||
|
||||
>>> a = MOnumber(2)
|
||||
>>> ta = tokenify(a)
|
||||
>>> ta == tokenify(ta)
|
||||
True
|
||||
|
||||
"""
|
||||
if isinstance(mo, MO):
|
||||
return _tokenify(mo, name, ancestor)
|
||||
elif isinstance(mo, Token):
|
||||
return _tokenify(mo._mo, name, ancestor)
|
||||
return _tokenify(moify(mo), name, ancestor)
|
||||
|
||||
|
||||
def _tokenify(mo, name="", ancestor=None):
|
||||
""" Transform a MO (from core) to the appropriate token (from API)
|
||||
|
||||
:example:
|
||||
>>> a = MOnumber(2)
|
||||
>>> _tokenify(a)
|
||||
<Integer 2>
|
||||
>>> a = MOnumber(2.5)
|
||||
>>> _tokenify(a)
|
||||
<Decimal 2.5>
|
||||
>>> a = MOFraction(2, 5)
|
||||
>>> _tokenify(a)
|
||||
<Fraction 2 / 5>
|
||||
>>> a = MOstr('x')
|
||||
>>> _tokenify(a)
|
||||
<Linear x>
|
||||
>>> a = MOstrPower('x', 2)
|
||||
>>> _tokenify(a)
|
||||
<Quadratic x^2>
|
||||
>>> a = Expression(MOstrPower('x', 3))
|
||||
>>> factory(a)
|
||||
>>> a = MOstrPower('x', 3)
|
||||
>>> _tokenify(a)
|
||||
<Polynomial x^3>
|
||||
>>> a = Expression(MOMonomial(3, 'x', 1))
|
||||
>>> factory(a)
|
||||
>>> a = MOMonomial(3, 'x', 1)
|
||||
>>> _tokenify(a)
|
||||
<Linear 3x>
|
||||
>>> a = Expression(MOMonomial(3, 'x', 2))
|
||||
>>> factory(a)
|
||||
>>> a = MOMonomial(3, 'x', 2)
|
||||
>>> _tokenify(a)
|
||||
<Quadratic 3x^2>
|
||||
>>> a = Expression(MOMonomial(3, 'x', 3))
|
||||
>>> factory(a)
|
||||
>>> a = MOMonomial(3, 'x', 3)
|
||||
>>> _tokenify(a)
|
||||
<Polynomial 3x^3>
|
||||
"""
|
||||
mo = exp._tree
|
||||
if not isinstance(mo, MO):
|
||||
raise TypeError(f"Can't build Token from not computed Expression (got {mo})")
|
||||
|
||||
if isinstance(mo, MOnumber):
|
||||
if isinstance(mo.value, int):
|
||||
from .number import Integer
|
||||
@ -104,6 +136,47 @@ def factory(exp, name="", ancestor=None):
|
||||
raise TypeError(f"{type(mo)} is unknown MathObject")
|
||||
|
||||
|
||||
|
||||
def factory(exp, name="", ancestor=None):
|
||||
""" Transform a Expression with on single MathObject (from core) to a appropriate token (from API)
|
||||
|
||||
:example:
|
||||
>>> from ..expression import Expression
|
||||
>>> a = Expression(MOnumber(2))
|
||||
>>> factory(a)
|
||||
<Integer 2>
|
||||
>>> a = Expression(MOnumber(2.5))
|
||||
>>> factory(a)
|
||||
<Decimal 2.5>
|
||||
>>> a = Expression(MOFraction(2, 5))
|
||||
>>> factory(a)
|
||||
<Fraction 2 / 5>
|
||||
>>> a = Expression(MOstr('x'))
|
||||
>>> factory(a)
|
||||
<Linear x>
|
||||
>>> a = Expression(MOstrPower('x', 2))
|
||||
>>> factory(a)
|
||||
<Quadratic x^2>
|
||||
>>> a = Expression(MOstrPower('x', 3))
|
||||
>>> factory(a)
|
||||
<Polynomial x^3>
|
||||
>>> a = Expression(MOMonomial(3, 'x', 1))
|
||||
>>> factory(a)
|
||||
<Linear 3x>
|
||||
>>> a = Expression(MOMonomial(3, 'x', 2))
|
||||
>>> factory(a)
|
||||
<Quadratic 3x^2>
|
||||
>>> a = Expression(MOMonomial(3, 'x', 3))
|
||||
>>> factory(a)
|
||||
<Polynomial 3x^3>
|
||||
"""
|
||||
mo = exp._tree
|
||||
if not isinstance(mo, MO):
|
||||
raise TypeError(f"Can't build Token from not computed Expression (got {mo})")
|
||||
|
||||
return _tokenify(mo, name, ancestor)
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
|
@ -91,6 +91,12 @@ class MOnumber(Atom):
|
||||
>>> MOnumber(Decimal("-23.3"))
|
||||
<MOnumber - 23.3>
|
||||
|
||||
Or directly passe a decimal string
|
||||
>>> MOnumber("23.3")
|
||||
<MOnumber 23.3>
|
||||
>>> MOnumber("-23.3")
|
||||
<MOnumber - 23.3>
|
||||
|
||||
MOnumber initialisation is idempotent
|
||||
|
||||
>>> a = MOnumber(23)
|
||||
@ -100,7 +106,7 @@ class MOnumber(Atom):
|
||||
>>> MOnumber("a")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
mapytex.calculus.core.MO.exceptions.MOError: ('The value of an MOnumber need to be a int, a float or a Decimal', "(got <class 'str'>)")
|
||||
mapytex.calculus.core.MO.exceptions.MOError: ('The value of an MOnumber need to be a int, a float, a Decimal or a decimal string', "(got <class 'str'>)")
|
||||
|
||||
Atoms specific property and methods
|
||||
|
||||
@ -122,10 +128,15 @@ class MOnumber(Atom):
|
||||
elif isinstance(value, float):
|
||||
Atom.__init__(self, Decimal(value))
|
||||
else:
|
||||
try:
|
||||
float(value)
|
||||
except (ValueError, TypeError):
|
||||
raise MOError(
|
||||
"The value of an MOnumber need to be a int, a float or a Decimal",
|
||||
"The value of an MOnumber need to be a int, a float, a Decimal or a decimal string",
|
||||
f"(got {type(value)})",
|
||||
)
|
||||
else:
|
||||
Atom.__init__(self, Decimal(value))
|
||||
|
||||
self._signature = "scalar"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user