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
1 changed files with 50 additions and 37 deletions

View File

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