I tried to make a Python class to for a Quadratic polynomial
with some “dunder” methods to overload the operators + and -, and to use ()
and []
, and to try to make it iterable.
There’s methods for the Quadratic Formula (real number version only) and related stuff.
I also messed with the dict
keyword close to the end of the code.
from math import sqrt
#import cmath # complex numbers library
class Quadratic():
def __init__(self, a = 1.0, b = 0.0, c = 0.0):
if isinstance(a, list):
length = len(a)
if (length > 0):
self.c = a[0]
else:
self.c = 0
if (length > 1):
self.b = a[1]
else:
self.b = 0
if (length > 2):
self.a = a[2]
else:
self.a = 0
elif isinstance(a, dict):
try:
self.a = a['a']
except:
self.a = 1
try:
self.b = a['b']
except:
self.b = 0
try:
self.c = a['c']
except:
self.c = 0
else: # a is not a list nor a dict
self.a = a
self.b = b
self.c = c
if (self.a == 0):
print("not a quadratic")
@staticmethod
def create(lst):
return Quadratic(*lst)
def __call__(self, x):
return (self.a * (x ** 2)) + (self.b * x) + self.c
def __repr__(self):
return str(self.a) + "x^2 + " + str(self.b) + "x + " + str(self.c)
def roots(self):
a = self.a
b = self.b
c = self.c
d = (b ** 2) - (4 * a * c) # discriminant
if (a != 0):
if (d > 0):
return [ (-b - sqrt(d)) / (2 * a) , (-b + sqrt(d)) / (2 * a) ]
elif (d == 0):
return [ -b / (2 * a) ]
else: #(d < 0):
return []
#return [ (-b - cmath.sqrt(d)) / (2 * a) , (-b + cmath.sqrt(d)) / (2 * a) ]
else: #(a == 0):
return [ -c / b ]
"""
def __list__(self):
return [self.c, self.b, self.a]
"""
def __add__(self, other):
if isinstance(other, Quadratic):
a = self.a + other.a
b = self.b + other.b
c = self.c + other.c
return Quadratic(a, b, c)
else:
c = self.c + other
return Quadratic(self.a, self.b, c)
def __sub__(self, other):
if isinstance(other, Quadratic):
a = self.a - other.a
b = self.b - other.b
c = self.c - other.c
return Quadratic(a, b, c)
else:
c = self.c - other
return Quadratic(self.a, self.b, c)
def __neg__(self):
return Quadratic(-self.a, -self.b, -self.c)
def __rsub__(self, other):
c = other - self.c
return Quadratic(-self.a, -self.b, c)
def __mul__(self, other):
a = self.a * other
b = self.b * other
c = self.c * other
return Quadratic(a, b, c)
def __div__(self, other):
a = self.a / other
b = self.b / other
c = self.c / other
return Quadratic(a, b, c)
def __rmul__(self, other):
return self.__mul__(other)
def __eq__(self, other):
try:
return ( \
(self.a == other.a) and \
(self.b == other.b) and \
(self.c == other.c) )
except:
return ( \
(self.a == 0) and \
(self.b == 0) and \
(self.c == other) )
def __len__(self):
return 3
def __getitem__(self, index):
if (type(index) == int):
if (index < 0):
index = index + 2
if (index == 0):
return self.c
elif (index == 1):
return self.b
elif (index == 2):
return self.a
elif (index == 'a'):
return self.a
elif (index == 'b'):
return self.b
elif (index == 'c'):
return self.c
raise IndexError
def __setitem__(self, index, value):
if (type(index) == int):
if (index < 0):
index = index + 2
if (index == 0):
self.c = value
elif (index == 1):
self.b = value
elif (index == 2):
self.a = value
elif (index == 'a'):
self.a = value
elif (index == 'b'):
self.b = value
elif (index == 'c'):
self.c = value
#raise IndexError
def __iter__(self): # iterate inside for-in loop
return iter([self.c, self.b, self.a])
# does not support assignment inside for-in loop
def vertex(self):
x = - self.b / (2 * self.a)
return (x, self.__call__(x))
def focus(self):
x = - self.b / (2 * self.a)
y = self.__call__(x) + (a / 4)
return (x, y)
@staticmethod
def from_roots(r1, r2 = None):
if (r2 is None):
r2 = r1
b = r1 + r2
c = r1 * r2
return Quadratic(1, b, c)
# end of Quadratic class #
f = Quadratic(1, -2, -3)
print("f(x) =", f)
a = 5
print(f'f({a}) =' , f(a))
#g = f + 4
#print('f + 4 = ', g)
print("roots", end = " ")
print(f.roots())
print("vertex", f.vertex())
print("focus", f.focus())
g = Quadratic([5, 6, 1])
print(g)
h = Quadratic.create([-2, 5, 1])
print(h)
y = g + h
print(y)
#z = Quadratic({'a': 2, 'b': -6, 'c': 1})
#y = Quadratic.from_roots(1)
print('y =', y)
for co in y:
print(co)
Dictionary = dict
def dict(obj):
try:
return Dictionary(obj)
except:
if isinstance(obj, list):
length = len(obj)
keys = list(range(length))
return Dictionary(zip(keys, obj))
return obj.__dict__
print(dict( [('e', 1), ('f', 2)] ))
print(dict( [5, 6] ))
print(dict(f))
print(list(f))
def maximum(stuff):
if isinstance(stuff, Quadratic):
if (stuff.a < 0):
return stuff.vertex()[1]
else:
return max(stuff)
def minimum(stuff):
if isinstance(stuff, Quadratic):
if (stuff.a > 0):
return stuff.vertex()[1]
else:
return min(stuff)
print("h =", h)
print("max: ", maximum(h))
print("f =", f)
print("min: ", minimum(f))
Please let me know if you find any bugs, or any way to improve the code.