In: Computer Science
Implement the following functions in the given code:
def babylonian_square_root(N, estimate, precision):
This function is provided for you to use:
def close_enough(x, y, maximum_allowable_difference):
My biggest piece of advice to you is to go one line at a time and check your return values after each little change you make.
Starter code:
# There are different ways of implementing the same idea in
math.
# Today we will explore a simple way to calculate square
roots.
#
#
#
# "Close Enough"
#
# Let's look at the digits of pi:
# pi = 3.14159265359...
#
# Realistically, though, for most uses outside of science
# we could probably get away with using 3.14159 or even 3.14
.
# For example, if I'm a painter who is painting a solid
yellow
# circle (disc) on a wall and I need a rough estimate of how
# many square feet that circle takes up I can use the
# circle area formula:
# area = pi * radius * radius
# = 3.14 * radius * radius
#
# Another example is money. When it comes to charging
interest
# or calculating tax it makes no difference if the final
number
# is $40.2295 or $40.2311 because the amount that will show
up
# on the bill is $40.23.
#
# So we have this concept of "close enough" when it comes to
numbers.
#
# Let's make a function to check if two numbers are close
enough
# to be considered the same value.
#
# Let's take the money example above.
# pretend that x = 40.2295
# y = 40.2311
# so what is the difference between them?
# x - y ----> -0.0016
# y - x ----> +0.0016
# Since we don't know which one is bigger, we will have to account
for that.
def close_enough(x, y, maximum_allowable_difference):
''' Returns True if x and y are within maximum_allowable_difference
of each other. '''
# Note: "maximum" implies that we should use <= , but for this
to work mathematically we need to use < .
# So the difference might be positive or negative, right?
# A few ways to account for this:
# 1. Use the built-in function abs() to get the absolute value
of (x - y):
return abs(x - y) < maximum_allowable_difference
# 2. Check BOTH (x - y) AND (y - x):
return (x - y) < maximum_allowable_difference and (y - x) <
maximum_allowable_difference
# 3. Shorten the inequality into chained comparisons:
return -maximum_allowable_difference < (x - y) <
maximum_allowable_difference
# All three of the above return statements are equivalent.
# Please note that Python is the ONLY language I have
encountered
# that allows comparisons to be combined as shown in answer
#3.
#
#
# NOTE --- only one return statement is necessary, but I am just
showing you options.
#
#
print()
print("Testing close_enough():")
print(" Are 1.3 and 1.25 within 0.1 of each other? ",
close_enough(1.3, 1.25, 0.1)) # <--- True
print(" Are 1.3 and 1.25 within 0.01 of each other? ",
close_enough(1.3, 1.25, 0.01)) # <--- False
print()
#
#
# Let's use our new function close_enough() to explore
# the Babylonian method of calculating square roots.
#
# Did you know you can calculate a square root using just addition
and division?
# You start with an estimate, and then improve that estimate by
taking the average
# of your current estimate and the original number divided by your
estimate.
# Repeat this until you're happy with the estimate.
#
# Let's say we want the square root of 100.
# And let's say that we don't know any better, so we'll start with
an estimate of 1.
print()
print("Finding square root of 100 using Babylonion method:")
N = 100 # N is the value for which we want the square root
estimate = 1
print(estimate) # estimate: 1
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 50.5
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 26.24009900990099
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 15.025530119986813
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 10.840434673026925
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 10.032578510960604
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 10.000052895642693
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 10.000000000139897
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 10.0
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 10.0
estimate = (estimate + (N / estimate)) / 2
print(estimate) # estimate: 10.0 <---- value is not
changing
print("(end of demonstration)")
print()
# The estimate gets closer and closer with each iteration, until
finally
# the estimate doesn't change any more and we know that we have our
answer.
#
#
# The float type gives us approximately 16 digits of precision, but
what if
# we don't care about that? What if we're happy to be within 1/1000
of the
# right answer? We could have stopped earlier in the process and
been happy.
#
---------------------------------------------------------
# ---------------------------------------------------------
#
# Fill in the missing code below using the function
close_enough().
def babylonian_square_root(N, estimate, precision):
new_estimate = (estimate + (N / estimate)) / 2
# Keep looping until new_estimate and estimate are CLOSE ENOUGH
(hint, hint).
# Return the last calculated estimate (i.e. new_estimate).
pass
# To use this function we need three things:
# - N, the number of which we want to find the square root
# - estimate, our first estimate
# - precision, how precise we want our answer to be
# For example, to find the square root of 5 to within 0.01 with an
initial estimate of 1 we would write:
print("Square root of 5 is", babylonian_square_root(5, 1,
0.01))
#
# Hint: If you are trying to use math.sqrt() you are going down the
wrong path. Step back and rethink your plan.
#
# Examples of expected results:
# babylonian_square_root(100, 1, 0.00000001) ----> 10.0
# babylonian_square_root(100, 1, 0.0000001) ----> 10.0
# babylonian_square_root(100, 1, 0.000001) ----> 10.0
# babylonian_square_root(100, 1, 0.00001) ----> 10.0
# babylonian_square_root(100, 1, 0.0001) ---->
10.000000000139897
# babylonian_square_root(100, 1, 0.001) ---->
10.000000000139897
# babylonian_square_root(100, 1, 0.01) ---->
10.000000000139897
# babylonian_square_root(100, 1, 0.1) ---->
10.000052895642693
# babylonian_square_root(100, 1, 1) ---->
10.032578510960604
# babylonian_square_root(100, 1, 10) ---->
10.840434673026925
#
# babylonian_square_root(100, 10, 1) ----> 10.0
#
# babylonian_square_root(5, 1, 0.001) ---->
2.236067977499978
# babylonian_square_root(5, 1, 0.00000001) ---->
2.23606797749979
#
# ---------------------------------------------------------
# ---------------------------------------------------------
def babylonian_square_root(N, estimate, precision):
new_estimate = (estimate + (N / estimate)) / 2
while not close_enough(new_estimate,estimate,precision):
estimate=new_estimate
new_estimate = (estimate + (N / estimate)) / 2
return new_estimate