Style: apply black
This commit is contained in:
parent
7097801306
commit
09b04d2703
@ -14,6 +14,7 @@ from ..core import AssocialTree, Tree, compute, typing, TypingError
|
|||||||
from .tokens import factory
|
from .tokens import factory
|
||||||
from .renders import renders
|
from .renders import renders
|
||||||
|
|
||||||
|
|
||||||
class Expression(object):
|
class Expression(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -32,7 +33,7 @@ class Expression(object):
|
|||||||
14
|
14
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RENDER = 'txt'
|
RENDER = "txt"
|
||||||
|
|
||||||
def __init__(self, tree, ancestor=None):
|
def __init__(self, tree, ancestor=None):
|
||||||
"""
|
"""
|
||||||
@ -128,6 +129,7 @@ class Expression(object):
|
|||||||
>>> print(e._order())
|
>>> print(e._order())
|
||||||
x + 5x + 6x^3 + 2x^2 + 4x^2 + 1 + 3
|
x + 5x + 6x^3 + 2x^2 + 4x^2 + 1 + 3
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def signature(leaf):
|
def signature(leaf):
|
||||||
try:
|
try:
|
||||||
leaf.node
|
leaf.node
|
||||||
@ -148,8 +150,9 @@ class Expression(object):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
organised = AssocialTree.from_any_tree(self._tree).\
|
organised = AssocialTree.from_any_tree(self._tree).organise_by(
|
||||||
organise_by(signature, recursive=True, exclude_nodes=exclude_nodes)
|
signature, recursive=True, exclude_nodes=exclude_nodes
|
||||||
|
)
|
||||||
return Expression(organised)
|
return Expression(organised)
|
||||||
|
|
||||||
def _optimize(self, exclude_nodes=["/", "**"]):
|
def _optimize(self, exclude_nodes=["/", "**"]):
|
||||||
@ -380,6 +383,7 @@ class Expression(object):
|
|||||||
else:
|
else:
|
||||||
yield self
|
yield self
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -12,6 +12,7 @@ Expression
|
|||||||
"""
|
"""
|
||||||
from ..core import tree2txt, tree2tex
|
from ..core import tree2txt, tree2tex
|
||||||
|
|
||||||
|
|
||||||
def _txt(mo_tree):
|
def _txt(mo_tree):
|
||||||
""" txt render for MOs or Trees"""
|
""" txt render for MOs or Trees"""
|
||||||
try:
|
try:
|
||||||
@ -24,6 +25,7 @@ def _txt(mo_tree):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return str(mo_tree)
|
return str(mo_tree)
|
||||||
|
|
||||||
|
|
||||||
def _tex(mo_tree):
|
def _tex(mo_tree):
|
||||||
""" Tex render for MOs or Trees"""
|
""" Tex render for MOs or Trees"""
|
||||||
try:
|
try:
|
||||||
@ -36,10 +38,8 @@ def _tex(mo_tree):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return str(mo_tree)
|
return str(mo_tree)
|
||||||
|
|
||||||
renders = {
|
|
||||||
'txt': _txt,
|
renders = {"txt": _txt, "tex": _tex}
|
||||||
'tex': _tex,
|
|
||||||
}
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
|
@ -21,6 +21,7 @@ from .polynomial import Polynomial, Linear, Quadratic
|
|||||||
|
|
||||||
__all__ = ["factory"]
|
__all__ = ["factory"]
|
||||||
|
|
||||||
|
|
||||||
def factory(exp, name="", ancestor=None):
|
def factory(exp, name="", ancestor=None):
|
||||||
""" Transform a Expression with on MathObject (from core) to a appropriate token (from API)
|
""" Transform a Expression with on MathObject (from core) to a appropriate token (from API)
|
||||||
|
|
||||||
@ -67,22 +68,31 @@ def factory(exp, name="", ancestor=None):
|
|||||||
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(
|
||||||
isinstance(mo._numerator, MOnumber):
|
mo._numerator, MOnumber
|
||||||
|
):
|
||||||
return Fraction.from_mo(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"
|
||||||
|
)
|
||||||
|
|
||||||
elif isinstance(mo, (MOstr, MOstrPower, MOMonomial, MOpolynomial)):
|
elif isinstance(mo, (MOstr, MOstrPower, MOMonomial, MOpolynomial)):
|
||||||
if not isinstance(mo._variable, (MOstr, str)):
|
if not isinstance(mo._variable, (MOstr, str)):
|
||||||
raise TypeError(f"Can't build Polynom over something else than a letter (got {mo._variable})")
|
raise TypeError(
|
||||||
if isinstance(mo, MOstr) or \
|
f"Can't build Polynom over something else than a letter (got {mo._variable})"
|
||||||
(isinstance(mo, MOMonomial) and mo.power.value == 1) or \
|
)
|
||||||
(isinstance(mo, MOpolynomial) and mo.power.value == 1):
|
if (
|
||||||
|
isinstance(mo, MOstr)
|
||||||
|
or (isinstance(mo, MOMonomial) and mo.power.value == 1)
|
||||||
|
or (isinstance(mo, MOpolynomial) and mo.power.value == 1)
|
||||||
|
):
|
||||||
return Linear.from_mo(mo, name, ancestor)
|
return Linear.from_mo(mo, name, ancestor)
|
||||||
elif (isinstance(mo, MOstrPower) and mo.power.value == 2) or \
|
elif (
|
||||||
(isinstance(mo, MOMonomial) and mo.power.value == 2) or \
|
(isinstance(mo, MOstrPower) and mo.power.value == 2)
|
||||||
(isinstance(mo, MOpolynomial) and mo.power.value == 2):
|
or (isinstance(mo, MOMonomial) and mo.power.value == 2)
|
||||||
|
or (isinstance(mo, MOpolynomial) and mo.power.value == 2)
|
||||||
|
):
|
||||||
return Quadratic.from_mo(mo, name, ancestor)
|
return Quadratic.from_mo(mo, name, ancestor)
|
||||||
else:
|
else:
|
||||||
return Polynomial.from_mo(mo, name, ancestor)
|
return Polynomial.from_mo(mo, name, ancestor)
|
||||||
@ -90,6 +100,7 @@ def factory(exp, name="", ancestor=None):
|
|||||||
else:
|
else:
|
||||||
raise TypeError(f"{type(mo)} is unknown MathObject")
|
raise TypeError(f"{type(mo)} is unknown MathObject")
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -19,6 +19,7 @@ from ...core.MO.fraction import MOFraction
|
|||||||
|
|
||||||
__all__ = ["Integer", "Decimal"]
|
__all__ = ["Integer", "Decimal"]
|
||||||
|
|
||||||
|
|
||||||
class Integer(Token):
|
class Integer(Token):
|
||||||
|
|
||||||
""" Token representing a integer
|
""" Token representing a integer
|
||||||
@ -41,7 +42,7 @@ class Integer(Token):
|
|||||||
mo = a
|
mo = a
|
||||||
|
|
||||||
Token.__init__(self, mo, name, ancestor)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
self._mathtype = 'entier'
|
self._mathtype = "entier"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_mo(cls, mo, name="", ancestor=None):
|
def from_mo(cls, mo, name="", ancestor=None):
|
||||||
@ -53,12 +54,8 @@ class Integer(Token):
|
|||||||
return cls(mo, name, ancestor)
|
return cls(mo, name, ancestor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(cls,
|
def random(
|
||||||
name = "",
|
cls, name="", min_value=-10, max_value=10, rejected=[0, 1], accept_callbacks=[]
|
||||||
min_value = -10,
|
|
||||||
max_value = 10,
|
|
||||||
rejected = [0, 1],
|
|
||||||
accept_callbacks=[],
|
|
||||||
):
|
):
|
||||||
""" Generate a random Integer
|
""" Generate a random Integer
|
||||||
|
|
||||||
@ -69,11 +66,11 @@ class Integer(Token):
|
|||||||
:param accept_callbacks: list of function for value acceptation
|
:param accept_callbacks: list of function for value acceptation
|
||||||
|
|
||||||
"""
|
"""
|
||||||
candidate = filter_random(min_value, max_value,
|
candidate = filter_random(min_value, max_value, rejected, accept_callbacks)
|
||||||
rejected, accept_callbacks)
|
|
||||||
|
|
||||||
return Integer(candidate, name)
|
return Integer(candidate, name)
|
||||||
|
|
||||||
|
|
||||||
class Decimal(Token):
|
class Decimal(Token):
|
||||||
|
|
||||||
""" Token representing a decimal
|
""" Token representing a decimal
|
||||||
@ -98,7 +95,7 @@ class Decimal(Token):
|
|||||||
else:
|
else:
|
||||||
mo = a
|
mo = a
|
||||||
|
|
||||||
self._mathtype = 'décimal'
|
self._mathtype = "décimal"
|
||||||
Token.__init__(self, mo, name, ancestor)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -111,7 +108,8 @@ class Decimal(Token):
|
|||||||
return cls(mo, name, ancestor)
|
return cls(mo, name, ancestor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(cls,
|
def random(
|
||||||
|
cls,
|
||||||
name="",
|
name="",
|
||||||
min_value=-10,
|
min_value=-10,
|
||||||
max_value=10,
|
max_value=10,
|
||||||
@ -152,14 +150,14 @@ class Fraction(Token):
|
|||||||
def __init__(self, a, name="", ancestor=None):
|
def __init__(self, a, name="", ancestor=None):
|
||||||
if not isinstance(a, MO):
|
if not isinstance(a, MO):
|
||||||
if isinstance(a, str):
|
if isinstance(a, str):
|
||||||
num, denom = a.split('/')
|
num, denom = a.split("/")
|
||||||
mo = MOFraction(int(num), int(denom))
|
mo = MOFraction(int(num), int(denom))
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
else:
|
else:
|
||||||
mo = a
|
mo = a
|
||||||
|
|
||||||
self._mathtype = 'fraction'
|
self._mathtype = "fraction"
|
||||||
Token.__init__(self, mo, name, ancestor)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -174,16 +172,21 @@ class Fraction(Token):
|
|||||||
return cls(mo, name, ancestor)
|
return cls(mo, name, ancestor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(cls,
|
def random(
|
||||||
|
cls,
|
||||||
name="",
|
name="",
|
||||||
fix_num="",
|
fix_num="",
|
||||||
min_num=-10, max_num=10, rejected_num=[0],
|
min_num=-10,
|
||||||
|
max_num=10,
|
||||||
|
rejected_num=[0],
|
||||||
accept_num_callbacks=[],
|
accept_num_callbacks=[],
|
||||||
fix_denom="",
|
fix_denom="",
|
||||||
min_denom=-10, max_denom=10, rejected_denom=[0, 1, -1],
|
min_denom=-10,
|
||||||
|
max_denom=10,
|
||||||
|
rejected_denom=[0, 1, -1],
|
||||||
accept_denom_callbacks=[],
|
accept_denom_callbacks=[],
|
||||||
irreductible=False,
|
irreductible=False,
|
||||||
not_integer=True
|
not_integer=True,
|
||||||
):
|
):
|
||||||
""" Generate a random Fraction
|
""" Generate a random Fraction
|
||||||
|
|
||||||
@ -202,9 +205,7 @@ class Fraction(Token):
|
|||||||
:param not_integer: can the generated fraction be egal to an interger
|
:param not_integer: can the generated fraction be egal to an interger
|
||||||
"""
|
"""
|
||||||
if fix_num == "":
|
if fix_num == "":
|
||||||
num = filter_random(min_num, max_num,
|
num = filter_random(min_num, max_num, rejected_num, accept_num_callbacks)
|
||||||
rejected_num,
|
|
||||||
accept_num_callbacks)
|
|
||||||
else:
|
else:
|
||||||
num = fix_num
|
num = fix_num
|
||||||
|
|
||||||
@ -212,17 +213,21 @@ class Fraction(Token):
|
|||||||
accept_callbacks = accept_denom_callbacks
|
accept_callbacks = accept_denom_callbacks
|
||||||
|
|
||||||
if irreductible:
|
if irreductible:
|
||||||
|
|
||||||
def prime_with_num(denom):
|
def prime_with_num(denom):
|
||||||
return gcd(num, denom) == 1
|
return gcd(num, denom) == 1
|
||||||
|
|
||||||
accept_callbacks.append(prime_with_num)
|
accept_callbacks.append(prime_with_num)
|
||||||
if not_integer:
|
if not_integer:
|
||||||
|
|
||||||
def not_divise_num(denom):
|
def not_divise_num(denom):
|
||||||
return num % denom != 0
|
return num % denom != 0
|
||||||
|
|
||||||
accept_callbacks.append(not_divise_num)
|
accept_callbacks.append(not_divise_num)
|
||||||
|
|
||||||
denom = filter_random(min_denom, max_denom,
|
denom = filter_random(
|
||||||
rejected_denom,
|
min_denom, max_denom, rejected_denom, accept_callbacks
|
||||||
accept_callbacks)
|
)
|
||||||
else:
|
else:
|
||||||
denom = fix_denom
|
denom = fix_denom
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ from ...core.MO import MO
|
|||||||
|
|
||||||
__all__ = ["Polynomial", "Quadratic", "Linear"]
|
__all__ = ["Polynomial", "Quadratic", "Linear"]
|
||||||
|
|
||||||
|
|
||||||
class Polynomial(Token):
|
class Polynomial(Token):
|
||||||
|
|
||||||
""" Token representing a polynomial """
|
""" Token representing a polynomial """
|
||||||
@ -29,7 +30,7 @@ class Polynomial(Token):
|
|||||||
mo = a
|
mo = a
|
||||||
|
|
||||||
Token.__init__(self, mo, name, ancestor)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
self._mathtype = 'polynome'
|
self._mathtype = "polynome"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_mo(cls, mo, name="", ancestor=None):
|
def from_mo(cls, mo, name="", ancestor=None):
|
||||||
@ -52,6 +53,7 @@ class Polynomial(Token):
|
|||||||
""" Call a Polynomial to evaluate itself on value """
|
""" Call a Polynomial to evaluate itself on value """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Linear(Polynomial):
|
class Linear(Polynomial):
|
||||||
|
|
||||||
""" Token representing a linear """
|
""" Token representing a linear """
|
||||||
@ -59,12 +61,13 @@ class Linear(Polynomial):
|
|||||||
def __init__(self, mo, name="", ancestor=None):
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
|
|
||||||
Polynomial.__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(Polynomial):
|
class Quadratic(Polynomial):
|
||||||
|
|
||||||
""" Token representing a quadratic """
|
""" Token representing a quadratic """
|
||||||
@ -72,7 +75,7 @@ class Quadratic(Polynomial):
|
|||||||
def __init__(self, mo, name="", ancestor=None):
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
|
|
||||||
Polynomial.__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
|
||||||
def random(cls):
|
def random(cls):
|
||||||
|
@ -12,11 +12,12 @@ Tokens: practical envelop of math object
|
|||||||
"""
|
"""
|
||||||
from ..renders import renders
|
from ..renders import renders
|
||||||
|
|
||||||
|
|
||||||
class Token(object):
|
class Token(object):
|
||||||
|
|
||||||
""" Token: practical envelop of an math object """
|
""" Token: practical envelop of an math object """
|
||||||
|
|
||||||
RENDER = 'txt'
|
RENDER = "txt"
|
||||||
|
|
||||||
def __init__(self, mo, name="", ancestor=None):
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
self._mo = mo
|
self._mo = mo
|
||||||
@ -71,6 +72,7 @@ class Token(object):
|
|||||||
from ..expression import Expression
|
from ..expression import Expression
|
||||||
from ...core import Tree
|
from ...core import Tree
|
||||||
from . import factory
|
from . import factory
|
||||||
|
|
||||||
if not isinstance(other, Token):
|
if not isinstance(other, Token):
|
||||||
_other = factory(other)
|
_other = factory(other)
|
||||||
else:
|
else:
|
||||||
@ -165,6 +167,7 @@ class Token(object):
|
|||||||
"""
|
"""
|
||||||
return self._operate(other, "/")
|
return self._operate(other, "/")
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -15,6 +15,7 @@ from ..coroutine import coroutine, STOOOP
|
|||||||
|
|
||||||
__all__ = ["moify", "MOnumber", "MOstr"]
|
__all__ = ["moify", "MOnumber", "MOstr"]
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def moify(target):
|
def moify(target):
|
||||||
""" Coroutine which try to convert a parsed token into an MO
|
""" Coroutine which try to convert a parsed token into an MO
|
||||||
@ -47,6 +48,7 @@ def moify(target):
|
|||||||
except STOOOP as err:
|
except STOOOP as err:
|
||||||
yield target_.throw(err)
|
yield target_.throw(err)
|
||||||
|
|
||||||
|
|
||||||
@total_ordering
|
@total_ordering
|
||||||
class MOnumber(Atom):
|
class MOnumber(Atom):
|
||||||
|
|
||||||
@ -116,8 +118,10 @@ class MOnumber(Atom):
|
|||||||
elif isinstance(value, float):
|
elif isinstance(value, float):
|
||||||
Atom.__init__(self, Decimal(value))
|
Atom.__init__(self, Decimal(value))
|
||||||
else:
|
else:
|
||||||
raise MOError("The value of an MOnumber need to be a int, a float or a Decimal",
|
raise MOError(
|
||||||
f"(got {type(value)})")
|
"The value of an MOnumber need to be a int, a float or a Decimal",
|
||||||
|
f"(got {type(value)})",
|
||||||
|
)
|
||||||
|
|
||||||
self._signature = "scalar"
|
self._signature = "scalar"
|
||||||
|
|
||||||
@ -215,9 +219,13 @@ class MOstr(Atom):
|
|||||||
val = value
|
val = value
|
||||||
|
|
||||||
if not isinstance(val, str):
|
if not isinstance(val, str):
|
||||||
raise MOError(f"An MOstr should be initiate with a string - the unknown, got {val}")
|
raise MOError(
|
||||||
|
f"An MOstr should be initiate with a string - the unknown, got {val}"
|
||||||
|
)
|
||||||
if len(val) != 1:
|
if len(val) != 1:
|
||||||
raise MOError(f"An MOstr should be initiate with a single caracter string, got {val}")
|
raise MOError(
|
||||||
|
f"An MOstr should be initiate with a single caracter string, got {val}"
|
||||||
|
)
|
||||||
if not val.isalpha():
|
if not val.isalpha():
|
||||||
raise MOError(f"An MOstr should be initiate with a alpha string, got {val}")
|
raise MOError(f"An MOstr should be initiate with a alpha string, got {val}")
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
Exceptions for core tools
|
Exceptions for core tools
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class MOError(Exception):
|
class MOError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ from .mo import Molecule, MO
|
|||||||
|
|
||||||
__all__ = ["MOFraction"]
|
__all__ = ["MOFraction"]
|
||||||
|
|
||||||
|
|
||||||
class MOFraction(Molecule):
|
class MOFraction(Molecule):
|
||||||
|
|
||||||
""" Fraction math object"""
|
""" Fraction math object"""
|
||||||
@ -42,10 +43,7 @@ class MOFraction(Molecule):
|
|||||||
"""
|
"""
|
||||||
_numerator = MO.factory(numerator)
|
_numerator = MO.factory(numerator)
|
||||||
_denominator = MO.factory(denominator)
|
_denominator = MO.factory(denominator)
|
||||||
base_tree = Tree("/",
|
base_tree = Tree("/", _numerator, _denominator)
|
||||||
_numerator,
|
|
||||||
_denominator,
|
|
||||||
)
|
|
||||||
if negative:
|
if negative:
|
||||||
tree = Tree("-", None, base_tree)
|
tree = Tree("-", None, base_tree)
|
||||||
else:
|
else:
|
||||||
@ -71,9 +69,8 @@ class MOFraction(Molecule):
|
|||||||
|
|
||||||
def inverse(self):
|
def inverse(self):
|
||||||
""" return the inverse fraction """
|
""" return the inverse fraction """
|
||||||
return MOFraction(self._denominator,
|
return MOFraction(self._denominator, self._numerator, self.negative)
|
||||||
self._numerator,
|
|
||||||
self.negative)
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
|
@ -12,6 +12,7 @@ from ..renders import tree2txt, tree2tex
|
|||||||
|
|
||||||
__all__ = ["MO"]
|
__all__ = ["MO"]
|
||||||
|
|
||||||
|
|
||||||
class MO(ABC):
|
class MO(ABC):
|
||||||
|
|
||||||
"""MO for math object
|
"""MO for math object
|
||||||
@ -50,7 +51,6 @@ class MO(ABC):
|
|||||||
|
|
||||||
return Atom.factory(value)
|
return Atom.factory(value)
|
||||||
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def content(self):
|
def content(self):
|
||||||
""" content of the mo """
|
""" content of the mo """
|
||||||
@ -97,6 +97,7 @@ class MO(ABC):
|
|||||||
"""
|
"""
|
||||||
return self._signature
|
return self._signature
|
||||||
|
|
||||||
|
|
||||||
class Atom(MO):
|
class Atom(MO):
|
||||||
|
|
||||||
""" Base Math Object with only one component.
|
""" Base Math Object with only one component.
|
||||||
@ -196,8 +197,6 @@ class Molecule(MO):
|
|||||||
return tree2tex(self._tree)
|
return tree2tex(self._tree)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -13,6 +13,7 @@ from .exceptions import MOError
|
|||||||
|
|
||||||
__all__ = ["MOMonomial"]
|
__all__ = ["MOMonomial"]
|
||||||
|
|
||||||
|
|
||||||
class MOstrPower(Molecule):
|
class MOstrPower(Molecule):
|
||||||
|
|
||||||
""" Power of a MOstr """
|
""" Power of a MOstr """
|
||||||
@ -68,10 +69,7 @@ class MOstrPower(Molecule):
|
|||||||
raise MOError("The power of a monomial should be a integer")
|
raise MOError("The power of a monomial should be a integer")
|
||||||
self._power = _power
|
self._power = _power
|
||||||
|
|
||||||
_tree = Tree("^",
|
_tree = Tree("^", self._variable, self._power)
|
||||||
self._variable,
|
|
||||||
self._power,
|
|
||||||
)
|
|
||||||
|
|
||||||
Molecule.__init__(self, _tree)
|
Molecule.__init__(self, _tree)
|
||||||
|
|
||||||
@ -113,6 +111,7 @@ class MOstrPower(Molecule):
|
|||||||
"""
|
"""
|
||||||
return f"monome{self.power}"
|
return f"monome{self.power}"
|
||||||
|
|
||||||
|
|
||||||
class MOMonomial(Molecule):
|
class MOMonomial(Molecule):
|
||||||
|
|
||||||
""" Monomial math object"""
|
""" Monomial math object"""
|
||||||
@ -164,7 +163,9 @@ class MOMonomial(Molecule):
|
|||||||
if coefficient == 0:
|
if coefficient == 0:
|
||||||
raise MOError("The coefficient of a monomial should not be 0")
|
raise MOError("The coefficient of a monomial should not be 0")
|
||||||
elif coefficient == 1:
|
elif coefficient == 1:
|
||||||
raise MOError("The coefficient of a monomial should not be 1, it is a MOstrPower or MOstr")
|
raise MOError(
|
||||||
|
"The coefficient of a monomial should not be 1, it is a MOstrPower or MOstr"
|
||||||
|
)
|
||||||
self._coefficient = _coefficient
|
self._coefficient = _coefficient
|
||||||
|
|
||||||
_variable = MO.factory(variable)
|
_variable = MO.factory(variable)
|
||||||
@ -174,7 +175,9 @@ class MOMonomial(Molecule):
|
|||||||
elif isinstance(_variable, MOstr):
|
elif isinstance(_variable, MOstr):
|
||||||
_power = MO.factory(power)
|
_power = MO.factory(power)
|
||||||
else:
|
else:
|
||||||
raise MOError(f"variable need to be a MOstrPower or a MOstr. Got {type(variable)}.")
|
raise MOError(
|
||||||
|
f"variable need to be a MOstrPower or a MOstr. Got {type(variable)}."
|
||||||
|
)
|
||||||
|
|
||||||
self._variable = _variable
|
self._variable = _variable
|
||||||
self._power = _power
|
self._power = _power
|
||||||
@ -187,10 +190,8 @@ class MOMonomial(Molecule):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
_tree = Tree("*", self._coefficient, self.strpower)
|
_tree = Tree("*", self._coefficient, self.strpower)
|
||||||
|
|
||||||
|
|
||||||
Molecule.__init__(self, _tree)
|
Molecule.__init__(self, _tree)
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self._coefficient != -1:
|
if self._coefficient != -1:
|
||||||
return super(MOMonomial, self).__str__()
|
return super(MOMonomial, self).__str__()
|
||||||
@ -244,6 +245,7 @@ class MOMonomial(Molecule):
|
|||||||
@property
|
@property
|
||||||
def degree(self):
|
def degree(self):
|
||||||
return self._power.value
|
return self._power.value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def signature(self):
|
def signature(self):
|
||||||
""" Name of the mo in the API
|
""" Name of the mo in the API
|
||||||
@ -256,6 +258,7 @@ class MOMonomial(Molecule):
|
|||||||
"""
|
"""
|
||||||
return f"monome{self.power}"
|
return f"monome{self.power}"
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -14,6 +14,7 @@ from .monomial import MOMonomial, MOstrPower
|
|||||||
|
|
||||||
__all__ = ["MOpolynomial"]
|
__all__ = ["MOpolynomial"]
|
||||||
|
|
||||||
|
|
||||||
class MOpolynomial(Molecule):
|
class MOpolynomial(Molecule):
|
||||||
|
|
||||||
""" MO polynomial"""
|
""" MO polynomial"""
|
||||||
@ -45,11 +46,13 @@ class MOpolynomial(Molecule):
|
|||||||
self._variable = _variable
|
self._variable = _variable
|
||||||
|
|
||||||
if isinstance(coefs, dict):
|
if isinstance(coefs, dict):
|
||||||
_coefs = {MO.factory(d): MO.factory(c) for (d, c) in coefs.items()
|
_coefs = {
|
||||||
if c != 0 }
|
MO.factory(d): MO.factory(c) for (d, c) in coefs.items() if c != 0
|
||||||
|
}
|
||||||
elif isinstance(coefs, list):
|
elif isinstance(coefs, list):
|
||||||
_coefs = {MO.factory(d): MO.factory(c) for (d, c) in enumerate(coefs)
|
_coefs = {
|
||||||
if c != 0 }
|
MO.factory(d): MO.factory(c) for (d, c) in enumerate(coefs) if c != 0
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
raise TypeError("Coefs needs to be a dictionnary or a list")
|
raise TypeError("Coefs needs to be a dictionnary or a list")
|
||||||
self._coefs = _coefs
|
self._coefs = _coefs
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['gcd']
|
__all__ = ["gcd"]
|
||||||
|
|
||||||
|
|
||||||
def gcd(a, b):
|
def gcd(a, b):
|
||||||
@ -28,7 +28,7 @@ def gcd(a, b):
|
|||||||
pos_a, _a = (a >= 0), abs(a)
|
pos_a, _a = (a >= 0), abs(a)
|
||||||
pos_b, _b = (b >= 0), abs(b)
|
pos_b, _b = (b >= 0), abs(b)
|
||||||
|
|
||||||
gcd_sgn = (-1 + 2 * (pos_a or pos_b))
|
gcd_sgn = -1 + 2 * (pos_a or pos_b)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
_a = a
|
_a = a
|
||||||
_b = b
|
_b = b
|
||||||
@ -48,6 +48,7 @@ def gcd(a, b):
|
|||||||
else:
|
else:
|
||||||
return gcd_sgn * gcd(min(_a, _b), c)
|
return gcd_sgn * gcd(min(_a, _b), c)
|
||||||
|
|
||||||
|
|
||||||
def lcm(a, b):
|
def lcm(a, b):
|
||||||
"""Compute lcm(a,b)
|
"""Compute lcm(a,b)
|
||||||
|
|
||||||
@ -69,7 +70,8 @@ def lcm(a, b):
|
|||||||
"""
|
"""
|
||||||
return (a * b) // gcd(a, b)
|
return (a * b) // gcd(a, b)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
print(gcd(3, 15))
|
print(gcd(3, 15))
|
||||||
print(gcd(3, 15))
|
print(gcd(3, 15))
|
||||||
print(gcd(-15, -3))
|
print(gcd(-15, -3))
|
||||||
|
@ -27,13 +27,8 @@ from tabulate import tabulate
|
|||||||
|
|
||||||
MOS = [MOnumber, MOstr, MOFraction, MOstrPower, MOMonomial, MOpolynomial]
|
MOS = [MOnumber, MOstr, MOFraction, MOstrPower, MOMonomial, MOpolynomial]
|
||||||
|
|
||||||
OPERATIONS = {
|
OPERATIONS = {"+": add, "-": minus, "*": multiply, "/": divide, "^": power}
|
||||||
"+": add,
|
|
||||||
"-": minus,
|
|
||||||
"*": multiply,
|
|
||||||
"/": divide,
|
|
||||||
"^": power,
|
|
||||||
}
|
|
||||||
|
|
||||||
def compute(node, left_v, right_v):
|
def compute(node, left_v, right_v):
|
||||||
"""
|
"""
|
||||||
@ -60,6 +55,7 @@ def compute(node, left_v, right_v):
|
|||||||
|
|
||||||
return operation(left_v, right_v)
|
return operation(left_v, right_v)
|
||||||
|
|
||||||
|
|
||||||
def compute_capacities(node):
|
def compute_capacities(node):
|
||||||
""" Test an operation through all MOs
|
""" Test an operation through all MOs
|
||||||
|
|
||||||
@ -74,19 +70,17 @@ def compute_capacities(node):
|
|||||||
op = OPERATIONS[node]
|
op = OPERATIONS[node]
|
||||||
lines = [[node] + [mo.__name__ for mo in MOS]]
|
lines = [[node] + [mo.__name__ for mo in MOS]]
|
||||||
for left_mo in MOS:
|
for left_mo in MOS:
|
||||||
lines.append(
|
lines.append([left_mo.__name__] + [(left_mo, i) in op.funcs for i in MOS])
|
||||||
[left_mo.__name__] + \
|
|
||||||
[(left_mo, i) in op.funcs for i in MOS]
|
|
||||||
)
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def describe_compute():
|
def describe_compute():
|
||||||
""" Explain which operation are handle by compue """
|
""" Explain which operation are handle by compue """
|
||||||
|
|
||||||
ans = "Implemented compute operations among MOs"
|
ans = "Implemented compute operations among MOs"
|
||||||
for op in OPERATIONS:
|
for op in OPERATIONS:
|
||||||
ans += "\n"
|
ans += "\n"
|
||||||
ans += tabulate(compute_capacities(op), tablefmt='grid')
|
ans += tabulate(compute_capacities(op), tablefmt="grid")
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ add_doc = """ Adding MOs
|
|||||||
|
|
||||||
add = Dispatcher("add", doc=add_doc)
|
add = Dispatcher("add", doc=add_doc)
|
||||||
|
|
||||||
|
|
||||||
def add_filter(left, right):
|
def add_filter(left, right):
|
||||||
""" Automatic add on MO
|
""" Automatic add on MO
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ def add_filter(left, right):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOnumber, MOnumber)
|
@add.register(MOnumber, MOnumber)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def monumber_monumber(left, right):
|
def monumber_monumber(left, right):
|
||||||
@ -72,6 +74,7 @@ def monumber_monumber(left, right):
|
|||||||
"""
|
"""
|
||||||
return MO.factory(left.value + right.value)
|
return MO.factory(left.value + right.value)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOnumber, MOFraction)
|
@add.register(MOnumber, MOFraction)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def monumber_mofraction(left, right):
|
def monumber_mofraction(left, right):
|
||||||
@ -87,6 +90,7 @@ def monumber_mofraction(left, right):
|
|||||||
left_fraction = MOFraction(left, MOnumber(1))
|
left_fraction = MOFraction(left, MOnumber(1))
|
||||||
return Tree("+", left_fraction, right)
|
return Tree("+", left_fraction, right)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOFraction, MOnumber)
|
@add.register(MOFraction, MOnumber)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mofraction_monumber(left, right):
|
def mofraction_monumber(left, right):
|
||||||
@ -103,6 +107,7 @@ def mofraction_monumber(left, right):
|
|||||||
right_fraction = MOFraction(right, MOnumber(1))
|
right_fraction = MOFraction(right, MOnumber(1))
|
||||||
return Tree("+", left, right_fraction)
|
return Tree("+", left, right_fraction)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOFraction, MOFraction)
|
@add.register(MOFraction, MOFraction)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mofraction_mofraction(left, right):
|
def mofraction_mofraction(left, right):
|
||||||
@ -200,6 +205,7 @@ def mofraction_mofraction(left, right):
|
|||||||
|
|
||||||
return Tree("+", left_frac, right_frac)
|
return Tree("+", left_frac, right_frac)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, MOstr)
|
@add.register(MOstr, MOstr)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mostr_mostr(left, right):
|
def mostr_mostr(left, right):
|
||||||
@ -215,6 +221,7 @@ def mostr_mostr(left, right):
|
|||||||
raise NotImplementedError("Can't add 2 MOstr with not same letter")
|
raise NotImplementedError("Can't add 2 MOstr with not same letter")
|
||||||
return MOMonomial(2, left)
|
return MOMonomial(2, left)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstrPower, MOstrPower)
|
@add.register(MOstrPower, MOstrPower)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mostrpower_mostrpower(left, right):
|
def mostrpower_mostrpower(left, right):
|
||||||
@ -230,6 +237,7 @@ def mostrpower_mostrpower(left, right):
|
|||||||
raise NotImplementedError("Can't add 2 MOstrPower with not same power")
|
raise NotImplementedError("Can't add 2 MOstrPower with not same power")
|
||||||
return MOMonomial(2, left.variable, left.power)
|
return MOMonomial(2, left.variable, left.power)
|
||||||
|
|
||||||
|
|
||||||
@add.register((MOnumber, MOFraction), MOpolynomial)
|
@add.register((MOnumber, MOFraction), MOpolynomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def moscalar_mopolynomial(left, right):
|
def moscalar_mopolynomial(left, right):
|
||||||
@ -254,7 +262,8 @@ def moscalar_mopolynomial(left, right):
|
|||||||
right_top = [mo for deg, mo in right.monomials.items() if deg > 0][::-1]
|
right_top = [mo for deg, mo in right.monomials.items() if deg > 0][::-1]
|
||||||
|
|
||||||
adds = right_top + [Tree("+", left, right_const)]
|
adds = right_top + [Tree("+", left, right_const)]
|
||||||
return Tree.from_list('+', adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, (MOnumber, MOFraction))
|
@add.register(MOpolynomial, (MOnumber, MOFraction))
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
@ -280,7 +289,8 @@ def mopolynomial_moscalar(left, right):
|
|||||||
left_top = [mo for deg, mo in left.monomials.items() if deg > 0][::-1]
|
left_top = [mo for deg, mo in left.monomials.items() if deg > 0][::-1]
|
||||||
|
|
||||||
adds = left_top + [Tree("+", left_const, right)]
|
adds = left_top + [Tree("+", left_const, right)]
|
||||||
return Tree.from_list('+', adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, MOpolynomial)
|
@add.register(MOstr, MOpolynomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
@ -313,6 +323,7 @@ def mostr_mopolynomial(left, right):
|
|||||||
|
|
||||||
return Tree.from_list("+", adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOstr)
|
@add.register(MOpolynomial, MOstr)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mopolynomial_mostr(left, right):
|
def mopolynomial_mostr(left, right):
|
||||||
@ -344,6 +355,7 @@ def mopolynomial_mostr(left, right):
|
|||||||
|
|
||||||
return Tree.from_list("+", adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstrPower, MOpolynomial)
|
@add.register(MOstrPower, MOpolynomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mostrpower_mopolynomial(left, right):
|
def mostrpower_mopolynomial(left, right):
|
||||||
@ -387,6 +399,7 @@ def mostrpower_mopolynomial(left, right):
|
|||||||
|
|
||||||
return Tree.from_list("+", adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOstrPower)
|
@add.register(MOpolynomial, MOstrPower)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mopolynomial_mostrpower(left, right):
|
def mopolynomial_mostrpower(left, right):
|
||||||
@ -431,6 +444,7 @@ def mopolynomial_mostrpower(left, right):
|
|||||||
|
|
||||||
return Tree.from_list("+", adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOpolynomial)
|
@add.register(MOMonomial, MOpolynomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def momonomial_mopolynomial(left, right):
|
def momonomial_mopolynomial(left, right):
|
||||||
@ -474,6 +488,7 @@ def momonomial_mopolynomial(left, right):
|
|||||||
|
|
||||||
return Tree.from_list("+", adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOMonomial)
|
@add.register(MOpolynomial, MOMonomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mopolynomial_momonomial(left, right):
|
def mopolynomial_momonomial(left, right):
|
||||||
@ -517,6 +532,7 @@ def mopolynomial_momonomial(left, right):
|
|||||||
|
|
||||||
return Tree.from_list("+", adds)
|
return Tree.from_list("+", adds)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOpolynomial)
|
@add.register(MOpolynomial, MOpolynomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mopolynomial_mopolynomial(left, right):
|
def mopolynomial_mopolynomial(left, right):
|
||||||
@ -573,6 +589,7 @@ def mopolynomial_mopolynomial(left, right):
|
|||||||
|
|
||||||
return Tree.from_list("+", list(merge_monomials.values())[::-1])
|
return Tree.from_list("+", list(merge_monomials.values())[::-1])
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, MOMonomial)
|
@add.register(MOstr, MOMonomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mostr_momonomial(left, right):
|
def mostr_momonomial(left, right):
|
||||||
@ -593,6 +610,7 @@ def mostr_momonomial(left, right):
|
|||||||
add_scal = Tree("+", 1, right.coefficient)
|
add_scal = Tree("+", 1, right.coefficient)
|
||||||
return Tree("*", add_scal, left)
|
return Tree("*", add_scal, left)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOstr)
|
@add.register(MOMonomial, MOstr)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def momonomial_mostr(left, right):
|
def momonomial_mostr(left, right):
|
||||||
@ -613,6 +631,7 @@ def momonomial_mostr(left, right):
|
|||||||
add_scal = Tree("+", left.coefficient, 1)
|
add_scal = Tree("+", left.coefficient, 1)
|
||||||
return Tree("*", add_scal, right)
|
return Tree("*", add_scal, right)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstrPower, MOMonomial)
|
@add.register(MOstrPower, MOMonomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def mostrpower_momonomial(left, right):
|
def mostrpower_momonomial(left, right):
|
||||||
@ -633,6 +652,7 @@ def mostrpower_momonomial(left, right):
|
|||||||
add_scal = Tree("+", 1, right.coefficient)
|
add_scal = Tree("+", 1, right.coefficient)
|
||||||
return Tree("*", add_scal, left)
|
return Tree("*", add_scal, left)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOstrPower)
|
@add.register(MOMonomial, MOstrPower)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def momonomial_mostrpower(left, right):
|
def momonomial_mostrpower(left, right):
|
||||||
@ -653,6 +673,7 @@ def momonomial_mostrpower(left, right):
|
|||||||
add_scal = Tree("+", left.coefficient, 1)
|
add_scal = Tree("+", left.coefficient, 1)
|
||||||
return Tree("*", add_scal, right)
|
return Tree("*", add_scal, right)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOMonomial)
|
@add.register(MOMonomial, MOMonomial)
|
||||||
@special_case(add_filter)
|
@special_case(add_filter)
|
||||||
def momonomial_momonomial(left, right):
|
def momonomial_momonomial(left, right):
|
||||||
|
@ -28,6 +28,7 @@ divide_doc = """ Dividing MOs
|
|||||||
|
|
||||||
divide = Dispatcher("divide", doc=divide_doc)
|
divide = Dispatcher("divide", doc=divide_doc)
|
||||||
|
|
||||||
|
|
||||||
def divide_filter(left, right):
|
def divide_filter(left, right):
|
||||||
""" Automatic divide on MO
|
""" Automatic divide on MO
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ def divide_filter(left, right):
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@divide.register(MOnumber, MOnumber)
|
@divide.register(MOnumber, MOnumber)
|
||||||
@special_case(divide_filter)
|
@special_case(divide_filter)
|
||||||
def monumber_monumber(left, right):
|
def monumber_monumber(left, right):
|
||||||
@ -78,11 +80,13 @@ def monumber_monumber(left, right):
|
|||||||
...
|
...
|
||||||
NotImplementedError: Can't divide 2 int. Need to create a Fraction instead
|
NotImplementedError: Can't divide 2 int. Need to create a Fraction instead
|
||||||
"""
|
"""
|
||||||
if type(left.value) in [float, Decimal] or \
|
if type(left.value) in [float, Decimal] or type(right.value) in [float, Decimal]:
|
||||||
type(right.value) in [float, Decimal]:
|
|
||||||
return MO.factory(left.value / right.value)
|
return MO.factory(left.value / right.value)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError("Can't divide 2 int. Need to create a Fraction instead")
|
raise NotImplementedError(
|
||||||
|
"Can't divide 2 int. Need to create a Fraction instead"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@divide.register(MOnumber, MOFraction)
|
@divide.register(MOnumber, MOFraction)
|
||||||
@special_case(divide_filter)
|
@special_case(divide_filter)
|
||||||
@ -103,6 +107,7 @@ def monumber_mofraction(left, right):
|
|||||||
"""
|
"""
|
||||||
return Tree("*", left, right.inverse())
|
return Tree("*", left, right.inverse())
|
||||||
|
|
||||||
|
|
||||||
@divide.register(MOFraction, MOnumber)
|
@divide.register(MOFraction, MOnumber)
|
||||||
@special_case(divide_filter)
|
@special_case(divide_filter)
|
||||||
def mofraction_monumber(left, right):
|
def mofraction_monumber(left, right):
|
||||||
@ -119,6 +124,7 @@ def mofraction_monumber(left, right):
|
|||||||
right_fraction = MOFraction(MOnumber(1), right)
|
right_fraction = MOFraction(MOnumber(1), right)
|
||||||
return Tree("*", left, right_fraction)
|
return Tree("*", left, right_fraction)
|
||||||
|
|
||||||
|
|
||||||
@divide.register(MOFraction, MOFraction)
|
@divide.register(MOFraction, MOFraction)
|
||||||
@special_case(divide_filter)
|
@special_case(divide_filter)
|
||||||
def mofraction_mofraction(left, right):
|
def mofraction_mofraction(left, right):
|
||||||
@ -134,6 +140,7 @@ def mofraction_mofraction(left, right):
|
|||||||
"""
|
"""
|
||||||
return Tree("*", left, right.inverse())
|
return Tree("*", left, right.inverse())
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -10,18 +10,23 @@
|
|||||||
Exceptions for computing
|
Exceptions for computing
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ComputeError(Exception):
|
class ComputeError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AddError(ComputeError):
|
class AddError(ComputeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MinusError(ComputeError):
|
class MinusError(ComputeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MultiplyError(ComputeError):
|
class MultiplyError(ComputeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DivideError(ComputeError):
|
class DivideError(ComputeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ Decorator to filter MO before operate
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from .exceptions import ComputeError
|
from .exceptions import ComputeError
|
||||||
|
|
||||||
|
|
||||||
def args_are(left_type, right_type):
|
def args_are(left_type, right_type):
|
||||||
""" Decorator which filter arguments type
|
""" Decorator which filter arguments type
|
||||||
|
|
||||||
@ -21,21 +22,27 @@ def args_are(left_type, right_type):
|
|||||||
:returns: a decorator which will allow only some type
|
:returns: a decorator which will allow only some type
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def type_filter(func):
|
def type_filter(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def filtered_func(left, right):
|
def filtered_func(left, right):
|
||||||
if not isinstance(left, left_type):
|
if not isinstance(left, left_type):
|
||||||
raise ComputeError("Wrong type for left argument"
|
raise ComputeError(
|
||||||
|
"Wrong type for left argument"
|
||||||
f"Require {left_type}, got {left.__class__.__name__}"
|
f"Require {left_type}, got {left.__class__.__name__}"
|
||||||
)
|
)
|
||||||
if not isinstance(right, right_type):
|
if not isinstance(right, right_type):
|
||||||
raise ComputeError("Wrong type for right argument"
|
raise ComputeError(
|
||||||
|
"Wrong type for right argument"
|
||||||
f"Require {right_type}, got {right.__class__.__name__}"
|
f"Require {right_type}, got {right.__class__.__name__}"
|
||||||
)
|
)
|
||||||
return func(left, right)
|
return func(left, right)
|
||||||
|
|
||||||
return filtered_func
|
return filtered_func
|
||||||
|
|
||||||
return type_filter
|
return type_filter
|
||||||
|
|
||||||
|
|
||||||
def special_case(filter):
|
def special_case(filter):
|
||||||
""" Decorate operation to filter special cases before call the function
|
""" Decorate operation to filter special cases before call the function
|
||||||
|
|
||||||
@ -43,6 +50,7 @@ def special_case(filter):
|
|||||||
:returns: decorator
|
:returns: decorator
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def _func(left, right):
|
def _func(left, right):
|
||||||
@ -50,9 +58,12 @@ def special_case(filter):
|
|||||||
if ans is None:
|
if ans is None:
|
||||||
return func(left, right)
|
return func(left, right)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
return _func
|
return _func
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -28,6 +28,7 @@ minus_doc = """ Opposite of a MO
|
|||||||
|
|
||||||
minus = Dispatcher("minus", doc=minus_doc)
|
minus = Dispatcher("minus", doc=minus_doc)
|
||||||
|
|
||||||
|
|
||||||
@minus.register(type(None), MOnumber)
|
@minus.register(type(None), MOnumber)
|
||||||
def monumber(_, right):
|
def monumber(_, right):
|
||||||
"""
|
"""
|
||||||
@ -39,6 +40,7 @@ def monumber(_, right):
|
|||||||
"""
|
"""
|
||||||
return MO.factory(-right.value)
|
return MO.factory(-right.value)
|
||||||
|
|
||||||
|
|
||||||
@minus.register(type(None), MOFraction)
|
@minus.register(type(None), MOFraction)
|
||||||
def mofraction(_, right):
|
def mofraction(_, right):
|
||||||
""" 4 differents cases
|
""" 4 differents cases
|
||||||
@ -84,6 +86,7 @@ def mofraction(_, right):
|
|||||||
|
|
||||||
return MOFraction(right._numerator, right._denominator, True)
|
return MOFraction(right._numerator, right._denominator, True)
|
||||||
|
|
||||||
|
|
||||||
@minus.register(type(None), MOstr)
|
@minus.register(type(None), MOstr)
|
||||||
def mostr(_, right):
|
def mostr(_, right):
|
||||||
""" Opposite of 'x' is '-x'
|
""" Opposite of 'x' is '-x'
|
||||||
@ -95,6 +98,7 @@ def mostr(_, right):
|
|||||||
"""
|
"""
|
||||||
return MOMonomial(-1, right)
|
return MOMonomial(-1, right)
|
||||||
|
|
||||||
|
|
||||||
@minus.register(type(None), MOstrPower)
|
@minus.register(type(None), MOstrPower)
|
||||||
def mostrpower(_, right):
|
def mostrpower(_, right):
|
||||||
""" Opposite of 'x^n' is '-x^n'
|
""" Opposite of 'x^n' is '-x^n'
|
||||||
@ -106,6 +110,7 @@ def mostrpower(_, right):
|
|||||||
"""
|
"""
|
||||||
return MOMonomial(-1, right.variable, right.power)
|
return MOMonomial(-1, right.variable, right.power)
|
||||||
|
|
||||||
|
|
||||||
@minus.register(type(None), MOMonomial)
|
@minus.register(type(None), MOMonomial)
|
||||||
def momonomial(_, right):
|
def momonomial(_, right):
|
||||||
""" Opposite of 'ax^n' is '-ax^n'
|
""" Opposite of 'ax^n' is '-ax^n'
|
||||||
@ -121,6 +126,7 @@ def momonomial(_, right):
|
|||||||
coef = Tree("-", None, right.coefficient)
|
coef = Tree("-", None, right.coefficient)
|
||||||
return Tree("*", coef, right.strpower)
|
return Tree("*", coef, right.strpower)
|
||||||
|
|
||||||
|
|
||||||
@minus.register(type(None), MOpolynomial)
|
@minus.register(type(None), MOpolynomial)
|
||||||
def mopolynomial(_, right):
|
def mopolynomial(_, right):
|
||||||
""" Opposite of a polynomial
|
""" Opposite of a polynomial
|
||||||
@ -133,6 +139,7 @@ def mopolynomial(_, right):
|
|||||||
neg_coefs = {p: -c.value for (p, c) in right.coefficients.items()}
|
neg_coefs = {p: -c.value for (p, c) in right.coefficients.items()}
|
||||||
return MOpolynomial(right.variable, neg_coefs)
|
return MOpolynomial(right.variable, neg_coefs)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -28,6 +28,7 @@ multiply_doc = """ Multiply MOs
|
|||||||
|
|
||||||
multiply = Dispatcher("multiply", doc=multiply_doc)
|
multiply = Dispatcher("multiply", doc=multiply_doc)
|
||||||
|
|
||||||
|
|
||||||
def multiply_filter(left, right):
|
def multiply_filter(left, right):
|
||||||
""" Automatic multiply on MO
|
""" Automatic multiply on MO
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ def multiply_filter(left, right):
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOnumber, MOnumber)
|
@multiply.register(MOnumber, MOnumber)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def monumber_monumber(left, right):
|
def monumber_monumber(left, right):
|
||||||
@ -81,6 +83,7 @@ def monumber_monumber(left, right):
|
|||||||
"""
|
"""
|
||||||
return MO.factory(left.value * right.value)
|
return MO.factory(left.value * right.value)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOnumber, MOFraction)
|
@multiply.register(MOnumber, MOFraction)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def monumber_mofraction(left, right):
|
def monumber_mofraction(left, right):
|
||||||
@ -108,6 +111,7 @@ def monumber_mofraction(left, right):
|
|||||||
num = Tree("*", left, right.numerator)
|
num = Tree("*", left, right.numerator)
|
||||||
return Tree("/", num, right._denominator)
|
return Tree("/", num, right._denominator)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOFraction, MOnumber)
|
@multiply.register(MOFraction, MOnumber)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mofraction_monumber(left, right):
|
def mofraction_monumber(left, right):
|
||||||
@ -125,6 +129,7 @@ def mofraction_monumber(left, right):
|
|||||||
num = Tree("*", left.numerator, right)
|
num = Tree("*", left.numerator, right)
|
||||||
return Tree("/", num, left._denominator)
|
return Tree("/", num, left._denominator)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOFraction, MOFraction)
|
@multiply.register(MOFraction, MOFraction)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mofraction_mofraction(left, right):
|
def mofraction_mofraction(left, right):
|
||||||
@ -145,6 +150,7 @@ def mofraction_mofraction(left, right):
|
|||||||
denom = Tree("*", left.denominator, right.denominator)
|
denom = Tree("*", left.denominator, right.denominator)
|
||||||
return Tree("/", num, denom)
|
return Tree("/", num, denom)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register((MOnumber, MOFraction), MOMonomial)
|
@multiply.register((MOnumber, MOFraction), MOMonomial)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def moscalar_monomonial(left, right):
|
def moscalar_monomonial(left, right):
|
||||||
@ -161,8 +167,9 @@ def moscalar_monomonial(left, right):
|
|||||||
> x^4
|
> x^4
|
||||||
|
|
||||||
"""
|
"""
|
||||||
coefficient = Tree('*', left, right.coefficient)
|
coefficient = Tree("*", left, right.coefficient)
|
||||||
return Tree('*', coefficient, right.strpower)
|
return Tree("*", coefficient, right.strpower)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOMonomial, (MOnumber, MOFraction))
|
@multiply.register(MOMonomial, (MOnumber, MOFraction))
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
@ -180,8 +187,9 @@ def monomonial_moscalar(left, right):
|
|||||||
> x^4
|
> x^4
|
||||||
|
|
||||||
"""
|
"""
|
||||||
coefficient = Tree('*', right, left.coefficient)
|
coefficient = Tree("*", right, left.coefficient)
|
||||||
return Tree('*', coefficient, left.strpower)
|
return Tree("*", coefficient, left.strpower)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstr, MOstrPower)
|
@multiply.register(MOstr, MOstrPower)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
@ -200,10 +208,13 @@ def mostr_mostrpower(left, right):
|
|||||||
NotImplementedError: Can't multiply MOstr and MOstrPower if they don'thave same variable (got x and y)
|
NotImplementedError: Can't multiply MOstr and MOstrPower if they don'thave same variable (got x and y)
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstr and MOstrPower if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstr and MOstrPower if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
return MOstrPower(left.variable, right.power.value + 1)
|
return MOstrPower(left.variable, right.power.value + 1)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstrPower, MOstr)
|
@multiply.register(MOstrPower, MOstr)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mostr_mostrpower(left, right):
|
def mostr_mostrpower(left, right):
|
||||||
@ -221,10 +232,13 @@ def mostr_mostrpower(left, right):
|
|||||||
NotImplementedError: Can't multiply MOstr and MOstrPower if they don'thave same variable (got x and y)
|
NotImplementedError: Can't multiply MOstr and MOstrPower if they don'thave same variable (got x and y)
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstr and MOstrPower if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstr and MOstrPower if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
return MOstrPower(left.variable, left.power.value + 1)
|
return MOstrPower(left.variable, left.power.value + 1)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstr, MOstr)
|
@multiply.register(MOstr, MOstr)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mostr_mostr(left, right):
|
def mostr_mostr(left, right):
|
||||||
@ -243,10 +257,13 @@ def mostr_mostr(left, right):
|
|||||||
NotImplementedError: Can't multiply MOstr and MOstr if they don'thave same variable (got y and x)
|
NotImplementedError: Can't multiply MOstr and MOstr if they don'thave same variable (got y and x)
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstr and MOstr if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstr and MOstr if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
return MOstrPower(left.variable, 2)
|
return MOstrPower(left.variable, 2)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstrPower, MOstrPower)
|
@multiply.register(MOstrPower, MOstrPower)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mostr_mostrpower(left, right):
|
def mostr_mostrpower(left, right):
|
||||||
@ -268,11 +285,14 @@ def mostr_mostrpower(left, right):
|
|||||||
NotImplementedError: Can't multiply MOstrPower and MOstrPower if they don'thave same variable (got x and y)
|
NotImplementedError: Can't multiply MOstrPower and MOstrPower if they don'thave same variable (got x and y)
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstrPower and MOstrPower if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstrPower and MOstrPower if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
power = Tree("+", left.power, right.power)
|
power = Tree("+", left.power, right.power)
|
||||||
return Tree("^", left.variable, power)
|
return Tree("^", left.variable, power)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstrPower, MOMonomial)
|
@multiply.register(MOstrPower, MOMonomial)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mostrpower_momonomial(left, right):
|
def mostrpower_momonomial(left, right):
|
||||||
@ -296,12 +316,15 @@ def mostrpower_momonomial(left, right):
|
|||||||
NotImplementedError: Can't multiply MOstrPower and Monomial if they don'thave same variable (got x and y)
|
NotImplementedError: Can't multiply MOstrPower and Monomial if they don'thave same variable (got x and y)
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstrPower and Monomial if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstrPower and Monomial if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
power = Tree("+", left.power, right.power)
|
power = Tree("+", left.power, right.power)
|
||||||
monome = Tree("^", left.variable, power)
|
monome = Tree("^", left.variable, power)
|
||||||
return Tree("*", right.coefficient, monome)
|
return Tree("*", right.coefficient, monome)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOMonomial, MOstrPower)
|
@multiply.register(MOMonomial, MOstrPower)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def momonomial_mostr(left, right):
|
def momonomial_mostr(left, right):
|
||||||
@ -326,12 +349,15 @@ def momonomial_mostr(left, right):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstrPower and Monomial if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstrPower and Monomial if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
power = Tree("+", left.power, right.power)
|
power = Tree("+", left.power, right.power)
|
||||||
monome = Tree("^", left.variable, power)
|
monome = Tree("^", left.variable, power)
|
||||||
return Tree("*", left.coefficient, monome)
|
return Tree("*", left.coefficient, monome)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstr, MOMonomial)
|
@multiply.register(MOstr, MOMonomial)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mostr_momonomial(left, right):
|
def mostr_momonomial(left, right):
|
||||||
@ -349,10 +375,13 @@ def mostr_momonomial(left, right):
|
|||||||
NotImplementedError: Can't multiply MOstr and Monomial if they don'thave same variable (got x and y)
|
NotImplementedError: Can't multiply MOstr and Monomial if they don'thave same variable (got x and y)
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstr and Monomial if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstr and Monomial if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
return MOMonomial(right.coefficient, right.variable, right.power.value + 1)
|
return MOMonomial(right.coefficient, right.variable, right.power.value + 1)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOMonomial, MOstr)
|
@multiply.register(MOMonomial, MOstr)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def momonomial_mostr(left, right):
|
def momonomial_mostr(left, right):
|
||||||
@ -371,10 +400,13 @@ def momonomial_mostr(left, right):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOstr and Monomial if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOstr and Monomial if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
return MOMonomial(left.coefficient, left.variable, left.power.value + 1)
|
return MOMonomial(left.coefficient, left.variable, left.power.value + 1)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOMonomial, MOMonomial)
|
@multiply.register(MOMonomial, MOMonomial)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def momonomial_momonomial(left, right):
|
def momonomial_momonomial(left, right):
|
||||||
@ -401,15 +433,17 @@ def momonomial_momonomial(left, right):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't multiply MOMonomial and Monomial if they don't"
|
raise NotImplementedError(
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
"Can't multiply MOMonomial and Monomial if they don't"
|
||||||
|
f"have same variable (got {left.variable} and {right.variable})"
|
||||||
|
)
|
||||||
powers = Tree("+", left.power, right.power)
|
powers = Tree("+", left.power, right.power)
|
||||||
monome = Tree("^", left.variable, powers)
|
monome = Tree("^", left.variable, powers)
|
||||||
coefs = Tree("*", left.coefficient, right.coefficient)
|
coefs = Tree("*", left.coefficient, right.coefficient)
|
||||||
return Tree("*", coefs, monome)
|
return Tree("*", coefs, monome)
|
||||||
|
|
||||||
@multiply.register((MOnumber, MOFraction, MOstr, MOstrPower, MOMonomial), \
|
|
||||||
MOpolynomial)
|
@multiply.register((MOnumber, MOFraction, MOstr, MOstrPower, MOMonomial), MOpolynomial)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def lotsmo_mopolynomial(left, right):
|
def lotsmo_mopolynomial(left, right):
|
||||||
""" Multiply a scalar and a MOMonomial
|
""" Multiply a scalar and a MOMonomial
|
||||||
@ -492,13 +526,11 @@ def lotsmo_mopolynomial(left, right):
|
|||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
coefs = [Tree("*", left, monom) \
|
coefs = [Tree("*", left, monom) for monom in list(right.monomials.values())[::-1]]
|
||||||
for monom in list(right.monomials.values())[::-1]\
|
|
||||||
]
|
|
||||||
return Tree.from_list("+", coefs)
|
return Tree.from_list("+", coefs)
|
||||||
|
|
||||||
@multiply.register(MOpolynomial, \
|
|
||||||
(MOnumber, MOFraction, MOstr, MOstrPower, MOMonomial))
|
@multiply.register(MOpolynomial, (MOnumber, MOFraction, MOstr, MOstrPower, MOMonomial))
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mopolynomial_lotsmo(left, right):
|
def mopolynomial_lotsmo(left, right):
|
||||||
""" Multiply a MOpolynomial with nearly everything
|
""" Multiply a MOpolynomial with nearly everything
|
||||||
@ -581,11 +613,10 @@ def mopolynomial_lotsmo(left, right):
|
|||||||
| | > 3x^2
|
| | > 3x^2
|
||||||
|
|
||||||
"""
|
"""
|
||||||
coefs = [Tree("*", monom, right) \
|
coefs = [Tree("*", monom, right) for monom in list(left.monomials.values())[::-1]]
|
||||||
for monom in list(left.monomials.values())[::-1] \
|
|
||||||
]
|
|
||||||
return Tree.from_list("+", coefs)
|
return Tree.from_list("+", coefs)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOpolynomial, MOpolynomial)
|
@multiply.register(MOpolynomial, MOpolynomial)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
def mopolynomial_mopolynomial(left, right):
|
def mopolynomial_mopolynomial(left, right):
|
||||||
@ -619,9 +650,10 @@ def mopolynomial_mopolynomial(left, right):
|
|||||||
| | | > 4
|
| | | > 4
|
||||||
|
|
||||||
"""
|
"""
|
||||||
coefs = [Tree("*", l_monom, r_monom) \
|
coefs = [
|
||||||
for l_monom in list(left.monomials.values())[::-1] \
|
Tree("*", l_monom, r_monom)
|
||||||
for r_monom in list(right.monomials.values())[::-1] \
|
for l_monom in list(left.monomials.values())[::-1]
|
||||||
|
for r_monom in list(right.monomials.values())[::-1]
|
||||||
]
|
]
|
||||||
return Tree.from_list("+", coefs)
|
return Tree.from_list("+", coefs)
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ power_doc = """ Power of MOs
|
|||||||
|
|
||||||
power = Dispatcher("power", doc=power_doc)
|
power = Dispatcher("power", doc=power_doc)
|
||||||
|
|
||||||
|
|
||||||
def power_filter(left, right):
|
def power_filter(left, right):
|
||||||
""" Automatic power on MO
|
""" Automatic power on MO
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ def power_filter(left, right):
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@power.register(MOnumber, MOnumber)
|
@power.register(MOnumber, MOnumber)
|
||||||
@special_case(power_filter)
|
@special_case(power_filter)
|
||||||
def monumber_monumber(left, right):
|
def monumber_monumber(left, right):
|
||||||
@ -73,6 +75,7 @@ def monumber_monumber(left, right):
|
|||||||
"""
|
"""
|
||||||
return MO.factory(left.value ** right.value)
|
return MO.factory(left.value ** right.value)
|
||||||
|
|
||||||
|
|
||||||
@power.register(MOFraction, MOnumber)
|
@power.register(MOFraction, MOnumber)
|
||||||
@special_case(power_filter)
|
@special_case(power_filter)
|
||||||
def mofraction_monumber(left, right):
|
def mofraction_monumber(left, right):
|
||||||
@ -93,6 +96,7 @@ def mofraction_monumber(left, right):
|
|||||||
denom = Tree("^", left.denominator, right)
|
denom = Tree("^", left.denominator, right)
|
||||||
return Tree("/", num, denom)
|
return Tree("/", num, denom)
|
||||||
|
|
||||||
|
|
||||||
@power.register(MOstrPower, MOnumber)
|
@power.register(MOstrPower, MOnumber)
|
||||||
@special_case(power_filter)
|
@special_case(power_filter)
|
||||||
def mostrpower_monumber(left, right):
|
def mostrpower_monumber(left, right):
|
||||||
@ -110,6 +114,7 @@ def mostrpower_monumber(left, right):
|
|||||||
power = Tree("*", left.power, right)
|
power = Tree("*", left.power, right)
|
||||||
return Tree("^", left.variable, power)
|
return Tree("^", left.variable, power)
|
||||||
|
|
||||||
|
|
||||||
@power.register(MOMonomial, MOnumber)
|
@power.register(MOMonomial, MOnumber)
|
||||||
@special_case(power_filter)
|
@special_case(power_filter)
|
||||||
def mostrpower_monumber(left, right):
|
def mostrpower_monumber(left, right):
|
||||||
@ -133,6 +138,7 @@ def mostrpower_monumber(left, right):
|
|||||||
strpower = Tree("^", left.variable, power)
|
strpower = Tree("^", left.variable, power)
|
||||||
return Tree("*", coef, strpower)
|
return Tree("*", coef, strpower)
|
||||||
|
|
||||||
|
|
||||||
@power.register(MOpolynomial, MOnumber)
|
@power.register(MOpolynomial, MOnumber)
|
||||||
@special_case(power_filter)
|
@special_case(power_filter)
|
||||||
def mopolynomial_monumber(left, right):
|
def mopolynomial_monumber(left, right):
|
||||||
@ -148,7 +154,6 @@ def mopolynomial_monumber(left, right):
|
|||||||
return Tree.from_list("*", [left] * right.value)
|
return Tree.from_list("*", [left] * right.value)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -14,17 +14,23 @@ from functools import wraps
|
|||||||
|
|
||||||
__all__ = ["coroutine", "STOOOP", "RESTAAART"]
|
__all__ = ["coroutine", "STOOOP", "RESTAAART"]
|
||||||
|
|
||||||
|
|
||||||
def coroutine(func):
|
def coroutine(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def start(*args, **kwargs):
|
def start(*args, **kwargs):
|
||||||
cr = func(*args, **kwargs)
|
cr = func(*args, **kwargs)
|
||||||
next(cr)
|
next(cr)
|
||||||
return cr
|
return cr
|
||||||
|
|
||||||
return start
|
return start
|
||||||
|
|
||||||
class STOOOP(Exception): pass
|
|
||||||
class RESTAAART(Exception): pass
|
|
||||||
|
|
||||||
|
class STOOOP(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class RESTAAART(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
|
@ -8,32 +8,20 @@
|
|||||||
|
|
||||||
__all__ = ["OperatorError", "OPERATORS", "is_operator"]
|
__all__ = ["OperatorError", "OPERATORS", "is_operator"]
|
||||||
|
|
||||||
|
|
||||||
class OperatorError(Exception):
|
class OperatorError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
OPERATORS = {
|
OPERATORS = {
|
||||||
"+": {'repr': "+",
|
"+": {"repr": "+", "arity": 2, "precedence": 0},
|
||||||
'arity': 2,
|
"-": {"repr": "-", "arity": 1, "precedence": 1},
|
||||||
'precedence': 0,
|
"*": {"repr": "*", "arity": 2, "precedence": 2},
|
||||||
},
|
"/": {"repr": "/", "arity": 2, "precedence": 3},
|
||||||
"-": {'repr': "-",
|
"^": {"repr": "^", "arity": 2, "precedence": 4},
|
||||||
'arity': 1,
|
|
||||||
'precedence': 1,
|
|
||||||
},
|
|
||||||
"*": {'repr': "*",
|
|
||||||
'arity': 2,
|
|
||||||
'precedence': 2,
|
|
||||||
},
|
|
||||||
"/": {'repr': "/",
|
|
||||||
'arity': 2,
|
|
||||||
'precedence': 3,
|
|
||||||
},
|
|
||||||
"^": {'repr': "^",
|
|
||||||
'arity': 2,
|
|
||||||
'precedence': 4,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def is_operator(string):
|
def is_operator(string):
|
||||||
""" Return whether a string is an operator or not
|
""" Return whether a string is an operator or not
|
||||||
|
|
||||||
|
@ -14,11 +14,8 @@ import random
|
|||||||
|
|
||||||
__all__ = ["reject_random", "filter_random", "FilterRandom"]
|
__all__ = ["reject_random", "filter_random", "FilterRandom"]
|
||||||
|
|
||||||
def reject_random(min_value = -10,
|
|
||||||
max_value = 10,
|
def reject_random(min_value=-10, max_value=10, rejected=[0, 1], accept_callbacks=[]):
|
||||||
rejected = [0, 1],
|
|
||||||
accept_callbacks=[],
|
|
||||||
):
|
|
||||||
""" Generate a random integer with the rejection method
|
""" Generate a random integer with the rejection method
|
||||||
|
|
||||||
:param name: name of the Integer
|
:param name: name of the Integer
|
||||||
@ -61,11 +58,8 @@ def reject_random(min_value = -10,
|
|||||||
|
|
||||||
return candidate
|
return candidate
|
||||||
|
|
||||||
def filter_random(min_value = -10,
|
|
||||||
max_value = 10,
|
def filter_random(min_value=-10, max_value=10, rejected=[0, 1], accept_callbacks=[]):
|
||||||
rejected = [0, 1],
|
|
||||||
accept_callbacks=[],
|
|
||||||
):
|
|
||||||
""" Generate a random integer by filtering then choosing a candidate
|
""" Generate a random integer by filtering then choosing a candidate
|
||||||
|
|
||||||
:param name: name of the Integer
|
:param name: name of the Integer
|
||||||
@ -102,24 +96,28 @@ def filter_random(min_value = -10,
|
|||||||
candidates = set(range(min_value, max_value + 1))
|
candidates = set(range(min_value, max_value + 1))
|
||||||
candidates = {c for c in candidates if c not in rejected}
|
candidates = {c for c in candidates if c not in rejected}
|
||||||
|
|
||||||
candidates = [candidate for candidate in candidates \
|
candidates = [
|
||||||
if all(c(candidate) for c in accept_callbacks)]
|
candidate
|
||||||
|
for candidate in candidates
|
||||||
|
if all(c(candidate) for c in accept_callbacks)
|
||||||
|
]
|
||||||
|
|
||||||
if len(candidates) == 0:
|
if len(candidates) == 0:
|
||||||
raise OverflowError("There is no candidates for this range and those conditions")
|
raise OverflowError(
|
||||||
|
"There is no candidates for this range and those conditions"
|
||||||
|
)
|
||||||
return random.choice(candidates)
|
return random.choice(candidates)
|
||||||
|
|
||||||
|
|
||||||
class FilterRandom(object):
|
class FilterRandom(object):
|
||||||
|
|
||||||
""" Integer random generator which filter then choose candidate
|
""" Integer random generator which filter then choose candidate
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: Faire un cache pour éviter de reconstruire les listes à chaque fois |ven. déc. 21 19:07:42 CET 2018
|
# TODO: Faire un cache pour éviter de reconstruire les listes à chaque fois |ven. déc. 21 19:07:42 CET 2018
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(
|
||||||
rejected = [0, 1],
|
self, rejected=[0, 1], accept_callbacks=[], min_value=-10, max_value=10
|
||||||
accept_callbacks=[],
|
|
||||||
min_value = -10,
|
|
||||||
max_value = 10,
|
|
||||||
):
|
):
|
||||||
self.conditions = (lambda x: x not in rejected,) + tuple(accept_callbacks)
|
self.conditions = (lambda x: x not in rejected,) + tuple(accept_callbacks)
|
||||||
|
|
||||||
@ -128,8 +126,11 @@ class FilterRandom(object):
|
|||||||
|
|
||||||
candidates = set(range(self._min, self._max + 1))
|
candidates = set(range(self._min, self._max + 1))
|
||||||
|
|
||||||
self._candidates = { candidate for candidate in candidates \
|
self._candidates = {
|
||||||
if all(c(candidate) for c in self.conditions) }
|
candidate
|
||||||
|
for candidate in candidates
|
||||||
|
if all(c(candidate) for c in self.conditions)
|
||||||
|
}
|
||||||
|
|
||||||
def add_candidates(self, low, high):
|
def add_candidates(self, low, high):
|
||||||
""" Add candidates between low and high to _candidates """
|
""" Add candidates between low and high to _candidates """
|
||||||
@ -147,10 +148,13 @@ class FilterRandom(object):
|
|||||||
if not (useless_low and useless_high):
|
if not (useless_low and useless_high):
|
||||||
candidates = set(range(low, high + 1))
|
candidates = set(range(low, high + 1))
|
||||||
|
|
||||||
self._candidates = self._candidates.union({
|
self._candidates = self._candidates.union(
|
||||||
candidate for candidate in candidates \
|
{
|
||||||
if all(c(candidate) for c in self.conditions) \
|
candidate
|
||||||
})
|
for candidate in candidates
|
||||||
|
if all(c(candidate) for c in self.conditions)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def candidates(self, min_value=-10, max_value=10):
|
def candidates(self, min_value=-10, max_value=10):
|
||||||
""" Return candidates between min_value and max_value """
|
""" Return candidates between min_value and max_value """
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
from mapytex.calculus.core.operator import OPERATORS
|
from mapytex.calculus.core.operator import OPERATORS
|
||||||
|
|
||||||
__all__ = ['tree2tex']
|
__all__ = ["tree2tex"]
|
||||||
|
|
||||||
|
|
||||||
def plus2tex(left, right):
|
def plus2tex(left, right):
|
||||||
r""" + rendering
|
r""" + rendering
|
||||||
@ -51,6 +52,7 @@ def plus2tex(left, right):
|
|||||||
|
|
||||||
return f"{left_} {right_}"
|
return f"{left_} {right_}"
|
||||||
|
|
||||||
|
|
||||||
def minus2tex(left, right):
|
def minus2tex(left, right):
|
||||||
r""" - rendering
|
r""" - rendering
|
||||||
|
|
||||||
@ -64,7 +66,7 @@ def minus2tex(left, right):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
right_need_parenthesis = False
|
right_need_parenthesis = False
|
||||||
if OPERATORS[right.node]["precedence"] < OPERATORS['-']["precedence"]:
|
if OPERATORS[right.node]["precedence"] < OPERATORS["-"]["precedence"]:
|
||||||
right_need_parenthesis = True
|
right_need_parenthesis = True
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
right_ = right.__tex__
|
right_ = right.__tex__
|
||||||
@ -76,6 +78,7 @@ def minus2tex(left, right):
|
|||||||
|
|
||||||
return f"- {right_}"
|
return f"- {right_}"
|
||||||
|
|
||||||
|
|
||||||
def mul2tex(left, right):
|
def mul2tex(left, right):
|
||||||
r""" * rendering
|
r""" * rendering
|
||||||
|
|
||||||
@ -101,14 +104,16 @@ def mul2tex(left, right):
|
|||||||
right_ = render_with_parenthesis(right, "*")
|
right_ = render_with_parenthesis(right, "*")
|
||||||
|
|
||||||
display_time = True
|
display_time = True
|
||||||
if (right_[0].isalpha() and (left_.isnumeric() or left_.isdecimal())) or \
|
if (right_[0].isalpha() and (left_.isnumeric() or left_.isdecimal())) or right_[
|
||||||
right_[0] == '(':
|
0
|
||||||
|
] == "(":
|
||||||
display_time = False
|
display_time = False
|
||||||
|
|
||||||
if display_time:
|
if display_time:
|
||||||
return f"{left_} \\times {right_}"
|
return f"{left_} \\times {right_}"
|
||||||
return f"{left_}{right_}"
|
return f"{left_}{right_}"
|
||||||
|
|
||||||
|
|
||||||
def div2tex(left, right):
|
def div2tex(left, right):
|
||||||
r""" / rendering
|
r""" / rendering
|
||||||
|
|
||||||
@ -137,6 +142,7 @@ def div2tex(left, right):
|
|||||||
|
|
||||||
return "\\frac{" + left_ + "}{" + right_ + "}"
|
return "\\frac{" + left_ + "}{" + right_ + "}"
|
||||||
|
|
||||||
|
|
||||||
def pow2tex(left, right):
|
def pow2tex(left, right):
|
||||||
r""" ^ rendering
|
r""" ^ rendering
|
||||||
|
|
||||||
@ -159,7 +165,7 @@ def pow2tex(left, right):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
left_need_parenthesis = False
|
left_need_parenthesis = False
|
||||||
if OPERATORS[left.node]["precedence"] < OPERATORS['^']["precedence"]:
|
if OPERATORS[left.node]["precedence"] < OPERATORS["^"]["precedence"]:
|
||||||
left_need_parenthesis = True
|
left_need_parenthesis = True
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
left_ = left.__tex__
|
left_ = left.__tex__
|
||||||
@ -185,7 +191,10 @@ def render_with_parenthesis(subtree, operator):
|
|||||||
subtree.node
|
subtree.node
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
if OPERATORS[subtree.MAINOP]["precedence"] < OPERATORS[operator]["precedence"]:
|
if (
|
||||||
|
OPERATORS[subtree.MAINOP]["precedence"]
|
||||||
|
< OPERATORS[operator]["precedence"]
|
||||||
|
):
|
||||||
subtree_need_parenthesis = True
|
subtree_need_parenthesis = True
|
||||||
except (AttributeError, KeyError):
|
except (AttributeError, KeyError):
|
||||||
pass
|
pass
|
||||||
@ -200,13 +209,8 @@ def render_with_parenthesis(subtree, operator):
|
|||||||
return subtree_
|
return subtree_
|
||||||
|
|
||||||
|
|
||||||
OPERATOR2TEX = {
|
OPERATOR2TEX = {"+": plus2tex, "-": minus2tex, "*": mul2tex, "/": div2tex, "^": pow2tex}
|
||||||
"+": plus2tex,
|
|
||||||
"-": minus2tex,
|
|
||||||
"*": mul2tex,
|
|
||||||
"/": div2tex,
|
|
||||||
"^": pow2tex,
|
|
||||||
}
|
|
||||||
|
|
||||||
def tree2tex(tree):
|
def tree2tex(tree):
|
||||||
r""" Convert a tree into its tex version
|
r""" Convert a tree into its tex version
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
from ..operator import OPERATORS
|
from ..operator import OPERATORS
|
||||||
|
|
||||||
__all__ = ['tree2txt']
|
__all__ = ["tree2txt"]
|
||||||
|
|
||||||
|
|
||||||
def plus2txt(left, right):
|
def plus2txt(left, right):
|
||||||
""" + rendering
|
""" + rendering
|
||||||
@ -41,6 +42,7 @@ def plus2txt(left, right):
|
|||||||
|
|
||||||
return f"{left_} {right_}"
|
return f"{left_} {right_}"
|
||||||
|
|
||||||
|
|
||||||
def minus2txt(left, right):
|
def minus2txt(left, right):
|
||||||
""" - rendering
|
""" - rendering
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ def minus2txt(left, right):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
right_need_parenthesis = False
|
right_need_parenthesis = False
|
||||||
if OPERATORS[right.node]["precedence"] < OPERATORS['-']["precedence"]:
|
if OPERATORS[right.node]["precedence"] < OPERATORS["-"]["precedence"]:
|
||||||
right_need_parenthesis = True
|
right_need_parenthesis = True
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
right_ = right.__txt__
|
right_ = right.__txt__
|
||||||
@ -66,6 +68,7 @@ def minus2txt(left, right):
|
|||||||
|
|
||||||
return f"- {right_}"
|
return f"- {right_}"
|
||||||
|
|
||||||
|
|
||||||
def mul2txt(left, right):
|
def mul2txt(left, right):
|
||||||
""" * rendering
|
""" * rendering
|
||||||
|
|
||||||
@ -96,9 +99,9 @@ def mul2txt(left, right):
|
|||||||
|
|
||||||
if right_[0].isalpha():
|
if right_[0].isalpha():
|
||||||
# TODO: C'est bien beurk en dessous... |ven. déc. 21 12:03:07 CET 2018
|
# TODO: C'est bien beurk en dessous... |ven. déc. 21 12:03:07 CET 2018
|
||||||
if type(left).__name__ == 'MOnumber':
|
if type(left).__name__ == "MOnumber":
|
||||||
display_time = False
|
display_time = False
|
||||||
elif right_[0] == '(':
|
elif right_[0] == "(":
|
||||||
display_time = False
|
display_time = False
|
||||||
|
|
||||||
if display_time:
|
if display_time:
|
||||||
@ -106,6 +109,7 @@ def mul2txt(left, right):
|
|||||||
else:
|
else:
|
||||||
return f"{left_}{right_}"
|
return f"{left_}{right_}"
|
||||||
|
|
||||||
|
|
||||||
def div2txt(left, right):
|
def div2txt(left, right):
|
||||||
""" / rendering
|
""" / rendering
|
||||||
|
|
||||||
@ -125,7 +129,7 @@ def div2txt(left, right):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
left_need_parenthesis = False
|
left_need_parenthesis = False
|
||||||
if OPERATORS[left.node]["precedence"] < OPERATORS['/']["precedence"]:
|
if OPERATORS[left.node]["precedence"] < OPERATORS["/"]["precedence"]:
|
||||||
left_need_parenthesis = True
|
left_need_parenthesis = True
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
left_ = left.__txt__
|
left_ = left.__txt__
|
||||||
@ -136,7 +140,7 @@ def div2txt(left, right):
|
|||||||
left_ = tree2txt(left)
|
left_ = tree2txt(left)
|
||||||
try:
|
try:
|
||||||
right_need_parenthesis = False
|
right_need_parenthesis = False
|
||||||
if OPERATORS[right.node]["precedence"] < OPERATORS['/']["precedence"]:
|
if OPERATORS[right.node]["precedence"] < OPERATORS["/"]["precedence"]:
|
||||||
right_need_parenthesis = True
|
right_need_parenthesis = True
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
right_ = right.__txt__
|
right_ = right.__txt__
|
||||||
@ -148,6 +152,7 @@ def div2txt(left, right):
|
|||||||
|
|
||||||
return f"{left_} / {right_}"
|
return f"{left_} / {right_}"
|
||||||
|
|
||||||
|
|
||||||
def pow2txt(left, right):
|
def pow2txt(left, right):
|
||||||
""" ^ rendering
|
""" ^ rendering
|
||||||
|
|
||||||
@ -169,7 +174,7 @@ def pow2txt(left, right):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
right_need_parenthesis = False
|
right_need_parenthesis = False
|
||||||
if OPERATORS[right.node]["precedence"] < OPERATORS['^']["precedence"]:
|
if OPERATORS[right.node]["precedence"] < OPERATORS["^"]["precedence"]:
|
||||||
right_need_parenthesis = True
|
right_need_parenthesis = True
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
right_ = right.__txt__
|
right_ = right.__txt__
|
||||||
@ -181,13 +186,17 @@ def pow2txt(left, right):
|
|||||||
|
|
||||||
return f"{left_}^{right_}"
|
return f"{left_}^{right_}"
|
||||||
|
|
||||||
|
|
||||||
def render_with_parenthesis(subtree, operator):
|
def render_with_parenthesis(subtree, operator):
|
||||||
subtree_need_parenthesis = False
|
subtree_need_parenthesis = False
|
||||||
try:
|
try:
|
||||||
subtree.node
|
subtree.node
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
if OPERATORS[subtree.MAINOP]["precedence"] < OPERATORS[operator]["precedence"]:
|
if (
|
||||||
|
OPERATORS[subtree.MAINOP]["precedence"]
|
||||||
|
< OPERATORS[operator]["precedence"]
|
||||||
|
):
|
||||||
subtree_need_parenthesis = True
|
subtree_need_parenthesis = True
|
||||||
except (AttributeError, KeyError):
|
except (AttributeError, KeyError):
|
||||||
pass
|
pass
|
||||||
@ -201,13 +210,9 @@ def render_with_parenthesis(subtree, operator):
|
|||||||
return f"({subtree_})"
|
return f"({subtree_})"
|
||||||
return subtree_
|
return subtree_
|
||||||
|
|
||||||
OPERATOR2TXT = {
|
|
||||||
"+": plus2txt,
|
OPERATOR2TXT = {"+": plus2txt, "-": minus2txt, "*": mul2txt, "/": div2txt, "^": pow2txt}
|
||||||
"-": minus2txt,
|
|
||||||
"*": mul2txt,
|
|
||||||
"/": div2txt,
|
|
||||||
"^": pow2txt,
|
|
||||||
}
|
|
||||||
|
|
||||||
def tree2txt(tree):
|
def tree2txt(tree):
|
||||||
""" Convert a tree into its txt version
|
""" Convert a tree into its txt version
|
||||||
@ -224,6 +229,7 @@ def tree2txt(tree):
|
|||||||
'2 + 3 * 4'
|
'2 + 3 * 4'
|
||||||
"""
|
"""
|
||||||
from ..tree import Tree
|
from ..tree import Tree
|
||||||
|
|
||||||
if not isinstance(tree, Tree):
|
if not isinstance(tree, Tree):
|
||||||
raise ValueError(f"Can only render a Tree (got {type(tree).__name__}: {tree})")
|
raise ValueError(f"Can only render a Tree (got {type(tree).__name__}: {tree})")
|
||||||
return OPERATOR2TXT[tree.node](tree.left_value, tree.right_value)
|
return OPERATOR2TXT[tree.node](tree.left_value, tree.right_value)
|
||||||
|
@ -16,7 +16,8 @@ from .coroutine import *
|
|||||||
from .operator import is_operator
|
from .operator import is_operator
|
||||||
from .MO import moify
|
from .MO import moify
|
||||||
|
|
||||||
__all__ = ["str2", ]
|
__all__ = ["str2"]
|
||||||
|
|
||||||
|
|
||||||
class ParsingError(Exception):
|
class ParsingError(Exception):
|
||||||
pass
|
pass
|
||||||
@ -44,6 +45,7 @@ def maybe_it_is(cara):
|
|||||||
>>> it_is_iuo("uo")
|
>>> it_is_iuo("uo")
|
||||||
False
|
False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def func(c):
|
def func(c):
|
||||||
if c == cara:
|
if c == cara:
|
||||||
return True
|
return True
|
||||||
@ -51,20 +53,25 @@ def maybe_it_is(cara):
|
|||||||
return "maybe"
|
return "maybe"
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def something_in(cara_list):
|
def something_in(cara_list):
|
||||||
""" Return a function which sais whether a caracter is in cara_list or not
|
""" Return a function which sais whether a caracter is in cara_list or not
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def func(c):
|
def func(c):
|
||||||
if c in cara_list:
|
if c in cara_list:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def lookfor(condition, replace = lambda x:''.join(x)):
|
def lookfor(condition, replace=lambda x: "".join(x)):
|
||||||
""" Sink which is looking for term and yield replace founded patern
|
""" Sink which is looking for term and yield replace founded patern
|
||||||
with the lenght of the accumulation.
|
with the lenght of the accumulation.
|
||||||
|
|
||||||
@ -165,7 +172,7 @@ def lookfor(condition, replace = lambda x:''.join(x)):
|
|||||||
else:
|
else:
|
||||||
if c is not None:
|
if c is not None:
|
||||||
acc.append(c)
|
acc.append(c)
|
||||||
found = condition(''.join([str(i) for i in acc]))
|
found = condition("".join([str(i) for i in acc]))
|
||||||
if found == "maybe":
|
if found == "maybe":
|
||||||
ans = "maybe"
|
ans = "maybe"
|
||||||
elif found:
|
elif found:
|
||||||
@ -175,6 +182,7 @@ def lookfor(condition, replace = lambda x:''.join(x)):
|
|||||||
ans = False
|
ans = False
|
||||||
acc = []
|
acc = []
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def remember_lookfor(lookfor):
|
def remember_lookfor(lookfor):
|
||||||
""" Coroutine which remember sent value before the lookfor finds something
|
""" Coroutine which remember sent value before the lookfor finds something
|
||||||
@ -235,6 +243,7 @@ def remember_lookfor(lookfor):
|
|||||||
acc.append(c)
|
acc.append(c)
|
||||||
ans = False
|
ans = False
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def concurent_broadcast(target, lookfors=[]):
|
def concurent_broadcast(target, lookfors=[]):
|
||||||
""" Coroutine which broadcasts multiple lookfor coroutines and reinitializes
|
""" Coroutine which broadcasts multiple lookfor coroutines and reinitializes
|
||||||
@ -316,6 +325,7 @@ def concurent_broadcast(target, lookfors = []):
|
|||||||
target_.send(i)
|
target_.send(i)
|
||||||
yield target_.throw(err)
|
yield target_.throw(err)
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def missing_times(target):
|
def missing_times(target):
|
||||||
""" Coroutine which send a "*" when it's missing
|
""" Coroutine which send a "*" when it's missing
|
||||||
@ -379,15 +389,14 @@ def missing_times(target):
|
|||||||
previous = None
|
previous = None
|
||||||
|
|
||||||
if isinstance(tok, str):
|
if isinstance(tok, str):
|
||||||
if tok == '(':
|
if tok == "(":
|
||||||
target_.send("*")
|
target_.send("*")
|
||||||
elif not is_operator(tok) and tok != ')':
|
elif not is_operator(tok) and tok != ")":
|
||||||
target_.send("*")
|
target_.send("*")
|
||||||
|
|
||||||
if isinstance(tok, int) or \
|
if isinstance(tok, int) or (
|
||||||
(isinstance(tok, str) and \
|
isinstance(tok, str) and not is_operator(tok) and not tok == "("
|
||||||
not is_operator(tok) and \
|
):
|
||||||
not tok == '('):
|
|
||||||
previous = tok
|
previous = tok
|
||||||
|
|
||||||
target_.send(tok)
|
target_.send(tok)
|
||||||
@ -395,6 +404,7 @@ def missing_times(target):
|
|||||||
except STOOOP as err:
|
except STOOOP as err:
|
||||||
yield target_.throw(err)
|
yield target_.throw(err)
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def lookforNumbers(target):
|
def lookforNumbers(target):
|
||||||
""" Coroutine which parse numbers
|
""" Coroutine which parse numbers
|
||||||
@ -467,12 +477,12 @@ def lookforNumbers(target):
|
|||||||
try:
|
try:
|
||||||
int(tok)
|
int(tok)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if tok == '.':
|
if tok == ".":
|
||||||
if current.replace("-", "", 1).isdigit():
|
if current.replace("-", "", 1).isdigit():
|
||||||
current += tok
|
current += tok
|
||||||
else:
|
else:
|
||||||
raise ParsingError(f"Can't build decimal with '{current}'")
|
raise ParsingError(f"Can't build decimal with '{current}'")
|
||||||
elif tok == '-':
|
elif tok == "-":
|
||||||
if current == "":
|
if current == "":
|
||||||
current = tok
|
current = tok
|
||||||
elif current == ("("):
|
elif current == ("("):
|
||||||
@ -489,13 +499,15 @@ def lookforNumbers(target):
|
|||||||
target_.send(typifiy_numbers(current))
|
target_.send(typifiy_numbers(current))
|
||||||
except InvalidOperation:
|
except InvalidOperation:
|
||||||
target_.send(current)
|
target_.send(current)
|
||||||
target_.send('+')
|
target_.send("+")
|
||||||
current = tok
|
current = tok
|
||||||
else:
|
else:
|
||||||
if current == "":
|
if current == "":
|
||||||
current = tok
|
current = tok
|
||||||
elif is_operator(current) and is_operator(tok):
|
elif is_operator(current) and is_operator(tok):
|
||||||
raise ParsingError(f"Can't parse with 2 operators next to each other")
|
raise ParsingError(
|
||||||
|
f"Can't parse with 2 operators next to each other"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
target_.send(typifiy_numbers(current))
|
target_.send(typifiy_numbers(current))
|
||||||
@ -522,6 +534,7 @@ def lookforNumbers(target):
|
|||||||
target_.send(current)
|
target_.send(current)
|
||||||
yield target_.throw(err)
|
yield target_.throw(err)
|
||||||
|
|
||||||
|
|
||||||
def typifiy_numbers(number):
|
def typifiy_numbers(number):
|
||||||
""" Transform a str number into a integer or a decimal """
|
""" Transform a str number into a integer or a decimal """
|
||||||
try:
|
try:
|
||||||
@ -529,6 +542,7 @@ def typifiy_numbers(number):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
return Decimal(number)
|
return Decimal(number)
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def pparser(target):
|
def pparser(target):
|
||||||
""" Parenthesis parser sink
|
""" Parenthesis parser sink
|
||||||
@ -565,6 +579,7 @@ def pparser(target):
|
|||||||
except STOOOP as err:
|
except STOOOP as err:
|
||||||
yield target_.throw(err)
|
yield target_.throw(err)
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def list_sink():
|
def list_sink():
|
||||||
""" Testing sink for coroutines
|
""" Testing sink for coroutines
|
||||||
@ -588,6 +603,7 @@ def list_sink():
|
|||||||
except STOOOP:
|
except STOOOP:
|
||||||
yield ans
|
yield ans
|
||||||
|
|
||||||
|
|
||||||
def str2(sink, convert_to_mo=True):
|
def str2(sink, convert_to_mo=True):
|
||||||
""" Return a pipeline which parse an expression with the sink as an endpont
|
""" Return a pipeline which parse an expression with the sink as an endpont
|
||||||
|
|
||||||
@ -776,9 +792,12 @@ def str2(sink, convert_to_mo=True):
|
|||||||
"""
|
"""
|
||||||
lfop = lookfor(is_operator)
|
lfop = lookfor(is_operator)
|
||||||
operator_corout = partial(concurent_broadcast, lookfors=[lfop])
|
operator_corout = partial(concurent_broadcast, lookfors=[lfop])
|
||||||
|
|
||||||
def pipeline(expression):
|
def pipeline(expression):
|
||||||
if convert_to_mo:
|
if convert_to_mo:
|
||||||
str2_corout = lookforNumbers(operator_corout(missing_times(moify(pparser(sink)))))
|
str2_corout = lookforNumbers(
|
||||||
|
operator_corout(missing_times(moify(pparser(sink))))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
str2_corout = lookforNumbers(operator_corout(missing_times(pparser(sink))))
|
str2_corout = lookforNumbers(operator_corout(missing_times(pparser(sink))))
|
||||||
|
|
||||||
|
@ -9,10 +9,7 @@ Tree class
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .tree_tools import (to_nested_parenthesis,
|
from .tree_tools import to_nested_parenthesis, postfix_concatenate, show_tree
|
||||||
postfix_concatenate,
|
|
||||||
show_tree,
|
|
||||||
)
|
|
||||||
from .coroutine import coroutine, STOOOP
|
from .coroutine import coroutine, STOOOP
|
||||||
from .str2 import str2
|
from .str2 import str2
|
||||||
from .operator import OPERATORS, is_operator
|
from .operator import OPERATORS, is_operator
|
||||||
@ -20,7 +17,7 @@ from .operator import OPERATORS, is_operator
|
|||||||
__all__ = ["Tree", "MutableTree"]
|
__all__ = ["Tree", "MutableTree"]
|
||||||
|
|
||||||
|
|
||||||
class Tree():
|
class Tree:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Binary tree
|
Binary tree
|
||||||
@ -118,8 +115,7 @@ class Tree():
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
raise ValueError("Nested parenthesis are not composed of lists")
|
raise ValueError("Nested parenthesis are not composed of lists")
|
||||||
|
|
||||||
if nested_len != 2 and \
|
if nested_len != 2 and num_len != 2:
|
||||||
num_len != 2:
|
|
||||||
raise ValueError("Nested parenthesis don't have right shape")
|
raise ValueError("Nested parenthesis don't have right shape")
|
||||||
|
|
||||||
node = nested_parenthesis[0]
|
node = nested_parenthesis[0]
|
||||||
@ -241,9 +237,10 @@ class Tree():
|
|||||||
left_value = tree.left_value
|
left_value = tree.left_value
|
||||||
right_value = tree.right_value
|
right_value = tree.right_value
|
||||||
|
|
||||||
if node is None or \
|
if node is None or right_value is None:
|
||||||
right_value is None:
|
raise TypeError(
|
||||||
raise TypeError(f"Tree can't have empty node or leaf. Got node = {node} and right_value = {right_value}")
|
f"Tree can't have empty node or leaf. Got node = {node} and right_value = {right_value}"
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
left_value.IMLEAF
|
left_value.IMLEAF
|
||||||
@ -336,16 +333,14 @@ class Tree():
|
|||||||
|
|
||||||
left_is_leaf = 0
|
left_is_leaf = 0
|
||||||
try:
|
try:
|
||||||
left_applied = self.left_value.\
|
left_applied = self.left_value.apply_on_last_level(function)
|
||||||
apply_on_last_level(function)
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
left_applied = self.left_value
|
left_applied = self.left_value
|
||||||
left_is_leaf = 1
|
left_is_leaf = 1
|
||||||
|
|
||||||
right_is_leaf = 0
|
right_is_leaf = 0
|
||||||
try:
|
try:
|
||||||
right_applied = self.right_value.\
|
right_applied = self.right_value.apply_on_last_level(function)
|
||||||
apply_on_last_level(function)
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
right_applied = self.right_value
|
right_applied = self.right_value
|
||||||
right_is_leaf = 1
|
right_is_leaf = 1
|
||||||
@ -836,22 +831,22 @@ class Tree():
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
r_depth = 1
|
r_depth = 1
|
||||||
|
|
||||||
if l_depth > r_depth+1 and\
|
if (
|
||||||
self.node == self.left_value.node and \
|
l_depth > r_depth + 1
|
||||||
self.node not in exclude_nodes:
|
and self.node == self.left_value.node
|
||||||
|
and self.node not in exclude_nodes
|
||||||
|
):
|
||||||
new_left = self.left_value.long_branch
|
new_left = self.left_value.long_branch
|
||||||
new_right = Tree(self.node,
|
new_right = Tree(self.node, self.left_value.short_branch, self.right_value)
|
||||||
self.left_value.short_branch,
|
|
||||||
self.right_value)
|
|
||||||
return Tree(self.node, new_left, new_right).balance(exclude_nodes)
|
return Tree(self.node, new_left, new_right).balance(exclude_nodes)
|
||||||
|
|
||||||
if r_depth > l_depth+1 and\
|
if (
|
||||||
self.node == self.right_value.node and \
|
r_depth > l_depth + 1
|
||||||
self.node not in exclude_nodes:
|
and self.node == self.right_value.node
|
||||||
|
and self.node not in exclude_nodes
|
||||||
|
):
|
||||||
new_right = self.right_value.long_branch
|
new_right = self.right_value.long_branch
|
||||||
new_left = Tree(self.node,
|
new_left = Tree(self.node, self.left_value, self.right_value.short_branch)
|
||||||
self.left_value,
|
|
||||||
self.right_value.short_branch)
|
|
||||||
return Tree(self.node, new_left, new_right).balance(exclude_nodes)
|
return Tree(self.node, new_left, new_right).balance(exclude_nodes)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -874,10 +869,8 @@ class MutableTree(Tree):
|
|||||||
It is used to build a new tree before fixing it into a Tree
|
It is used to build a new tree before fixing it into a Tree
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,
|
|
||||||
node = None,
|
def __init__(self, node=None, left_value=None, right_value=None):
|
||||||
left_value = None,
|
|
||||||
right_value = None):
|
|
||||||
"""
|
"""
|
||||||
Initiate a tree with potentialy None values
|
Initiate a tree with potentialy None values
|
||||||
|
|
||||||
@ -1024,7 +1017,10 @@ class MutableTree(Tree):
|
|||||||
try:
|
try:
|
||||||
ans.set_node(c)
|
ans.set_node(c)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if OPERATORS[c]["precedence"] > OPERATORS[ans.node]["precedence"]:
|
if (
|
||||||
|
OPERATORS[c]["precedence"]
|
||||||
|
> OPERATORS[ans.node]["precedence"]
|
||||||
|
):
|
||||||
# the operation has to be done first
|
# the operation has to be done first
|
||||||
if nested_tree is not None:
|
if nested_tree is not None:
|
||||||
b_tree = cls(c, nested_tree, None)
|
b_tree = cls(c, nested_tree, None)
|
||||||
@ -1124,7 +1120,9 @@ class MutableTree(Tree):
|
|||||||
try:
|
try:
|
||||||
self.right_value.append(value)
|
self.right_value.append(value)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise ValueError("The right branch is full, use append_top or append_bot")
|
raise ValueError(
|
||||||
|
"The right branch is full, use append_top or append_bot"
|
||||||
|
)
|
||||||
|
|
||||||
def append(self, value):
|
def append(self, value):
|
||||||
""" Append the value at the bottom of the tree.
|
""" Append the value at the bottom of the tree.
|
||||||
@ -1272,6 +1270,7 @@ class AssocialTree(Tree):
|
|||||||
""" Tree which concider every subtree with a node different from itself
|
""" Tree which concider every subtree with a node different from itself
|
||||||
as a Leaf
|
as a Leaf
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def map_on_leaf(self, function):
|
def map_on_leaf(self, function):
|
||||||
""" Map on leafs a function
|
""" Map on leafs a function
|
||||||
|
|
||||||
@ -1492,10 +1491,9 @@ class AssocialTree(Tree):
|
|||||||
t = Tree.from_list(self.node, balanced_leafs)
|
t = Tree.from_list(self.node, balanced_leafs)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def organise_by(self,
|
def organise_by(
|
||||||
signature=lambda x: type(x),
|
self, signature=lambda x: type(x), recursive=True, exclude_nodes=[]
|
||||||
recursive=True,
|
):
|
||||||
exclude_nodes=[]):
|
|
||||||
""" Reoganise AssocialTree base on self order and groups by signature
|
""" Reoganise AssocialTree base on self order and groups by signature
|
||||||
|
|
||||||
:param signature: grouping function (default type)
|
:param signature: grouping function (default type)
|
||||||
@ -1648,11 +1646,11 @@ class AssocialTree(Tree):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return leaf
|
return leaf
|
||||||
|
|
||||||
return AssocialTree.from_any_tree(tree).\
|
return AssocialTree.from_any_tree(tree).map_on_leaf(contaminate_organise)
|
||||||
map_on_leaf(contaminate_organise)
|
|
||||||
|
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
a = MutableTree.from_str("(1+2)*3")
|
a = MutableTree.from_str("(1+2)*3")
|
||||||
print(a)
|
print(a)
|
||||||
|
@ -17,6 +17,7 @@ __all__ = []
|
|||||||
|
|
||||||
# Functions on (op, left, right)
|
# Functions on (op, left, right)
|
||||||
|
|
||||||
|
|
||||||
def to_nested_parenthesis(op, left, right):
|
def to_nested_parenthesis(op, left, right):
|
||||||
""" Get nested form for arguments
|
""" Get nested form for arguments
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ def to_nested_parenthesis(op, left, right):
|
|||||||
"""
|
"""
|
||||||
return (op, (left, right))
|
return (op, (left, right))
|
||||||
|
|
||||||
|
|
||||||
def infix_str_concatenate(op, left, right):
|
def infix_str_concatenate(op, left, right):
|
||||||
""" Concatenate arguments placing op on the middle.
|
""" Concatenate arguments placing op on the middle.
|
||||||
|
|
||||||
@ -37,6 +39,7 @@ def infix_str_concatenate(op, left, right):
|
|||||||
"""
|
"""
|
||||||
return f"{left} {op} {right}"
|
return f"{left} {op} {right}"
|
||||||
|
|
||||||
|
|
||||||
def postfix_concatenate(op, left, right):
|
def postfix_concatenate(op, left, right):
|
||||||
""" Concatenate arguments placing op on the middle.
|
""" Concatenate arguments placing op on the middle.
|
||||||
|
|
||||||
@ -61,6 +64,7 @@ def postfix_concatenate(op, left, right):
|
|||||||
|
|
||||||
return left_tokens + right_tokens + [op]
|
return left_tokens + right_tokens + [op]
|
||||||
|
|
||||||
|
|
||||||
def show_tree(op, left, right, sep="|", node_caracter=">"):
|
def show_tree(op, left, right, sep="|", node_caracter=">"):
|
||||||
""" Shape argument to make nice Tree display
|
""" Shape argument to make nice Tree display
|
||||||
|
|
||||||
@ -85,6 +89,7 @@ def show_tree(op, left, right, sep="|", node_caracter=">"):
|
|||||||
right_slided = leaf_suffix.join(str(right).splitlines())
|
right_slided = leaf_suffix.join(str(right).splitlines())
|
||||||
return node_suffix.join([op, left_slided, right_slided])
|
return node_suffix.join([op, left_slided, right_slided])
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -12,6 +12,7 @@ Typing with MO
|
|||||||
|
|
||||||
from .exceptions import TypingError
|
from .exceptions import TypingError
|
||||||
from .add import add
|
from .add import add
|
||||||
|
|
||||||
# from .minus import minus
|
# from .minus import minus
|
||||||
from .multiply import multiply
|
from .multiply import multiply
|
||||||
from .divide import divide
|
from .divide import divide
|
||||||
@ -35,8 +36,8 @@ OPERATIONS = {
|
|||||||
"^": power,
|
"^": power,
|
||||||
}
|
}
|
||||||
|
|
||||||
def typing(node, left_v, right_v,\
|
|
||||||
raiseTypingError = True):
|
def typing(node, left_v, right_v, raiseTypingError=True):
|
||||||
"""
|
"""
|
||||||
Typing a try base on his root node
|
Typing a try base on his root node
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ def typing(node, left_v, right_v,\
|
|||||||
raise NotImplementedError(f"Unknown operation ({node}) in typing")
|
raise NotImplementedError(f"Unknown operation ({node}) in typing")
|
||||||
return operation(left_v, right_v)
|
return operation(left_v, right_v)
|
||||||
|
|
||||||
|
|
||||||
def typing_capacities(node):
|
def typing_capacities(node):
|
||||||
""" Test an operation through all MOs
|
""" Test an operation through all MOs
|
||||||
|
|
||||||
@ -61,19 +63,17 @@ def typing_capacities(node):
|
|||||||
op = OPERATIONS[node]
|
op = OPERATIONS[node]
|
||||||
lines = [[node] + [mo.__name__ for mo in MOS]]
|
lines = [[node] + [mo.__name__ for mo in MOS]]
|
||||||
for left_mo in MOS:
|
for left_mo in MOS:
|
||||||
lines.append(
|
lines.append([left_mo.__name__] + [(left_mo, i) in op.funcs for i in MOS])
|
||||||
[left_mo.__name__] + \
|
|
||||||
[(left_mo, i) in op.funcs for i in MOS]
|
|
||||||
)
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def describe_typing():
|
def describe_typing():
|
||||||
""" Explain which operations are handle by typing """
|
""" Explain which operations are handle by typing """
|
||||||
|
|
||||||
ans = "Implemented typing operations among MOs\n"
|
ans = "Implemented typing operations among MOs\n"
|
||||||
for op in OPERATIONS:
|
for op in OPERATIONS:
|
||||||
ans += "\n"
|
ans += "\n"
|
||||||
ans += tabulate(typing_capacities(op), tablefmt='grid')
|
ans += tabulate(typing_capacities(op), tablefmt="grid")
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ add_doc = """ Add MOs
|
|||||||
|
|
||||||
add = Dispatcher("add", doc=add_doc)
|
add = Dispatcher("add", doc=add_doc)
|
||||||
|
|
||||||
|
|
||||||
@add.register((MOnumber, MOFraction), MOstr)
|
@add.register((MOnumber, MOFraction), MOstr)
|
||||||
def moscalar_mostr(left, right):
|
def moscalar_mostr(left, right):
|
||||||
""" add a scalar with a letter to create a MOpolynomial
|
""" add a scalar with a letter to create a MOpolynomial
|
||||||
@ -41,6 +42,7 @@ def moscalar_mostr(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOpolynomial(right, [left, 1])
|
return MOpolynomial(right, [left, 1])
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, (MOnumber, MOFraction))
|
@add.register(MOstr, (MOnumber, MOFraction))
|
||||||
def mostr_moscalar(left, right):
|
def mostr_moscalar(left, right):
|
||||||
""" add a scalar with a letter to create a MOpolynomial
|
""" add a scalar with a letter to create a MOpolynomial
|
||||||
@ -55,6 +57,7 @@ def mostr_moscalar(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOpolynomial(left, [right, 1])
|
return MOpolynomial(left, [right, 1])
|
||||||
|
|
||||||
|
|
||||||
@add.register((MOnumber, MOFraction), MOstrPower)
|
@add.register((MOnumber, MOFraction), MOstrPower)
|
||||||
def moscalar_mostrpower(left, right):
|
def moscalar_mostrpower(left, right):
|
||||||
""" add a scalar with a letter to create a MOpolynomial
|
""" add a scalar with a letter to create a MOpolynomial
|
||||||
@ -69,6 +72,7 @@ def moscalar_mostrpower(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOpolynomial(right.variable, {0: left, right.power: 1})
|
return MOpolynomial(right.variable, {0: left, right.power: 1})
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstrPower, (MOnumber, MOFraction))
|
@add.register(MOstrPower, (MOnumber, MOFraction))
|
||||||
def mostrpower_moscalar(left, right):
|
def mostrpower_moscalar(left, right):
|
||||||
""" add a scalar with a letter to create a MOpolynomial
|
""" add a scalar with a letter to create a MOpolynomial
|
||||||
@ -83,6 +87,7 @@ def mostrpower_moscalar(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOpolynomial(left.variable, {0: right, left.power: 1})
|
return MOpolynomial(left.variable, {0: right, left.power: 1})
|
||||||
|
|
||||||
|
|
||||||
@add.register((MOnumber, MOFraction), MOMonomial)
|
@add.register((MOnumber, MOFraction), MOMonomial)
|
||||||
def moscalar_momonomial(left, right):
|
def moscalar_momonomial(left, right):
|
||||||
""" add a scalar with a MOMonomial to create a MOpolynomial
|
""" add a scalar with a MOMonomial to create a MOpolynomial
|
||||||
@ -95,9 +100,8 @@ def moscalar_momonomial(left, right):
|
|||||||
>>> add(a, b)
|
>>> add(a, b)
|
||||||
<MOpolynomial 1 / 5 + 3x^4>
|
<MOpolynomial 1 / 5 + 3x^4>
|
||||||
"""
|
"""
|
||||||
return MOpolynomial(right.variable,
|
return MOpolynomial(right.variable, {right.power: right.coefficient, 0: left})
|
||||||
{right.power: right.coefficient, 0: left}
|
|
||||||
)
|
|
||||||
|
|
||||||
@add.register(MOMonomial, (MOnumber, MOFraction))
|
@add.register(MOMonomial, (MOnumber, MOFraction))
|
||||||
def momonial_moscalar(left, right):
|
def momonial_moscalar(left, right):
|
||||||
@ -112,9 +116,8 @@ def momonial_moscalar(left, right):
|
|||||||
<MOpolynomial 3x^4 + 1 / 5>
|
<MOpolynomial 3x^4 + 1 / 5>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return MOpolynomial(left.variable,
|
return MOpolynomial(left.variable, {0: right, left.power: left.coefficient})
|
||||||
{0: right, left.power: left.coefficient}
|
|
||||||
)
|
|
||||||
|
|
||||||
@add.register((MOnumber, MOFraction), MOpolynomial)
|
@add.register((MOnumber, MOFraction), MOpolynomial)
|
||||||
def moscalar_mopolynomial(left, right):
|
def moscalar_mopolynomial(left, right):
|
||||||
@ -129,13 +132,16 @@ def moscalar_mopolynomial(left, right):
|
|||||||
<MOpolynomial 1 / 5 + 3x^2 + 2x>
|
<MOpolynomial 1 / 5 + 3x^2 + 2x>
|
||||||
"""
|
"""
|
||||||
if 0 in right.coefficients.keys():
|
if 0 in right.coefficients.keys():
|
||||||
raise NotImplementedError(f"Polynomial with constant ({right.coefficients[0]}), calculus to do")
|
raise NotImplementedError(
|
||||||
|
f"Polynomial with constant ({right.coefficients[0]}), calculus to do"
|
||||||
|
)
|
||||||
|
|
||||||
new_coefs = {**right.coefficients}
|
new_coefs = {**right.coefficients}
|
||||||
#! Need to be add at the end to be printed at the beginning
|
#! Need to be add at the end to be printed at the beginning
|
||||||
new_coefs[0] = left
|
new_coefs[0] = left
|
||||||
return MOpolynomial(right.variable, new_coefs)
|
return MOpolynomial(right.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, (MOnumber, MOFraction))
|
@add.register(MOpolynomial, (MOnumber, MOFraction))
|
||||||
def mopolynomial_moscalar(left, right):
|
def mopolynomial_moscalar(left, right):
|
||||||
""" add a scalar with a MOpolynomial to create a MOpolynomial
|
""" add a scalar with a MOpolynomial to create a MOpolynomial
|
||||||
@ -156,6 +162,7 @@ def mopolynomial_moscalar(left, right):
|
|||||||
new_coefs = {**new_coefs, **left.coefficients}
|
new_coefs = {**new_coefs, **left.coefficients}
|
||||||
return MOpolynomial(left.variable, new_coefs)
|
return MOpolynomial(left.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, MOstr)
|
@add.register(MOstr, MOstr)
|
||||||
def mostr_mostr(left, right):
|
def mostr_mostr(left, right):
|
||||||
""" add 2 mostr
|
""" add 2 mostr
|
||||||
@ -169,6 +176,7 @@ def mostr_mostr(left, right):
|
|||||||
raise NotImplementedError("Can't add 2 Mostr without same letter")
|
raise NotImplementedError("Can't add 2 Mostr without same letter")
|
||||||
return MOMonomial(2, left)
|
return MOMonomial(2, left)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, MOstrPower)
|
@add.register(MOstr, MOstrPower)
|
||||||
def mostr_mostrpower(left, right):
|
def mostr_mostrpower(left, right):
|
||||||
""" add a scalar with a letter to create a MOpolynomial
|
""" add a scalar with a letter to create a MOpolynomial
|
||||||
@ -185,6 +193,7 @@ def mostr_mostrpower(left, right):
|
|||||||
raise
|
raise
|
||||||
return MOpolynomial(left, {1: 1, right.power: 1})
|
return MOpolynomial(left, {1: 1, right.power: 1})
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstrPower, MOstr)
|
@add.register(MOstrPower, MOstr)
|
||||||
def mostrpower_mostr(left, right):
|
def mostrpower_mostr(left, right):
|
||||||
""" add a scalar with a letter to create a MOpolynomial
|
""" add a scalar with a letter to create a MOpolynomial
|
||||||
@ -201,6 +210,7 @@ def mostrpower_mostr(left, right):
|
|||||||
raise
|
raise
|
||||||
return MOpolynomial(right, {1: 1, left.power: 1})
|
return MOpolynomial(right, {1: 1, left.power: 1})
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstrPower, MOstrPower)
|
@add.register(MOstrPower, MOstrPower)
|
||||||
def mostrpower_mostrpower(left, right):
|
def mostrpower_mostrpower(left, right):
|
||||||
""" add 2 mostrpower
|
""" add 2 mostrpower
|
||||||
@ -213,10 +223,13 @@ def mostrpower_mostrpower(left, right):
|
|||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise NotImplementedError("Can't add 2 Mostrpower without same letter")
|
raise NotImplementedError("Can't add 2 Mostrpower without same letter")
|
||||||
if left.power != right.power:
|
if left.power != right.power:
|
||||||
raise NotImplementedError("Can't add 2 Mostrpower with compute if not same degree")
|
raise NotImplementedError(
|
||||||
|
"Can't add 2 Mostrpower with compute if not same degree"
|
||||||
|
)
|
||||||
|
|
||||||
return MOMonomial(2, left.variable, left.power)
|
return MOMonomial(2, left.variable, left.power)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, MOpolynomial)
|
@add.register(MOstr, MOpolynomial)
|
||||||
def mostr_mopolynomial(left, right):
|
def mostr_mopolynomial(left, right):
|
||||||
""" add a str with a MOpolynomial to create a MOpolynomial
|
""" add a str with a MOpolynomial to create a MOpolynomial
|
||||||
@ -234,6 +247,7 @@ def mostr_mopolynomial(left, right):
|
|||||||
new_coefs[1] = 1
|
new_coefs[1] = 1
|
||||||
return MOpolynomial(right.variable, new_coefs)
|
return MOpolynomial(right.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOstr)
|
@add.register(MOpolynomial, MOstr)
|
||||||
def mopolynomial_mostr(left, right):
|
def mopolynomial_mostr(left, right):
|
||||||
""" add a str with a MOpolynomial to create a MOpolynomial
|
""" add a str with a MOpolynomial to create a MOpolynomial
|
||||||
@ -250,6 +264,7 @@ def mopolynomial_mostr(left, right):
|
|||||||
new_coefs = {**new_coefs, **left.coefficients}
|
new_coefs = {**new_coefs, **left.coefficients}
|
||||||
return MOpolynomial(left.variable, new_coefs)
|
return MOpolynomial(left.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstrPower, MOpolynomial)
|
@add.register(MOstrPower, MOpolynomial)
|
||||||
def mostrpower_mopolynomial(left, right):
|
def mostrpower_mopolynomial(left, right):
|
||||||
""" add a strPower with a MOpolynomial to create a MOpolynomial
|
""" add a strPower with a MOpolynomial to create a MOpolynomial
|
||||||
@ -267,6 +282,7 @@ def mostrpower_mopolynomial(left, right):
|
|||||||
new_coefs[left.power] = 1
|
new_coefs[left.power] = 1
|
||||||
return MOpolynomial(right.variable, new_coefs)
|
return MOpolynomial(right.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOstrPower)
|
@add.register(MOpolynomial, MOstrPower)
|
||||||
def mopolynomial_mostrpower(left, right):
|
def mopolynomial_mostrpower(left, right):
|
||||||
""" add a strPower with a MOpolynomial to create a MOpolynomial
|
""" add a strPower with a MOpolynomial to create a MOpolynomial
|
||||||
@ -283,6 +299,7 @@ def mopolynomial_mostrpower(left, right):
|
|||||||
new_coefs = {**new_coefs, **left.coefficients}
|
new_coefs = {**new_coefs, **left.coefficients}
|
||||||
return MOpolynomial(left.variable, new_coefs)
|
return MOpolynomial(left.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOpolynomial)
|
@add.register(MOMonomial, MOpolynomial)
|
||||||
def momonomial_mopolynomial(left, right):
|
def momonomial_mopolynomial(left, right):
|
||||||
""" add a Monomial with a MOpolynomial to create a MOpolynomial
|
""" add a Monomial with a MOpolynomial to create a MOpolynomial
|
||||||
@ -300,6 +317,7 @@ def momonomial_mopolynomial(left, right):
|
|||||||
new_coefs[left.power] = left.coefficient
|
new_coefs[left.power] = left.coefficient
|
||||||
return MOpolynomial(right.variable, new_coefs)
|
return MOpolynomial(right.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOMonomial)
|
@add.register(MOpolynomial, MOMonomial)
|
||||||
def mopolynomial_momonomial(left, right):
|
def mopolynomial_momonomial(left, right):
|
||||||
""" add a Monomial with a MOpolynomial to create a MOpolynomial
|
""" add a Monomial with a MOpolynomial to create a MOpolynomial
|
||||||
@ -316,6 +334,7 @@ def mopolynomial_momonomial(left, right):
|
|||||||
new_coefs = {**new_coefs, **left.coefficients}
|
new_coefs = {**new_coefs, **left.coefficients}
|
||||||
return MOpolynomial(left.variable, new_coefs)
|
return MOpolynomial(left.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOpolynomial, MOpolynomial)
|
@add.register(MOpolynomial, MOpolynomial)
|
||||||
def mopolynomial_mopolynomial(left, right):
|
def mopolynomial_mopolynomial(left, right):
|
||||||
""" add a polynomial with a MOpolynomial to create a MOpolynomial
|
""" add a polynomial with a MOpolynomial to create a MOpolynomial
|
||||||
@ -334,6 +353,7 @@ def mopolynomial_mopolynomial(left, right):
|
|||||||
new_coefs = {**right.coefficients, **left.coefficients}
|
new_coefs = {**right.coefficients, **left.coefficients}
|
||||||
return MOpolynomial(right.variable, new_coefs)
|
return MOpolynomial(right.variable, new_coefs)
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOstr, MOMonomial)
|
@add.register(MOstr, MOMonomial)
|
||||||
def mostr_monomial(left, right):
|
def mostr_monomial(left, right):
|
||||||
""" add a mostr with a MOMonomial to create a MOpolynomial
|
""" add a mostr with a MOMonomial to create a MOpolynomial
|
||||||
@ -346,9 +366,8 @@ def mostr_monomial(left, right):
|
|||||||
if right.power == 1:
|
if right.power == 1:
|
||||||
raise NotImplementedError("Monomial is deg 1, need to compute")
|
raise NotImplementedError("Monomial is deg 1, need to compute")
|
||||||
|
|
||||||
return MOpolynomial(right.variable,
|
return MOpolynomial(right.variable, {right.power: right.coefficient, 1: 1})
|
||||||
{right.power: right.coefficient, 1: 1}
|
|
||||||
)
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOstr)
|
@add.register(MOMonomial, MOstr)
|
||||||
def monomial_mostr(left, right):
|
def monomial_mostr(left, right):
|
||||||
@ -362,9 +381,8 @@ def monomial_mostr(left, right):
|
|||||||
if left.power == 1:
|
if left.power == 1:
|
||||||
raise NotImplementedError("Monomial is deg 1, need to compute")
|
raise NotImplementedError("Monomial is deg 1, need to compute")
|
||||||
|
|
||||||
return MOpolynomial(left.variable,
|
return MOpolynomial(left.variable, {1: 1, left.power: left.coefficient})
|
||||||
{1: 1, left.power: left.coefficient}
|
|
||||||
)
|
|
||||||
|
|
||||||
@add.register(MOstrPower, MOMonomial)
|
@add.register(MOstrPower, MOMonomial)
|
||||||
def mostrpower_monomial(left, right):
|
def mostrpower_monomial(left, right):
|
||||||
@ -376,12 +394,13 @@ def mostrpower_monomial(left, right):
|
|||||||
<MOpolynomial x^2 + 3x^4>
|
<MOpolynomial x^2 + 3x^4>
|
||||||
"""
|
"""
|
||||||
if left.power == right.power:
|
if left.power == right.power:
|
||||||
raise NotImplementedError("MostrPower and MOMonomial are same degree, need to compute")
|
raise NotImplementedError(
|
||||||
|
"MostrPower and MOMonomial are same degree, need to compute"
|
||||||
return MOpolynomial(right.variable,
|
|
||||||
{right.power: right.coefficient, left.power: 1}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return MOpolynomial(right.variable, {right.power: right.coefficient, left.power: 1})
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOstrPower)
|
@add.register(MOMonomial, MOstrPower)
|
||||||
def monomial_mostrpower(left, right):
|
def monomial_mostrpower(left, right):
|
||||||
""" add a mostrPower with a MOMonomial to create a MOpolynomial
|
""" add a mostrPower with a MOMonomial to create a MOpolynomial
|
||||||
@ -392,12 +411,13 @@ def monomial_mostrpower(left, right):
|
|||||||
<MOpolynomial 3x^4 + x^3>
|
<MOpolynomial 3x^4 + x^3>
|
||||||
"""
|
"""
|
||||||
if left.power == right.power:
|
if left.power == right.power:
|
||||||
raise NotImplementedError("MostrPower and MOMonomial are same degree, need to compute")
|
raise NotImplementedError(
|
||||||
|
"MostrPower and MOMonomial are same degree, need to compute"
|
||||||
return MOpolynomial(left.variable,
|
|
||||||
{right.power: 1, left.power: left.coefficient}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return MOpolynomial(left.variable, {right.power: 1, left.power: left.coefficient})
|
||||||
|
|
||||||
|
|
||||||
@add.register(MOMonomial, MOMonomial)
|
@add.register(MOMonomial, MOMonomial)
|
||||||
def monomial_momonomial(left, right):
|
def monomial_momonomial(left, right):
|
||||||
""" add a moMonomial with a MOMonomial to create a MOpolynomial
|
""" add a moMonomial with a MOMonomial to create a MOpolynomial
|
||||||
@ -410,8 +430,8 @@ def monomial_momonomial(left, right):
|
|||||||
if left.power == right.power:
|
if left.power == right.power:
|
||||||
raise NotImplementedError("MOMonomials are same degree, need to compute")
|
raise NotImplementedError("MOMonomials are same degree, need to compute")
|
||||||
|
|
||||||
return MOpolynomial(left.variable,
|
return MOpolynomial(
|
||||||
{right.power: right.coefficient, left.power: left.coefficient}
|
left.variable, {right.power: right.coefficient, left.power: left.coefficient}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ divide_doc = """ Typing trees a divide root
|
|||||||
|
|
||||||
divide = Dispatcher("divide", doc=divide_doc)
|
divide = Dispatcher("divide", doc=divide_doc)
|
||||||
|
|
||||||
|
|
||||||
@divide.register(MOnumber, MOnumber)
|
@divide.register(MOnumber, MOnumber)
|
||||||
def monumber_monumber(left, right):
|
def monumber_monumber(left, right):
|
||||||
""" A divide tree with 2 MOnumbers is a MOFraction
|
""" A divide tree with 2 MOnumbers is a MOFraction
|
||||||
|
@ -10,9 +10,11 @@
|
|||||||
Exceptions for typing trees
|
Exceptions for typing trees
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TypingError(Exception):
|
class TypingError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -26,6 +26,7 @@ multiply_doc = """ Multiply MOs
|
|||||||
|
|
||||||
multiply = Dispatcher("multiply", doc=multiply_doc)
|
multiply = Dispatcher("multiply", doc=multiply_doc)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register((MOnumber, MOFraction), MOstr)
|
@multiply.register((MOnumber, MOFraction), MOstr)
|
||||||
def moscalar_mostr(left, right):
|
def moscalar_mostr(left, right):
|
||||||
""" Multiply a scalar with a letter to create a MOMonomial
|
""" Multiply a scalar with a letter to create a MOMonomial
|
||||||
@ -40,6 +41,7 @@ def moscalar_mostr(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOMonomial(left, right)
|
return MOMonomial(left, right)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstr, (MOnumber, MOFraction))
|
@multiply.register(MOstr, (MOnumber, MOFraction))
|
||||||
def mostr_moscalar(left, right):
|
def mostr_moscalar(left, right):
|
||||||
""" Multiply a scalar with a letter to create a MOMonomial
|
""" Multiply a scalar with a letter to create a MOMonomial
|
||||||
@ -54,6 +56,7 @@ def mostr_moscalar(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOMonomial(right, left)
|
return MOMonomial(right, left)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register((MOnumber, MOFraction), MOstrPower)
|
@multiply.register((MOnumber, MOFraction), MOstrPower)
|
||||||
def moscalar_mostrpower(left, right):
|
def moscalar_mostrpower(left, right):
|
||||||
""" Multiply a scalar with a MOstrPower
|
""" Multiply a scalar with a MOstrPower
|
||||||
@ -66,6 +69,7 @@ def moscalar_mostrpower(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOMonomial(left, right)
|
return MOMonomial(left, right)
|
||||||
|
|
||||||
|
|
||||||
@multiply.register(MOstrPower, (MOnumber, MOFraction))
|
@multiply.register(MOstrPower, (MOnumber, MOFraction))
|
||||||
def mostrpower_moscalar(left, right):
|
def mostrpower_moscalar(left, right):
|
||||||
""" Multiply a MOstrPower with a scalar
|
""" Multiply a MOstrPower with a scalar
|
||||||
@ -78,6 +82,7 @@ def mostrpower_moscalar(left, right):
|
|||||||
"""
|
"""
|
||||||
return MOMonomial(right, left)
|
return MOMonomial(right, left)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
@ -25,6 +25,7 @@ power_doc = """ Typing Power of MOs
|
|||||||
|
|
||||||
power = Dispatcher("power", doc=power_doc)
|
power = Dispatcher("power", doc=power_doc)
|
||||||
|
|
||||||
|
|
||||||
@power.register(MOstr, MOnumber)
|
@power.register(MOstr, MOnumber)
|
||||||
def mostr_monumber(left, right):
|
def mostr_monumber(left, right):
|
||||||
""" Create MOstrPower over powered MOstr
|
""" Create MOstrPower over powered MOstr
|
||||||
@ -38,7 +39,6 @@ def mostr_monumber(left, right):
|
|||||||
return MOstrPower(left, right)
|
return MOstrPower(left, right)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
Loading…
Reference in New Issue
Block a user