diff --git a/mapytex/calculus/core/MO/mo.py b/mapytex/calculus/core/MO/mo.py index eca6891..043b25b 100644 --- a/mapytex/calculus/core/MO/mo.py +++ b/mapytex/calculus/core/MO/mo.py @@ -80,7 +80,7 @@ class MO(object): return f"<{self.__class__.__name__} {self.__txt__}>" def __str__(self): - return self.__txt__ + return str(self.value) @property def __txt__(self): @@ -154,11 +154,13 @@ class MOnumber(MO): >>> MOnumber(23) >>> MOnumber(-23) - + >>> MOnumber(23.3) >>> MOnumber(Decimal("23.3")) + >>> MOnumber(Decimal("-23.3")) + >>> a = MOnumber(23) >>> MOnumber(a) @@ -180,6 +182,13 @@ class MOnumber(MO): else: raise MOError("The value of an MOnumber need to be a int, a float or a Decimal") + @property + def __txt__(self): + if self.value > 0: + return str(self.value) + + return f"- {abs(self.value)}" + class MOstr(MO): diff --git a/mapytex/calculus/core/tree2txt.py b/mapytex/calculus/core/tree2txt.py index 82f4dcd..98c3cce 100644 --- a/mapytex/calculus/core/tree2txt.py +++ b/mapytex/calculus/core/tree2txt.py @@ -6,45 +6,210 @@ # # Distributed under terms of the MIT license. +from .operator import OPERATORS + def plus2txt(left, right): """ + rendering >>> from .MO import mo - >>> plus2txt(mo.MO(2), mo.MO(3)) + >>> plus2txt(mo.MOnumber(2), mo.MOnumber(3)) '2 + 3' >>> from .tree import Tree >>> t = Tree.from_str("1+2") - >>> plus2txt(t, mo.MO(3)) + >>> plus2txt(t, mo.MOnumber(3)) '1 + 2 + 3' + >>> plus2txt(t, mo.MOnumber(-3)) + '1 + 2 - 3' + >>> plus2txt(mo.MOnumber(-3), t) + '- 3 + 1 + 2' + >>> t = Tree.from_str("-2*3") + >>> plus2txt(mo.MOnumber(3), t) + '3 - 2 * 3' """ + display_plus = True try: left.node except AttributeError: left_ = left.__txt__ else: left_ = tree2txt(left) + try: right.node except AttributeError: right_ = right.__txt__ else: right_ = tree2txt(right) + finally: + if right_.startswith("-"): + display_plus = False - return f"{left_} + {right_}" - + if display_plus: + return f"{left_} + {right_}" + return f"{left_} {right_}" def minus2txt(left, right): - pass + """ - rendering + + >>> from .MO import mo + >>> minus2txt(None, mo.MO(3)) + '- 3' + >>> from .tree import Tree + >>> t = Tree.from_str("1+2") + >>> minus2txt(None, t) + '- (1 + 2)' + """ + try: + right_need_parenthesis = False + if OPERATORS[right.node]["precedence"] < OPERATORS['-']["precedence"]: + right_need_parenthesis = True + except AttributeError: + right_ = right.__txt__ + else: + if right_need_parenthesis: + right_ = f"({tree2txt(right)})" + else: + right_ = tree2txt(right) + + return f"- {right_}" def mul2txt(left, right): - pass + """ * rendering + + >>> from .MO import mo + >>> mul2txt(mo.MO(2), mo.MO(3)) + '2 * 3' + >>> from .tree import Tree + >>> t = Tree.from_str("1*2") + >>> mul2txt(t, mo.MO(3)) + '1 * 2 * 3' + >>> t = Tree.from_str("1+2") + >>> mul2txt(t, mo.MO(3)) + '(1 + 2) * 3' + >>> mul2txt(mo.MO(3), t) + '3(1 + 2)' + >>> a = mo.MOstr('x') + >>> mul2txt(mo.MO(3), a) + '3x' + """ + display_time = True + try: + left_need_parenthesis = False + if OPERATORS[left.node]["precedence"] < OPERATORS['*']["precedence"]: + left_need_parenthesis = True + except AttributeError: + left_ = left.__txt__ + else: + if left_need_parenthesis: + left_ = f"({tree2txt(left)})" + else: + left_ = tree2txt(left) + + try: + right_need_parenthesis = False + if OPERATORS[right.node]["precedence"] < OPERATORS['*']["precedence"]: + right_need_parenthesis = True + except AttributeError: + right_ = right.__txt__ + else: + if right_need_parenthesis: + display_time = False + right_ = f"({tree2txt(right)})" + else: + right_ = tree2txt(right) + finally: + if right_[0].isalpha(): + display_time = False + + if display_time: + return f"{left_} * {right_}" + else: + return f"{left_}{right_}" def div2txt(left, right): - pass + """ / rendering + + >>> from .MO import mo + >>> div2txt(mo.MO(2), mo.MO(3)) + '2 / 3' + >>> from .tree import Tree + >>> t = Tree.from_str("1/2") + >>> div2txt(t, mo.MO(3)) + '1 / 2 / 3' + >>> t = Tree.from_str("1+2") + >>> div2txt(t, mo.MO(3)) + '(1 + 2) / 3' + >>> t = Tree.from_str("1*2") + >>> div2txt(mo.MO(3), t) + '3 / (1 * 2)' + """ + try: + left_need_parenthesis = False + if OPERATORS[left.node]["precedence"] < OPERATORS['/']["precedence"]: + left_need_parenthesis = True + except AttributeError: + left_ = left.__txt__ + else: + if left_need_parenthesis: + left_ = f"({tree2txt(left)})" + else: + left_ = tree2txt(left) + try: + right_need_parenthesis = False + if OPERATORS[right.node]["precedence"] < OPERATORS['/']["precedence"]: + right_need_parenthesis = True + except AttributeError: + right_ = right.__txt__ + else: + if right_need_parenthesis: + right_ = f"({tree2txt(right)})" + else: + right_ = tree2txt(right) + + return f"{left_} / {right_}" def pow2txt(left, right): - pass + """ ^ rendering + + >>> from .MO import mo + >>> pow2txt(mo.MO(2), mo.MO(3)) + '2 ^ 3' + >>> from .tree import Tree + >>> t = Tree.from_str("1^2") + >>> pow2txt(t, mo.MO(3)) + '1 ^ 2 ^ 3' + >>> t = Tree.from_str("1+2") + >>> pow2txt(t, mo.MO(3)) + '(1 + 2) ^ 3' + >>> t = Tree.from_str("1*2") + >>> pow2txt(mo.MO(3), t) + '3 ^ (1 * 2)' + """ + try: + left_need_parenthesis = False + if OPERATORS[left.node]["precedence"] < OPERATORS['^']["precedence"]: + left_need_parenthesis = True + except AttributeError: + left_ = left.__txt__ + else: + if left_need_parenthesis: + left_ = f"({tree2txt(left)})" + else: + left_ = tree2txt(left) + try: + right_need_parenthesis = False + if OPERATORS[right.node]["precedence"] < OPERATORS['^']["precedence"]: + right_need_parenthesis = True + except AttributeError: + right_ = right.__txt__ + else: + if right_need_parenthesis: + right_ = f"({tree2txt(right)})" + else: + right_ = tree2txt(right) + + return f"{left_} ^ {right_}" OPERATOR2TXT = { "+": plus2txt, @@ -62,7 +227,7 @@ def tree2txt(tree): >>> from .tree import Tree >>> t = Tree.from_str("2+3*4") >>> tree2txt(t) - "2 + 3 * 4" + '2 + 3 * 4' """ return OPERATOR2TXT[tree.node](tree.left_value, tree.right_value)