diff --git a/pymath/calculus/abstract_polynom.py b/pymath/calculus/abstract_polynom.py index 9bfe0fd..c6c7f96 100644 --- a/pymath/calculus/abstract_polynom.py +++ b/pymath/calculus/abstract_polynom.py @@ -4,9 +4,8 @@ from .explicable import Explicable from .expression import Expression from .operator import op -from .generic import spe_zip, expand_list, isNumber, transpose_fill, flatten_list, isPolynom, isNumerand +from .generic import spe_zip, expand_list, isNumber, transpose_fill, flatten_list, isPolynom, isNumerand, postfix_op from .render import txt, tex -from itertools import chain from functools import wraps @@ -340,7 +339,7 @@ class AbstractPolynom(Explicable): coef_steps += s # Convert last element into postfix addition. - postfix_add = self.postfix_add([i for i in last if i != 0]) + postfix_add = postfix_op([i for i in last if i != 0], op.add) # Convert it to an expression coef_exp = Expression(postfix_add) @@ -376,33 +375,6 @@ class AbstractPolynom(Explicable): """Same as reduce """ return self.reduce() - @staticmethod - def postfix_add(numbers): - """Convert a list of numbers into a postfix addition - - :numbers: list of numbers - :returns: Postfix list of succecive attition of number - - >>> AbstractPolynom.postfix_add([1]) - [1] - >>> AbstractPolynom.postfix_add([1, 2]) - [1, 2, '+'] - >>> AbstractPolynom.postfix_add([1, 2, 3]) - [1, 2, '+', 3, '+'] - >>> AbstractPolynom.postfix_add(1) - [1] - >>> AbstractPolynom.postfix_add([]) - [0] - """ - if not isinstance(numbers, list): - return [numbers] - elif numbers == []: - return [0] - else: - ans = [[a, op.add] if i != 0 else [a] - for (i, a) in enumerate(numbers)] - return list(chain.from_iterable(ans)) - def __eq__(self, other): try: o_poly = self.conv2poly(other) diff --git a/pymath/calculus/fraction.py b/pymath/calculus/fraction.py index 5f18698..9f0e592 100644 --- a/pymath/calculus/fraction.py +++ b/pymath/calculus/fraction.py @@ -2,7 +2,7 @@ # encoding: utf-8 from .arithmetic import gcd -from .generic import isNumber +from .generic import isNumber, postfix_op from .operator import op from .expression import Expression from .explicable import Explicable @@ -309,22 +309,23 @@ class Fraction(Explicable): < Fraction 1 / 3> >>> print("\\n".join([repr(i) for i in (f*g).steps])) < [< Fraction 1 / 2>, < Fraction 2 / 3>, '*'] > - < [1, 2, '*', 2, 3, '*', '/'] > + < [1, 2, '*', 2, 3, '*', '/'] > < [1, 3, '/'] > >>> f * 0 0 >>> (f*0).steps - [] + [< [< Fraction 1 / 2>, 0, '*'] >] >>> f*1 < Fraction 1 / 2> >>> (f*1).steps - [] + [< [< Fraction 1 / 2>, 1, '*'] >] >>> f*4 2 >>> print("\\n".join([repr(i) for i in (f*4).steps])) - < [1, 2, '/', 4, '*'] > + < [< Fraction 1 / 2>, 4, '*'] > < [1, 2, '*', 2, '*', 1, 2, '*', '/'] > - < [2, 2, '*', 2, '/'] > + < [1, 2, '*', 1, '/'] > + < [2, 1, '/'] > """ steps = [Expression([self, other, op.mul])] @@ -359,8 +360,8 @@ class Fraction(Explicable): num1_s = [gcd1] + [int(self._num / gcd1), op.mul] * (int(self._num / gcd1) != 1) denom2_s = [gcd1] + [int(number._denom / gcd1), op.mul] * (int(number._denom / gcd1) != 1) - num1 = [int(self._num / gcd1)] - denom2 = [int(number._denom / gcd1)] + num1 = [int(self._num / gcd1)] * (int(self._num / gcd1) != 1) + denom2 = [int(number._denom / gcd1)] * (int(self._denom / gcd1) != 1) else: num1_s = [self._num] denom2_s = [number._denom] @@ -373,8 +374,8 @@ class Fraction(Explicable): num2_s = [gcd2] + [int(number._num / gcd2), op.mul] * (int(number._num / gcd2) != 1) denom1_s = [gcd2] + [int(self._denom / gcd2), op.mul] * (int(self._denom / gcd2) != 1) - num2 = [int(number._num / gcd2)] - denom1 = [int(self._denom / gcd2)] + num2 = [int(number._num / gcd2)] * (int(number._num / gcd2) != 1) + denom1 = [int(self._denom / gcd2)] * (int(number._denom / gcd2) != 1) else: num2_s = [number._num] denom1_s = [self._denom] @@ -382,12 +383,12 @@ class Fraction(Explicable): num2 = [number._num] denom1 = [self._denom] - # TODO: Pour enlever encore des *1, il faudrait réutililser postfix_add de Abstract_polynom et le mettre dans générique en postfix_op. Et mettre une liste vide quand num ou denom est égal à 1 |dim. févr. 14 17:51:41 EAT 2016 steps.append(Expression(num1_s + num2_s + [op.mul] + \ denom1_s + denom2_s + [op.mul, op.div])) - exp = Expression(num1 + num2 + [op.mul] + - denom1 + denom2 + [op.mul, op.div]) + exp = Expression(postfix_op(num1 + num2, op.mul, 1) + + postfix_op(denom1 + denom2, op.mul, 1) + + [op.div]) ans = exp.simplify() ans.steps = steps + ans.steps diff --git a/pymath/calculus/generic.py b/pymath/calculus/generic.py index d000f01..1f7700c 100644 --- a/pymath/calculus/generic.py +++ b/pymath/calculus/generic.py @@ -2,7 +2,7 @@ # encoding: utf-8 -from itertools import zip_longest +from itertools import zip_longest, chain class Stack(object): @@ -287,6 +287,39 @@ def transpose_fill(list_lists): yield col +def postfix_op(numbers, operator, neutral = 0): + """Convert a list of numbers into a postfix addition + + :numbers: list of numbers + :operator: the operator to join with + :neutral: default value if the list is empty + :returns: Postfix list of succecive attition of number + + >>> from .operator import op + >>> postfix_op([1], op.add) + [1] + >>> postfix_op([1, 2], op.add) + [1, 2, '+'] + >>> postfix_op([1, 2, 3], op.add) + [1, 2, '+', 3, '+'] + >>> postfix_op([1, 2, 3], op.mul) + [1, 2, '*', 3, '*'] + >>> postfix_op(1, op.add) + [1] + >>> postfix_op([], op.add) + [0] + >>> postfix_op([], op.mul, 1) + [1] + """ + if not isinstance(numbers, list): + return [numbers] + elif numbers == []: + return [neutral] + else: + ans = [[a, operator] if i != 0 else [a] + for (i, a) in enumerate(numbers)] + return list(chain.from_iterable(ans)) + def isOperator(exp): """Check if the expression is an opération in "+-*/:^"