Home > Mobile >  Iteration starting at the wrong point (List index out of Range)
Iteration starting at the wrong point (List index out of Range)

Time:09-27

I am working on code that uses loops (currently for loop), utilizing Heron's method, to find an estimate of the square root, while also displaying the iteration and relative change.

Here is what I have so far:

# Problem 1.

def square_root_for(a, x0, max_iter = 10, tol=1e-14):  
    
    """ (number, integer, number) -> float

    Return an estimate of the square root of a number using the Heron's method.
        
    >>> square_root_for(5, 5)
    Iteration | Estimate         | Relative Change
    -------------------------------------------------
    1         | 3.00000000000000 | 0.4000000000000000
    2         | 2.33333333333333 | 0.2222222222222222
    3         | 2.23809523809524 | 0.0408163265306123
    4         | 2.23606889564336 | 0.0009053870529653
    5         | 2.23606797749998 | 0.0000004106060359
    6         | 2.23606797749979 | 0.0000000000000842
    7         | 2.23606797749979 | 0.0000000000000000
    2.23606797749979
    """
    
    x = [x0]
    x.append(a/x0)
  
    print('Iteration | Estimate         | Relative Change')
    print('-------------------------------------------------')
         
    
    for i in list(range(1,( max_iter   1),1)):
       #x[i 1] = (s1   x[i]) / 2
      
        change = (abs(x[i] - x[i-1]) / x[i-1])
        if change > tol:
            x.append(1/2 * (x[i]   (a / x[i])))
        print('{}         | {:.14f} | {:.16f}'.format(i, x[i], change))
        i = i   1
    
           
# Don't change or delete the 5 lines of code below.
a = 5
max_iter = 100
tol = 1e-15
x_final = square_root_for(a, a, max_iter, tol)
print('Final estimate using square_root_for is {0}'.format(x_final))

It mostly works, but my example displays as:

Iteration | Estimate         | Relative Change
-------------------------------------------------
1         | 1.00000000000000 | 0.8000000000000000
2         | 3.00000000000000 | 2.0000000000000000
3         | 2.33333333333333 | 0.2222222222222222
4         | 2.23809523809524 | 0.0408163265306123
5         | 2.23606889564336 | 0.0009053870529653
6         | 2.23606797749998 | 0.0000004106060359
7         | 2.23606797749979 | 0.0000000000000842
8         | 2.23606797749979 | 0.0000000000000000

This is incorrect. The first row's estimate and relative change should not be there, and instead it should be the second row's estimate and relative change corresponding to Iteration 1. There should also only be 7 iterations, but because of this problem there are 8.

The code returns the following error:

Traceback (most recent call last):

  File "C:\Users\agsmi\Desktop\st114\homework6.py", line 61, in <module>
    x_final = square_root_for(a, a, max_iter, tol)

  File "C:\Users\agsmi\Desktop\st114\homework6.py", line 50, in square_root_for
    change = (abs(x[i] - x[i-1]) / x[i-1])

IndexError: list index out of range

Overall my question is, how do I fix this and have my first iteration return what the second returned, so that then there are only 7 iterations instead of 8.

Thank you!

CodePudding user response:

Remove list() from for loop then test it.

for i in range(1,( max_iter   1),1):

Also delete i = i 1 in your for loop.

and change the if statement:

if change > tol:
    x.append(1/2 * (x[i]   (a / x[i])))
    print('{}         | {:.14f} | {:.16f}'.format(i, x[i], change))
else:
    break

CodePudding user response:


# Problem 1.

def square_root_for(a, x0, max_iter = 10, tol=1e-14):  
    
    """ (number, integer, number) -> float

    Return an estimate of the square root of a number using the Heron's method.
        
    >>> square_root_for(5, 5)
    Iteration | Estimate         | Relative Change
    -------------------------------------------------
    1         | 3.00000000000000 | 0.4000000000000000
    2         | 2.33333333333333 | 0.2222222222222222
    3         | 2.23809523809524 | 0.0408163265306123
    4         | 2.23606889564336 | 0.0009053870529653
    5         | 2.23606797749998 | 0.0000004106060359
    6         | 2.23606797749979 | 0.0000000000000842
    7         | 2.23606797749979 | 0.0000000000000000
    2.23606797749979
    """
    
    x = [x0]
    x.append(a/x0)
  
    print('Iteration | Estimate         | Relative Change')
    print('-------------------------------------------------')
         
    
    for i in range(1,max_iter):
       #x[i 1] = (s1   x[i]) / 2
        change = (abs(x[i] - x[i-1]) / x[i-1])
        if change > tol:
            x.append(1/2 * (x[i]   (a / x[i])))
        else:
            break
        print('{}         | {:.14f} | {:.16f}'.format(i, x[i], change))
    return(x[i])
# Don't change or delete the 5 lines of code below.
a = 5
max_iter = 100
tol = 1e-15
x_final = square_root_for(a, a, max_iter, tol)
print('Final estimate using square_root_for is {0}'.format(x_final))

I took out the i = i 1 line, simplified the range statement as mentioned by AAR, but the error you were getting was because it was looping and expecting to find an array value so you needed a break to escape from the for loop when the required precision is achieved. edit - you also need to return a value x[i] from the function.

Output

Iteration | Estimate         | Relative Change
-------------------------------------------------
1         | 1.00000000000000 | 0.8000000000000000
2         | 3.00000000000000 | 2.0000000000000000
3         | 2.33333333333333 | 0.2222222222222222
4         | 2.23809523809524 | 0.0408163265306123
5         | 2.23606889564336 | 0.0009053870529653
6         | 2.23606797749998 | 0.0000004106060359
7         | 2.23606797749979 | 0.0000000000000842
Final estimate using square_root_for is 2.23606797749979
  • Related