Learn Interfaces by Building an Equation Solver - Step 57

Tell us what’s happening:

i really am interested in what it is that is disallowing my code to pass this step

Your code so far

from abc import ABC, abstractmethod
import re


class Equation(ABC):
    degree: int
    type: str
  
    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'"
            )
        if not hasattr(cls, "type"):
            raise AttributeError(
                f"Cannot create '{cls.__name__}' class: missing required attribute 'type'"
            )

    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
    type = 'Linear Equation'
    
    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}


class QuadraticEquation(Equation):
    degree = 2
    type = 'Quadratic Equation'

    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 not isinstance(equation, Equation):
        raise TypeError("Argument must be an Equation object")

    output_string = f'\n{equation.type:-^24}'
    output_string += f'\n\n{equation!s:^24}\n\n'
    output_string += f'{"Solutions":-^24}\n\n'
    results = equation.solve()

# User Editable Region

    match len(results):
        case 0:
            result_list = ['No real roots']
        case 1:
            result_list = [f'x = {results[0]:+}']
        case 2:
            result_list = [f'x1 = {results[1]:+},x2 = {results[2]:+}']

# User Editable Region

    return output_string

lin_eq = LinearEquation(2, 3)
quadr_eq = QuadraticEquation(1, 2, 1)
print(solver(lin_eq))

Your browser information:

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 57

Hard to say since you didn’t say much but I’d assume your solution here is not

a list containing two strings with the format x1 = <root1> and x2 = <root2>.

yeah i should of said more, but i don’t know what to say. ill say more in relation to this code

case 2:
            result_list = [f'x1 = {results[1]:+}','x2 = {results[2]:+}']

i have put made a varible result_list and assigned a list containing f’x1… so on and split it into two different string via the comma, i used a f string because the wording of the last step was the same as this step therefore i assume the instructions mean do the same thing. i have also put [1] and [2] because it says and< root2> in the instructions

idk why me saying root 1 isnt coming up in the reply but i say "it says and

Syntax coloring is showing an issue here.

Also, 0 or 1 based indexing here?

is it not 1? wdym syntax colouring, isn’t the syntax colour for string always red?

The color is different between your two strings

Here you are using 0 based indexing

well if im guessing correctly you are hinting my index is incorrect and that they two should somehow match or relate, but i don’t know how. I was using 0 based indexing there because it was

it was root but them ones were root 1 and root 2 so i used indexes 1 and 2

Nope. The 1st thing in an array is at index 0

okay good explanation i implemented what you said and got

case 2:
            result_list = [f'x1 = {results[0]:+}','x2 = {results[2]:+}']

however my code is still wrong

That’s the first thing I was talking about. How are your two strings different? The variable name is the middle of the second string should not be red.

Also, if 0 corresponds to the 1st entry, then 2 cannot correspond to the 2nd

okay so you are essentially saying they should all be the same index?

No. Index 0 only can correspond to one thing. It cannot be the index of both the 1st and 2nd entry in the array

okay based on that i’ve got this, however if index 0 can correspond to one thing how can it correspond to root aswell as x1?

  case 1:
            result_list = [f'x = {results[0]:+}']
        case 2:
            result_list = [f'x1 = {results[0]:+}','x2 = {results[1]:+}']

lines are bugging for some reason but case is indented to right same level as case 2

This brings me again to the question of how your two strings in that array are different. There’s a 1 character difference that’s causing the different coloring.

I don’t understand the question. What is in the ‘results’ array? It should be full of roots.

match len(results):
        case 0:
            result_list = ['No real roots']
        case 1:
            result_list = [f'x = {results[0]:+}']
        case 2:
            result_list = [f'x1 = {results[0]:+}','x2 = {results[1]:+}']

case 2 is the results array, my question is how to case 1 and case 2 results share the same index even though they are diff values, x1, x

The results array always holds roots. It can only hold as many roots as there are.