"""W01: exact quadratic rates. Inputs are int or Fraction, not binary floats."""fromdataclassesimportdataclassfromfractionsimportFractiondefrational(value):iftype(value)notin(int,Fraction):raiseTypeError("use an integer or Fraction for this exact lab")returnFraction(value)@dataclass(frozen=True)classQuadratic:a:Fractionb:Fractionc:Fractiondef__post_init__(self):forkeyin('a','b','c'):object.__setattr__(self,key,rational(getattr(self,key)))defvalue(self,x):x=rational(x)returnself.a*x*x+self.b*x+self.cdefaverage_rate(self,x,h):x,h=rational(x),rational(h)ifh==0:raiseValueError("average rate needs a nonzero interval")return(self.value(x+h)-self.value(x))/hdeftangent(self,x):x=rational(x)slope=2*self.a*x+self.bintercept=self.value(x)-slope*xreturnslope,interceptif__name__=='__main__':f=Quadratic(3,2,-4)print('point height:',f.value(-1))print('average rate:',f.average_rate(-1,Fraction(1,10)))print('tangent slope and intercept:',f.tangent(-1))