SimonSK
SimonSK

Reputation: 311

Iterating print() between classes

BlackJack game. I have the following classes defined:

class Card:
    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank
    def __str__(self):
        return ('{} of {},'
                .format(self.rank,self.suit))
class Deck:
    def __init__(self):
        self.deck = []  # starting with empty list
        for suit in suits:
            for rank in ranks:
                self.deck.append(Card(suit,rank))
    def deal(self):
        return self.deck.pop(0) //I'm dealing a card and taking
                                  him out of the deck
class Hand:
    def __init__(self):
        self.cards = []  //start with emptpy list and add Cards objects

    def add_card(self,card):
        self.cards.append(card)

    def __str__(self):
        for i in self.cards:
            return (f"{i}")

I'm creating a new deck, want to append to dealer's hand using the deal() method and to print the dealer's hand:

GameDeck = Deck()
DealerHand = Hand()
DealerHand.add_card(GameDeck.deal())

I'm printing the dealer's hand all good:

print(DealerHand)

OUTPUT: 5 of ♥

The problem starts when Im dealing another card from the deck:

DealerHand.add_card(GameDeck.deal())
print(DealerHand)

I'm getting the same result: 5 of ♥.

After debbuing it looks like self.hand (what I am trying to print) consists of 2 card classes (it's ok) but manages to print only the first one because it's going back to the str method in the Card class and not moving to the second iterable i in self.cards list:

from Hand class, fails to move to the next i and print it

def __str__(self):
        for i in self.cards:
            return (f"{i}")

Any thoughts why it prints only the first object in self.cards list?

Upvotes: 2

Views: 45

Answers (2)

L3viathan
L3viathan

Reputation: 27333

A return statement returns the given expression immediately, and therefore quits the function. Something like this will therefore not have the desired effect:

def __str__(self):
    for i in self.cards:
        return (f"{i}")

The __str__ method needs to return a single string. If, for example, you want to return a string of the cards all on their own line, you can create that string first, and then return it:

def __str__(self):
    return_value = ""
    for card in self.cards:
        return_value += card + "\n"

Or join the cards with a single, idiomatic expression. str.join joins the given iterable of strings with a given string (in this case, a newline character: \n):

def __str__(self):
    return "\n".join(self.cards)

Upvotes: 2

Bill the Lizard
Bill the Lizard

Reputation: 405965

Your __str__ function returns inside the for loop, which will terminate the loop after only one iteration. Instead, you want to return a string representation of the whole list of cards. Something like

def __str__(self):
    return ", ".join(self.cards)

Upvotes: 1

Related Questions