diff --git a/nessesary/polynomial.py b/nessesary/polynomial.py index 5d00013..4baef8e 100644 --- a/nessesary/polynomial.py +++ b/nessesary/polynomial.py @@ -1,7 +1,9 @@ from parser.parser import parse_poly +from fraction import to_fraction +from math import sqrt class Polynomial: - def __init__(self, poly): + def __init__(self, poly, fracmode=False): if isinstance(poly, str): self.coeff = parse_poly(poly) self.degree = len(parse_poly(poly)) - 1 @@ -12,6 +14,13 @@ class Polynomial: self.string_form = self.to_str() else: raise ValueError + self.fracmode = fracmode + if fracmode: + for c_index in range(len(self.coeff)): + try: + self.coeff[c_index] = to_fraction(self.coeff[c_index]) + except: + raise ValueError("Can't turn all number into fraction.") #[degree0, degree1, degree2] def __add__(self, other): @@ -19,67 +28,194 @@ class Polynomial: >>> p1 = Polynomial([1, 1, 1, 1, 1]) >>> p2 = Polynomial([1, 1, 1, 1, 1]) >>> p3 = p1 + p2 - >>> p3 - 2x^4+2x^3+2x^2+2x+2 + >>> str(p3) + '2x^4+2x^3+2x^2+2x+2' """ if isinstance(other, Polynomial): + large_index = max([self.degree, other.degree]) + temp = [0 for i in range(large_index)] + result = Polynomial(temp) for degree_index in range(self.degree): - self.coeff[degree_index] += other.coeff[degree_index] - if isinstance(other, int) or isinstance(other, float): - pass - + result.coeff[degree_index] = self.coeff[degree_index] + other.coeff[degree_index] + return result + elif isinstance(other, (int, float)): + result = Polynomial(self.coeff) + result.coeff[0] += other + return result def __sub__(self, other): """ >>> p1 = Polynomial([1, 1, 1, 1, 1]) >>> p2 = Polynomial([1, 1, 1, 1, 1]) >>> p3 = p1 - p2 - >>> p3 - 0 + >>> str(p3) + '0' """ if isinstance(other, Polynomial): + large_index = max([self.degree, other.degree]) + temp = [0 for i in range(large_index)] + result = Polynomial(temp) for degree_index in range(self.degree): - self.coeff[degree_index] -= other.coeff[degree_index] - + result.coeff[degree_index] = self.coeff[degree_index] - other.coeff[degree_index] + return result + elif isinstance(other, (int, float)): + result = Polynomial(self.coeff) + result.coeff[0] -= other + return result + def __mul__(self, other): + """ + >>> p1 = Polynomial([1, 1]) + >>> p2 = Polynomial([1, 1]) + >>> p3 = p1 * p2 + >>> str(p3) + x^2+2x+1 + """ if isinstance(other, Polynomial): result = [0 for i in self.degree + other.degree] for self_index in range(self.degree): for other_index in range(other.degree): result[self_index+other_index] += self.coeff[self_index]*other.coeff[other_index] + poly_result = Polynomial(result) + return poly_result + elif isinstance(other, int) or isinstance(other, float): + result = [0 for i in self.degree + other.degree] + for self_index in range(self.degree): + result[self_index+other_index] += self.coeff[self_index]*other + poly_result = Polynomial(result) + return poly_result - def __pow__(self): - pass + def __pow__(self, other): + """ + >>> p1 = Polynomial([1, 1]) + >>> str(p1 ** 2) + x^2+2x+1 + """ + result = Polynomial([0]) + if isinstance(other, int) and other >= 0: + if other == 0: + return Polynomial([1]) + else: + for i in range(other): + result += self * self + return result def __truediv__(self): pass - def to_str(self): + def to_str(self) -> str: """ convert coefficient list into string. >>> p1 = Polynomial([1, 1, 1, 1, 1]) >>> p1.to_str() - x^4+x^3+x^2+x+1 + 'x^4+x^3+x^2+x+1' >>> p2 = Polynomial([-2, 4, 0, -1, 2]) >>> p2.to_str() - 2x^4-x^3+4x-2 + '2x^4-x^3+4x-2' """ - result = [] - for ind in range(len(self.coeff)): - if self.coeff[ind]: - if ind == 0: - temp = "" - elif ind == 1: - temp = "x" - else: - temp = "x^"+str(ind) - result.append(str(self.coeff[ind])+temp) + # result = [] + # for ind in range(len(self.coeff)): + # if self.coeff[ind]: + # if ind == 0: + # temp = "" + # elif ind == 1: + # temp = "x" + # else: + # temp = "x^"+str(ind) + # result.append(str(self.coeff[ind])+temp) - if result: - result.reverse() - return " + ".join(result) - else: - return "0" + # if result: + # result.reverse() + # return "+".join(result) + # else: + # return "0" + + result = [] + i = len(self.coeff) - 1 + while i >= 0: + if self.coeff[i] != 0: + if self.coeff[i] < 0: + result.append("-") + + elif len(self.coeff) != 0: + result.append("+") + + elif self.coeff[i] == 0: + i -= 1 + continue + + if self.coeff[i] != 1 and self.coeff[i] != -1: + result.append(str(abs(self.coeff[i]))) + + if (i == len(self.coeff) - 1): + result.append(str(self.coeff[i])) + + if (self.coeff[i] == 1) and (i != len(self.coeff) - 1): + result.append(str(1)) + + if i == 1: + result.append("x") + + if i > 1: + result.append("x^"+str(i)) + i -= 1 + + if result[0] == "+" or result[0] == "-": + del result[0] + result = "".join(result) + + return result + + def solve(self) -> tuple: + degree = len(self.coeff) - 1 + if degree == 2: + a, b, c = self.coeff[2], self.coeff[1], self.coeff[0] + if a == 0: + if b == 0: + if c == 0: + return (0, None) + else: + return (c, None) + else: + return (-c/b, None) + else: + root_term = b**2-4*a*c + if root_term < 0: + res1 = f"({-b}+{to_imag(sqrt(root_term))})/{2*a}" + res2 = f"({-b}-{to_imag(sqrt(root_term))})/{2*a}" + return (res1, res2) + else: + if root_term == 0: + return (-b/(2*a), None) + else: + try: + res1 = (-b-sqrt(root_term))/(2*a) + res2 = (-b+sqrt(root_term))/(2*a) + except TypeError: + res1 = (-b-(root_term)**0.5)/(2*a) + res2 = (-b+(root_term)**0.5)/(2*a) + return (res1, res2) def __str__(self) -> str: - return self.string_form \ No newline at end of file + return self.string_form + +def to_imag(num) -> str: + """ + >>> to_imag(-10) + '10i' + >>> to_imag(-10.12) + '10.12i' + """ + num = abs(float(num)) + return f"{num}i" + +# p1 = Polynomial("x^2+2x+1", fracmode=True) +# p2 = Polynomial("x^2+2x+1", fracmode=False) + +# print(p1.solve()) + +# if __name__ == "__main__": +# import doctest +# doctest.testmod() + # Use the following line INSTEAD if you want to print all tests anyway. + # doctest.testmod(verbose = True) \ No newline at end of file