I need help with a square root calculator.
The directions are as follows:
"You need to implement the Babylonian Method for computing square roots. Based on that core functionality, you are to write an interactive program that:
Prompts the user to enter an integer value above zero.
Checks to ensure that the value is indeed above zero. If not, the program displays an error message and asks for the input again.
Computes the square root of the value using the Babylonian Method outlined above.
Displays the square root to the user formatted to show exactly 3 decimal places (no more than 3, and no less than 3)."
I can't use the sqrt function. I'm getting really close but can't quite get to the right loop. Here's what I have so far
# Ask user if they would like to calculate a square root for a single number or range.
single = input("Enter 'single' or 'range' to solve for a single square root or a range of values, respectively: ")
# Set error message to let the user know 'range' calculation are not currently available.
if single == 'single' or 'Single':
# Ask user to enter a positive integer.
number = int(input("Enter a positive integer value: "))
# Set error message asking for valid number if user enters something other than a positive integer.
while number < 0:
print("Please enter a valid number.")
else:
# Choose epsilon
epsilon = .0001
# Choose estimate for the square root of x
estimate = 4
# Evaluate the estimate
while number - estimate > epsilon:
# Calculate the square root using the Babylonian Method.
estimate = (number + 1.0) / 2.0
second_estimate = (estimate + number / estimate) / 2.0
# Print the users selected value and its square root.
print("Value", " ", "Square Root")
print(" ", number, " ", format(second_estimate, '.3f'))
else:
# Tell user 'range' calculation are not currently available.
print("That function is not currently available.")
The condition for the while loop is wrong. number is 9 and estimate goes to 3. So you have to check number - estimate*estimate (take the absolute value because estimate converges to 3 from above for a starting value of 4). You dont need the first estimate according to Babylonian method on wikipedia.
Also estimate is always 5 in your code. (estimate = (number + 1.0) / 2.0 where number is always 9)
number = 9
epsilon = .0001
estimate = 4
while abs(number - estimate*estimate) > epsilon:
estimate = (estimate + number/estimate) / 2.0
print("Value", " ", "Square Root")
print(" ", number, " ", format(estimate, '.4f'))
Result:
Value Square Root
9 3.1250
Value Square Root
9 3.0025
Value Square Root
9 3.0000
Related
I am writing a program to output square root of an number in python. My current code looks like:
import math
num = int(input("Enter the number for which you want the square root"))
if math.floor(math.sqrt(num)) == math.ceil(math.sqrt(num)):
v = math.sqrt(num)
print(f"The given number is perfect square and the square root is {v} ")
elif num <0:
print("The square root of the given number is imaginary")
else:
print(f"The square root of the given number is \u221A{num}")
#\u221A is unicode for square root symbol
My current program checks if the entered number is perfect square then displays the square root. if it is not a perfect square it just displays √num. For example if num is 300, it will display √300. But i want it to display it as 10√3. Any ideas about how do i do that. I dont want any decimals in my result.
You can use sympy:
import sympy
sympy.init_printing(use_unicode=True)
sympy.sqrt(300)
Output:
10√3
You could find the largest root that is a divisor of your number and present the remainder as the √xxx part:
def root(N):
for r in range(int(N**0.5)+1,1,-1):
if N % (r*r) == 0:
n = N // (r*r)
return str(r) + f"√{n}"*(n>1)
return f"√{N}"
print(root(50)) # 5√2
print(root(81)) # 9
print(root(96)) # 4√6
print(root(97)) # √97
I'm trying to make a while loop that displays all possible perfect squared numbers up to the value is provided by the user input
Below is the code that I have produced for this however this only display the next possible perfect squared number
num = input("Type in a positive whole number: ")
count = 0
square = 0
while square <= num:
count = count + 1
square = count*count
print square
Using Python 3 syntax:
Convert input to int and use a list comprehension like so:
num = int(input("Type in a positive whole number: "))
print([i*i for i in range(int(num**0.5) + 1)])
For my program I must enter a positive number, but if I enter a negative number I need the program to error with a message saying, "Please use a positive number and try again", then go back to the part where you input a number. It's stuck in a loop. Here's my code:
import math
# Receive the input number from the user
x = float(input("Enter a positive number: "))
#Initialize the tolerance and estimate
tolerance = 0.000001
estimate = 1.0
#Perform the successive approximations
while True:
estimate = (estimate + x / estimate) / 2
diference = abs(x - estimate ** 2)
if diference <= tolerance:
break
elif x < 0:
print("Please enter a positive number")
#Output the result
print("The program's estimate:", estimate)
print("Python's estimate: ", math.sqrt(x))
You can fix it by put your input() into while loop
import math
#Initialize the tolerance and estimate
tolerance = 0.000001
estimate = 1.0
while True:
# Receive the input number from the user
x = float(input("Enter a positive number: "))
estimate = (estimate + x / estimate) / 2
diference = abs(x - estimate ** 2)
if diference <= tolerance:
break
elif x < 0:
print("Please enter a positive number")
--snip--
The issue is that you need to re-request the user input inside of the while loop as others have already mentioned.
A more thorough version of this answer would also be to refactor the order of operations inside of the while loop. In the code you are running the math operations on x before you validate that it is greater than zero. If the math is known to fail without a positive integer you would have a bug in your code that could lead to an unhandled exception. Here is another version with switches the if statement so we check the input before doing anything else - which makes the program less likely to throw an exception based on the input.
import math
#Initialize the tolerance and estimate
tolerance = 0.000001
estimate = 1.0
#Perform the successive approximations
while True:
# Receive the input number from the user
x = float(input("Please enter a positive number:"))
if x <= tolerance:
print("Invalid input.")
continue
else:
estimate = (estimate + x / estimate) / 2
diference = abs(x - estimate ** 2)
break
#Output the result
print("The program's estimate:", estimate)
print("Python's estimate: ", math.sqrt(x))
elif x < 0:
print("Please enter a positive number")
# Receive the input number from the user
x = float(input("Enter a positive number: "))
add the 4th line in your code. it will work. you were not receiving the input again after the fail attempt.
I want to calculate the root of a number up to four decimal places without rendering and I use the following code but I can not print out the output without rendering the output.
import math
num = float(input('Enter a number: '))
num_sqrt = math.sqrt(num)
print('The square root of %0.4f is %0.4f'%(num ,num_sqrt))
For example, if the inputs are as follows:
1
2
3
19
The output should be as follows:
1.0000
1.4142
1.7320
4.3588
If you're printing only 4 decimals and you don't want the number rounded that means you want the decimals truncated and regular formatting methods don't provide facilities for that.
You can easily achieve that if you pre-process your number as:
def truncate_number(number, decimals):
factor = 10.0 ** decimals
return int(number * factor) / factor
num = float(input('Enter a number: '))
num_sqrt = num ** 0.5 # or math.sqrt(num) if that's what you prefer.
print("The square root of {:.4f} is {:.4f}".format(num, truncate_number(num_sqrt, 4)))
It essentially just multiplies the number with 10^number_of_decimals, truncates the decimals by converting it to an int and then divides it with the same multiplication factor - this, in effect, leaves only the decimals you're interested in.
You don't even nedd to use formatting directives after pre-processing your number as Python won't print trailing zeros so a simple print("The square root of {} is {}".format(num, truncate_number(num_sqrt, 4))) should suffice.
If you want all answers to have four decimal places, you can use .format as in...
import math
num = float(input('Enter a number: '))
num_sqrt = math.sqrt(num)
print('The square root of {} is {:0.4f}'.format(num, num_sqrt))
notice the {:0.4f} in the print statment
: introduces the format spec
0 enables sign-aware zero-padding for numeric types
.4 sets the precision to 4
f displays the number as a fixed-point number
I have made a simple function called "Approx" which multiplies two numbers together then divides them by two. When I use the function by itself it works great but it seems in the hunk of code I have it doesn't divide the number in half and I have no idea why. This is my code where is the error and how can I fix it?
import math
def Approx(low,high):
base = low * high
return base/2
root = float(input("What to approx the sqrt of : "))
vague = float(input("How off can it be? : "))
wrong = True
oroot = root
root = math.floor(float(root))
trunk = root + 1
step = 0
while wrong:
if Approx(root,trunk) > oroot - vague and Approx(root,trunk) < oroot:
print("Done. " + str(step) + " steps taken.")
else:
if Approx(root,trunk) > oroot:
temproot = root
root = Approx(root,trunk)
trunk = temproot
step += 1
print("Step " + str(step) + " finished. Approx is " + str(Approx(root,trunk)))
else:
temptrunk = trunk
trunk = Approx(root,trunk)
root = trunk
step += 1
print("Step " + str(step) + " finished. Approx is " + str(Approx(root,trunk)))
if step > 50:
print("More than fifty steps required.")
wrong = False
It looks to me that it definitely does divide by two, it is just that dividing by two doesn't undo multiplying two large numbers together. For example, say you wanted to find the square root of 10. trunk is set to 11. Approx(root, trunk) is 10 * 11 / 2 = 55. This is set to root and trunk becomes the old root, 10. Now you have 55 and 10 instead of 10 and 11. Repeat this a few times and you end up with inf. Look more into the method you're trying to implement (is it the Babylonian method?) and see where your program and the method differ. That is likely the source of your woes, and not a lack of division.
Your function works the way you describe it, however I don't understand how you use it in the rest of the code.
It seems like you are trying to approximate square roots using a variant of Newton's method, but it's hard to understand how you implement it. Some variables in your code are not used (what is temptrunk for ?), and it's hard to determine if it's intended or a mistake.
If it is indeed the newton method you'd like to implement, you'll want to have an approximation function that converges to the target value. In order to do that, you compute the arithmetic mean of a guess and your target value divided by this guess (new_guess = mean([old_guess, target/old_guess])). Once you have that, you just need to compare the difference between new_guess and target, and once it reaches a given threshold (in your code, vague), you can break of the loop.
There are multiple ways to improve other aspects of your code:
I'd advise against using a sentinel value for breaking out of the loop, break statements are more explicit.
You can directly make a loop have maximum number of steps, with :
for step in range(MAX_STEPS):
guess = ... # try to guess
if abs(target - guess) < delta:
break
else:
print("Maximum steps reached.")
The else block will only be called if break is not reached.