Home > OS >  Why am I getting IndexError: index 20 is out of bounds for axis 0 with size 20?
Why am I getting IndexError: index 20 is out of bounds for axis 0 with size 20?

Time:05-16

import matplotlib.pyplot as plt

from matplotlib.pyplot import figure


import random

 

    
    
grid = np.array([

    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],

    [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],

    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

    [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],

    [1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],

    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])


class Worker():
    def __init__(self, name):
        while True:
            x = random.randint(2,18)
            y = random.randint(2,18)
            if grid[x,y] == 0:
                self.row = x
                self.col = y
                break
        self.name = name


    def move(self, workers):
        while True:
            self.row  = random.randint(-1,1)
            self.col  = random.randint(-1,1)
            if grid[self.col,self.row] == 0 and self.row != 20 and self.row != 0 and self.col != 20 and self.col != 0:
                self.row = self.row
                self.col = self.col
                break 
                
    def room_escape(self):
        
        room_door = [(3,6),(10,6),(16,6),(4,14),(10,14),(16,14)]

        if (self.col,self.row)==(3,6) or (self.col,self.row)==(10,6) or (self.col,self.row)==(16,6) or (self.col,self.row)==(4,14) or (self.col,self.row)==(10,14) or (self.col,self.row)==(16,14):
            distances2 = []
            building_door = [(0,10),(20,10)]
            for i in range(len(building_door)):
                distances2.append(sqrt((building_door[i][0]-self.col)**2 (building_door[i][1]-self.row)**2))
            m = distances2.index(min(distances2))
            if self.row < building_door[m][1]:
                self.row  = 1
            elif self.row > building_door[m][1]:
                self.row -= 1
            if self.col < building_door[m][0]:
                self.col  = 1
            elif self.col > building_door[m][0]:
                self.col -= 1
                
        
        elif self.row <= 6 or self.row >= 14:
            distances = []
            for i in range(len(room_door)):
                distances.append(sqrt((room_door[i][0]-self.col)**2 (room_door[i][1]-self.row)**2))
            n = distances.index(min(distances))
            if self.row < room_door[n][1]:
                self.row  = 1
            elif self.row > room_door[n][1]:
                self.row -= 1
            if self.col < room_door[n][0]:
                self.col  = 1
            elif self.col > room_door[n][0]:
                self.col -= 1
                
               
        elif self.row >= 6 or self.row <= 14:
            distances2 = []
            building_door = [(0,10),(20,10)]
            for i in range(len(building_door)):
                distances2.append(sqrt((building_door[i][0]-self.col)**2 (building_door[i][1]-self.row)**2))
            m = distances2.index(min(distances2))
            if self.row < building_door[m][1]:
                self.row  = 1
            elif self.row > building_door[m][1]:
                self.row -= 1
            if self.col < building_door[m][0]:
                self.col  = 1
            elif self.col > building_door[m][0]:
                self.col -= 1


from numpy import sqrt 

plt.pcolormesh(grid)
#plt.scatter(2,3,c="red")

MAXROWS = 20
MAXCOLS = 20


def plot_worker_scatter(workers):
    xlist = []
    ylist = []
    for k in range(len(workers)):
        xlist.append(workers[k].col)
        ylist.append(workers[k].row)
        plt.scatter(xlist,ylist,c="red")

def main():
    workerNames = ["1", "2","3","4","5","6","7","8","9","10"]
    numWorkers = 10
    workerList = []
    
    for i in range(numWorkers):
        workerList.append(Worker(workerNames[i]))
    
    for t in range(4):
        for i in range(numWorkers):
            workerList[i].move(workerList)
        print("Just a normal day")
        plt.pcolormesh(grid)
        plot_worker_scatter(workerList)
        plt.scatter(0,10,c="blue")
        plt.title("Normal Activity")
        plt.xlabel("Columns")
        plt.ylabel("Rows")
        plt.xlim(0,MAXCOLS)
        plt.ylim(0,MAXROWS)
        plt.show()
        
    for t in range(10):
        for i in range(numWorkers):
            workerList[i].room_escape()
        print("Run to Emergency exit! You have", 10 - t, "seconds")
        plt.pcolormesh(grid)
        plot_worker_scatter(workerList)
        plt.title("Building under Fire")
        plt.xlabel("Columns")
        plt.ylabel("Rows")
        plt.xlim(0,MAXCOLS)
        plt.ylim(0,MAXROWS)
        plt.show()
        
    for i in range(numWorkers):
        if (workerList[i].col,workerList[i].row) != (0,10) or (workerList[i].col,workerList[i].row) != (20,10):
            print("Sadly", workerList[i].name, "did not survive")
    for i in range(numWorkers):
        if (workerList[i].col,workerList[i].row) == (0,10):
            print(workerList[i].name, "survived")


if __name__ == "__main__":
    main()

It occurs when I use the move function. Sometimes it works but other times it comes up with the error. Happens when I excecute the move function. This is a program of a fire evacuation where workers run to the emergency excit. When I use move function it means they are doing their normal activity and is moving randomly around the building. They can move only 1 space at a time either up down left right or diagonally. So when I use this move function it comes up with this index error. I've tried so hard to fix it but it keeps happening at some point when I run the code. It only happens when I run the normal activity section of the code. However when I run the running to exit section it all works fine. Please help :(

CodePudding user response:

def move(self, workers):
    while True:
        self.row  = random.randint(-1,1)
        self.col  = random.randint(-1,1)
        # in the next line grid[self.col, self.row] isn't doing any bounds 
        # checking and is asking for index 20 when there is no index 20
        # to fix:
        # if self.col >= 20:
        #     self.col -= 1
        #     ... or something else
        if grid[self.col,self.row] == 0 and self.row != 20 and self.row != 0 and self.col != 20 and self.col != 0:
            self.row = self.row
            self.col = self.col
            break 
     

CodePudding user response:

I did not run the code, but it seems that you don't check if you're in array bounds when randomly changing the row and column indeces while running a loop.

Try:

def move(self, workers):
    while True:
        self.row  = random.randint(-1,1)
        self.col  = random.randint(-1,1)
        
        # check if we're still in array bounds
        # if not - adjust the values to be inside the bounds
        if self.row >= 20:
            self.row = 19
        elif self.row<0:
            self.row=0

        if self.col >= 20:
            self.col = 19
        elif self.col<0:
            self.col=0

        # i am not sure why do you check if row and column
        # are not zero or 20, so i didn't remove it.
        # in case it was meant to check if we are in bounds,
        # then you can safely remove it and leave only 
        # if grid[self.col,self.row]
        if grid[self.col,self.row] == 0 and self.row != 20 and self.row != 0 and self.col != 20 and self.col != 0:
            self.row = self.row
            self.col = self.col
            break 

Also note my comment before the last section

  • Related