refactor(MO): Separate value and tree in MOs
This commit is contained in:
parent
d89042391b
commit
abf056ce33
@ -32,18 +32,20 @@ class MOFraction(MO):
|
|||||||
>>> f
|
>>> f
|
||||||
<MOFraction - 2 / 3>
|
<MOFraction - 2 / 3>
|
||||||
"""
|
"""
|
||||||
base_value = Tree("/",
|
_numerator = MO.factory(numerator)
|
||||||
MO.factory(numerator),
|
_denominator = MO.factory(denominator)
|
||||||
MO.factory(denominator),
|
base_tree = Tree("/",
|
||||||
|
_numerator,
|
||||||
|
_denominator,
|
||||||
)
|
)
|
||||||
if negative:
|
if negative:
|
||||||
value = Tree("-", None, base_value)
|
tree = Tree("-", None, base_tree)
|
||||||
else:
|
else:
|
||||||
value = base_value
|
tree = base_tree
|
||||||
MO.__init__(self, value)
|
MO.__init__(self, tree)
|
||||||
|
|
||||||
self._numerator = numerator
|
self._numerator = _numerator
|
||||||
self._denominator = denominator
|
self._denominator = _denominator
|
||||||
self.negative = negative
|
self.negative = negative
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -42,8 +42,10 @@ class MO(object):
|
|||||||
|
|
||||||
"""MO for math object
|
"""MO for math object
|
||||||
|
|
||||||
This base class is representing int and Decimal. It stocks its value in
|
This base class is representing int and Decimal.
|
||||||
self.value and it
|
|
||||||
|
:attr value: sympy compatible version of the MO
|
||||||
|
:attr _tree: tree version of the MO
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -60,9 +62,9 @@ class MO(object):
|
|||||||
<MO 3>
|
<MO 3>
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.value = value.value
|
self._tree = value._tree
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self.value = value
|
self._tree = value
|
||||||
|
|
||||||
self.is_scalar = True
|
self.is_scalar = True
|
||||||
|
|
||||||
@ -100,31 +102,31 @@ class MO(object):
|
|||||||
return f"<{self.__class__.__name__} {self.__txt__}>"
|
return f"<{self.__class__.__name__} {self.__txt__}>"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.value)
|
return str(self._tree)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def __txt__(self):
|
def __txt__(self):
|
||||||
try:
|
try:
|
||||||
return tree2txt(self.value)
|
return tree2txt(self._tree)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return str(self.value)
|
return str(self._tree)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def __tex__(self):
|
def __tex__(self):
|
||||||
try:
|
try:
|
||||||
return tree2tex(self.value)
|
return tree2tex(self._tree)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return str(self.value)
|
return str(self._tree)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return self.value.__hash__()
|
return self._tree.__hash__()
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
""" == a MOnumber """
|
""" == a MOnumber """
|
||||||
try:
|
try:
|
||||||
return self.value == other.value
|
return self._tree == other._tree
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return self.value == other
|
return self._tree == other
|
||||||
|
|
||||||
@total_ordering
|
@total_ordering
|
||||||
class MOnumber(MO):
|
class MOnumber(MO):
|
||||||
@ -154,17 +156,19 @@ class MOnumber(MO):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
val = value.value
|
val = value._tree
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
val = value
|
val = value
|
||||||
|
|
||||||
if isinstance(val, (int, Decimal)):
|
if isinstance(val, (int, Decimal)):
|
||||||
MO.__init__(self, value)
|
MO.__init__(self, val)
|
||||||
elif isinstance(val, float):
|
elif isinstance(val, float):
|
||||||
MO.__init__(self, Decimal(val))
|
MO.__init__(self, Decimal(val))
|
||||||
else:
|
else:
|
||||||
raise MOError("The value of an MOnumber need to be a int, a float or a Decimal")
|
raise MOError("The value of an MOnumber need to be a int, a float or a Decimal")
|
||||||
|
|
||||||
|
self.value = self._tree
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def __txt__(self):
|
def __txt__(self):
|
||||||
if self.value >= 0:
|
if self.value >= 0:
|
||||||
@ -179,90 +183,6 @@ class MOnumber(MO):
|
|||||||
|
|
||||||
return f"- {abs(self.value)}"
|
return f"- {abs(self.value)}"
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
""" Adding a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value + other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value + other
|
|
||||||
|
|
||||||
def __radd__(self, other):
|
|
||||||
""" rAdding a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value + other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value + other
|
|
||||||
|
|
||||||
def __sub__(self, other):
|
|
||||||
""" Subing a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value - other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value - other
|
|
||||||
|
|
||||||
def __rsub__(self, other):
|
|
||||||
""" rSubing a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value - other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value - other
|
|
||||||
|
|
||||||
def __mul__(self, other):
|
|
||||||
""" Multiply a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value * other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value * other
|
|
||||||
|
|
||||||
def __rmul__(self, other):
|
|
||||||
""" rMultiply a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value * other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value * other
|
|
||||||
|
|
||||||
def __truediv__(self, other):
|
|
||||||
""" Divide a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value / other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value / other
|
|
||||||
|
|
||||||
def __rtruediv__(self, other):
|
|
||||||
""" rDivide a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value / other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value / other
|
|
||||||
|
|
||||||
def __floordiv__(self, other):
|
|
||||||
""" Integer Division a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value // other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value // other
|
|
||||||
|
|
||||||
def __rfloordiv__(self, other):
|
|
||||||
""" rInteger Division a MOnumber """
|
|
||||||
try:
|
|
||||||
return other.value // self.value
|
|
||||||
except AttributeError:
|
|
||||||
return other // self.value
|
|
||||||
|
|
||||||
def __mod__(self, other):
|
|
||||||
""" Moduling a MOnumber """
|
|
||||||
try:
|
|
||||||
return self.value % other.value
|
|
||||||
except AttributeError:
|
|
||||||
return self.value % other
|
|
||||||
|
|
||||||
def __rmod__(self, other):
|
|
||||||
""" rModuling a MOnumber """
|
|
||||||
try:
|
|
||||||
return other.value % self.value
|
|
||||||
except AttributeError:
|
|
||||||
return other % self.value
|
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
""" < a MOnumber """
|
""" < a MOnumber """
|
||||||
try:
|
try:
|
||||||
@ -300,7 +220,7 @@ class MOstr(MO):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
val = value.value
|
val = value._tree
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
val = value
|
val = value
|
||||||
|
|
||||||
|
@ -55,15 +55,15 @@ class MOstrPower(MO):
|
|||||||
_power = MO.factory(power)
|
_power = MO.factory(power)
|
||||||
if power <= 1:
|
if power <= 1:
|
||||||
raise MOError("The power of a MOstrPower should be greater than 1")
|
raise MOError("The power of a MOstrPower should be greater than 1")
|
||||||
elif not isinstance(_power.value, int):
|
elif not isinstance(_power._tree, int):
|
||||||
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
|
||||||
|
|
||||||
value = Tree("^",
|
_tree = Tree("^",
|
||||||
self._variable,
|
self._variable,
|
||||||
self._power
|
self._power
|
||||||
)
|
)
|
||||||
MO.__init__(self, value)
|
MO.__init__(self, _tree)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def variable(self):
|
def variable(self):
|
||||||
@ -103,13 +103,13 @@ class MOMonomial(MO):
|
|||||||
raise
|
raise
|
||||||
self._variable = variable
|
self._variable = variable
|
||||||
|
|
||||||
value = Tree("*",
|
_tree = Tree("*",
|
||||||
self._coefficient,
|
self._coefficient,
|
||||||
self._variable
|
self._variable
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
MO.__init__(self, value)
|
MO.__init__(self, _tree)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coefficient(self):
|
def coefficient(self):
|
||||||
|
@ -183,22 +183,22 @@ def mofraction_mofraction(left, right):
|
|||||||
num = Tree("+", left.numerator, right.numerator)
|
num = Tree("+", left.numerator, right.numerator)
|
||||||
return Tree("/", num, left.denominator)
|
return Tree("/", num, left.denominator)
|
||||||
|
|
||||||
denom_lcm = lcm(left.denominator, right.denominator)
|
denom_lcm = lcm(left.denominator.value, right.denominator.value)
|
||||||
|
|
||||||
if left.denominator == denom_lcm:
|
if left.denominator.value == denom_lcm:
|
||||||
left_frac = left
|
left_frac = left
|
||||||
else:
|
else:
|
||||||
multiply_by = denom_lcm // left.denominator
|
multiply_by = MO.factory(denom_lcm // left.denominator.value)
|
||||||
left_num = Tree("*", left.numerator, MO.factory(multiply_by))
|
left_num = Tree("*", left.numerator, multiply_by)
|
||||||
left_denom = Tree("*", left.denominator, MO.factory(multiply_by))
|
left_denom = Tree("*", left.denominator, multiply_by)
|
||||||
left_frac = Tree("/", left_num, left_denom)
|
left_frac = Tree("/", left_num, left_denom)
|
||||||
|
|
||||||
if right.denominator == denom_lcm:
|
if right.denominator.value == denom_lcm:
|
||||||
right_frac = right
|
right_frac = right
|
||||||
else:
|
else:
|
||||||
multiply_by = denom_lcm // right.denominator
|
multiply_by = MO.factory(denom_lcm // right.denominator.value)
|
||||||
right_num = Tree("*", right.numerator, MO.factory(multiply_by))
|
right_num = Tree("*", right.numerator, multiply_by)
|
||||||
right_denom = Tree("*", right.denominator, MO.factory(multiply_by))
|
right_denom = Tree("*", right.denominator, multiply_by)
|
||||||
right_frac = Tree("/", right_num, right_denom)
|
right_frac = Tree("/", right_num, right_denom)
|
||||||
|
|
||||||
return Tree("+", left_frac, right_frac)
|
return Tree("+", left_frac, right_frac)
|
||||||
|
@ -80,7 +80,7 @@ def monumber_monumber(left, right):
|
|||||||
"""
|
"""
|
||||||
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 / right)
|
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")
|
||||||
|
|
||||||
|
@ -78,14 +78,14 @@ def mofraction(left, right):
|
|||||||
return MOFraction(right._numerator, right._denominator)
|
return MOFraction(right._numerator, right._denominator)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if right._numerator < 0:
|
if right._numerator.value < 0:
|
||||||
return MOFraction(-right._numerator, right._denominator)
|
return MOFraction(-right._numerator.value, right._denominator)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if right._denominator < 0:
|
if right._denominator.value < 0:
|
||||||
return MOFraction(right._numerator, -right._denominator)
|
return MOFraction(right._numerator, -right._denominator.value)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ def mostr_mostrpower(left, right):
|
|||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise MultiplyError("Can't multiply MOstr and MOstrPower if they don't"
|
raise MultiplyError("Can't multiply MOstr and MOstrPower if they don't"
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
f"have same variable (got {left.variable} and {right.variable})")
|
||||||
return MOstrPower(left.variable, right.power+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)
|
||||||
@ -227,7 +227,7 @@ def mostr_mostrpower(left, right):
|
|||||||
if left.variable != right.variable:
|
if left.variable != right.variable:
|
||||||
raise MultiplyError("Can't multiply MOstr and MOstrPower if they don't"
|
raise MultiplyError("Can't multiply MOstr and MOstrPower if they don't"
|
||||||
f"have same variable (got {left.variable} and {right.variable})")
|
f"have same variable (got {left.variable} and {right.variable})")
|
||||||
return MOstrPower(left.variable, left.power+1)
|
return MOstrPower(left.variable, left.power.value+1)
|
||||||
|
|
||||||
@multiply.register(MOstrPower, MOstrPower)
|
@multiply.register(MOstrPower, MOstrPower)
|
||||||
@special_case(multiply_filter)
|
@special_case(multiply_filter)
|
||||||
|
Loading…
Reference in New Issue
Block a user