Guttag Chapter 3
Logical Steps:
Any concerns with this code?
Logical Steps:
Any concerns with this code?
Try it!
Exhaustive enumeration is like moving along a number line.
But number lines with integers are only useful for finding the square roots of perfect squares.
# Exhaustive Enumeration for non-perfect squares
def squareroot_ee(number: int) -> float:
"""Exhaustively check all possible non-integer roots."""
epsilon = 0.01 # margin of error
step_size = epsilon**2
possible_answer = 0
while possible_answer**2 < number + epsilon:
if possible_answer**2 > number - epsilon:
return possible_answer # good!
possible_answer += step_size
return possible_answer # not so good!
print(squareroot_ee(26))
5.098100000001457
Why is line 12 marked as “not so good” after the while loop?
How do you use this?
Logical Steps:
Pseudo Code:
# choose a number to take the sqrt of
# define an epsilon (allowed margin of error)
# initialize the search space starting and ending value
# initialize the possible answer to the middle of the search space
# while loop so long as possible_answer**2 is not _within_ the margin of error (±)
# if the possible_answer ** 2 was too large
# adjust the search space to be the lower half of the space
# Or, if the possible_answer ** 2 was too small
# adjust the search space to be the upper half of the space
# compute the middle of the new search space and assign that to possible answer
# assume possible_answer is within the margin of error!
Note how the start, middle, and end of the search space are used repeatedly
# Bisection Search for non-perfect squares
def squareroot_bs(number: int) -> float:
"""Perform bisection search to find root."""
epsilon = 0.01 # margin of error, could be a parameter
lower_bound = 0
upper_bound = number
midpoint = (lower_bound+upper_bound)/2
while abs(number - midpoint**2) > epsilon:
if midpoint**2 > number:
upper_bound = midpoint
else:
lower_bound = midpoint
midpoint = (lower_bound+upper_bound)/2
return midpoint
print(squareroot_bs(144.3))
12.012155914306641
# Bisection Search for non-perfect squares
def squareroot_bs(number: int) -> float:
"""Perform bisection search to find root."""
epsilon = 0.01 # margin of error, could be a parameter
lower_bound = 0
if number < 1:
upper_bound = 1
else:
upper_bound = number
midpoint = (lower_bound+upper_bound)/2
while abs(number - midpoint**2) > epsilon:
if midpoint**2 > number:
upper_bound = midpoint
else:
lower_bound = midpoint
midpoint = (lower_bound+upper_bound)/2
return midpoint
print(squareroot_bs(0.5))
0.703125
What changed?