dimanche 26 juin 2016

Receiving TypeError: object.__new__() takes no parameters when __new__ not changed

The following is an incomplete implementation for Conway's Game Of Life in Python 3.0 using Tkinter in PyCharm Community Edition.

The program consists of four files:

  • Cell.py : Contains a class for a Cell
  • Grid.py : Contains a class for a Game of Life Grid
  • Windows.py : Contains a class for the tkinter layout
  • main.py : Executes the script

Cell.py:

from random import randint
from tkinter import *

class Cell:
    def __init__(self, master, state=None):
        if state is None:
            state = randint(0,2)
        self.state = state
        self.next_state = state
        self.button = Button(master, width=2, height=1, bg = 'black' if self.state == 1 else 'white').pack(side=LEFT)

    def __del__(self):
        self.button.destroy()

    def set_next_state(self, neighbours):
        if self.state == 1:
            self.next_state = 0 if neighbours < 2 or neighbours > 3 else 1
        else:
            self.next_state = 1 if neighbours == 3 else 0

    def update(self):
        self.state = self.next_state
        self.button.config( bg = 'black' if self.state == 1 else 'white')

Grid.py:

from tkinter import *
from Cell import Cell

class Grid:
    def __init__(self, master, rows=15, cols=15, wraparound=True, pattern=None):
        self.master = master
        self.rows = rows
        self.cols = cols
        self.wraparound = wraparound

        if len(self.pattern) == rows*cols:  self.pattern = pattern
        else:  self.pattern = None

        self.create_frames()
        self.create_cells()

    def create_frames(self):
        self.frames = [Frame(self.master).pack(side=TOP) for r in range(self.rows)]

    def destroy_frames(self):
        for r in range(self.rows):
            self.frames[r].destroy()

    def create_cells(self):
        self.cells = {}
        for r in range(self.rows):
            for c in range(self.cols):
                if self.pattern is None:  self.cells[(r,c)] = Cell(self.frames[r])
                else:  self.cells[(r,c)] = Cell(self.frames[r], state=self.pattern[r*self.cols+c])

    def destroy_cells(self):
        for r in range(self.rows):
            for c in range(self.cols):
                del self.cells[(r,c)]

    def count_neighbours(self, r, c):
        offsets = [(i,j) for j in range(-1,2) for i in range(-1,2)]
        offsets.remove((0,0))
        neighbours = 0
        for offset in offsets:
            if self.wraparound:
                neighbours += self.cells[((r+offset[0])%self.rows, (c+offset[1])%self.cols)].state
            else:
                if r+offset[0] >= self.rows or r+offset[0] < 0 or c+offset[1] >= self.cols or c+offset[1] < 0:
                    neighbours += 0
                else:
                    neighbours += self.cells[(r+offset[0], c+offset[1])].state
        return neighbours

    def calculate_next_state(self):
        for r in range(self.rows):
            for c in range(self.cols):
                neighbours = self.count_neighbours(r,c)
                self.cells[(r,c)].set_next_state(neighbours)

    def update_cells(self):
        for r in range(self.rows):
            for c in range(self.cols):
                self.cells[(r,c)].update()

    def step(self):
        self.calculate_next_state()
        self.update_cells()

     def load_pattern(self, rows=10, cols=10, wraparound=True, pattern=None):
        self.destroy_cells()
        self.destroy_frames()

        self.rows = rows
        self.cols = cols
        self.wraparound = wraparound
        self.pattern = pattern

        self.create_frames()
        self.create_cells()

Windows.py:

from Grid import Grid
from tkinter import *

class MainWindow:
    def __init__(self, rows=10, cols=10, wraparound=True, pattern=None):
        self.root = Tk()

        grid_frame = Frame(self.root).pack(side=TOP)
        self.grid = Grid(grid_frame, rows=rows, cols=cols, wraparound=wraparound, pattern=pattern)

        button_frame = Frame(self.root).pack(side=BOTTOM)
        self.time_interval = 1000
        self.start_stop_button = Button(button_frame, text='START', command=self.start_stepper).pack(side=LEFT)
        self.step_button = Button(button_frame, text='STEP', command=self.grid.step)

        self.menubar = Menu(self.root)
        self.menubar.add_command(label='Change Time Interval', command=self.change_time_interval)
        self.root.config(menu=self.menubar)

        self.root.mainloop()

    def change_time_interval(self):
        # Incomplete
        pass

    def start_stepper(self):
        # Incomplete
        pass

    def stop_stepper(self):
        # Incomplete
        pass

main.py:

from Windows import MainWindow
game = MainWindow()

When I run main.py I get the following output:

Output:

Traceback (most recent call last):
  File "C:/Users/Tyler/PycharmProjects/GameOfLife/main.py", line 3, in <module>
    game = MainWindow()
  File "C:UsersTylerPycharmProjectsGameOfLifeWindows.py", line 9, in __init__
    self.grid = Grid(grid_frame, rows=rows, cols=cols, wraparound=wraparound, pattern=pattern)
TypeError: object.__new__() takes no parameters

I am at my wits end with this as I never overwrite the default __new__ method. After checking all of the other stack overflow questions of this type most solutions were correcting some form of spelling __init__ to __init__. I am relatively new to python scripting so any help to debug this with an explenation as to why the error is produced would be most appreciated.

Aucun commentaire:

Enregistrer un commentaire