diff --git a/pymath/calculus/abstract_polynom.py b/pymath/calculus/abstract_polynom.py index 57fc0a3..eefe8a7 100644 --- a/pymath/calculus/abstract_polynom.py +++ b/pymath/calculus/abstract_polynom.py @@ -302,76 +302,110 @@ class AbstractPolynom(Explicable): >>> Q < AbstractPolynom x [1, 2, 3]> >>> Q.steps - [] + [< AbstractPolynom x [1, 2, 3]>] >>> P = AbstractPolynom([[1,2], [3,4,5], 6]) >>> Q = P.reduce() >>> Q < AbstractPolynom x [3, 12, 6]> + >>> Q.steps + [< AbstractPolynom x [[1, 2], [3, 4, 5], 6]>, < AbstractPolynom x [< Expression [1, 2, +]>, < Expression [3, 4, +, 5, +]>, 6]>, < AbstractPolynom x [3, < Expression [7, 5, +]>, 6]>] >>> for i in Q.explain(): ... print(i) 6 x^{ 2 } + 3 x + 4 x + 5 x + 1 + 2 6 x^{ 2 } + ( 3 + 4 + 5 ) x + 1 + 2 6 x^{ 2 } + ( 7 + 5 ) x + 3 6 x^{ 2 } + 12 x + 3 - >>> Q.steps - [< AbstractPolynom x [[1, 2], [3, 4, 5], 6]>, < AbstractPolynom x [< Expression [1, 2, +]>, < Expression [3, 4, +, 5, +]>, 6]>, < AbstractPolynom x [3, < Expression [7, 5, +]>, 6]>] """ - # TODO: It doesn't not compute quick enough |ven. févr. 27 18:04:01 CET - # 2015 + # TODO: Il manque le ini_step |jeu. mars 10 12:39:40 EAT 2016 # gather steps for every coefficients - coefs_steps = [] + smpl_coef = [] for coef in self._coef: - coef_steps = [] if isinstance(coef, list): - # Simplify each element before adding them - s = [] - for c in coef: - try: - with Expression.tmp_render(): - s.append(list(c.simplify().explain())) - except AttributeError: - s.append([c]) - - s = list(transpose_fill(s)) - - last = s[-1] - coef_steps += s - - # Convert last element into postfix addition. - postfix_add = postfix_op([i for i in last if i != 0], op.add) - # Convert it to an expression - coef_exp = Expression(postfix_add) - - with Expression.tmp_render(): - coef_steps += list(coef_exp.simplify().explain()) + coef_exp = AbstractPolynom.smpl_coef_list(coef) else: try: - with Expression.tmp_render(): - coef_steps += coef.simplify().explain() + coef_exp = coef.simplify() except AttributeError: - coef_steps = [coef] + coef_exp = coef - # On ajoute toutes ces étapes - coefs_steps.append(coef_steps) + smpl_coef.append(coef_exp) - # On retourne la matrice - steps = [] - for coefs in transpose_fill(coefs_steps): - steps.append(AbstractPolynom(coefs, self._letter)) + ans = AbstractPolynom(smpl_coef, self._letter) - ans, steps = steps[-1], steps[:-1] - ans.this_append_before(steps) + print("smpl_coef -> ", smpl_coef) + print("Expression.develop_steps(smpl_coef) -> ", Expression.develop_steps(smpl_coef)) + + ini_step = [self] + for s in Expression.develop_steps(smpl_coef): + print("s -> ", repr(s)) + ini_step.append(AbstractPolynom(s)) + + ans.this_append_before( + ini_step + #AbstractPolynom(s) + #for s in Expression.develop_steps(smpl_coef) + ) return ans + ## On retourne la matrice + #steps = [] + #for coefs in transpose_fill(coefs_steps): + # steps.append(AbstractPolynom(coefs, self._letter)) + + #ans, steps = steps[-1], steps[:-1] + #ans.this_append_before(steps) + + #return ans + def simplify(self): """Same as reduce """ return self.reduce() + @classmethod + def smpl_coef_list(cls, coef_list): + """ Simplify the coef when it is a list + + :param coef_list: the list discribing the coef + :returns: the simplify coef + + >>> c = AbstractPolynom.smpl_coef_list([1, 2, 3]) + >>> c + 6 + >>> c.steps + [< Expression [1, 2, +, 3, +]>, < Expression [3, 3, +]>] + >>> c = AbstractPolynom.smpl_coef_list([Expression('2*2'), 3]) + >>> c + 7 + >>> c.steps + [< Expression [2, 2, *, 3, +]>, < Expression [4, 3, +]>] + + """ + # Simplify each element before adding them + smpl_elem = [] + for c in coef_list: + try: + smpl_c = c.simplify() + except AttributeError: + smpl_c = c + smpl_elem.append(smpl_c) + + pstfx_add = postfix_op( + smpl_elem, + #[i for i in smpl_elem if i != 0], + op.add + ) + + steps = Expression.develop_steps(pstfx_add) + + ans = Expression(pstfx_add).simplify() + ans.this_append_before(steps) + return ans + def __eq__(self, other): try: o_poly = self.conv2poly(other) diff --git a/pymath/calculus/explicable.py b/pymath/calculus/explicable.py index 8d25daf..a66cf67 100644 --- a/pymath/calculus/explicable.py +++ b/pymath/calculus/explicable.py @@ -2,6 +2,7 @@ # encoding: utf-8 from .renderable import Renderable +from .step import Step from decimal import Decimal from .generic import transpose_fill @@ -132,7 +133,8 @@ class Explicable(Renderable): """ try: - self.this_append_before(list(arg1.explain())) + with Step.tmp_render(): + self.this_append_before(list(arg1.explain())) except AttributeError: pass @@ -147,17 +149,17 @@ class Explicable(Renderable): >>> from .expression import Expression >>> action1 = Explicable(['42']) - >>> action1.this_append_before([Expression('2+10*4'), Expression('2+40')]) + >>> action1.this_append_before([['2 + 4 * 10'], ['2 + 40']]) >>> action2 = Explicable(['24']) - >>> action2.this_append_before([Expression('2*12')]) + >>> action2.this_append_before([['12 * 2']]) >>> m_history = Explicable.merge_history([action1, action2]) >>> m_history >>> for i in m_history: ... print(i) - ['2 + 10 \\times 4', '2 \\times 12'] - ['2 + 40', '24'] - ['42', '24'] + [< Step ['2 + 4 * 10']>, < Step ['12 * 2']>] + [< Step ['2 + 40']>, < Step ['24']>] + [< Step ['42']>, < Step ['24']>] >>> # Now they are amnesiac >>> for i in action1.explain(): ... print(i) @@ -165,40 +167,42 @@ class Explicable(Renderable): >>> m_history = Explicable.merge_history([action1, action2]) >>> for i in m_history: ... print(i) - ['42', '24'] + [< Step ['42']>, < Step ['24']>] >>> action1 = Explicable(['42']) - >>> action1.this_append_before([Expression('2+10*4'), Expression('2+40')]) + >>> action1.this_append_before([['2+10*4'], ['2+40']]) >>> m_history = Explicable.merge_history([action1, 12]) >>> m_history >>> for i in m_history: ... print(i) - ['2 + 10 \\times 4', 12] - ['2 + 40', 12] - ['42', 12] + [< Step ['2+10*4']>, < Step [12]>] + [< Step ['2+40']>, < Step [12]>] + [< Step ['42']>, < Step [12]>] >>> action1 = Explicable(['42']) - >>> action1.this_append_before([Expression('2+10*4'), Expression('2+40')]) + >>> action1.this_append_before([['2+10*4'], ['2+40']]) >>> action2 = Explicable(['24']) - >>> action2.this_append_before([Expression('2*12')]) + >>> action2.this_append_before([['2*12']]) >>> action3 = Explicable(['0']) - >>> action3.this_append_before([Expression('3-3')]) + >>> action3.this_append_before([['3-3']]) >>> m_history = Explicable.merge_history([action1, action2, action3]) >>> for i in m_history: ... print(i) - ['2 + 10 \\times 4', '2 \\times 12', '3 - 3'] - ['2 + 40', '24', '0'] - ['42', '24', '0'] + [< Step ['2+10*4']>, < Step ['2*12']>, < Step ['3-3']>] + [< Step ['2+40']>, < Step ['24']>, < Step ['0']>] + [< Step ['42']>, < Step ['24']>, < Step ['0']>] >>> m_history = Explicable.merge_history([1,2,3]) >>> for i in m_history: ... print(i) - [1, 2, 3] + [< Step [1]>, < Step [2]>, < Step [3]>] """ + from .expression import Expression steps = [] for expl in explicables: try: - steps.append(list(expl.explain())) + with Step.tmp_render(): + steps.append(list(expl.explain())) except AttributeError: - steps.append([expl]) + steps.append([Step([expl])]) return transpose_fill(steps) diff --git a/pymath/calculus/expression.py b/pymath/calculus/expression.py index 7601901..324bb5d 100644 --- a/pymath/calculus/expression.py +++ b/pymath/calculus/expression.py @@ -16,43 +16,6 @@ from .random_expression import RdExpression __all__ = ['Expression'] -# def pstf_factory(pstf_tokens): -# """Factory which tranform postfix tokens list into an Expression or the simpliest object type ready to be rendered -# -# :param pstf_tokens: a postfix tokens list -# :returns: the object -# -# >>> from .operator import op -# >>> pstf_t = [2, 3, op.add] -# >>> pstf_factory(pstf_t) -# < Expression [2, 3, +]> -# >>> pstf_factory([2]) -# 2 -# >>> type(pstf_factory([2])) -# -# >>> pstf_factory([2.45]) -# Decimal('2.45') -# >>> type(pstf_factory([2.45])) -# -# >>> from .fraction import Fraction -# >>> f = Fraction(1,2) -# >>> pstf_factory([f]) -# < Fraction 1 / 2> -# -# """ -# if len(pstf_tokens) == 1: -# if isinstance(pstf_tokens[0], int): -# return Explicable_int(pstf_tokens[0]) -# elif isinstance(pstf_tokens[0], Decimal): -# return Explicable_Decimal(pstf_tokens[0]) -# elif isinstance(pstf_tokens[0], float): -# return Explicable_Decimal(Decimal(str(pstf_tokens[0]))) -# elif hasattr(pstf_tokens[0], 'STR_RENDER'): -# return pstf_tokens[0] -# -# return Expression(pstf_tokens) - - class Expression(Explicable): """A calculus expression. Today it can andle only expression with numbers later it will be able to manipulate unknown""" @@ -69,44 +32,6 @@ class Expression(Explicable): random_generator = RdExpression(form, conditions) return Expression(random_generator(val_min, val_max)) - # @classmethod - # def tmp_render(cls, render=lambda _, x: pstf_factory(x)): - # """ Same ad tmp_render for Renderable but default render is Expression - - # >>> exp = Expression("2*3/5") - # >>> print(exp) - # 2 \\times \\frac{ 3 }{ 5 } - # >>> for i in exp.simplify().explain(): - # ... print(i) - # 2 \\times \\frac{ 3 }{ 5 } - # \\frac{ 3 }{ 5 } \\times 2 - # \\frac{ 3 \\times 2 }{ 5 } - # \\frac{ 6 }{ 5 } - # >>> with Expression.tmp_render(): - # ... for i in exp.simplify().explain(): - # ... i - # < Expression [2, 3, 5, /, *]> - # < Expression [2, < Fraction 3 / 5>, *]> - # < Expression [< Fraction 3 / 5>, 2, *]> - # < Expression [3, 2, *, 5, /]> - # < Expression [6, 5, /]> - # >>> from .render import txt - # >>> with Expression.tmp_render(txt): - # ... for i in exp.simplify().explain(): - # ... print(i) - # 2 * 3 / 5 - # 3 / 5 * 2 - # ( 3 * 2 ) / 5 - # 6 / 5 - # >>> for i in exp.simplify().explain(): - # ... print(i) - # 2 \\times \\frac{ 3 }{ 5 } - # \\frac{ 3 }{ 5 } \\times 2 - # \\frac{ 3 \\times 2 }{ 5 } - # \\frac{ 6 }{ 5 } - - # """ - # return super(Expression, cls).tmp_render(render) def __init__(self, exp): """Create Expression objects