import old polynom and test_polynom from polynom branch

This commit is contained in:
lafrite 2014-11-11 10:45:45 +01:00
parent 20bc84bf6a
commit 73e6c74c72
2 changed files with 480 additions and 0 deletions

318
pymath/polynom.py Normal file
View File

@ -0,0 +1,318 @@
#!/usr/bin/env python
# encoding: utf-8
from pymath.fraction import Fraction
from pymath.expression import Expression
from pymath.generic import mix_list, sum_postfix, expand_list
__all__ = ["Polynom"]
class Polynom(object):
"""Docstring for Polynom. """
def __init__(self, coef = [1], letter = "x" ):
"""Initiate the polynom
:param coef: coefficients of the polynom (ascending degree sorted) - can be a list of list of coefficients.
3 possibles type of list:
- [a,b,..] simple list of coefficients. [1,2] designate 1 + 2x
- [a, [c,b],...] list of coefficients with x^i repeated. [1,[2,3],4) designate 1 + 2x + 3x + 4x^2
- [a, [b,c,"+"],...] list of coefficients with arithmetic expression (postfix form) in. [1, [2,3,"+"], 4] designate 1 + (2+3)x + 4x^2
:param letter: the string describing the unknown
"""
self.feed_coef(coef)
self._letter = letter
if self.is_monom():
self.mainOp = "*"
else:
self.mainOp = "+"
def feed_coef(self, l_coef):
"""Feed coef of the polynom. Manage differently whether it's a number or an expression
:l_coef: list of coef
"""
self._coef = []
for coef in l_coef:
if type(coef) == list and len(coef)==1:
self._coef.append(coef[0])
else:
self._coef.append(coef)
def get_degree(self):
"""Getting the degree fo the polynom
:returns: the degree of the polynom
"""
return len(self._coef) - 1
def is_monom(self):
"""is the polynom a monom (only one coefficent)
:returns: 1 if yes 0 otherwise
"""
if len([i for i in self._coef if i != 0])==1:
return 1
else:
return 0
def __str__(self):
# TODO: Voir si on peut utiliser un render |sam. juin 14 08:56:16 CEST 2014
from .renders import txt
return txt(self.get_postfix())
def __repr__(self):
return "< Polynom " + str(self._coef) + ">"
def coef_postfix(self, a, i):
"""Return the postfix display of a coeficient
:param a: value for the coeficient (/!\ as a list)
:param i: power
:returns: postfix tokens of coef
"""
ans =[]
if a == 0:
return ans
if i == 0:
ans = a
elif i == 1:
ans = a * (a!=[1]) + [self._letter] + ["*"] * (a!=[1])
else:
ans = a * (a!=[1]) + [self._letter, i, "^"] + ["*"] * (a!=[1])
return ans
def get_postfix(self):
"""Return the postfix form of the polynom
:returns: the postfix list of polynom's tokens
"""
self._postfix = []
first_elem = 1
for (i,a) in list(enumerate(self._coef))[::-1]:
if type(a) == list and str(a[-1]) in "+-*^/":
# case coef is an arithmetic expression
self._postfix += self.coef_postfix(a,i)
if not first_elem:
self._postfix.append("+")
first_elem = 0
elif type(a) == list and str(a[-1]) not in "+-*^/":
# case need to repeat the x^i
for b in a:
if type(b) == list:
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:
self._postfix += self.coef_postfix([a],i)
if not first_elem:
self._postfix.append("+")
first_elem = 0
return self._postfix
def convert_into_poly(self, other):
"""Convert anything (int and fract) into a polynom """
if type(other) in [int, Fraction]:
return Polynom([other])
elif type(other) == Polynom:
return other
else:
raise ValueError(type(other) + " can't be converted into a polynom")
def reduce(self):
"""Compute coefficients which have same degree
:returns: new Polynom with numbers coefficients
"""
steps = []
for a in self._coef:
coef_steps = []
if type(a) == list and str(a[-1]) in "+-*^":
# case coef is an arithmetic expression
exp = Expression(a)
coef_steps = list(exp.simplify(render = lambda x:x))
steps.append(coef_steps)
elif type(a) == list and str(a[-1]) not in "+-*^":
# 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:
steps.append(a)
steps = expand_list(steps)
return [Polynom(s) for s in steps]
@staticmethod
def list_or_num(x):
if len(x) == 1:
return x[0]
else:
return x
def simplify(self):
"""Same as reduce """
return self.reduce()
def __eq__(self, other):
if type(other) in [int, Fraction, Polynom] or other.isnumeric():
o_poly = self.convert_into_poly(other)
return self._coef == o_poly._coef
else:
return 0
def __add__(self, other):
steps = []
o_poly = self.convert_into_poly(other)
n_coef = mix_list(self._coef, o_poly._coef)
p = Polynom(n_coef)
steps.append(p)
steps += p.simplify()
return steps
def __radd__(self, other):
return self.__add__(other)
def __neg__(self):
return Polynom([-i for i in self._coef], letter = self._letter)
def __sub__(self, other):
o_poly = self.convert_into_poly(other)
o_poly = -o_poly
return self.__add__(o_poly)
def __rsub__(self, other):
o_poly = self.convert_into_poly(other)
return o_poly.__sub__(-self)
def __mul__(self, other):
steps = []
o_poly = self.convert_into_poly(other)
coefs = []
for (i,a) in enumerate(self._coef):
for (j,b) in enumerate(o_poly._coef):
if a == 0 or b == 0:
elem = 0
else:
elem = [a, b, "*"]
try:
if coefs[i+j]==0:
coefs[i+j] = elem
elif elem != 0:
coefs[i+j] = [coefs[i+j], elem]
except IndexError:
coefs.append(elem)
p = Polynom(coefs)
steps.append(p)
steps += p.simplify()
return steps
def __rmul__(self, other):
o_poly = self.convert_into_poly(other)
return o_poly.__mul__(self)
def __div__(self, other):
pass
def __truediv__(self, other):
pass
def test(p,q):
print("---------------------")
print("---------------------")
print("p : ",p)
print("q : ",q)
print("\n Plus ------")
for i in (p + q):
#print(repr(i))
#print("\t", str(i.get_postfix()))
print(i)
print("\n Moins ------")
for i in (p - q):
#print(repr(i))
#print("\t", str(i.get_postfix()))
print(i)
print("\n Multiplier ------")
for i in (p * q):
#print(repr(i))
#print("\t", str(i.get_postfix()))
print(i)
if __name__ == '__main__':
p = Polynom([1, -2 ])
q = Polynom([4, 7])
#test(p,q)
q = Polynom([0, Fraction(1,2), 0, Fraction(-4,3)])
#test(p,q)
p = Polynom([1, 1, 1 ])
print(p)
#print("-- Poly étrange --")
#p = Polynom([1, [[2, 3, "*"],3], 4], "x")
#print(repr(p))
#for i in p.simplify():
# print(repr(i))
#print("-- Poly étrange --")
#p = Polynom([1, [[2, 3, "*"], [4,5,"*"]], 4], "x")
#print(repr(p))
#print(p)
#for i in p.simplify():
# print(repr(i))
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

