Search code examples
pythonloopswhile-loopminimum

Python 3.3, returning smallest value in a while loop


I'm trying to return the smallest value for the square root of k using Newton's method.

k=float(input("Number? "))
x = k/2

def newton(x):
    while abs(x**(1/2)- k) >= 10**(-10):
        if k >= 0:
            x = (x+k/x)/(2)
            return x
        elif k < 0:
            raise ValueError ("Cannot take the square root of a negative number")


print ("The approximate square root of", k, "is", newton(k))
print ("The error is", abs(x**(1/2)- k))

However, the above code only returns the first iteration. For example, if k is 2, the accurate square root by Newton's method should be 1.41422, which is the third iteration. However, the code is currently returning 1.5, the first iteration. How do I return the more accurate square root of 1.41422 instead of 1.5? Likewise, the error needs to reflect this change.


Solution

  • You need to place your return statement outside your loop, otherwise it will always return on the first iteration:

    def newton(x):
        while abs(x**(1/2)- k) >= 10**(-10):
            if k >= 0:
                x = (x+k/x)/(2)
            elif k < 0:
                raise ValueError ("Cannot take the square root of a negative number")
        return x
    

    Note that using variables from the global scope like that is a recipe for disaster, it's unclear and means you can't use your function as easily. Pass it as a parameter instead.

    It's also impossible for k to change inside the loop so you can do the check once at the beginning, rather than on every iteration:

    def newton(x, k):
        if k < 0:
                raise ValueError ("Cannot take the square root of a negative number")
        while abs(x ** (1 / 2) - k) >= 10 ** (-10):
            x = (x + k / x) / 2
        return x