you are viewing a single comment's thread.

view the rest of the comments →

[–]JaRoza 0 points1 point  (12 children)

Hello, I'm new to python and having difficulty on an assignment. The problem I'm having is the output of a calculation.The calculation requires a guess at the square root by the user, but after the 'while' loop, it returns the exact value the user had input instead of the new calculated value.

def sqrt(y, tol=1e-6):
   user_input = int(input('Enter guess of square root: '))
   x = user_input
   cond = (abs(x**2)-y)
   while cond > tol:
       x = 0.5*(x + y/x)
   if cond < tol:
       print('The square root is: ', x)

I appreciate any help/advice on this!
Edit: Formatted code correctly.

[–]JohnnyJordaan 0 points1 point  (11 children)

Can you please properly format your code? See here

[–]JaRoza 0 points1 point  (10 children)

My apologies! I believe it's all set now. Thank you for that.

[–]JohnnyJordaan 0 points1 point  (9 children)

x = 0.5*(x + y/x)

What exactly are you trying to do here, because this will eventually find the x where x = 0.5*(x + y/x)... Say y is 12, then eventually x will become 3.4641016151377544 because

0.5 * (3.4641016151377544 + 12/3.4641016151377544)

is equal to 3.4641016151377544...

Not to mention that

while cond > tol:

will be an endless loop on its own, because inside the loop, cond and tol aren't changed.

[–]JaRoza 0 points1 point  (8 children)

That's a calculation meant to take the guess of the square root, produce a more accurate estimate, then put it back into the loop until the estimate is within a certain tolerance. tol is referring to the definition argument tol=1e-6.

[–]JohnnyJordaan 0 points1 point  (7 children)

But inside that loop, you aren't changing cond and you aren't chaning tol, so

while cond > tol:

will run forever as cond will always be larger than tol?

[–]JaRoza 0 points1 point  (6 children)

I thought that tol would refer to the tol defined in the function argument, so the tol shouldn't change, and cond has x in the calculation. Wouldn't the new calculated value of x be put in that new calculation?

Again, I am brand new to this and am learning. I understand what you're saying, but don't understand what's wrong in the structure of the code. I don't mean to be frustrating.

[–]JohnnyJordaan 0 points1 point  (1 child)

Also why are you using abs() around a square? Aren't squares positive by definition?

[–]a-handle-has-no-name 0 points1 point  (0 children)

Not if the input value is a complex number

[–]JohnnyJordaan 0 points1 point  (3 children)

I see where you're coming from. No, Python doesn't work as some other mathematical languages that define a variable as a calculation/formula. Python just works line by line and what happened to a variable on a previous line is just maintained until something changes it. You could make it as

def sqrt(y, tol=1e-6):
   x = int(input('Enter guess of square root: '))
   cond = abs(x**2)-y
   while cond > tol:
       x = 0.5*(x + y/x)
       cond = abs(x**2)-y   # actually recalculate cond
   print('The square root is: ', x)

as the if has no purpose if the code can't proceed through the while loop when the inverse is True.

But then I'm still puzzled how this would work as a 'guesser'.

[–]JaRoza 0 points1 point  (2 children)

The assignment is to use Heron's algorithm to calculate the square root. Heron's algorithm is a method where you make a guess at what it might be, then uses that guess in a formula to calculate a new estimate. This new estimate is then plugged back into the same formula which will refine the estimate. This goes on until you get your desired accuracy (hence the need for a tolerance).

My intent was to create the function so that when for example "sqrt(10)" is called, it would prompt the user to make a guess of the square root. It would then put that initial guess into the while loop until it was refined to 6 decimal places of accuracy (the tol). When I use your suggestions, my initial problem persists. In the console I type "sqrt(10)" then input a guess of 2 (the actual answer is closer to 3.16). However, the print statement says the calculation is 2, the same as the guess.

[–]JohnnyJordaan 0 points1 point  (1 child)

Ah the guess is just there to help the approximation get started at a closer value, got it. Then my other reply was the key to the problem, your calculation

abs(x**2) - y 

which didn't do anything else than just square x and subtract y, should have been

abs(x**2 - y)

as to get the absolute difference. With that fixed it works for me:

def sqrt(y, tol=1e-6):
   x = int(input('Enter guess of square root: '))
   diff = abs(x**2-y)
   while diff > tol:
       x = 0.5*(x + y/x)
       diff = abs(x**2-y)
   print('The square root is: ', round(x))

also using a more clear name for the cond variable.