Attribute error: Object has no attribute Python

26,309

The issue appears to be that your for row in cells loop is inside of your previous for x in range(0, self.sizex) loop. Here's what the step method should look like if you get it correctly indented:

def step (self):
    cells = self.cells
    for x in range (0,self.sizex):
        if x==0: x_down = self.sizex-1
        else: x_down = x-1
        if x==self.sizex-1: x_up = 0
        else: x_up = x+1
        for y in range(0,self.sizey):
            if y==0: y_down = self.sizey-1
            else: Y_down = y-1
            if y==self.sizey-1: y_up = 0
            else: y_up = y+1
            sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
            cells[x][y].setNextState(sum)
    for row in cells:                     # unindent these
        for cell in row:                  # lines by one
            cell.stepToNextState()        # level each

If all the indentation issues are taken care of (or were not in the original code), there's still an issue that may cause an issue in certain situations. The issue is that the Cell.setNextState method doesn't handle every situation. Specifically, it doesn't set nextState if a cell is alive and should stay so (it has two or three living neighbors). The lack of an else on your chain of if and elif statements should have raised this as a red flag for me, but I overlooked it the first time I examined the function.

Here's how it can be fixed:

def setNextState (self , Neighbours):
    if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
        self.nextState = Cell.Dead
    elif self.state == Cell.Dead and Neighbours == 3:
        self.nextState = Cell.Live
    else: # remove the conditions on this block, all the state changes were handled above
        self.nextState = self.state
Share:
26,309

Related videos on Youtube

Chubzorz
Author by

Chubzorz

Updated on April 04, 2020

Comments

  • Chubzorz
    Chubzorz about 4 years

    I am trying to program a version of conway's game of life however I keep getting the message 'Cell' Object Has no attribute 'nextState' when it seems like it should declare the value of nextState before asking to reference it. here is my code:

    from tkinter import *
    root = Tk()
    
    class Cell (Button):
        Dead = 0
        Live = 1
    
        def __init__ (self,parent):
            Button.__init__(self,parent, relief = "raised" , width = 2 , borderwidth = 1 , command = self.onpress)
            self.displayState(Cell.Dead)
    
        def onpress (self):
            if self.state == Cell.Live:
                self.displayState(Cell.Dead)
            elif self.state == Cell.Dead:
                self.displayState(Cell.Live)
    
        def setNextState (self , Neighbours):
            if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
                self.nextState = Cell.Dead
            elif self.state == Cell.Dead and Neighbours == 3:
                self.nextState = Cell.Live
            elif self.state == Cell.Dead and Neighbours != 3:
                self.nextState = self.state
    
        def stepToNextState(self):
            self.displayState(self.nextState)
    
        def displayState (self , newstate):
            self.state = newstate
            if self.state == Cell.Live:
                self["bg"] = "black"
            if self.state == Cell.Dead:
                self["bg"] = "white"
    
    class Grid:
        def __init__(self,parent,sizex,sizey):
            self.sizex = sizex
            self.sizey = sizey
            self.cells = []
            for a in range (0,self.sizex):
                rowcells = []
                for b in range (0, self.sizey):
                    c = Cell(parent)
                    c.grid(row=b , column=a)
                    rowcells.append(c)
                self.cells.append(rowcells)
    
        def step (self):
            cells = self.cells
            for x in range (0,self.sizex):
                if x==0: x_down = self.sizex-1
                else: x_down = x-1
                if x==self.sizex-1: x_up = 0
                else: x_up = x+1
                for y in range(0,self.sizey):
                    if y==0: y_down = self.sizey-1
                    else: Y_down = y-1
                    if y==self.sizey-1: y_up = 0
                    else: y_up = y+1
                    sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
                    cells[x][y].setNextState(sum)
                for row in cells:
                    for cell in row:
                        cell.stepToNextState()
    
        def clear(self):
            for row in self.cells:
                for cell in row:
                    cell.displayState(Cell.Dead)
    
    if __name__ == "__main__":
        frame = Frame(root)
        frame.pack()
        grid = Grid(frame,25,25)
        bottomFrame = Frame(root)
        bottomFrame.pack (side = BOTTOM)
        buttonStep = Button(bottomFrame , text="Step" , command=grid.step)
        buttonStep.pack(side = LEFT)
        buttonClear = Button(bottomFrame, text = "Clear", command=grid.clear)
        buttonClear.pack(side=LEFT , after=buttonStep)
        root.mainloop()
    

    The error message is:

    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
        return self.func(*args)
      File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 65, in step
        cell.stepToNextState()
      File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 27, in stepToNextState
        self.displayState(self.nextState)
    AttributeError: 'Cell' object has no attribute 'nextState'
    

    If anyone could point out where the error is occuring / what is causing it and possibly a way to fix it I would be very grateful.

    • Barmar
      Barmar about 10 years
      Looks like you have lots of indentation problems, and correct indentation is critical in Python. Is that just an error in copying to SO?
    • Alok
      Alok about 10 years
      I indented your question & after that if was working fine...
    • Barmar
      Barmar about 10 years
      @shaktimaan If his problem is with indentation, don't correct it in the question -- post it as an answer.
    • Alok
      Alok about 10 years
      @Barmar: I just indented the question for other people to understand & help solve the issue,after that i ran it & voila...didn't knew it was the only issue
    • Barmar
      Barmar about 10 years
      That was the point of my question in the first comment. It's important to know whether his actual code is indented correctly or not. In the case of Python, indentation isn't just a readability issue, it affects whether the code is correct or not.
    • Alok
      Alok about 10 years
      okay,thanks sir..will keep that in mind :)
    • Chubzorz
      Chubzorz about 10 years
      All of the indentation errors are just from copying to stack overflow and not from the actual program.
  • Chubzorz
    Chubzorz about 10 years
    After trying unindenting it I still recieved the same error. 'Cell" object has no attribute 'nextState'.
  • Blckknght
    Blckknght about 10 years
    @Chubzorz: I've found the remaining issue and edited my answer.