Newton's method for approximating square roots - python

I'm trying to program a function to compute Newton's method. Expect I keep getting an error in my code.
This is the prompt that I was given to write a code for
And this is my code that I have written down
import math
def newton(x):
tolerance = 0.000001
estimate = 1.0
while True:
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference <= tolerance:
break
return estimate
def main():
while True:
x = input("Enter a positive number or enter/return to quit: ")
if x == '':
break
x = float(x)
print("The program's estimate is", newton(x))
print("Python's estimate is ", math.sqrt(x))
main()
And it seems to be working but I keep getting this error when I run checks on Cengage
I'm not really sure what it means because my code seems to be running just fine. Can anyone help explain this?

The issue seems to occur when the input is blank. A potential workaround, assuming you would only want positive numbers as input, would be to set a negative number (or anything else of your choice), like -1 for example, as an exit condition:
x = input("Enter a positive number or enter/return to quit: ")
if not x:
break
x = float(x)
This should avoid the EOFError.
Edit
If you want to use a blank input (hitting the return line) to break out of the loop, you can try this alternative syntax:
x = input("Enter a positive number or enter/return to quit: ")
if not x:
break
x = float(x)
The not x checks if x is blank. It is also more pythonic than x == "". Additional methods to detect a blank input are in this post as well: How do you get Python to detect for no input.

I did mine like this and Cengage accepted it.
import math
tolerance = 0.000001
def newton(x):
estimate = 1.0
while True:
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference <= tolerance:
break
return estimate
def main():
while True:
x = input("Enter a positive number or enter/return to quit: ")
if x == "":
break
x = float(x)
print("The program's estimate is", newton(x))
print("Python's estimate is ", math.sqrt(x))
if __name__ == "__main__":
main()

Related

Wrong Answer in Google Kickstart Practice Round 2019 Question 1 (Number Guessing)

So I am still learning to code and use python as my primary language. The question is we have two numbers. A and B which we have to take as input. A will be 0 and B is given in two test cases as 30 and 10^9. The system will pick a number (say P) between A(exclusive) and B(inclusive). We have to write a program to guess the number. If our guess is higher than P, the system will output "TOO_BIG" and we have to adjust our next guess. If our guess is lower than P, then we'll get "TOO_SMALL". If it's right, then we'll get "CORRECT". We have N tries to guess the number and N = 30.
This is my code:
import sys
def solve(lower,upper):
guessed_right = False
for _ in range(no_of_guesses):
midpoint = (lower + upper)//2
guess = midpoint
print(guess)
sys.stdout.flush()
judge = input()
if judge == "CORRECT":
guessed_right = True
break
elif judge == "TOO_BIG":
upper = midpoint - 1
elif judge == "TOO_SMALL":
lower = midpoint + 1
elif judge == "WRONG_ANSWER":
sys.exit()
def run():
T = int(input())
for case in range(T):
lower, upper = map(int(input().split()))
no_of_guesses = int(input())
solve(lower + 1, upper)
I am getting wrong answer for this and can't seem to find the problem

I have this while loop : while x == False or y != 10: , but when the Y turn to 10 it keeps to run the loop

I have this code but when the Y turns to 10 it keeps to run the loop, WHY?
I'm a very beginner in python so pls don't think I'm stupid or something :)
def destiny_calculator():
mass = str(input("enter the mass of your material (it could be in gram, milligram, kilogram or ton "))
if mass.isdigit() == False:
try:
float(mass)
except Exception:
x = False
y = 0
while x == False or y != 10:
print("Please enter JUST a number")
mass = str(input("enter the mass of your material (it could be in gram, milligram, kilogram or ton - "))
y = y + 1
print (y)
if y == int(10):
print("Too many errors")
exit()
else:
pass
else:
pass
Since you use or the code only checks to see if one of the conditions is satisfied. Therefore, as long as x == False is true, the code will run. If you want the code to end when y == 10, then you should use the and operator instead. This will only run the code if both conditions are true and as soon as one becomes false (e.g. y == 10) the code will not run.

Calculating when the amount will be doubled using while loop

