mod fraction to work with operations and fix render in Expression

This commit is contained in:
lafrite 2014-11-14 16:20:02 +01:00
parent e93e14133d
commit 895408109d
5 changed files with 53 additions and 34 deletions

View File

@ -32,6 +32,9 @@ class Expression(object):
""" """
return self.STR_RENDER(self.postfix_tokens) return self.STR_RENDER(self.postfix_tokens)
def __repr__(self):
return "< Expression " + str(self.postfix_tokens) + ">"
def render(self, render = lambda x:str(x)): def render(self, render = lambda x:str(x)):
""" Same as __str__ but accept render as argument """ Same as __str__ but accept render as argument
:param render: function which render the list of token (postfix form) to string :param render: function which render the list of token (postfix form) to string
@ -56,7 +59,7 @@ class Expression(object):
if new_s != old_s: if new_s != old_s:
old_s = new_s old_s = new_s
yield new_s yield new_s
for s in self.child.simplify(): for s in self.child.simplify(render = render):
if old_s != s: if old_s != s:
yield s yield s
@ -128,6 +131,9 @@ class Expression(object):
return 0 return 0
return 1 return 1
# -----------
# Some math manipulations
def test(exp): def test(exp):

View File

@ -2,6 +2,8 @@
# encoding: utf-8 # encoding: utf-8
from .arithmetic import gcd from .arithmetic import gcd
from .generic import isNumber
from .operator import op
__all__ = ['Fraction'] __all__ = ['Fraction']
@ -45,7 +47,7 @@ class Fraction(object):
elif gcd_ != 1: elif gcd_ != 1:
n_frac = Fraction(n_frac._num // gcd_ , n_frac._denom // gcd_) n_frac = Fraction(n_frac._num // gcd_ , n_frac._denom // gcd_)
steps.append([n_frac._num, gcd_, '*', n_frac._denom, gcd_, '*', '/' ]) steps.append([n_frac._num, gcd_, op.mul, n_frac._denom, gcd_, op.mul, op.div ])
steps.append(n_frac) steps.append(n_frac)
@ -100,13 +102,13 @@ class Fraction(object):
coef1 = number._denom // gcd_denom coef1 = number._denom // gcd_denom
coef2 = self._denom // gcd_denom coef2 = self._denom // gcd_denom
steps.append([self._num, coef1, "*", self._denom, coef1, "*", '/', number._num, coef2, "*", number._denom, coef2, "*", "/",'+']) steps.append([self._num, coef1, op.mul, self._denom, coef1, op.mul, op.div, number._num, coef2, op.mul, number._denom, coef2, op.mul, op.div,op.add])
com_denom = self._denom * coef1 com_denom = self._denom * coef1
num1 = self._num * coef1 num1 = self._num * coef1
num2 = number._num * coef2 num2 = number._num * coef2
steps.append([num1, num2, '+', com_denom, '/']) steps.append([num1, num2, op.add, com_denom, op.div])
num = num1 + num2 num = num1 + num2
@ -142,13 +144,13 @@ class Fraction(object):
coef1 = number._denom // gcd_denom coef1 = number._denom // gcd_denom
coef2 = self._denom // gcd_denom coef2 = self._denom // gcd_denom
steps.append([self._num, coef1, "*", self._denom, coef1, "*", '/', number._num, coef2, "*", number._denom, coef2, "*", "/",'-']) steps.append([self._num, coef1, op.mul, self._denom, coef1, op.mul, op.div, number._num, coef2, op.mul, number._denom, coef2, op.mul, op.div,op.sub])
com_denom = self._denom * coef1 com_denom = self._denom * coef1
num1 = self._num * coef1 num1 = self._num * coef1
num2 = number._num * coef2 num2 = number._num * coef2
steps.append([num1, num2, '-', com_denom, '/']) steps.append([num1, num2, op.sub, com_denom, op.div])
num = num1 - num2 num = num1 - num2
@ -180,12 +182,12 @@ class Fraction(object):
elif type(other) == int: elif type(other) == int:
gcd1 = gcd(other, self._denom) gcd1 = gcd(other, self._denom)
if gcd1 != 1: if gcd1 != 1:
num = [self._num, int(other/gcd1), "*", gcd1,"*"] num = [self._num, int(other/gcd1), op.mul, gcd1,op.mul]
denom = [int(self._denom/gcd1), gcd1, "*"] denom = [int(self._denom/gcd1), gcd1, op.mul]
else: else:
num = [self._num, other, "*"] num = [self._num, other, op.mul]
denom = [self._denom] denom = [self._denom]
steps.append(num + denom + ["/"]) steps.append(num + denom + [op.div])
num = int(self._num * other / gcd1) num = int(self._num * other / gcd1)
denom = int(self._denom / gcd1) denom = int(self._denom / gcd1)
@ -195,22 +197,22 @@ class Fraction(object):
gcd1 = gcd(self._num, number._denom) gcd1 = gcd(self._num, number._denom)
if gcd1 != 1: if gcd1 != 1:
num1 = [int(self._num/ gcd1), gcd1, "*"] num1 = [int(self._num/ gcd1), gcd1, op.mul]
denom2 = [int(number._denom/ gcd1), gcd1, "*"] denom2 = [int(number._denom/ gcd1), gcd1, op.mul]
else: else:
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, "*"] num2 = [int(number._num/ gcd2), gcd2, op.mul]
denom1 = [int(self._denom/ gcd2), gcd2, "*"] denom1 = [int(self._denom/ gcd2), gcd2, op.mul]
else: else:
num2 = [number._num] num2 = [number._num]
denom1 = [self._denom] denom1 = [self._denom]
steps.append(num1 + num2 + [ '*'] + denom1 + denom2 + ['*', '/']) steps.append(num1 + num2 + [ op.mul] + denom1 + denom2 + [op.mul, op.div])
num = int(self._num * number._num / (gcd1 * gcd2)) num = int(self._num * number._num / (gcd1 * gcd2))
denom = int(self._denom * number._denom / (gcd1 * gcd2)) denom = int(self._denom * number._denom / (gcd1 * gcd2))
@ -234,7 +236,7 @@ class Fraction(object):
steps = [] steps = []
number = Fraction(number._denom, number._num) number = Fraction(number._denom, number._num)
steps.append([self, number, "*"]) steps.append([self, number, op.mul])
steps += self * number steps += self * number
return steps return steps
@ -249,9 +251,12 @@ class Fraction(object):
def __eq__(self, other): def __eq__(self, other):
""" == """ """ == """
number = self.convert2fraction(other) if isNumber(other):
number = self.convert2fraction(other)
return self._num * number._denom == self._denom * number._num return self._num * number._denom == self._denom * number._num
else:
return 0
def __lt__(self, other): def __lt__(self, other):
""" < """ """ < """

