TypeError:list indices必须是整数或切片,而不是Coordinate

时间:2016-12-13 04:31:08

标签: python list class matrix

尝试通过用户输入的坐标时遇到此错误。我该怎么做才能修复该行中的错误。

line_cell = self.grid [users_coords.row] [users_coords.col]

import random
import time

class Coordinate:
    '''
    '''
    def __init__(self, row, col):
        ''' 

        '''
        self.row = row 
        self.col = col

    def __str__(self):
        '''

        '''
        return "(%d, %d)" %(self.row, self.col)

class Cell:
    '''

    '''

    def __init__(self, row, col):
        '''

        '''
        self.row = row
        self.col = col
        self.coords = Coordinate(row, col)
        self.fish = ""
        self.contains_line = False

    def __str__(self):
        '''
        '''

        if self.fish:
            if self.contains_line:
                result = 'F*'
            else:
                result = 'F'
        else:
            if self.contains_line:
                result = '*'
            else:
                result = ' '

        return result


class CarpetSea:
    '''

    '''

    fish_caught = 0 
    def __init__(self, N):
        '''

        '''

        self.N = N
        self.grid = []
        for i in range(self.N):
            row = []
            for j in range(self.N):
                cell = Cell(i, j)
                row.append(cell)
            self.grid.append(row)


        self.available_fish = ["Salmon", "Marlin", "Tuna", "Halibut"]


    def __str__(self):
        '''
        returns a string representation of a CarpetSea, i.e. display the organized contents of each cell. 
        Rows and columns should be labeled with indices.

        Example (see "Example Run" in the PA8 specs for more):
          0  1  
        --------
        0|M |  |
        --------
        1|  |* |
        --------

        Note: call Cell's __str__() to get a string representation of each Cell in grid
        i.e. "M " for Cell at (0,0) in the example above
        '''        

        return 


    def randomly_place_fish(self):
        '''
        randomly selects coordinates of a cell and randomly selects a fish from the available_fish list attribute. 
        Marks the cell as containing the fish.
        '''

        cell = random.choice(random.choice(self.grid))
        cell.fish = random.choice(self.available_fish)
        fish_name = cell.fish[0]
        return(fish_name)


    def drop_fishing_line(self, users_coords):
        '''
        accepts the location of the user's fishing line (a Coordinate object). 
        Marks the cell as containing the line.
        '''        
        users_coords = Cell(users_coords, users_coords)

        line_cell = self.grid[users_coords.row][users_coords.col]


        line_cell.contains_line = True

    def main():

    '''

    '''
    print("Welcome to Dilbert's Carpet Fishing Game!")
    print("To play, you will cast your fishing line into a location in Carpet Sea")
    print("After a certain amount of time, you will reel in your line adn find out if you caught a fish!")
    print("You can keep re-casting and re-reeling until you want to quit")

    print("\n")

    #user_row = str(input("Please enter a row: "))
    #user_col = str(input("Please enter a column: "))
    user_row = 2
    user_col = 2
    while True:
        user_coords = Coordinate(user_row, user_col)
        info = CarpetSea(2)
        game = GameStats()

        info.randomly_place_fish()
        info.drop_fishing_line(user_coords)
        #print(info)
        game.total_time_passed()
        info.check_fish_caught()

        info.display()

        answer = str(input("Please enter 'y' to continue or 'n' to end: "))

        if answer == "n":
            break


    gameinfo = GameStats()
    print(gameinfo)


main()

学习课程还是一个新手。对不起,如果有很多多余的代码,我切断了一些定义,但是离开了我的主要功能,这样你就可以看到发生了什么。我现在有一些硬编码的参数,只是为了节省一些时间在路上,我正在调试。

当前 str 功能

    def __str__(self):
    '''
    returns a string representation of a CarpetSea, i.e. display the organized contents of each cell. 
    Rows and columns should be labeled with indices.

    Example (see "Example Run" in the PA8 specs for more):
      0  1  
    --------
    0|M |  |
    --------
    1|  |* |
    --------

    Note: call Cell's __str__() to get a string representation of each Cell in grid
    i.e. "M " for Cell at (0,0) in the example above
    '''        

    str1 = '   ' + ' '.join([str1(i) for i in range(len(self.grid[0]))]) + '\n'
    for i, el in enumerate(self.grid):
        str1 += '{0}  '.format(i)
        for e in el:
            str1 += '{0} '.format(e)
        str1 += '\n'
    return(str1)

