#!/usr/bin/python
# ==========================================================
# based on:
# www.youtube.com/watch?v=MXveVqBxFow
# Ancient trick to calculate ANY square root
# ==========================================================
import math
import user_interface as ui
# ----------------------------------------------------------
# ---- Find the nearest perfect square to a given number.
# ---- Using it makes the video's algorithm more efficient.
# ---- -----------------------------------------------------
# ---- Apparently the Babylonians used a table to do this.
# ---- A table is simple, fast and only needs to be
# ---- done one time.
# ---- -----------------------------------------------------
# ---- This algorithm was found on the web
# ---- 1. calculate the square root of the number
# ---- 2. round it to the nearest integer
# ---- 3. square that rounded integer to get the closest
# ---- perfect square
# ----------------------------------------------------------
def nearest_perfect_square(num):
sqrt_num = math.sqrt(num)
rnd_sqrt_num = round(sqrt_num)
return (rnd_sqrt_num,
rnd_sqrt_num*rnd_sqrt_num)
# ----------------------------------------------------------
# ---- Test if a string is a number greater than zero.
# ---- If true, return the number.
# ----------------------------------------------------------
def positive_number_greater_than_zero(string):
tf,n = ui.is_integer(string)
if tf:
if n > 0: return (True,n)
return (False,0)
tf,n = ui.is_float(string)
if tf:
if n > 0.0: return (True,n)
return (False,0.0)
# ----------------------------------------------------------
# ---- Babylonian (Video's) square root algorithm
# ----------------------------------------------------------
def video_square_root_algorithm(num,loop):
# ---- generate algorithm seed (nearest perfect square)
nps_root,nps = nearest_perfect_square(num)
print()
print('nearst perfect square root')
print(f'root = {nps_root} (squared = {nps})')
# ---- algorithm loop (increase accuracy)
estimate = nps_root # initial estimated squae root
for i in range(loop):
##print()
##print(f'loop={i} estimate={estimate}')
new_estimate = estimate + \
(num - (estimate*estimate))/(2*estimate)
##print(f'loop={i} new estimate={new_estimate}')
estimate = new_estimate
return estimate
# ----------------------------------------------------------
# ---- Main
# ----------------------------------------------------------
loop_count = 4
while True:
# ---- get user input
print()
s = ui.get_user_input(
'Enter a positive number greater that 0: ')
if not s: break # empty string?
tf,num = positive_number_greater_than_zero(s)
if not tf:
print()
print('Bad input. Try again.')
continue
# ---- estimate the number's square root
estimated_square_root = \
video_square_root_algorithm(num,loop_count)
print()
print(f'loop count = {loop_count}')
print(
f'algorithm square root = {estimated_square_root}')
print(
f'math.sqrt(num) = {math.sqrt(num)}')