This is a simple exercise found in a book, which asks us to determine how long it takes for an amount to double at a given interest rate. My code is like this:
def main():
x = eval(raw_input("Initial Principal: "))
y = eval(raw_input("Interest rate: "))
count = 0
while x < 2*x:
x = x * (1 + y)
count = count + 1
print (x)
print (count)
main()
What it returns is:
Initial Principal: 1000
Interest rate: 0.5
inf
1734
What's wrong with my code?
Also I wonder if the above code would work if my amount and interest is small, e.g. amount = 1 and interest rate = 0.05, since there would include some floating point arithmetic I guess.
Thank you!
The culprit is the fact that you write:
while x < 2*x:
Since x > 0, that relation will always be False, you do not compare the new x with the old x, you compare the new x with twice the new x.
We can solve this effectively by using a variable x0 that store the initial amount:
def main():
x = x0 = eval(raw_input("Initial Principal: "))
y = eval(raw_input("Interest rate: "))
count = 0
while x < 2*x0:
x = x * (1 + y)
count = count + 1
print (x)
print (count)
main()
But there are still some problems with the code. For example you use eval. Do not use eval unless you absolutely have to: now a person can enter any type of Python code, also code that will break the system. Use float(..) instead to convert a string to an int:
def main():
x = x0 = float(raw_input("Initial Principal: "))
y = float(raw_input("Interest rate: "))
count = 0
while x < 2*x0:
x = x * (1 + y)
count = count + 1
print (x)
print (count)
main()
But now the code is still inefficient. There exists a fast way to calcuate the number of years using logarithms:
from math import log, ceil, pow
def main():
x = x0 = float(raw_input("Initial Principal: "))
y = float(raw_input("Interest rate: "))
count = ceil(log(2.0, y+1.0))
newx = x * pow(1.0+y, count)
print (newx)
print (count)
The problem is your while guard, which checks if the number is less than two times itself. To solve this, save the threshold you want to reach in a variable before the loop, and you have done:
threshold = 2 * x
count = 0
while x < threshold:
x = x * (1 + y)
count = count + 1

Program to find cuberoot of a number [duplicate]

This question already has answers here:
How to find cube root using Python? [duplicate]
(3 answers)
Closed 5 years ago.
So I'm a complete beginner (like less than a week) and wrote this code in python. It's supposed to find the cuberoot of a number if the solution is an integer, and approximate it otherwise. It does both instead of just one or the other. I've tried it multiple ways for hours now but it doesn't work. Any suggestions?
cube=int(input("what number's cube root do you want to find"))
epsilon = 0.01
increment = 0.0001
num_guesses = 0
for guess in range(cube+1):
if guess**3 == cube:
guess += 1
print (guess)
else:
guess1 = 0.0
while abs(guess1**3 - cube) >= epsilon:
guess1 += increment
num_guesses += 1
print('num_guesses =', num_guesses)
else:
print(guess1)
The problem is your indentation. Everything in your "else" statement needs to be indented to show that it is inside the "else" statement. You also have a few logical errors in your code. If you have found a number that, when cubed, is the desired number, you should print that number, not that number plus 1. And if you've found the solution, your program should stop there.
for guess in range(cube+1):
if guess**3 == cube:
print (guess)
return
guess1 = 0.0
Here is the working solution:
cube=int(input("what number's cube root do you want to find: "))
epsilon = 0.01
increment = 0.0001
num_guesses = 0
int_result_found = False
for guess in range(cube+1):
if guess**3 == cube:
print guess
int_result_found = True
break
if not int_result_found:
guess1 = 0.0
while abs(guess1**3 - cube) >= epsilon:
guess1 += increment
num_guesses += 1
#print 'num_guesses =', num_guesses
print(guess1)
As Erik said, there were some errors in your code. Key point is to stop after you've found integer solution, I've used boolean flag int_result_found for that.
One of the problems with you code is indenting. Python requires specific spacing in order to work properly.
The easiest way to avoid getting both answers is to create a boolean variable (I used "found_answer") to check if it is necessary to run the second code.
I've fixed you code, modifying it as little as possible:
cube=int(input("what number's cube root do you want to find"))
found_answer = False
for guess in range(cube+1):
if guess**3 == cube:
print ("integer answer:", guess)
found_answer = True
if found_answer == False:
epsilon = 0.01
increment = 0.0001
num_guesses = 0
guess1 = 0.0
while abs(guess1**3 - cube) >= epsilon:
guess1 += increment
num_guesses += 1
print('num_guesses =', num_guesses)
print("approximate answer:", guess1)
For your interest, here is a much more efficient solver:
# target function: y = x**3
def cube(x):
return x * x * x
def diff(f, epsilon = 0.001):
"""
Given function f, return a numeric approximation function for f'(x)
"""
def df(x):
return (f(x + epsilon) - f(x)) / epsilon
return df
def newton_solver(target_y, f, df = None, start_x = None, epsilon = 0.001, max_reps = 40):
"""
Newton Raphson approximation
Given real target_y and function f,
return real x such that f(x) = target_y +/- epsilon
"""
# if no differential function is provided, use a numeric approximation
if df is None:
df = diff(f)
# if no starting point is given, guess f(x) ='= x
if start_x is None:
x = target_y
else:
x = start_x
for _ in range(max_reps):
y = f(x)
err = y - target_y
if abs(err) < epsilon:
# close enough
return x
else:
# project the tangent to find a closer approximation
x -= err / (df(x) or epsilon)
# no answer found, bail out
raise ValueError("max_reps exceeded, no solution found")
def main():
y = int(input("What integer do you want to find the cube root of? "))
# find x such that y == x**3
approx_x = newton_solver(y, cube)
# round to the nearest integer
int_x = round(approx_x)
if cube(int_x) == y:
print("The exact cube root of {} is {}.".format(y, int_x))
else:
print("The cube root of {} is approximately {}.".format(y, approx_x))
if __name__ == "__main__":
main()
when it comes to "guess**3 == cube", I think you need to "break"
try this:
cube=int(input("what number's cube root do you want to find"))
epsilon = 0.01
increment = 0.0001
for i in range(cube + 1):
if i**3 == cube:
# break the loop
break
elif (i+1)**3 > cube > i**3: # this is to reduce unnecessary calculations
while (abs(i**3 - cube) >= epsilon):
i += increment
break
print(i)
and I'd like to make it a func:
cube=int(input("what number's cube root do you want to find"))
epsilon = 0.01
increment = 0.0001
def cuberoot(cube):
for i in range(cube + 1):
if i**3 == cube:
break
elif (i+1)**3 > cube > i**3:
while (abs(i**3 - cube) >= epsilon):
i += increment
break
return i
print(cuberoot(cube))
and what is more easy:
def cuberoot(cube):
return cube**(1/3)