这就是错误

        str1 = '   ' + ' '.join([str1(i) for i in range(len(self.grid[0]))]) + '\n'
NameError: free variable 'str1' referenced before assignment in enclosing scope






import random
import time

class Coordinate:
    '''
    '''
    def __init__(self, row, col):
        ''' 

        '''
        self.row = row 
        self.col = col

    def __str__(self):
        '''

        '''
        return "(%d, %d)" %(self.row, self.col)

class Cell:
    '''

    '''

    def __init__(self, row, col):
        '''

        '''
        self.row = row
        self.col = col
        self.coords = Coordinate(row, col)
        self.fish = ""
        self.contains_line = False

    def __str__(self):
        '''
        '''

        if self.fish:
            if self.contains_line:
                result = 'F*'
            else:
                result = 'F'
        else:
            if self.contains_line:
                result = '*'
            else:
                result = ' '

        return result


class CarpetSea:
    '''

    '''

    fish_caught = 0 
    def __init__(self, N):
        '''

        '''

        self.N = N
        self.grid = []
        for i in range(self.N):
            row = []
            for j in range(self.N):
                cell = Cell(i, j)
                row.append(cell)
            self.grid.append(row)


        self.available_fish = ["Salmon", "Marlin", "Tuna", "Halibut"]


    def __str__(self):
        '''
        returns a string representation of a CarpetSea, i.e. display the organized contents of each cell. 
        Rows and columns should be labeled with indices.

        Example (see "Example Run" in the PA8 specs for more):
          0  1  
        --------
        0|M |  |
        --------
        1|  |* |
        --------

        Note: call Cell's __str__() to get a string representation of each Cell in grid
        i.e. "M " for Cell at (0,0) in the example above
        '''        

        str1 = '  | ' + ' | '.join([str(i) for i in range(len(self.grid[0]))]) + ' |\n'
        str1 += '-' * 12 + '\n'
        for i, k in enumerate(self.grid):
            str1 += ' {0}| '.format(i)
            for j in k:
                str1 += '{0} | '.format(j)
            str1 += '\n'
            str1 += '-' * 12 + '\n'
        return(str1)


    def randomly_place_fish(self):
        '''
        randomly selects coordinates of a cell and randomly selects a fish from the available_fish list attribute. 
        Marks the cell as containing the fish.
        '''

        cell = random.choice(random.choice(self.grid))
        cell.fish = random.choice(self.available_fish)
        #fish_name = cell.fish[0]

        return cell.fish


    def drop_fishing_line(self, users_coords):
        '''
        accepts the location of the user's fishing line (a Coordinate object). 
        Marks the cell as containing the line.
        '''        

        line_cell = self.grid[users_coords.row][users_coords.col]


        line_cell = Cell.contains_line == True

        print(line_cell)


    def check_fish_caught(self, fish, lineb, linec):
        '''
        If the cell containing the fishing line also contains a fish, returns the fish. 
        Otherwise, return False.

        '''

        if str(self.grid) == "F":
            print("The fish was caught!")
            print("\n")

        else:
            print("The fish was not caught!")
            print("\n")

class GameStats:
    hour = 0
    fish = CarpetSea.fish_caught
    fish = 0
    def __init__(self):
        self.time = time

    def __str__(self):
        average = CarpetSea.fish_caught / GameStats.hour
        return "Total amount of hours played: %d \nTotal amound of fish caught: %d\nOn aveage you caught %.2f fish her hour"%(self.hour, CarpetSea.fish_caught, average)        

    def total_time_passed(self):
        '''
        calcuate the total time played in the game 
        '''
        print("One hour has passed...")
        self.time = time.sleep(1)
        GameStats.hour += 1

    def Total_num_of_fish():
        '''
        seeing the total number of fish caught
        '''
        if str(CarpetSea.grid) == "F*":
            GameStats.fish += 1 

    def Average_amount_of_fish(self):
        '''
        average amount of fish caught in the time played
        '''
        self.average_fish = self.fish / self.hour


