Finding Square Roots

You're going to find the square root of any number — without using any built-in function. All you need is multiplication, a bit of guessing, and a clever trick that cuts your search in half every time.

Along the way, you'll pick up Python basics: expressions, variables, if-else, loops, and functions — all by solving one real problem.

Part 1: Squares and Square Roots~5 min

Open a Jupyter notebook or Google Colab. Use Python as a calculator for every step below — type an expression into a cell and press Shift+Enter to run it.

Type an expression into a cell and press Shift+Enter:

3 * 4

12

Python is your calculator. Now —

What is the square of 2?

(The square of a number is the number multiplied by itself.)

2 * 2

4

What is the square of 3? Of 4? Of 5?

3 × 3=9
4 × 4=16
5 × 5=25

Now reverse the question:

What is the square root of 16? Of 25? Of 9?

Check your answer by squaring your guess in Python.

sqrt(16) = 4,  sqrt(25) = 5,  sqrt(9) = 3

What is the square root of 5?

It’s not a whole number. But you already know something about it.

2 × 2 = 4→ too small
3 × 3 = 9→ too big

So the square root of 5 is between 2 and 3.

Just take a guess!

Part 2: The Guessing Game~10 min

You know sqrt(5) is between 2 and 3. Let's find it by guessing, checking, and narrowing down.

Check your guess: square it in Python.

guess = 2.5
print(guess * guess)

6.25

6.25 is bigger than 5. Your guess was too high!

So the answer is between …2 and 2.5. Take a better guess!

guess = 2.25
print(guess * guess)

5.0625

Still too high! Answer is between 2 and 2.25.

guess = 2.125
print(guess * guess)

4.515625

Too low! Answer is between 2.125 and 2.25.

Your next guess will be between which two numbers?

Call them lo and hi, then calculate the midpoint:

lo = 2
hi = 3

guess = (lo + hi) / 2
print(f"Guess: {guess}")
print(f"Guess squared: {guess * guess}")

Guess: 2.5
Guess squared: 6.25

Too high! So the answer is between lo and guess.

Update hi = guess and compute a new midpoint.

Can you automatically change lo or hi depending on whether your guess squared was higher or lower than 5?

This is Python’s if-else:

lo = 2
hi = 3
num = 5

guess = (lo + hi) / 2

if guess * guess > num:
    # guess was too high — which bound should change?
else:
    # guess was too low — which bound should change?

print(f"New range: [{lo}, {hi}]")
lo = 2
hi = 3
num = 5

guess = (lo + hi) / 2

if guess * guess > num:
    hi = guess       # too high — bring ceiling down
else:
    lo = guess       # too low — raise the floor

print(f"New range: [{lo}, {hi}]")

New range: [2, 2.5]

Run the logic again and again. Do you see your guess getting closer?

Roundlohiguessguess² 
1232.56.25↓ too high
222.52.255.0625↓ too high
322.252.1254.5156↑ too low
42.1252.252.18754.7852↑ too low
52.18752.252.21884.9231↑ too low

Each guess cuts the range in half. After 20 rounds, the range is smaller than 0.000001.

But copying this block 20 times is tedious…

Part 3: Let the Loop Do the Work~10 min

Copying and pasting the same block over and over is tedious. Python's for loop can repeat it for you — as many times as you want.

Run your logic 20 times using a for loop:

lo = 2
hi = 3
num = 5

for i in range(20):
    guess = (lo + hi) / 2
    # Use your if-else logic here to update lo or hi

print(f"sqrt({num}) = {guess}")
print(f"guess squared = {guess * guess}")
lo = 2
hi = 3
num = 5

for i in range(20):
    guess = (lo + hi) / 2
    if guess * guess > num:
        hi = guess
    else:
        lo = guess

print(f"sqrt({num}) = {guess}")
print(f"guess squared = {guess * guess}")

sqrt(5) = 2.2360679774961853
guess squared = 5.000000000000002

Did your guess squared get close to 5? Let’s compare with Python’s built-in:

