rewrite fraction and simplify op steps

This commit is contained in:
Benjamin Bertrand 2016-02-14 18:16:40 +03:00
parent bfafaac319
commit 29a25203c2

View File

@ -156,6 +156,7 @@ class Fraction(Explicable):
>>> print("\\n".join([repr(i) for i in (f+g).steps])) >>> print("\\n".join([repr(i) for i in (f+g).steps]))
< <class 'pymath.calculus.expression.Expression'> [3, 4, '/', 5, 4, '/', '+'] > < <class 'pymath.calculus.expression.Expression'> [3, 4, '/', 5, 4, '/', '+'] >
< <class 'pymath.calculus.expression.Expression'> [3, 5, '+', 4, '/'] > < <class 'pymath.calculus.expression.Expression'> [3, 5, '+', 4, '/'] >
< <class 'pymath.calculus.expression.Expression'> [8, 4, '/'] >
>>> f+0 >>> f+0
< Fraction 3 / 4> < Fraction 3 / 4>
>>> (f+0).steps >>> (f+0).steps
@ -307,11 +308,9 @@ class Fraction(Explicable):
>>> f*g >>> f*g
< Fraction 1 / 3> < Fraction 1 / 3>
>>> print("\\n".join([repr(i) for i in (f*g).steps])) >>> print("\\n".join([repr(i) for i in (f*g).steps]))
< <class 'pymath.calculus.expression.Expression'> [1, 2, '/', 2, 3, '/', '*'] > < <class 'pymath.calculus.expression.Expression'> [< Fraction 1 / 2>, < Fraction 2 / 3>, '*'] >
< <class 'pymath.calculus.expression.Expression'> [1, 1, 2, '*', '*', 1, 2, '*', 3, '*', '/'] >
< <class 'pymath.calculus.expression.Expression'> [1, 2, '*', 2, 3, '*', '/'] > < <class 'pymath.calculus.expression.Expression'> [1, 2, '*', 2, 3, '*', '/'] >
< <class 'pymath.calculus.expression.Expression'> [2, 6, '/'] > < <class 'pymath.calculus.expression.Expression'> [1, 3, '/'] >
< <class 'pymath.calculus.expression.Expression'> [1, 2, '*', 3, 2, '*', '/'] >
>>> f * 0 >>> f * 0
0 0
>>> (f*0).steps >>> (f*0).steps
@ -328,58 +327,70 @@ class Fraction(Explicable):
< <class 'pymath.calculus.expression.Expression'> [2, 2, '*', 2, '/'] > < <class 'pymath.calculus.expression.Expression'> [2, 2, '*', 2, '/'] >
""" """
steps = [] steps = [Expression([self, other, op.mul])]
if other == 0: if other == 0:
return Expression([0]) exp = Expression([0])
elif other == 1: elif other == 1:
return copy(self) exp = copy(self)
# TODO: Changer dans le cas où il y a trop de 1 |dim. déc. 28 10:44:10
# CET 2014
elif isinstance(other, int): elif isinstance(other, int):
gcd1 = gcd(other, self._denom) gcd1 = gcd(other, self._denom)
if gcd1 != 1: if gcd1 != 1:
num = [self._num, int(other / gcd1), op.mul, gcd1, op.mul] num_s = [self._num] + \
denom = [int(self._denom / gcd1), gcd1, op.mul] [int(other / gcd1), op.mul] * (int(other / gcd1) != 1) + \
[gcd1, op.mul]
denom_s = [int(self._denom / gcd1), gcd1, op.mul]
steps.append(Expression(num_s + denom_s + [op.div]))
num = [self._num] + [int(other / gcd1), op.mul]* (int(other / gcd1) != 1)
denom = [int(self._denom / gcd1)]
else: else:
num = [self._num, other, op.mul] num = [self._num, other, op.mul]
denom = [self._denom] denom = [self._denom]
exp = Expression(num + denom + [op.div]) exp = Expression(num + denom + [op.div])
ini_step = Expression(self.postfix_tokens + [other, op.mul])
else: else:
number = self.convert2fraction(other) number = self.convert2fraction(other)
gcd1 = gcd(self._num, number._denom) gcd1 = gcd(self._num, number._denom)
if gcd1 != 1: if gcd1 != 1:
num1 = [int(self._num / gcd1), gcd1, op.mul] num1_s = [gcd1] + [int(self._num / gcd1), op.mul] * (int(self._num / gcd1) != 1)
denom2 = [int(number._denom / gcd1), gcd1, op.mul] denom2_s = [gcd1] + [int(number._denom / gcd1), op.mul] * (int(number._denom / gcd1) != 1)
num1 = [int(self._num / gcd1)]
denom2 = [int(number._denom / gcd1)]
else: else:
num1_s = [self._num]
denom2_s = [number._denom]
num1 = [self._num] num1 = [self._num]
denom2 = [number._denom] denom2 = [number._denom]
gcd2 = gcd(self._denom, number._num) gcd2 = gcd(self._denom, number._num)
if gcd2 != 1: if gcd2 != 1:
num2 = [int(number._num / gcd2), gcd2, op.mul] num2_s = [gcd2] + [int(number._num / gcd2), op.mul] * (int(number._num / gcd2) != 1)
denom1 = [int(self._denom / gcd2), gcd2, op.mul] denom1_s = [gcd2] + [int(self._denom / gcd2), op.mul] * (int(self._denom / gcd2) != 1)
num2 = [int(number._num / gcd2)]
denom1 = [int(self._denom / gcd2)]
else: else:
num2_s = [number._num]
denom1_s = [self._denom]
num2 = [number._num] num2 = [number._num]
denom1 = [self._denom] denom1 = [self._denom]
exp = Expression(num1 + # 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
num2 + steps.append(Expression(num1_s + num2_s + [op.mul] + \
[op.mul] + denom1_s + denom2_s + [op.mul, op.div]))
denom1 +
denom2 + exp = Expression(num1 + num2 + [op.mul] +
[op.mul, op.div]) denom1 + denom2 + [op.mul, op.div])
ini_step = Expression(self.postfix_tokens +
number.postfix_tokens + [op.mul])
ans = exp.simplify() ans = exp.simplify()
ans.steps = [ini_step] + ans.steps ans.steps = steps + ans.steps
return ans return ans
def __rmul__(self, other): def __rmul__(self, other):
@ -430,23 +441,25 @@ class Fraction(Explicable):
>>> f**0 >>> f**0
1 1
>>> (f**0).steps >>> (f**0).steps
[] [< <class 'pymath.calculus.expression.Expression'> [< Fraction 3 / 4>, 0, '^'] >]
>>> f**1 >>> f**1
< Fraction 3 / 4> < Fraction 3 / 4>
>>> (f**1).steps >>> (f**1).steps
[] [< <class 'pymath.calculus.expression.Expression'> [< Fraction 3 / 4>, 1, '^'] >]
>>> f**3 >>> f**3
< Fraction 27 / 64> < Fraction 27 / 64>
>>> print("\\n".join([repr(i) for i in (f**3).steps])) >>> print("\\n".join([repr(i) for i in (f**3).steps]))
< <class 'pymath.calculus.expression.Expression'> [3, 4, '/', 3, '^'] > < <class 'pymath.calculus.expression.Expression'> [< Fraction 3 / 4>, 3, '^'] >
< <class 'pymath.calculus.expression.Expression'> [3, 3, '^', 4, 3, '^', '/'] > < <class 'pymath.calculus.expression.Expression'> [3, 3, '^', 4, 3, '^', '/'] >
< <class 'pymath.calculus.expression.Expression'> [27, 64, '/'] >
>>> f = Fraction(6, 4) >>> f = Fraction(6, 4)
>>> f**3 >>> f**3
< Fraction 27 / 8> < Fraction 27 / 8>
>>> print("\\n".join([repr(i) for i in (f**3).steps])) >>> print("\\n".join([repr(i) for i in (f**3).steps]))
< <class 'pymath.calculus.expression.Expression'> [6, 4, '/', 3, '^'] > < <class 'pymath.calculus.expression.Expression'> [< Fraction 6 / 4>, 3, '^'] >
< <class 'pymath.calculus.expression.Expression'> [6, 3, '^', 4, 3, '^', '/'] > < <class 'pymath.calculus.expression.Expression'> [6, 3, '^', 4, 3, '^', '/'] >
< <class 'pymath.calculus.expression.Expression'> [216, 64, '/'] > < <class 'pymath.calculus.expression.Expression'> [216, 64, '/'] >
< <class 'pymath.calculus.expression.Expression'> [216, 64, '/'] >
< <class 'pymath.calculus.expression.Expression'> [27, 8, '*', 8, 8, '*', '/'] > < <class 'pymath.calculus.expression.Expression'> [27, 8, '*', 8, 8, '*', '/'] >
""" """
@ -455,12 +468,12 @@ class Fraction(Explicable):
"Can't raise fraction to power {}".format( "Can't raise fraction to power {}".format(
str(power))) str(power)))
ini_step = Expression([self, power, op.pw])
if power == 0: if power == 0:
return Expression([1]) exp = Expression([1])
elif power == 1: elif power == 1:
return copy(self) exp = copy(self)
else: else:
ini_step = Expression(self.postfix_tokens + [power, op.pw])
exp = Expression( exp = Expression(
[self._num, power, op.pw, self._denom, power, op.pw, op.div]) [self._num, power, op.pw, self._denom, power, op.pw, op.div])