def instructions():
    '''
    game instructions
    '''
    print("Welcome to Dilbert's Carpet Fishing Game!")
    print("To play, you will cast your fishing line into a location in Carpet Sea")
    print("After a certain amount of time, you will reel in your line adn find out if you caught a fish!")
    print("You can keep re-casting and re-reeling until you want to quit")
    print("The Carpet Sea is a 2x2 grid, so please choose your row and column accordingly")
    print("\n")

def get_user_row():
    '''
    user row
    '''
    row = int(input("Please enter a row: "))

    return row

def get_user_col():
    '''
    user col
    '''
    col = int(input("Please enter a column: "))

    return col


def main():

    '''

    '''
    instructions()


    N = 2


    while True:

        row = get_user_row()
        col = get_user_col()

        user_coords = Coordinate(row, col)
        info = CarpetSea(N)
        game = GameStats()

        rando_fish = info.randomly_place_fish()
        user_line = info.drop_fishing_line(user_coords)


        game.total_time_passed()
        print(info)

        info.check_fish_caught(rando_fish, user_line, user_line)


        answer = str(input("Please enter 'y' to continue or 'n' to end: "))

        if answer == "n":
            break


    gameinfo = GameStats()
    print(gameinfo)


main()

1 个答案:

答案 0 :(得分:0)

似乎在此代码中:

def drop_fishing_line(self, users_coords):
    users_coords = Cell(users_coords, users_coords)
    line_cell = self.grid[users_coords.row][users_coords.col]

users_coords = Cell(users_coords, users_coords)过剩。

试试这个:

def drop_fishing_line(self, users_coords):
    line_cell = self.grid[users_coords.row][users_coords.col]

这里发生的事情users_coords = Cell(users_coords, users_coords)是你定义Cell的新实例并传递给它的属性为Coordinate类的row和col实例。但它必须是int。所以当你打电话时

line_cell = self.grid[users_coords.row][users_coords.col]

你只是试图通过索引获取元素,但索引不是int而代码会抛出异常。

只需删除users_coords = Cell(users_coords, users_coords)即可获得预期结果。或者如果你真的需要Cell类的实例,你可以这样做:

def drop_fishing_line(self, users_coords):
    users_coords = Cell(users_coords.row, users_coords.col)
    line_cell = self.grid[users_coords.row][users_coords.col]

<强>更新

要显示F *,您应该更改以下代码行:

line_cell = Cell.contains_line == True

到此:

line_cell.contains_line = True

检查鱼是否被捕获改变:

    if str(self.grid) == "F":
        print("The fish was caught!")
        print("\n")

    else:
        print("The fish was not caught!")
        print("\n")

到此:

    for cells in self.grid:
        for cell in cells:
            if str(cell) == "F*":
                print("The fish was caught!")
                print("\n")
                return 0
    print("The fish was not caught!")
    print("\n")

问题self.grid是一个Cell列表而不是一个单元格。 所以现在只需要做一件事就是Game stat :)

<强> UPDATE2

完整的代码现在看起来:

import random
import time

class Coordinate:
    '''
    '''
    def __init__(self, row, col):
        '''

        '''
        self.row = row
        self.col = col

    def __str__(self):
        '''

        '''
        return "(%d, %d)" %(self.row, self.col)

class Cell:
    '''

    '''

    def __init__(self, row, col):
        '''

        '''
        self.row = row
        self.col = col
        self.coords = Coordinate(row, col)
        self.fish = ""
        self.contains_line = False

    def __str__(self):
        '''
        '''

        if self.fish:
            if self.contains_line:
                result = self.fish[0] + '*'
            else:
                result = self.fish[0]
        else:
            if self.contains_line:
                result = '*'
            else:
                result = ' '

        return result


