# Learn Interfaces by Building an Equation Solver - Step 48

### Tell us what’s happening:

for this i know i will have to defind an equation class somewhere but i don’t know how or where, at least thats wht i think i need to do

``````from abc import ABC, abstractmethod
import re

class Equation(ABC):
degree: int

def __init__(self, *args):
if (self.degree + 1) != len(args):
raise TypeError(
f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given"
)
if any(not isinstance(arg, (int, float)) for arg in args):
raise TypeError("Coefficients must be of type 'int' or 'float'")
if args[0] == 0:
raise ValueError("Highest degree coefficient must be different from zero")
self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)}

def __init_subclass__(cls):
if not hasattr(cls, "degree"):
raise AttributeError(
f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"
)

def __str__(self):
terms = []
for n, coefficient in self.coefficients.items():
if not coefficient:
continue
if n == 0:
terms.append(f'{coefficient:+}')
elif n == 1:
terms.append(f'{coefficient:+}x')
else:
terms.append(f"{coefficient:+}x**{n}")
equation_string = ' '.join(terms) + ' = 0'
return re.sub(r"(?<!\d)1(?=x)", "", equation_string.strip("+"))

@abstractmethod
def solve(self):
pass

@abstractmethod
def analyze(self):
pass

class LinearEquation(Equation):
degree = 1

def solve(self):
a, b = self.coefficients.values()
x = -b / a
return [x]

def analyze(self):
slope, intercept = self.coefficients.values()
return {'slope': slope, 'intercept': intercept}

degree = 2

def __init__(self, *args):
super().__init__(*args)
a, b, c = self.coefficients.values()
self.delta = b**2 - 4 * a * c

def solve(self):
if self.delta < 0:
return []
a, b, _ = self.coefficients.values()
x1 = (-b + (self.delta) ** 0.5) / (2 * a)
x2 = (-b - (self.delta) ** 0.5) / (2 * a)
if self.delta == 0:
return [x1]

return [x1, x2]

def analyze(self):
a, b, c = self.coefficients.values()
x = -b / (2 * a)
y = a * x**2 + b * x + c
if a > 0:
concavity = 'upwards'
min_max = 'min'
else:
concavity = 'downwards'
min_max = 'max'
return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}

# User Editable Region

def solver(equation):
if self.equation != Equation:
raise TypeError('Argument must be an Equation object')

# User Editable Region

lin_eq = LinearEquation(2, 3)
print(Equation.)

``````

User Agent is: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36`

### Challenge Information:

Learn Interfaces by Building an Equation Solver - Step 48

also tried testing the code through

``````print(quadr_eq.solver())
``````

however i get an attribute error saying ‘QuadraticEquation’ object has no attribute ‘solver’

never mind my method wasn’t in the class smh

im still confused on the `if equation != lin_eq:` line tho its giving me a TypeError Argument must be an Equation object, i know its probably because of the lin_eq but dont know why

you are not checking if it’s not an instance, to do that you need to use something in particular

yes i know the self, and a instance is a variable in that class e.g. self.name = name inside a class, however, i dont see an self.equation = equation or anything of that sort anywhere

I am not sure I follow, `equation` is a parameter of the function `solver`, not an object property, you need to check if the function `solver` is being called with an argument of the right type

okay but when i go to test this code:

``````     if solver() != lin_eq:
raise TypeError('Argument must be an Equation object')
``````

it says NameError: name ‘solver’ is not defined

are you calling `solver` function inside the `solver` function? I am completely confused by what you are doing.
Also, where does `lin_eq` comes from?

okay so just to clarify this is my code now and im still working on it so expect changes:

``````from abc import ABC, abstractmethod
import re

class Equation(ABC):
degree: int

def __init__(self, *args):
if (self.degree + 1) != len(args):
raise TypeError(
f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given"
)
if any(not isinstance(arg, (int, float)) for arg in args):
raise TypeError("Coefficients must be of type 'int' or 'float'")
if args[0] == 0:
raise ValueError("Highest degree coefficient must be different from zero")
self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)}

def __init_subclass__(cls):
if not hasattr(cls, "degree"):
raise AttributeError(
f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"
)

def __str__(self):
terms = []
for n, coefficient in self.coefficients.items():
if not coefficient:
continue
if n == 0:
terms.append(f'{coefficient:+}')
elif n == 1:
terms.append(f'{coefficient:+}x')
else:
terms.append(f"{coefficient:+}x**{n}")
equation_string = ' '.join(terms) + ' = 0'
return re.sub(r"(?<!\d)1(?=x)", "", equation_string.strip("+"))

@abstractmethod
def solve(self):
pass

@abstractmethod
def analyze(self):
pass

class LinearEquation(Equation):
degree = 1

def solve(self):
a, b = self.coefficients.values()
x = -b / a
return [x]

def analyze(self):
slope, intercept = self.coefficients.values()
return {'slope': slope, 'intercept': intercept}

degree = 2

def __init__(self, *args):
super().__init__(*args)
a, b, c = self.coefficients.values()
self.delta = b**2 - 4 * a * c

def solve(self):
if self.delta < 0:
return []
a, b, _ = self.coefficients.values()
x1 = (-b + (self.delta) ** 0.5) / (2 * a)
x2 = (-b - (self.delta) ** 0.5) / (2 * a)
if self.delta == 0:
return [x1]

return [x1, x2]

def analyze(self):
a, b, c = self.coefficients.values()
x = -b / (2 * a)
y = a * x**2 + b * x + c
if a > 0:
concavity = 'upwards'
min_max = 'min'
else:
concavity = 'downwards'
min_max = 'max'
return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}
def solver(equation):
if solver() != lin_eq:
raise TypeError('Argument must be an Equation object')
lin_eq = LinearEquation(2, 3)

``````

to answer your first question yes i am, i have now realised that it is wrong, but i don’t know how it’s wrong, also i don’t know why i put lin_eq there thinking about it now, however im pretty sure i done it because i realised you can’t just call on a class how it is

1. solver is a global function, not a class method, restore that
2. `lin_eq` can’t be used there, remove it from the if statement
3. don’t call `solver` inside `solver`
4. you must check if the function parameter `equation` is an instance of `Equation`, what do you must use here?

oh okay that makes more sense, i have restored it, okay i understand the 3rd one but where should i call it? well to check if a function parameter equation is an instance of an equation shouldn’t you use self on the equation there but how would you check if func parameter is an equation?

you have `equation` which is the function parameter, and `Equation`, which is the class. No `self` here because you are not inside a class.
You check if `equation` is an instance of `Equation` with the function you already used in the project that checks exactly that (if a thing is an instance of an other)

1 Like

okay, that helps alot i appreiciate it, im getting closer:

``````def solver(equation):
if isinstance(equation,Equation):
raise TypeError('Argument must be an Equation object')
``````

however im still recieving error You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function.

Read the error/hint carefully, word by word. It tells you exactly what you need to do.

1 Like