""" Exercise 9.4 from "A primer on... Implement the Parabola and Line classes as sub-classes of the general Polynomial class. We need to reimplement the constructor since the arguments are different, but the rest of the functionality can be inherited. """ class Polynomial: """ class implementation of a polynomial, using a list to represent the polynomial coefficients. """ def __init__(self, coefficients): self.coeff = coefficients def __call__(self, x): s = 0 for i in range(len(self.coeff)): s += self.coeff[i]*x**i return s def __add__(self, other): # return self + other # start with the longest list and add in the other: if len(self.coeff) > len(other.coeff): coeffsum = self.coeff[:] # copy! for i in range(len(other.coeff)): coeffsum[i] += other.coeff[i] else: coeffsum = other.coeff[:] # copy! for i in range(len(self.coeff)): coeffsum[i] += self.coeff[i] return Polynomial(coeffsum) def __sub__(self, other): """ We want to compute and return self-other. If self is the longest we can use the same method as in __add__, but if other is longer we need a slightly different approach. """ if len(self.coeff) >= len(other.coeff): coeffdiff = self.coeff[:] # copy! for i in range(len(other.coeff)): coeffdiff[i] -= other.coeff[i] else: coeffdiff = [0] * len(other.coeff) for i in range(len(self.coeff)): coeffdiff[i] = self.coeff[i] for i in range(len(other.coeff)): coeffdiff[i] -= other.coeff[i] return Polynomial(coeffdiff) def __mul__(self, other): M = len(self.coeff) - 1 N = len(other.coeff) - 1 coeff = [0]*(M+N+1) # or zeros(M+N+1) for i in range(0, M+1): for j in range(0, N+1): coeff[i+j] += self.coeff[i] * other.coeff[j] return Polynomial(coeff) def differentiate(self): #in-place differentiation, changes self, for i in range(1, len(self.coeff)): self.coeff[i-1] = i*self.coeff[i] del self.coeff[-1] def derivative(self): # returns new polynomial, does not change self dpdx = Polynomial(self.coeff[:]) # copy dpdx.differentiate() return dpdx def __str__(self): s = '' for i in range(0, len(self.coeff)): if self.coeff[i] != 0: s += f' + {self.coeff[i]:g}*x^{i:g}' # fix layout (many special cases): s = s.replace('+ -', '- ') s = s.replace(' 1*', ' ') s = s.replace('x^0', '1') s = s.replace('x^1 ', 'x ') if s[0:3] == ' + ': # remove initial + s = s[3:] if s[0:3] == ' - ': # fix spaces for initial - s = '-' + s[3:] return s class Parabola(Polynomial): def __init__(self, c0, c1, c2): super().__init__([c0, c1, c2]) class Line(Parabola): def __init__(self, c0, c1): super().__init__(c0, c1, 0) #the new classes inherit __add__, __call__, # __str__ and other methods: p1 = Parabola(1,1,1) print(p1(2.0)) l1 = Line(0,1) print(p1 + l1)