Reduce and print poly ok!
This commit is contained in:
parent
693c982cbe
commit
2b67fc682c
@ -41,15 +41,15 @@ class Expression(object):
|
|||||||
## ---------------------
|
## ---------------------
|
||||||
## Mechanism functions
|
## Mechanism functions
|
||||||
|
|
||||||
def simplify(self):
|
def simplify(self, render=STR_RENDER):
|
||||||
""" Generator which return steps for computing the expression """
|
""" Generator which return steps for computing the expression """
|
||||||
if not self.can_go_further():
|
if not self.can_go_further():
|
||||||
yield self.STR_RENDER(self.postfix_tokens)
|
yield render(self.postfix_tokens)
|
||||||
else:
|
else:
|
||||||
self.compute_exp()
|
self.compute_exp()
|
||||||
old_s = ''
|
old_s = ''
|
||||||
for s in self.steps:
|
for s in self.steps:
|
||||||
new_s = self.STR_RENDER(s)
|
new_s = render(s)
|
||||||
# Astuce pour éviter d'avoir deux fois la même étape (par exemple pour la transfo d'une division en fraction)
|
# Astuce pour éviter d'avoir deux fois la même étape (par exemple pour la transfo d'une division en fraction)
|
||||||
if new_s != old_s:
|
if new_s != old_s:
|
||||||
old_s = new_s
|
old_s = new_s
|
||||||
|
@ -264,7 +264,23 @@ def spe_zip(l1,l2):
|
|||||||
ans.append(j)
|
ans.append(j)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
def transpose_fill(list_lists):
|
||||||
|
"""Transpose a list of list and if inside list have not the same length, fill with last token
|
||||||
|
|
||||||
|
:list_lists: a list of list to transpose
|
||||||
|
:returns: generator which generate lines of the transposed matrix
|
||||||
|
|
||||||
|
>>> Polynom.transpose_fill([[1], [2, 3], [4, 5, 6]])
|
||||||
|
[[1, 2, 4] , [1, 3, 5], [1, 3, 6]]
|
||||||
|
"""
|
||||||
|
for i in range(max([len(l) for l in list_lists])):
|
||||||
|
col = []
|
||||||
|
for l in list_lists:
|
||||||
|
try:
|
||||||
|
col.append(l[i])
|
||||||
|
except IndexError:
|
||||||
|
col.append(l[-1])
|
||||||
|
yield col
|
||||||
|
|
||||||
def isOperator(exp):
|
def isOperator(exp):
|
||||||
"""Check if the expression is an opération in "+-*/:^"
|
"""Check if the expression is an opération in "+-*/:^"
|
||||||
|
@ -3,8 +3,11 @@
|
|||||||
|
|
||||||
|
|
||||||
from .expression import Expression
|
from .expression import Expression
|
||||||
from .generic import spe_zip, sum_postfix, expand_list, isNumber
|
from .operator import op
|
||||||
|
from .generic import spe_zip, expand_list, isNumber, transpose_fill, flatten_list
|
||||||
|
#from .generic import spe_zip, sum_postfix, expand_list, isNumber
|
||||||
from .render import txt
|
from .render import txt
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
__all__ = ["Polynom"]
|
__all__ = ["Polynom"]
|
||||||
|
|
||||||
@ -23,6 +26,14 @@ class Polynom(object):
|
|||||||
- a: a Expression. [1, Expression("2+3"), 4] designate 1 + (2+3)x + 4x^2
|
- a: a Expression. [1, Expression("2+3"), 4] designate 1 + (2+3)x + 4x^2
|
||||||
:param letter: the string describing the unknown
|
:param letter: the string describing the unknown
|
||||||
|
|
||||||
|
>>> Polynom([1,2,3]).mainOp
|
||||||
|
'+'
|
||||||
|
>>> Polynom([1]).mainOp
|
||||||
|
'*'
|
||||||
|
>>> Polynom([1,2, 3])._letter
|
||||||
|
'x'
|
||||||
|
>>> Polynom([1, 2, 3], "y")._letter
|
||||||
|
'y'
|
||||||
"""
|
"""
|
||||||
self.feed_coef(coef)
|
self.feed_coef(coef)
|
||||||
self._letter = letter
|
self._letter = letter
|
||||||
@ -33,7 +44,7 @@ class Polynom(object):
|
|||||||
else:
|
else:
|
||||||
self.mainOp = "+"
|
self.mainOp = "+"
|
||||||
|
|
||||||
self._isPolynom
|
self._isPolynom = 1
|
||||||
|
|
||||||
def feed_coef(self, l_coef):
|
def feed_coef(self, l_coef):
|
||||||
"""Feed coef of the polynom. Manage differently whether it's a number or an expression
|
"""Feed coef of the polynom. Manage differently whether it's a number or an expression
|
||||||
@ -52,12 +63,22 @@ class Polynom(object):
|
|||||||
|
|
||||||
:returns: the degree of the polynom
|
:returns: the degree of the polynom
|
||||||
|
|
||||||
|
>>> Polynom([1, 2, 3]).get_degree()
|
||||||
|
2
|
||||||
|
>>> Polynom([1]).get_degree()
|
||||||
|
0
|
||||||
"""
|
"""
|
||||||
return len(self._coef) - 1
|
return len(self._coef) - 1
|
||||||
|
|
||||||
def is_monom(self):
|
def is_monom(self):
|
||||||
"""is the polynom a monom (only one coefficent)
|
"""is the polynom a monom (only one coefficent)
|
||||||
|
|
||||||
:returns: 1 if yes 0 otherwise
|
:returns: 1 if yes 0 otherwise
|
||||||
|
|
||||||
|
>>> Polynom([1, 2, 3]).is_monom()
|
||||||
|
0
|
||||||
|
>>> Polynom([1]).is_monom()
|
||||||
|
1
|
||||||
"""
|
"""
|
||||||
if len([i for i in self._coef if i != 0])==1:
|
if len([i for i in self._coef if i != 0])==1:
|
||||||
return 1
|
return 1
|
||||||
@ -65,8 +86,7 @@ class Polynom(object):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# TODO: Voir si on peut utiliser un render |sam. juin 14 08:56:16 CEST 2014
|
return txt(self.postfix)
|
||||||
return txt(self.get_postfix())
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "< Polynom " + str(self._coef) + ">"
|
return "< Polynom " + str(self._coef) + ">"
|
||||||
@ -74,7 +94,7 @@ class Polynom(object):
|
|||||||
def coef_postfix(self, a, i):
|
def coef_postfix(self, a, i):
|
||||||
"""Return the postfix display of a coeficient
|
"""Return the postfix display of a coeficient
|
||||||
|
|
||||||
:param a: value for the coeficient (/!\ as a list)
|
:param a: value for the coeficient (/!\ as a postfix list)
|
||||||
:param i: power
|
:param i: power
|
||||||
:returns: postfix tokens of coef
|
:returns: postfix tokens of coef
|
||||||
|
|
||||||
@ -86,46 +106,34 @@ class Polynom(object):
|
|||||||
if i == 0:
|
if i == 0:
|
||||||
ans = a
|
ans = a
|
||||||
elif i == 1:
|
elif i == 1:
|
||||||
ans = a * (a!=[1]) + [self._letter] + ["*"] * (a!=[1])
|
ans = a * (a!=[1]) + [self._letter] + [op.mul] * (a!=[1])
|
||||||
else:
|
else:
|
||||||
ans = a * (a!=[1]) + [self._letter, i, "^"] + ["*"] * (a!=[1])
|
ans = a * (a!=[1]) + [self._letter, i, op.pw] + [op.mul] * (a!=[1])
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def get_postfix(self):
|
@property
|
||||||
|
def postfix(self):
|
||||||
"""Return the postfix form of the polynom
|
"""Return the postfix form of the polynom
|
||||||
|
|
||||||
:returns: the postfix list of polynom's tokens
|
:returns: the postfix list of polynom's tokens
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._postfix = []
|
postfix = []
|
||||||
first_elem = 1
|
|
||||||
for (i,a) in list(enumerate(self._coef))[::-1]:
|
for (i,a) in list(enumerate(self._coef))[::-1]:
|
||||||
if type(a) == list and str(a[-1]) in "+-*^/":
|
if type(a) == Expression:
|
||||||
# case coef is an arithmetic expression
|
# case coef is an arithmetic expression
|
||||||
self._postfix += self.coef_postfix(a,i)
|
postfix.append(self.coef_postfix(a.postfix_tokens,i))
|
||||||
if not first_elem:
|
|
||||||
self._postfix.append("+")
|
|
||||||
first_elem = 0
|
|
||||||
|
|
||||||
elif type(a) == list and str(a[-1]) not in "+-*^/":
|
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:
|
||||||
if type(b) == list:
|
postfix.append(self.coef_postfix([b],i))
|
||||||
self._postfix += self.coef_postfix(b,i)
|
|
||||||
else:
|
|
||||||
self._postfix += self.coef_postfix([b],i)
|
|
||||||
if not first_elem:
|
|
||||||
self._postfix.append("+")
|
|
||||||
first_elem = 0
|
|
||||||
|
|
||||||
elif a != 0:
|
elif a != 0:
|
||||||
self._postfix += self.coef_postfix([a],i)
|
postfix.append(self.coef_postfix([a],i))
|
||||||
if not first_elem:
|
|
||||||
self._postfix.append("+")
|
|
||||||
first_elem = 0
|
|
||||||
|
|
||||||
return self._postfix
|
return flatten_list(self.postfix_add(postfix))
|
||||||
|
|
||||||
def conv2poly(self, other):
|
def conv2poly(self, other):
|
||||||
"""Convert anything number into a polynom"""
|
"""Convert anything number into a polynom"""
|
||||||
@ -149,53 +157,54 @@ class Polynom(object):
|
|||||||
:returns: new Polynom with numbers coefficients
|
:returns: new Polynom with numbers coefficients
|
||||||
"""
|
"""
|
||||||
steps = []
|
steps = []
|
||||||
for a in self._coef:
|
# gather steps for every coeficients
|
||||||
|
coefs_steps = []
|
||||||
|
for coef in self._coef:
|
||||||
coef_steps = []
|
coef_steps = []
|
||||||
if type(a) == Expression:
|
if type(coef) != Expression:
|
||||||
# case coef is an arithmetic expression
|
# On converti en postfix avec une addition
|
||||||
coef_steps = list(a.simplify(render = lambda x:x))
|
postfix_add = self.postfix_add(coef)
|
||||||
|
# On converti en Expression
|
||||||
steps.append(coef_steps)
|
coef_exp = Expression(postfix_add)
|
||||||
elif type(a) == list:
|
|
||||||
# case need to repeat the x^i
|
|
||||||
if [i for i in a if type(i) == list] != []:
|
|
||||||
# first we simplify arithmetic exp
|
|
||||||
# Et hop un coup de sorcelerie!
|
|
||||||
elem = [list(Expression(i).simplify(render = lambda x:self.list_or_num(x))) if type(i) == list else i for i in a ]
|
|
||||||
|
|
||||||
elem = expand_list(elem)
|
|
||||||
coef_steps += elem
|
|
||||||
exp = elem[-1]
|
|
||||||
|
|
||||||
else:
|
|
||||||
exp = a
|
|
||||||
|
|
||||||
exp = sum_postfix(exp)
|
|
||||||
exp = Expression(exp)
|
|
||||||
|
|
||||||
coef_steps += list(exp.simplify(render = lambda x:x))
|
|
||||||
|
|
||||||
steps.append(coef_steps)
|
|
||||||
else:
|
else:
|
||||||
steps.append(a)
|
coef_exp = coef
|
||||||
|
|
||||||
steps = expand_list(steps)
|
# On fait réduire l'expression puis on ajoute dans steps
|
||||||
|
coef_steps = list(coef_exp.simplify(render = lambda x:Expression(x)))
|
||||||
|
|
||||||
return [Polynom(s) for s in steps]
|
# On ajoute toutes ces étapes
|
||||||
|
coefs_steps.append(coef_steps)
|
||||||
|
|
||||||
|
# On retourne la matrice
|
||||||
|
for coefs in transpose_fill(coefs_steps):
|
||||||
|
yield Polynom(coefs, self._letter)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list_or_num(x):
|
def postfix_add(numbers):
|
||||||
if len(x) == 1:
|
"""Convert a list of numbers into a postfix addition
|
||||||
return x[0]
|
|
||||||
else:
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
:numbers: list of numbers
|
||||||
|
:returns: Postfix list of succecive attition of number
|
||||||
|
|
||||||
|
>>> Polynom.postfix_add([1])
|
||||||
|
[1]
|
||||||
|
>>> Polynom.postfix_add([1, 2])
|
||||||
|
[1, 2, '+']
|
||||||
|
>>> Polynom.postfix_add([1, 2, 3])
|
||||||
|
[1, 2, '+', 3, '+']
|
||||||
|
>>> Polynom.postfix_add(1)
|
||||||
|
[1]
|
||||||
|
"""
|
||||||
|
if not type(numbers) == list:
|
||||||
|
return [numbers]
|
||||||
|
else:
|
||||||
|
ans = [[a, op.add] if i!=0 else [a] for (i,a) in enumerate(numbers)]
|
||||||
|
return list(chain.from_iterable(ans))
|
||||||
|
|
||||||
def simplify(self):
|
def simplify(self):
|
||||||
"""Same as reduce """
|
"""Same as reduce """
|
||||||
return self.reduce()
|
return self.reduce()
|
||||||
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
o_poly = self.conv2poly(other)
|
o_poly = self.conv2poly(other)
|
||||||
return self._coef == o_poly._coef
|
return self._coef == o_poly._coef
|
||||||
@ -275,23 +284,24 @@ def test(p,q):
|
|||||||
print("\n Plus ------")
|
print("\n Plus ------")
|
||||||
for i in (p + q):
|
for i in (p + q):
|
||||||
#print(repr(i))
|
#print(repr(i))
|
||||||
#print("\t", str(i.get_postfix()))
|
#print("\t", str(i.postfix))
|
||||||
print(i)
|
print(i)
|
||||||
|
|
||||||
print("\n Moins ------")
|
print("\n Moins ------")
|
||||||
for i in (p - q):
|
for i in (p - q):
|
||||||
#print(repr(i))
|
#print(repr(i))
|
||||||
#print("\t", str(i.get_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.get_postfix()))
|
#print("\t", str(i.postfix))
|
||||||
print(i)
|
print(i)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
from .fraction import Fraction
|
||||||
p = Polynom([1, -2 ])
|
p = Polynom([1, -2 ])
|
||||||
q = Polynom([4, 7])
|
q = Polynom([4, 7])
|
||||||
#test(p,q)
|
#test(p,q)
|
||||||
@ -304,10 +314,10 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
|
|
||||||
#print("-- Poly étrange --")
|
#print("-- Poly étrange --")
|
||||||
#p = Polynom([1, [[2, 3, "*"],3], 4], "x")
|
p = Polynom([1, [2, 3], 4], "x")
|
||||||
#print(repr(p))
|
print(repr(p))
|
||||||
#for i in p.simplify():
|
for i in p.simplify():
|
||||||
# print(repr(i))
|
print(i)
|
||||||
#print("-- Poly étrange --")
|
#print("-- Poly étrange --")
|
||||||
#p = Polynom([1, [[2, 3, "*"], [4,5,"*"]], 4], "x")
|
#p = Polynom([1, [[2, 3, "*"], [4,5,"*"]], 4], "x")
|
||||||
#print(repr(p))
|
#print(repr(p))
|
||||||
@ -315,6 +325,9 @@ if __name__ == '__main__':
|
|||||||
#for i in p.simplify():
|
#for i in p.simplify():
|
||||||
# print(repr(i))
|
# print(repr(i))
|
||||||
|
|
||||||
|
import doctest
|
||||||
|
doctest.testmod()
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
|
Loading…
Reference in New Issue
Block a user