View File

@ -253,7 +253,6 @@ def spe_zip(l1,l2):
>>> spe_zip([1,2], [3,4,5]) >>> spe_zip([1,2], [3,4,5])
[[1, 3], [2, 4], 5] [[1, 3], [2, 4], 5]
""" """
tmp = list(zip_longest(l1,l2)) tmp = list(zip_longest(l1,l2))
ans = [] ans = []
for i in tmp: for i in tmp:
@ -280,6 +279,7 @@ def transpose_fill(list_lists):
col.append(l[i]) col.append(l[i])
except IndexError: except IndexError:
col.append(l[-1]) col.append(l[-1])
yield col yield col
def isOperator(exp): def isOperator(exp):

View File

@ -2,7 +2,6 @@
# encoding: utf-8 # encoding: utf-8
from .fraction import Fraction
from .generic import flatten_list, isNumber from .generic import flatten_list, isNumber
class Operator(str): class Operator(str):
@ -59,6 +58,8 @@ class Operator(str):
elif self.arity == 2: elif self.arity == 2:
# C'est moche mais je veux que ça marche... # C'est moche mais je veux que ça marche...
if str(self) == "/": if str(self) == "/":
# TODO: faudra changer ça c'est pas beau! |ven. nov. 14 16:13:49 CET 2014
from .fraction import Fraction
ans = [Fraction(args[0], args[1])] ans = [Fraction(args[0], args[1])]
ans += ans[0].simplify() ans += ans[0].simplify()
return ans return ans

View File

@ -101,15 +101,15 @@ class Polynom(object):
""" """
# TODO: Couille certaine avec txt à qui il fait donner des opérateurs tout beau! |mar. nov. 11 13:08:35 CET 2014 # TODO: Couille certaine avec txt à qui il fait donner des opérateurs tout beau! |mar. nov. 11 13:08:35 CET 2014
ans =[] ans =[]
if a == 0: if a == [0]:
return ans pass
if i == 0: elif i == 0:
ans = a ans = a
elif i == 1: elif i == 1:
ans = a * (a!=[1]) + [self._letter] + [op.mul] * (a!=[1]) ans = a * (a!=[1]) + [self._letter] + [op.mul] * (a!=[1])
else: else:
ans = a * (a!=[1]) + [self._letter, i, op.pw] + [op.mul] * (a!=[1]) ans = a * (a!=[1]) + [self._letter, i, op.pw] + [op.mul] * (a!=[1])
return ans return ans
@property @property
@ -123,15 +123,21 @@ class Polynom(object):
for (i,a) in list(enumerate(self._coef))[::-1]: for (i,a) in list(enumerate(self._coef))[::-1]:
if type(a) == Expression: if type(a) == Expression:
# case coef is an arithmetic expression # case coef is an arithmetic expression
postfix.append(self.coef_postfix(a.postfix_tokens,i)) c = self.coef_postfix(a.postfix_tokens,i)
if c != []:
postfix.append(c)
elif type(a) == list: elif type(a) == list:
# case need to repeat the x^i # case need to repeat the x^i
for b in a: for b in a:
postfix.append(self.coef_postfix([b],i)) c = self.coef_postfix([b],i)
if c != []:
postfix.append(c)
elif a != 0: elif a != 0:
postfix.append(self.coef_postfix([a],i)) c = self.coef_postfix([a],i)
if c != []:
postfix.append(c)
return flatten_list(self.postfix_add(postfix)) return flatten_list(self.postfix_add(postfix))
@ -179,6 +185,7 @@ class Polynom(object):
ans = [] ans = []
for coefs in transpose_fill(coefs_steps): for coefs in transpose_fill(coefs_steps):
ans.append(Polynom(coefs, self._letter)) ans.append(Polynom(coefs, self._letter))
return ans return ans
@staticmethod @staticmethod
@ -290,11 +297,11 @@ def test(p,q):
#print("\t", str(i.postfix)) #print("\t", str(i.postfix))
print(i) print(i)
print("\n Multiplier ------") #print("\n Multiplier ------")
for i in (p * q): #for i in (p * q):
#print(repr(i)) # #print(repr(i))
#print("\t", str(i.postfix)) # #print("\t", str(i.postfix))
print(i) # print(i)
if __name__ == '__main__': if __name__ == '__main__':
@ -304,9 +311,9 @@ if __name__ == '__main__':
test(p,q) test(p,q)
q = Polynom([0, Fraction(1,2), 0, Fraction(-4,3)]) q = Polynom([0, Fraction(1,2), 0, Fraction(-4,3)])
#test(p,q) test(p,q)
p = Polynom([1, 1, 1 ]) #p = Polynom([1, 1, 1 ])
#print(p) #print(p)