# CS 171 - Lab 12
# YOUR NAMES AND EMAILS HERE

class Polynomial:
    # example
    # p(x) = 9x^3 + 5x^2 - 7x + 8
    # [8, -7, 5, 9]
    #  0   1  2  3
    def __init__(self, lst):
        self.a = lst[:] # copy from lst to self.a
        
    def __str__(self):
        t = ""
        for i in range(len(self.a)-1, -1, -1):
            t += str(self.a[i])
            if i==1:
                t += "x + "
            elif i != 0:
                t += "x"+self.convert(i)+" + "
        return t

    # convert a number into a superscripted string
    def convert(self,n):
        s = str(n)
        digits = ["\u2070", "\u00B9", "\u00B2", "\u00B3", "\u2074"\
                  "\u2075", "\u2076", "\u2077", "\u2078", "\u2070"]
        t = ""
        for c in s:
            t += digits[int(c)]
        return t

    # return polynomial's degree (highest power of x)
    # a constant polynomial, such as p(x) = 5, has degree 0
    # the zero polynomial, p(x)=0, technically has no degree, but return 0
    def degree(self):
        return 0 # FIXME 

    # return coefficient of x^i
    def coeff(self, i):
        return 0 # FIXME

    # return the polynomial evaluated at x
    def f(self, x):
        return 0 # FIXME

    # return the derivative polynomial p'(x)
    # create a new array of coefficients
    # then use that to create a new Polynomial
    # don't change self.a!
    def derivative(self):
        b = []
        return Polynomial(b) # FIXME

    # Use the power rule to integrate p(x), assume constant C is zero
    # create a new array of coefficients
    # then use that to create a new Polynomial
    # don't change self.a!
    def integrate(self):
        return Polynomial([0]) # FIXME

    # compute the definite integral of p(x) from x1 to x2
    # use your integrate() method to compute P
    # then compute the difference of P(x2) and P(x1)
    def integral(self, x1, x2):
        return 0 # FIXME

    # negate this polynomials
    # create a new array of coefficients
    # then use that to create a new Polynomial
    # don't change self.a!
    def __neg__(self):
        return Polynomial([0]) # FIXME

    # add two polynomials
    # create a new array of coefficients
    # which polynomial has the largest degree?
    # then use that to create a new Polynomial
    # don't change self.a or p.a!
    def __add__(self, p):
        return Polynomial([0]) # FIXME

    # multiply two polynomials
    # create a new array of coefficients
    # then use that to create a new Polynomial
    # don't change self.a or p.a!
    def __mul__(self, p):
        return Polynomial([0]) # FIXME
    # plot the quadratic

def main():    
    polys = list()
    polys.append(Polynomial([0.0]))                # p(x) = 0
    polys.append(Polynomial([1.0]))                # p(x) = 1
    polys.append(Polynomial([2.0, -1.0]))          # p(x) = -x + 2
    polys.append(Polynomial([6.0, 5.0, 1.0]))      # p(x) = x^2 + 5x + 6
    polys.append(Polynomial([1.0, 5.0, 7.0, 3.0])) # p(x) = 3x^3 + 7x^2 + 5x + 1
    n = len(polys)

    for i in range(n):
        p = polys[i]
        p1 = polys[(i-1+n)%n]
        
        print("p(x) =", p)
        print("degree of p:", p.degree())
        
        x = 0.0
        print("p("+str(x)+") = "+str(p.f(x))+" =?", p.coeff(0))
        x = 1.0
        print("p("+str(x)+") = "+str(p.f(x)))
        x = -1.0
        print("p("+str(x)+") = "+str(p.f(x)))
        x = 2.0
        print("p("+str(x)+") = "+str(p.f(x)))

        print("coefficients: ", end="")
        for i in range(p.degree() + 1):
            print(p.coeff(i), end=" ")
        print()

        q = p.derivative()
        print("derivative: p'(x) =", q)
        print("degree of p':", q.degree())

        P = p.integrate()
        print("integrate: P(x) =", P)
        print("degree of P:", P.degree())
        
        r = P.derivative()
        print("derivative: P'(x) =", r, "=?", p)
        
        v = p.integral(1.0, 2.0)
        print("integral from 1.0 to 2.0 =", v)

        r = p+p1
        print("("+str(p)+") + ("+str(p1)+") =", r)
        print("degree of p+p1:", r.degree())

        r = p*p1
        print("("+str(p)+") * ("+str(p1)+") =", r)
        print("degree of p*p1:", r.degree())

        r = -p
        print("-("+str(p)+") =", r)
        print("degree of -p:", r.degree())

        print("--------------------------------------------------------")

    
main()
        