class CarpetSea:
    '''

    '''

    fish_caught = 0
    def __init__(self, N):
        '''

        '''

        self.N = N
        self.grid = []
        for i in range(self.N):
            row = []
            for j in range(self.N):
                cell = Cell(i, j)
                row.append(cell)
            self.grid.append(row)


        self.available_fish = ["Salmon", "Marlin", "Tuna", "Halibut"]


    def __str__(self):
        '''
        returns a string representation of a CarpetSea, i.e. display the organized contents of each cell.
        Rows and columns should be labeled with indices.

        Example (see "Example Run" in the PA8 specs for more):
          0  1
        --------
        0|M |  |
        --------
        1|  |* |
        --------

        Note: call Cell's __str__() to get a string representation of each Cell in grid
        i.e. "M " for Cell at (0,0) in the example above
        '''

        str1 = '  | ' + ' | '.join([str(i) for i in range(len(self.grid[0]))]) + ' |\n'
        str1 += '-' * 12 + '\n'
        for i, k in enumerate(self.grid):
            str1 += ' {0}| '.format(i)
            for j in k:
                str1 += '{0} | '.format(j)
            str1 += '\n'
            str1 += '-' * 12 + '\n'
        return(str1)


    def randomly_place_fish(self):
        '''
        randomly selects coordinates of a cell and randomly selects a fish from the available_fish list attribute.
        Marks the cell as containing the fish.
        '''

        cell = random.choice(random.choice(self.grid))
        cell.fish = random.choice(self.available_fish)
        #fish_name = cell.fish[0]

        return cell.fish


    def drop_fishing_line(self, users_coords):
        '''
        accepts the location of the user's fishing line (a Coordinate object).
        Marks the cell as containing the line.
        '''

        line_cell = self.grid[users_coords.row][users_coords.col]


        line_cell.contains_line = True

        print(line_cell)


    def check_fish_caught(self, fish, lineb, linec):
        '''
        If the cell containing the fishing line also contains a fish, returns the fish.
        Otherwise, return False.

        '''
        for cells in self.grid:
            for cell in cells:
                if str(cell) and str(cell) == str(cell)[0] + "*":
                    print("The fish was caught!")
                    print("\n")
                    return True
        print("The fish was not caught!")
        print("\n")
        return False

class GameStats:
    hour = 0
    fish = CarpetSea.fish_caught
    fish = 0
    def __init__(self):
        self.time = time

    def __str__(self):
        average = self.fish / GameStats.hour
        return "Total amount of hours played: %d \nTotal amound of fish caught: %d\nOn aveage you caught %.2f fish her hour"%(self.hour, self.fish, average)

    def total_time_passed(self):
        '''
        calcuate the total time played in the game
        '''
        print("One hour has passed...")
        self.time = time.sleep(1)
        GameStats.hour += 1

    def Total_num_of_fish(self):
        '''
        seeing the total number of fish caught
        '''
        GameStats.fish += 1

    def Average_amount_of_fish(self):
        '''
        average amount of fish caught in the time played
        '''
        self.average_fish = self.fish / self.hour


def instructions():
    '''
    game instructions
    '''
    print("Welcome to Dilbert's Carpet Fishing Game!")
    print("To play, you will cast your fishing line into a location in Carpet Sea")
    print("After a certain amount of time, you will reel in your line adn find out if you caught a fish!")
    print("You can keep re-casting and re-reeling until you want to quit")
    print("The Carpet Sea is a 2x2 grid, so please choose your row and column accordingly")
    print("\n")

def get_user_row():
    '''
    user row
    '''
    row = int(input("Please enter a row: "))

    return row

def get_user_col():
    '''
    user col
    '''
    col = int(input("Please enter a column: "))

    return col


def main():

    '''

    '''
    instructions()


    N = 2

    gameinfo = GameStats()
    while True:

        row = get_user_row()
        col = get_user_col()

        user_coords = Coordinate(row, col)
        info = CarpetSea(N)
        game = GameStats()

        rando_fish = info.randomly_place_fish()
        user_line = info.drop_fishing_line(user_coords)


        game.total_time_passed()
        print(info)

        if info.check_fish_caught(rando_fish, user_line, user_line):
            gameinfo.Total_num_of_fish()


        answer = str(input("Please enter 'y' to continue or 'n' to end: "))

        if answer == "n":
            break
    print(gameinfo)


main()