Factorial calculation using Python

I am new to Python and currently reading Python 3 for absolute beginner and face following problem.
I would like to calculate factorial with procedure.
request user to input an non negative number n
then use for loop to calculate factorial
and the code is like that:
N = input("Please input factorial you would like to calculate: ")
ans = 1
for i in range(1,N+1,1):
ans = ans*i
print(ans)
while i would like to add a feature to check whether input number N is non-negative number. like:
if N != int(N) and N < 0:
I want the user to input N again if it is NOT non-negative number.
Thanks for your gentle help.
The construct could look like this:
while True:
N = input("Please input factorial you would like to calculate: ")
try: # try to ...
N = int(N) # convert it to an integer.
except ValueError: # If that didn't succeed...
print("Invalid input: not an integer.")
continue # retry by restarting the while loop.
if N > 0: # valid input
break # then leave the while loop.
# If we are here, we are about to re-enter the while loop.
print("Invalid input: not positive.")
In Python 3, input() returns a string. You have to convert it to a number in all cases. Your N != int(N) thus makes no sense, as you cannot compare a string with an int.
Instead, try to convert it to an int directly, and if that doesn't work, let the user enter again. That rejects floating point numbers as well as everything else which is not valid as an integer.
In Python's math library, there is a factorial function. You can use it like so:
import math
...
ans = math.factorial(N)
Since you want to calculate using a loop however, have you considered the following?
ans = -1
while ans < 0:
N = input("Please enter a positive integer: ")
if N.isdigit() == True:
n = int(N)
if n >= 0:
ans = n
for x in range (n-1, 1, -1):
ans *= x
print (ans)
Note, the second solution doesn't work for N = 0, where ans = 1 is correct by definition of factorial.
Number = int(input("Enter the number to calculate the factorial: "))
factorial = 1
for i in range(1,Number+1):
factorial = i*factorial
print("Factorial of ",Number," is : ", factorial)
def factorial(a):
if a == 1:
return 1
else:
return a * factorial(a - 1)
print('factorial of number', factorial(5))
Start
Declare Integer n,i,n!
Display “Enter a nonnegative integer.”
Input n
For i=1 to n-1 Step1,
Display “n!=i*n”
End for
Stop
You can check math module for python.
# math.factorial(x)
Return x factorial.
Raises ValueError if x is not integral or is negative.

Categories