162
test/test_polynom.py Normal file
View File

@ -0,0 +1,162 @@
#!/usr/bin/env python
# encoding: utf-8
import unittest
from pymath.polynom import Polynom
from pymath.fraction import Fraction
class TestPolynom(unittest.TestCase):
"""Testing functions from pymath.polynom"""
def test_init(self):
p = Polynom([1, 2, 3], "x")
def test_init_multi(self):
p = Polynom([1, [2, 3], 4], "x")
def test_init_arith(self):
p = Polynom([1, [2, 3, "+"], 4], "x")
def test_init_arith_2(self):
p = Polynom([1, [[2, 3, "*"],3], 4], "x")
def test_deg(self):
pass
def test_eval(self):
pass
#def test_print(self):
# p = Polynom([1,2,3])
# ans = "1 + 2 x + 3 x^2"
# self.assertEqual(ans, str(p))
#def test_print_monom(self):
# p = Polynom([0,2])
# ans = "2 x"
# self.assertEqual(ans, str(p))
#def test_print_0_coef(self):
# p = Polynom([0,1,3])
# ans = "x + 3 x^2"
# self.assertEqual(ans, str(p))
#def test_print_multi_coef(self):
# p = Polynom([1,[2, -2],3])
# ans = "1 + 2 x - 2 x + 3 x^2"
# self.assertEqual(ans, str(p))
def test_get_postfix(self):
p = Polynom([1,2,3])
#ans = [1, 2, "x", "*", "+", 3, "x", 2, "^", "*", "+"]
ans = [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+']
self.assertEqual(ans, p.get_postfix())
def test_get_postfix_monom(self):
p = Polynom([0,2])
ans = [2, "x", "*"]
self.assertEqual(ans, p.get_postfix())
def test_get_postfix_0_coef(self):
p = Polynom([0,2,0,4])
#ans = [2, "x", "*", 4, "x", 3, "^", "*", "+"]
ans = [4, 'x', 3, '^', '*', 2, 'x', '*', '+']
self.assertEqual(ans, p.get_postfix())
def test_get_postfix_1_coef(self):
p = Polynom([0,1,1])
#ans = ["x", "x", 2, "^", "+"]
ans = ["x", 2, "^", "x", "+"]
self.assertEqual(ans, p.get_postfix())
def test_get_postfix_neg_coef(self):
# TODO: Choix arbitraire (vis à vis des + et des -) il faudra faire en fonction de render |sam. juin 14 09:45:55 CEST 2014
p = Polynom([-1,-2,-3])
#ans = [-1, -2, "x", "*", "+", -3, "x", 2, "^", "*", "+"]
ans = [-3, 'x', 2, '^', '*', -2, 'x', '*', '+', -1, '+']
self.assertEqual(ans, p.get_postfix())
def test_get_postfix_multi_coef(self):
p = Polynom([1,[2, 3],4])
#ans = [1, 2, "x", "*", "+", 3, "x", "*", "+", 4, "x", 2, "^", "*", "+"]
ans = [4, 'x', 2, '^', '*', 2, 'x', '*', '+', 3, 'x', '*', '+', 1, '+']
self.assertEqual(ans, p.get_postfix())
def test_get_postfix_arithm_coef(self):
p = Polynom([1,[2, 3, "+"],4])
#ans = [1, 2, 3, "+", "x", "*", "+", 4, "x", 2, "^", "*", "+"]
ans = [4, 'x', 2, '^', '*', 2, 3, '+', 'x', '*', '+', 1, '+']
self.assertEqual(ans, p.get_postfix())
def test_reduce_nilpo(self):
p = Polynom([1, 2, 3])
self.assertEqual(p, p.reduce()[-1])
def test_reduce(self):
p = Polynom([1, [2, 3], 4])
reducted = Polynom([1, 5, 4])
self.assertEqual(p.reduce()[-1],reducted)
def test_add_int(self):
p = Polynom([1, 2, 3])
q = (p + 2)[-1]
self.assertEqual(q, Polynom([3, 2, 3]))
def test_add_frac(self):
p = Polynom([1, 2, 3])
f = Fraction(1, 2)
q = (p + f)[-1]
self.assertEqual(q, Polynom([Fraction(3, 2), 2, 3]))
def test_add_poly(self):
p = Polynom([1, 0, 3])
q = Polynom([0, 2, 3])
r = (p + q)[-1]
self.assertEqual(r, Polynom([1, 2, 6]))
def test_radd_int(self):
pass
def test_radd_frac(self):
pass
def test_radd_poly(self):
pass
def test_mul_int(self):
pass
def test_mul_frac(self):
pass
def test_mul_poly(self):
pass
def test_rmul_int(self):
pass
def test_rmul_frac(self):
pass
def test_rmul_poly(self):
pass
if __name__ == '__main__':
unittest.main()
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del