0

I am learning OOP, have hard time grasping how to different classes interact with each other. I read so many examples but majority of them show how single class works, and that's clear, I want to see how different classes to interact among themselves. If someone has a good example how different classes interact it would be great.

Here I create Deck instance newDeck and then Player instance p1. Then I do this: newCard.append(player.generateCard(newDeck)) where player is p1, so I call Player method generateCard() and pass newDeck instance of class Deck. Is this allowed?

Here I get error:

 File "poker.py", line 67, in startGame
 newCard.append(player.generateCard(newDeck))
AttributeError: 'str' object has no attribute 'generateCard'`

My code:

import random, string, sys
class Deck:
 def __init__(self):
 self.suits = ['s', 'h', 'd', 'c']
 self.ranks = ['2', '3', '4', '5', '6' ,'7', '8', '9', '10', 'J', 'Q', 'K', 'A']
 self.deck = [i+j for i in self.ranks for j in self.suits]
 random.shuffle(self.deck)
 def selectCards(self):
 self.selectedCard = self.deck.pop()
 return self.selectedCard
class Player:
 def __init__(self, amount):
 self.amount = amount
 self.card = []
 def generateCard(self, whichDeck):
 self.whichDeck = whichDeck
 holeCards = 2
 for i in range(0, holeCards):
 selCard = self.whichDeck.selectCards()
 if len(selCard) == 2:
 self.cardRank = list(selCard[0])
 else:
 self.cardRank = list('10') 
 self.cardSuit = list(selCard[-1])
 self.generatedCard = list(self.cardRank + self.cardSuit)
 self.card.append(self.generatedCard)
 return self.card 
class Game:
 def __init__(self, numPlayers, startingStack):
 self.startingStack = startingStack
 self.numPlayers = numPlayers
 def startGame(self):
 newDeck = Deck()
 playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
 currentPlayer = 0
 for player in playerList:
 player = Player(self.startingStack)
 currentPlayer += 1 
 if currentPlayer == self.numPlayers:
 break
 totalPlayers = currentPlayer
 # -------------------------- GAME STARTS ---------------------------
 newCard = []
 currentPlayer = 0
 for player in playerList: 
 newCard.append(player.generateCard(newDeck)) # ERROR IS HERE 
 if currentPlayer == self.numPlayers:
 break
def main():
 numberOfPlayers = 1
 playerStack = 100
 newGame = Game(numberOfPlayers, playerStack) 
 newGame.startGame()
if __name__ == '__main__':
 main()
Martijn Pieters
1.1m326 gold badges4.2k silver badges3.5k bronze badges
asked Jul 28, 2014 at 9:51
5
  • player is not a Player instance; it is a string. Commented Jul 28, 2014 at 9:53
  • Wait, but using the for loop I created Player instance with p1, so why I can't again use method of Player with same p1? Commented Jul 28, 2014 at 9:55
  • You never stored those Player objects anywhere; the playerList object is not updated. Commented Jul 28, 2014 at 9:58
  • You misunderstand Python assignment; see e.g. here for an explanation of names in Python. Commented Jul 28, 2014 at 10:20
  • Yes, agree, will read that one :) Commented Jul 28, 2014 at 10:22

2 Answers 2

1

You do not have any Player instances, you create list of strings:

playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']

then in the loop you just do

for player in playerList:
 player = Player(self.startingStack)
 currentPlayer += 1 
 if currentPlayer == self.numPlayers:
 break

and this local variable player is lost, it is not magically appended to your playerList

Simply do something like

playerList = [ Player(self.startingStack) for _ in range(self.numPlayers) ]

instead of your loop

answered Jul 28, 2014 at 9:56
Sign up to request clarification or add additional context in comments.

3 Comments

Why did you delete [ Player(0) for _ in range(self.numPlayers) ]? This actually works perfectly, now everything works!
I moved it to the end of the answer to make it more complete
Now I get it, your list comprehension example made it easy understandable :)
0

Your playerList object is still a list of strings. Your loop:

for player in playerList:
 player = Player(self.startingStack)
 currentPlayer += 1 
 if currentPlayer == self.numPlayers:
 break

re-binds player to a Player() instance, but this doesn't change the playerList object. In fact, by the time you get to the next iteration, the Player() instance is discarded again as nothing else references it.

The for player in playerList binds player to each string in the list in turn, but the reference does not work the other direction, player is just another Python name, another reference to the same object contained in playerList. Assigning a different object to it will not also alter the list from which the strings were taken.

You probably wanted to build a new list here:

def startGame(self):
 newDeck = Deck()
 playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
 players = []
 for player in playerList[:self.numPlayers]:
 player = Player(self.startingStack)
 players.append(player)
 totalPlayers = self.numPlayers
 # -------------------------- GAME STARTS ---------------------------
 newCard = []
 for player in players: 
 newCard.append(player.generateCard(newDeck))

However, you are entirely ignoring the strings in playerList here; may as well just build the list without consulting those:

def startGame(self):
 newDeck = Deck()
 players = [Player(self.startingStack) for _ in range(self.numPlayers)]
 newCard = [player.generateCard(newDeck) for player in players]

but you don't need players then as a separate list either:

def startGame(self):
 newDeck = Deck()
 newCard = [Player(self.startingStack).generateCard(newDeck)
 for _ in range(self.numPlayers)]
answered Jul 28, 2014 at 9:57

2 Comments

Now I understand my problem, and you are right about last point. Thank you for making it clear for me.
And I made code much shorter, I had so much useless stuff apparently.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.