Feat(API): integrate Token to Expression simplify
This commit is contained in:
parent
5938cc7875
commit
5bf23a4793
@ -11,6 +11,7 @@ Expression
|
||||
|
||||
"""
|
||||
from ..core import AssocialTree, Tree, compute, typing, TypingError
|
||||
from .tokens import factory
|
||||
from .renders import renders
|
||||
|
||||
class Expression(object):
|
||||
@ -79,6 +80,7 @@ class Expression(object):
|
||||
'tex'
|
||||
>>> print(e)
|
||||
2 + 3 \\times 4
|
||||
>>> Expression.set_render('txt')
|
||||
"""
|
||||
cls.RENDER = render
|
||||
|
||||
@ -218,7 +220,7 @@ class Expression(object):
|
||||
""" Set ancestor """
|
||||
self._ancestor = ancestor
|
||||
|
||||
def simplify(self, optimize=True):
|
||||
def _simplify(self, optimize=True):
|
||||
""" Compute as much as possible the expression
|
||||
|
||||
:param optimize: bool to optimize tree when it's possible
|
||||
@ -227,8 +229,8 @@ class Expression(object):
|
||||
:example:
|
||||
>>> e = Expression.from_str("2+3*4")
|
||||
>>> e
|
||||
<Exp: 2 + 3 \\times 4>
|
||||
>>> f = e.simplify()
|
||||
<Exp: 2 + 3 * 4>
|
||||
>>> f = e._simplify()
|
||||
>>> f
|
||||
<Exp: 14>
|
||||
>>> f._ancestor
|
||||
@ -249,7 +251,26 @@ class Expression(object):
|
||||
return typed_exp
|
||||
else:
|
||||
comp_exp.set_ancestor(self)
|
||||
return comp_exp.simplify(optimize=optimize)
|
||||
return comp_exp._simplify(optimize=optimize)
|
||||
|
||||
def simplify(self, optimize=True):
|
||||
""" Compute as much as possible the expression
|
||||
|
||||
:param optimize: bool to optimize tree when it's possible
|
||||
:return: an expression
|
||||
|
||||
:example:
|
||||
>>> e = Expression.from_str("2+3*4")
|
||||
>>> e
|
||||
<Exp: 2 + 3 * 4>
|
||||
>>> f = e.simplify()
|
||||
>>> f
|
||||
<Integer 14>
|
||||
>>> f._ancestor
|
||||
<Exp: 2 + 12>
|
||||
"""
|
||||
self._child = self._simplify(optimize=optimize)
|
||||
return factory(self._child, ancestor=self._child._ancestor)
|
||||
|
||||
def explain(self):
|
||||
""" Yield every calculus step which have lead to self
|
||||
|
53
mapytex/calculus/API/tokens/__init__.py
Normal file
53
mapytex/calculus/API/tokens/__init__.py
Normal file
@ -0,0 +1,53 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim:fenc=utf-8
|
||||
#
|
||||
# Copyright © 2017 lafrite <lafrite@Poivre>
|
||||
#
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
"""
|
||||
Tokens represents MathObject at API level
|
||||
|
||||
"""
|
||||
from ...core.MO.mo import MO, MOnumber, MOstr
|
||||
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 .number import Integer, Decimal, Fraction
|
||||
from .polynomial import Polynomial, Linear, Quadratic
|
||||
|
||||
__all__ = ["factory"]
|
||||
|
||||
def factory(exp, name="", ancestor=None):
|
||||
""" Transform a Expression with on MathObject (from core) to a appropriate token (from API)
|
||||
"""
|
||||
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):
|
||||
return Integer(mo, name, ancestor)
|
||||
elif isinstance(mo.value, _Decimal):
|
||||
return Decimal(mo, name, ancestor)
|
||||
else:
|
||||
raise TypeError(f"Can't build from MOnumber ({mo}) neither int nor decimal")
|
||||
|
||||
elif isinstance(mo, MOFraction):
|
||||
if isinstance(mo._denominator, MOnumber) and \
|
||||
isinstance(mo._numerator, MOnumber):
|
||||
return Fraction(mo, name, ancestor)
|
||||
else:
|
||||
raise TypeError(f"Can't build from MOFraction ({mo}) numerator and denominator are not MOnumber")
|
||||
|
||||
elif isinstance(mo, (MOstr, MOstrPower, MOMonomial, MOpolynomial)):
|
||||
raise TypeError(f"Can't build Polynom yet")
|
||||
else:
|
||||
raise TypeError(f"{type(mo)} is unknown MathObject")
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
@ -11,7 +11,8 @@ Tokens representing interger and decimal
|
||||
|
||||
"""
|
||||
from .token import Token
|
||||
from ...core.MO import MOnumber, MOFraction
|
||||
from ...core.MO.mo import MOnumber
|
||||
from ...core.MO.fraction import MOFraction
|
||||
from decimal import Decimal as _Decimal
|
||||
|
||||
__all__ = ["Integer", "Decimal"]
|
||||
@ -20,13 +21,13 @@ class Integer(Token):
|
||||
|
||||
""" Token representing a integer """
|
||||
|
||||
def __init__(self, mo, name=""):
|
||||
def __init__(self, mo, name="", ancestor=None):
|
||||
if not isinstance(mo, MOnumber):
|
||||
raise TypeError
|
||||
if not isinstance(mo.value, int):
|
||||
raise TypeError
|
||||
|
||||
Token.__init__(self, mo, name)
|
||||
Token.__init__(self, mo, name, ancestor)
|
||||
self._mathtype = 'entier'
|
||||
|
||||
@classmethod
|
||||
@ -37,13 +38,13 @@ class Decimal(Token):
|
||||
|
||||
""" Token representing a decimal """
|
||||
|
||||
def __init__(self, mo, name=""):
|
||||
def __init__(self, mo, name="", ancestor=None):
|
||||
if not isinstance(mo, MOnumber):
|
||||
raise TypeError
|
||||
if not isinstance(mo.value, _Decimal):
|
||||
raise TypeError
|
||||
|
||||
Token.__init__(self, mo, name)
|
||||
Token.__init__(self, mo, name, ancestor)
|
||||
self._mathtype = 'décimal'
|
||||
|
||||
@classmethod
|
||||
@ -54,7 +55,7 @@ class Fraction(Token):
|
||||
|
||||
""" Token representing a fraction """
|
||||
|
||||
def __init__(self, mo, name=""):
|
||||
def __init__(self, mo, name="", ancestor=None):
|
||||
if not isinstance(mo, MOFraction):
|
||||
raise TypeError
|
||||
if not isinstance(mo._numerator, MOnumber):
|
||||
@ -62,7 +63,7 @@ class Fraction(Token):
|
||||
if not isinstance(mo._denominator, MOnumber):
|
||||
raise TypeError
|
||||
|
||||
Token.__init__(self, mo, name)
|
||||
Token.__init__(self, mo, name, ancestor)
|
||||
self._mathtype = 'fraction'
|
||||
|
||||
@classmethod
|
||||
|
@ -7,7 +7,7 @@
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
"""
|
||||
Tokens representing interger and decimal
|
||||
Tokens representing polynomials functions
|
||||
|
||||
"""
|
||||
from .token import Token
|
||||
@ -18,13 +18,13 @@ class Polynomial(Token):
|
||||
|
||||
""" Token representing a polynomial """
|
||||
|
||||
def __init__(self, mo, name=""):
|
||||
def __init__(self, mo, name="", ancestor=None):
|
||||
if not isinstance(mo, MOpolynomial):
|
||||
raise TypeError
|
||||
if not isinstance(mo.value, int):
|
||||
raise TypeError
|
||||
|
||||
Token.__init__(self, mo, name)
|
||||
Token.__init__(self, mo, name, ancestor)
|
||||
self._mathtype = 'polynome'
|
||||
|
||||
@classmethod
|
||||
@ -43,6 +43,40 @@ class Polynomial(Token):
|
||||
""" Call a Polynomial to evaluate itself on value """
|
||||
pass
|
||||
|
||||
class Linear(Token):
|
||||
|
||||
""" Token representing a linear """
|
||||
|
||||
def __init__(self, mo, name="", ancestor=None):
|
||||
if not isinstance(mo, MOpolynomial):
|
||||
raise TypeError
|
||||
if not isinstance(mo.value, int):
|
||||
raise TypeError
|
||||
|
||||
Token.__init__(self, mo, name, ancestor)
|
||||
self._mathtype = 'affine'
|
||||
|
||||
@classmethod
|
||||
def random(cls):
|
||||
raise NotImplemented
|
||||
|
||||
class Quadratic(Token):
|
||||
|
||||
""" Token representing a quadratic """
|
||||
|
||||
def __init__(self, mo, name="", ancestor=None):
|
||||
if not isinstance(mo, MOpolynomial):
|
||||
raise TypeError
|
||||
if not isinstance(mo.value, int):
|
||||
raise TypeError
|
||||
|
||||
Token.__init__(self, mo, name, ancestor)
|
||||
self._mathtype = 'polynome du 2nd degré'
|
||||
|
||||
@classmethod
|
||||
def random(cls):
|
||||
raise NotImplemented
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
|
@ -10,20 +10,61 @@
|
||||
Tokens: practical envelop of math object
|
||||
|
||||
"""
|
||||
from ..renders import renders
|
||||
|
||||
class Token(object):
|
||||
|
||||
""" Token: practical envelop of an math object """
|
||||
|
||||
def __init__(self, mo, name=""):
|
||||
RENDER = 'txt'
|
||||
|
||||
def __init__(self, mo, name="", ancestor = None):
|
||||
self._mo = mo
|
||||
self.name = name
|
||||
self._mathtype = None
|
||||
self._ancestor = ancestor
|
||||
|
||||
@classmethod
|
||||
def random(cls):
|
||||
raise NotImplemented
|
||||
|
||||
def explain(self):
|
||||
""" Yield every calculus step which have lead to self
|
||||
|
||||
:example:
|
||||
>>> from mapytex.calculus.API import Expression
|
||||
>>> e = Expression.from_str("2+3*4")
|
||||
>>> f = e.simplify()
|
||||
>>> f
|
||||
<Integer 14>
|
||||
>>> for s in f.explain():
|
||||
... print(s)
|
||||
2 + 3 * 4
|
||||
2 + 12
|
||||
14
|
||||
"""
|
||||
try:
|
||||
yield from self._ancestor.explain()
|
||||
yield self
|
||||
except AttributeError:
|
||||
yield self
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__} {self.__txt__}>"
|
||||
|
||||
def __str__(self):
|
||||
return renders[self.RENDER](self._mo)
|
||||
|
||||
@property
|
||||
def __txt__(self):
|
||||
return self._mo.__txt__
|
||||
|
||||
@property
|
||||
def __tex__(self):
|
||||
return self._mo.__tex__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# -----------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user