为什么抛出一个IndexError?

时间:2016-11-27 23:56:25

标签: python postgresql

我正在试图弄清楚它为什么会抛出这个错误。元组的长度应该是4,它是。任何提示,想法?

此代码适用于瑞士风格的项目,我正致力于编程Udacity纳米学位课程。

来自tournament.py的相关代码Python代码:

def playerStandings():
    """Returns a list of the players and their win records, sorted by wins.

    The first entry in the list should be the player in first place, or a player
    tied for first place if there is currently a tie.

    Returns:
     A list of tuples, each of which contains (id, name, wins, matches):
      id: the player's unique id (assigned by the database)
        name: the player's full name (as registered)
        wins: the number of matches the player has won
        matches: the number of matches the player has played 
    """
    conn = connect()
    c = conn.cursor()
    c.execute("SELECT COUNT(id) FROM Players;")
    total = c.fetchone()[0]

    num_of_players = countPlayers()
    standings = [None]*num_of_players

    c.execute("SELECT * FROM wincounter;")
    winners = c.fetchall()

    i = 0
    for player in winners:
        standings[i] = (player[0], player[1], player[2], player[3])
        i += 1

    conn.close()
    return standings

来自tournament_test.py的相关代码:

def testStandingsBeforeMatches():
    """
    Test to ensure players are properly represented in standings prior
    to any matches being reported.
    """
    deleteMatches()
    deletePlayers()
    registerPlayer("Melpomene Murray")
    registerPlayer("Randy Schwartz")
    standings = playerStandings()
    if len(standings) < 2:
        raise ValueError("Players should appear in playerStandings even before "
                         "they have played any matches.")
    elif len(standings) > 2:
        raise ValueError("Only registered players should appear in standings.")
    if len(standings[0]) != 4:
        raise ValueError("Each playerStandings row should have four columns.")
    [(id1, name1, wins1, matches1), (id2, name2, wins2, matches2)] = standings
    if matches1 != 0 or matches2 != 0 or wins1 != 0 or wins2 != 0:
        raise ValueError(
            "Newly registered players should have no matches or wins.")
    if set([name1, name2]) != set(["Melpomene Murray", "Randy Schwartz"]):
        raise ValueError("Registered players' names should appear in standings, "
                         "even if they have no matches played.")
    print ("6. Newly registered players appear in the standings with no matches.")

PostgreSQL架构:

DROP DATABASE IF EXISTS tournament;
CREATE DATABASE tournament;
\c tournament;


CREATE TABLE players (
    id serial PRIMARY KEY NOT NULL,
    Name text
);

CREATE TABLE matches (
    match_id serial PRIMARY KEY NOT NULL,
    winner int REFERENCES players(id),
    loser int REFERENCES players(id)
);

CREATE VIEW wincounter
AS
  SELECT players.id,
         players.name,
         COUNT(matches.winner) AS wins
  FROM   players
         LEFT JOIN matches
                ON players.id = matches.winner
  GROUP  BY players.id;

错误讯息:

vagrant@vagrant-ubuntu-trusty-32:/vagrant/tournament$ python tournament_test.py
    1. countPlayers() returns 0 after initial deletePlayers() execution.
    2. countPlayers() returns 1 after one player is registered.
    3. countPlayers() returns 2 after two players are registered.
    4. countPlayers() returns zero after registered players are deleted.
    5. Player records successfully deleted.
    Traceback (most recent call last):
      File "tournament_test.py", line 152, in <module>
        testStandingsBeforeMatches()
      File "tournament_test.py", line 54, in testStandingsBeforeMatches
        standings = playerStandings()
      File "/vagrant/tournament/tournament.py", line 85, in playerStandings
        standings[i] = (player[0], player[1], player[2], player[3])
    IndexError: tuple index out of range
    vagrant@vagrant-ubuntu-trusty-32:/vagrant/tournament$

1 个答案:

答案 0 :(得分:0)

错误发生在该行:

standings[i] = (player[0], player[1], player[2], player[3])

您的player变量是一个元组,表示数据库中wincounter视图的一行。该视图只有三列(players.idplayers.namewins),因此当您尝试访问第四个值(player[3])时会出现索引错误。

目前还不完全清楚为什么你会这样行。如果您希望player元组中的所有项都添加到standings,您可以执行standings[i] = player,甚至可以删除显式循环,只需编写standings = list(winners)