I am trying to simulate a baseball game to learn more about python and programming in general... I ran into an interesting learning point in programing... and was wondering if someone could explain this error...
import random
rosterHome = []
rosterAway = []
class Player:
def __init__(self, number, battingAverage):
self.number = number
self.battingAverage = battingAverage
class Game:
def __init__(self):
self.inning = 0
self.homeScore = 0
self.awayScore = 0
self.outs = 0
def createStats():
for i in range(40):
stats = random.random()
x = Player(i, stats)
rosterHome.append(x)
for y in range(40):
stats = random.random()
y = Player(i, stats)
rosterAway.append(y)
def startGame():
Game.createStats()
Game.inning = 0
Game.homeScore = 0
Game.awayScore = 0
Game.outs = 0
Game.playInning()
def playInning():
totalHits = 0
if Game.inning >= 10:
print('Game is Over')
return
while Game.outs < 3:
for i in rosterHome:
x = rosterHome[i]
if x.battingAverage > random.random():
totalHits = 1
player = 1
print('batter ', player, ' got a hit')
else:
Game.outs = 1
player = 1
print('batter ', player, ' got out')
print('there are ', Game.outs, ' outs.')
Game.startGame()
x = rosterHome[i] TypeError: list indices must be integers or slices, not Player
CodePudding user response:
TLDR:
List indices must be integers or slices
The interpreter says "Hey, I see you're trying to access an item in a List by its index, but indices should be of type integer
, however, you passed a value of type Player
"
In Python and most programming languages, to reference an item in a List/Array, one way would be by index. Lists are zero-indexed, so the first item is of index 0, the second index 1, and so on.
Given an Array
my_array = ["bread", "foo", "bar"]
my_array[0] # would give you "bread"
my_array[1] # would give you "foo"
my_array[2] # would give you "bar"
However in your case, if we trace back up from where the error occurred, right here:
x = rosterHome[i]
You want to ask, what is the value of i
? above this line is a for loop, and i
represents each value in a list called rosterHome
. So what the heck is in rosterHome
anyways?
Moving up into your createStats
method where you populated the rosterHome
list, we see that you're pushing an instance of Player
into the rosterHome
list.
x = Player(i, stats)
rosterHome.append(x)
So rosterHome really isn't a list of numbers but instead a list of Player
instances. You might want to review and try again, maybe accessing the number property of the Player object instead.
CodePudding user response:
The error happens because rosterHome
is a list of instances of the Player
class, so when you iterate on the list (for i in rosterHome
) each element will be an instance of said class (i
is a Player
). If you want to access the number of each player you'll have to access the attribute number
of your Player
instances, but it seems like actually you want to find the player instance. This means, you don't even need to lookup the value in the table, just use the value of the for loop. I'll use a different naming of variables to improve readability:
while Game.outs < 3:
for player in rosterHome:
# x wanted to access a player, but we don't need to do that actually
if player.battingAverage > random.random():
# ...
else:
# ...
This part of the answer considers that you actually want to meet both requirements (number of outs and iterate players once):
player_index = 0
while Game.outs < 3 and player_index< len(rosterHome):
player = rosterHome[player_index]
if player.battingAverage > random.random():
# ...
else:
# ...
if Game.outs == 3:
# Reached 3 outs
else:
# No players left and game outs < 3