Attribute error: Object has no attribute Python
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
Related videos on Youtube
Chubzorz
Updated on April 04, 2020Comments
-
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 about 10 yearsLooks like you have lots of indentation problems, and correct indentation is critical in Python. Is that just an error in copying to SO?
-
Alok about 10 yearsI indented your question & after that if was working fine...
-
Barmar about 10 years@shaktimaan If his problem is with indentation, don't correct it in the question -- post it as an answer.
-
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 about 10 yearsThat 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 about 10 yearsokay,thanks sir..will keep that in mind :)
-
Chubzorz about 10 yearsAll of the indentation errors are just from copying to stack overflow and not from the actual program.
-
-
Chubzorz about 10 yearsAfter trying unindenting it I still recieved the same error.
'Cell" object has no attribute 'nextState'
. -
Blckknght about 10 years@Chubzorz: I've found the remaining issue and edited my answer.