Implement the Bisection Method - Why should tests 22,23 fail?

I don’t understand these tests:

  1. square_root_bisection(225, 1e-7, 10) should return None.
  2. square_root_bisection(225, 1e-7, 10) should print Failed to converge within 10 iterations.

225 = 15^2 my code converges in four iterations.

What am I missing?

    Min = 1
    Max = number
    
    for i in range(max_iterations):
        Mid = (Min + Max)/2
        guess = Mid **2
        if guess > number:
            Max = Mid
        elif guess < number:
            Min = Mid  
    if guess == number or abs(Max - Min) < tolerance:
        print(f'The square root of {number} is approximately {Mid}')
        return Mid 
    else:
        print(f"Failed to converge within {max_iterations} iterations")
        return None

can you share your whole function? with incomplete code it’s not easy to debug

also please share a link to the project

Here’s a link to the lab:

def square_root_bisection(number, tolerance = 1e-3, max_iterations = 20):

    if number == 0  or number == 1:
        print(f'The square root of {number} is {number}')
        return number

    if number < 0:
        raise ValueError('Square root of negative number is not defined in real numbers') 

    if number < 1:
        Min = 0
        Max = 1
    
        for i in range(max_iterations): 
            Mid = (Min+Max)/2
            guess = Mid **2
            if guess > number:
                Max = Mid
            elif guess < number:
                Min = Mid
        if guess == number or abs(Max-Min) <= tolerance:
            print(f'The square root of {number} is approximately {Mid}')
            return Mid
        else:
            print(f"Failed to converge within {max_iterations} iterations")
            return None

    Min = 1
    Max = number
    
    for i in range(max_iterations):
        Mid = (Min + Max)/2
        guess = Mid **2
        if guess > number:
            Max = Mid
        elif guess < number:
            Min = Mid  
    if guess == number or abs(Max - Min) < tolerance:
        print(f'The square root of {number} is approximately {Mid}')
        return Mid 
    else:
        print(f"Failed to converge within {max_iterations} iterations")
        return None

are you sure that either of these conditions are good for saying which is the square root?

if that’s so, when should you return None? Please review the user stories carefully

Well…. yes, I am confident those are good conditions.

guess = Mid**2 ie the square of the current estimate of the square root.
if guess == number, Mid IS the square root.

The reader story:
”For example, if the tolerance is 0.01, the bisection method will keep halving the interval until the difference between the upper and lower bounds is less than or equal to 0.01.”

Max - Min is the size of the interval, so if it’s less than tolerance, the estimate should be acceptable.

If the max_iterations have been completed and Max - Min !< tolerance, the failed to converge message is displayed

I appreciate your help, but I continue to miss the point here.
It seems like there’s some nuance of what’s expected from the algorithm I’m not getting because it’s supposed fail the artificial tests 22, 23 when the algorithm I’ve written finds the actual square root of the number.

The main issue is when your function should return None. Right now, you’re returning a result inside the loop even if it hasn’t truly converged. For tests like square_root_bisection(225, 1e-7, 10), 10 iterations aren’t enough to reach that tiny tolerance.

You want to:

Check convergence inside the loop using abs(guess - number) <= tolerance.

Only return a result if it converges.

Return None after the loop if it doesn’t converge.

Here’s a cleaned-up version:

removed

This way, tests expecting None for insufficient iterations will pass

It is great that you solved the challenge, but instead of posting your full working solution, it is best to stay focused on answering the original poster’s question(s) and help guide them with hints and suggestions to solve their own issues with the challenge. How to Help Someone with Their Code Using the Socratic Method

We are trying to cut back on the number of spoiler solutions found on the forum and instead focus on helping other campers with their questions and definitely not posting full working solutions.

You are actually very close.

Your program is finding the number too quickly, right? The tests that are failing you are finding the root within the max iterations.

How can you increase the number if iterations it will take?

I’m just venting now, but I still say tests 22 and 23 are BOGUS.
The square root of 225 is 15.
I implemented a version of the bisection method to find square roots, but I can’t get the confetti on this test because my algorithm is NOT tripped up by the quirk of the algorithm FCC expects me to write.

Am I wrong?

Ah, I see another problem now, sorry.

for i in range(max_iterations):
        ...
if guess == number or abs(Max - Min) < tolerance:
    print(f'The square root of {number} is approximately {Mid}')
    return Mid 
else:
    print(f"Failed to converge within {max_iterations} iterations")
    return None

For example, if the tolerance is 0.01, the bisection method will keep halving the interval until the difference between the upper and lower bounds is less than or equal to 0.01.

When abs(Max - Min) < tolerance is true, will your program stop halving the interval? Or will it keep going and getting smaller and smaller?

You might have a point about the initial high and low values as there isn’t any guidance to set them.

However it’s something you can adjust. Try setting it higher or lower?

Thanks all for the help.

I didn’t learn much python in this lab since it’s more about the bisection method than python, but I learned a great deal about the bisection method. I abandoned all the above code and the FCC explanation of the algorithm and refactored my final code to reflect the idea of finding the root of the function ie. for number a, x^2 - a = 0 and use bisection to solve for x < tolerance. It’s all the same thing, really but looking at it the other way lead me to a much cleaner solution.

I may or may not have included a guard function to pass tests 22 and 23, which I still claim are BOGUS since 225 is a perfect square…

it does not matter if it’s a perfect square

we start with interval 1-225 (1)

now interval is 1-113 (2)

then it’s 1-57 (3)

1-29 (4)

15-29 (5)

15-22 (6)

15-18.5 (7)

15-16.75 (8)

15-15.875 (9)

15-15.4375 (10)

the distance between the upper and lowe bounds of the interval is 0.4375 which is higher than the tolerance, so the bisection method has not found a solution

It’s a lab, you are applying what you’ve learned and practice is part of learning.

fCC is an open source project and if you think you can improve the curriculum you can propose changes as GitHub Issues.