Question

I have read in a matrix of numbers and I am trying to work with each cell and perform tests on each one. If the number is != 0 I want to use it so if it is 0 I am currently incrementing x and y to find a non zero number.

In the end I will just be first looking across the top row and then if they are all 0 start looking down the first column and this works fine as long as I am referring to just one (row or column).

Why am I receiving this error? Am I thinking incorrectly about how the cells are set up or is my code wrong?

The matrix looks like this:

0,2,4,1,6,0,0
2,0,0,0,5,0,0
4,0,0,0,0,5,0
1,0,0,0,1,1,0
6,5,0,1,0,5,5
0,0,5,1,5,0,0
0,0,0,0,5,0,0

When I start trying to do this:

y = y + 5
x = x + 5
node = Alist[x][y]

I receieve an error saying:

node = Alist[x][y]
IndexError: list index out of range

If I was to just write:

y = y + 5
node = Alist[x][y]
print node

It would work completely fine but when I introduce both x and y I start to get list index out of range problems. In my mind it should now read:

node = Alist[5][5] 

Which is 0 if you follow the matrix

def create_matrix(file):
    with open('network.txt') as f:
        Alist = []
        for line in f:
            part = []
            for x in line.split(','):
                part.append(int(x))
            Alist.append(part)
    return Alist

#used to set the start node, used once          
def start_node(Alist):
        x=0
        y=0
        #point node to pos [0][0] of Alist
        node = Alist[x][y]
        #test if node == 0
        while node == 0:
                y = y + 5
                x = x + 5
                node = Alist[x][y]
        #create a list to hold co-ordinates
        if node != 0:
                #return node for processing by check_neighbours
                return node, x, y

#def current_node(Alist, x, y)

#test neighbours to see if they can be used
def check_neighbours(node, Alist, i, j):
        #print out values of x and y
        print "x = %d" %i
        print "y = %d" % j
        print "node in check_neighbours is " + str(node)


#running of code begins here
def main():
        file = ("F:/media/KINGSTON/Networking/network.txt")
        Alist = create_matrix(file)
        node, x, y = start_node(Alist)
        check_neighbours(node, Alist, x, y)
main()
Was it helpful?

Solution

It's the second iteration round the loop that's failing, because it sets x and y to 10, where you only have 7 items in each dimension.

Your loop while node == 0: moves down the diagonal of the matrix five steps at a time, falling off the end. It would fall off the end even if it went one at a time, because that diagonal is all zeros.

Perhaps you meant if node == 0?

I don't know what the code is actually trying to do, but you need to rethink the algorithm. :-)

OTHER TIPS

If I follow your code in start_node you are

a) Not performing any kind of bounds checking

and

b) Jumping down the diagonal elements of your matrix, which are all zero, until you go out of bounds, as your error tells you. Presumably when you are incrementing only one of your indices you are lucky in that you hit a non-zero element before going out of bounds

In this code, start_node returns the first non-zero "node".
I used mat instead of Alist as I feel it is more Pythonic.
Comments note the changes and tips.

def create_matrix(fname): # don't use built-ins as variable names!!
    with open(fname) as f: # you take filename in arguments, but don't use it..
        # why not use in-built functions and list comprehensions ?
        mat = [map(int,line.split(',')) for line in f]
    return mat

#used to set the start node, used once          
def start_node(mat):
    # for each row in matrix (index)..
    for i1 in range(len(mat)):
        # for each cell in row (index)..
        for i2 in range(len(mat[i1])):
            # mat[i1][i2] is the node/cell..
            if mat[i1][i2] != 0:
                # return node, x, y :)
                return mat[i1][i2], i2, i1

# test neighbours to see if they can be used
# same as yours
def check_neighbours(node, Alist, i, j):
    #print out values of x and y
    print "x = %d" % (i,)
    print "y = %d" % (j,)
    print "node (in check_neighbours) is " + str(node)


#running of code begins here
def main():
    fname = "F:/media/KINGSTON/Networking/network.txt"
    mat = create_matrix(fname)
    node, x, y = start_node(mat)
    check_neighbours(node, mat, x, y)
main()

A difference highlighter


Explanation:

  1. mat = [map(int,line.split(',')) for line in f]
    This is a list comprehension. map is an in-built method.
  2. The for loops in start_node...

    for i1 in range(len(mat)):         # 1
        for i2 in range(len(mat[i1])): # 2
    
    1. len(mat) is the number of rows in your matrix.
      range(len(mat)) gives us the indexes of each row.
    2. len(mat[i1]) gives us the length of the current row.
      range(len(mat[i1])) gives us the indexes of each column in that row.

    In your code, you were incrementing both x and y (here i2 and i1 respectively) so were moving diagonally.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top