import math
print(f"Your answer:  {guess}")
print(f"math.sqrt(5): {math.sqrt(5)}")

Your answer:  2.2360679774961853
math.sqrt(5): 2.23606797749979

They match! Your simple guessing loop matches the built-in function.

Now repeat the process for square root of 10.

What should lo and hi start at?

3² = 9 (too small), 4² = 16 (too big) → lo = 3, hi = 4

Run the same loop — it works!

Every guess eliminates half of the remaining range.

After 1 guess:half the range left
After 5 guesses:1/32 of the range
After 10 guesses:1/1024 of the range
After 20 guesses:1/1,048,576 of the range

This “halving” strategy is called binary search — “binary” because you split the range in two each time.

It is one of the most important algorithms in computer science — and you just invented it.

Part 4: Build Your Own Function~5 min

You've found sqrt(5) and sqrt(10) by repeating the same code with different numbers. Copying code is messy — a function packages it so you can call it with any input.

Consolidate your for-loop and if-else into one function. Fill in the two missing lines:

def mysqrt(num, lo, hi, iterations):
    for i in range(iterations):
        guess = (lo + hi) / 2
        if guess * guess > num:
            pass   # Your code goes here
        else:
            pass   # Your code goes here
    return guess
def mysqrt(num, lo, hi, iterations):
    for i in range(iterations):
        guess = (lo + hi) / 2
        if guess * guess > num:
            hi = guess
        else:
            lo = guess
    return guess

When guess * guess > num (too high), bring the ceiling down: hi = guess.

When too low, raise the floor: lo = guess.

Same logic you’ve been doing all along — now packaged as a reusable function.

Test it:

import math

result = mysqrt(15, 3, 4, 20)
print(f"mysqrt(15):    {result}")
print(f"math.sqrt(15): {math.sqrt(15)}")

mysqrt(15):    3.872983346207417
math.sqrt(15): 3.872983346207417

They match!

Try more:

print(mysqrt(5,  2, 3, 20))   # 2.2360679...
print(mysqrt(10, 3, 4, 20))   # 3.1622776...
print(mysqrt(2,  1, 2, 20))   # 1.4142135...

Congratulations! In one sitting you learned:

StepWhat you didPython concept
1Computed squares (2×2, 3×3)Expressions
2Reversed the question (sqrt of 16, 25)Thinking backwards
3Guessed sqrt(5), checked by squaringVariables
4Tracked the range with lo and hiVariables (lo, hi)
5Automated the high/low decisionif / else
6Repeated the guessing 20 timesfor loop
7Packaged it as mysqrtFunctions (def)

The algorithm you built — binary search — doesn’t just work for square roots. It’s one of the most important algorithms in computer science.

And you just invented it.

Exercises: Your mysqrt checks guess * guess. What if you change that one line?

1. Cube root: Write mycuberoot(num, lo, hi, iterations). What would you check instead of guess * guess > num?

That’s right! Just check guess * guess * guess > num instead.

Test: mycuberoot(27, 2, 4, 20) should give 3.0, and mycuberoot(8, 1, 3, 20) should give 2.0.

2. Fourth root: Write myfourthroot(num, lo, hi, iterations). Same idea — what power do you check?

That’s right! Check guess ** 4 > num.

Test: myfourthroot(16, 1, 3, 20) should give 2.0, and myfourthroot(81, 2, 4, 20) should give 3.0.

3. Nth root: Can you write one function mynthroot(num, n, lo, hi, iterations) that works for any root — square, cube, 5th, 10th…?

That’s right! Check guess ** n > num. One function to rule them all!

Test: mynthroot(32, 5, 1, 3, 20) should give 2.0, because 25 = 32.

Glossary

Square
A number multiplied by itself: 3² = 3 × 3 = 9.
Square Root
The reverse of squaring: sqrt(9) = 3, because 3 × 3 = 9.
Binary Search
Finding an answer by repeatedly halving the search range — guess the middle, eliminate the wrong half, repeat.
Variable
A named box that stores a value: lo = 2, hi = 3, guess = 2.5.