Reputation: 119
I am new to Python, busy creating a blackjack game. I have almost got printing out my deck of cards right, but I can't seem to iterate through all the cards stored in the list.
suits = ['Hearts','Diamonds','Spades','Clubs']
ranks = ['Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace']
values = {'Two':2, 'Three':3,'Four':4,'Five':5,'Six':6,'Seven':7,'Eight':8,'Nine':9,'Ten':10,'Jack':10,'Queen':10,'King':10,'Ace':(1,11)}
playing = True
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def __str__(self):
print(f"{self.rank} of {self.suit}")
class Deck:
def __init__(self):
self.deck = []
for suit in suits:
for rank in ranks:
self.deck.append(Card(suit, rank))
def __str__(self):
for card in self.deck:
return f"{card.rank} of {card.suit}"
deck = Deck()
print(deck)
Output with return:
Two of hearts
Output with print:
Two of Hearts
Three of Hearts
Four of Hearts
Five of Hearts
Six of Hearts
Seven of Hearts
Eight of Hearts
Nine of Hearts
Ten of Hearts
Jack of Hearts
Queen of Hearts
King of Hearts
Ace of Hearts etc...plus error
So I know the correct syntax for str is to use return and not print. But if I use print then I get exactly what I want, all my cards in the deck, except with this error: str returned non-string (type NoneType). If I use return, which is the correct syntax, then when I print my deck all that prints out is the first card, the two of hearts. Why is that?
Upvotes: 0
Views: 179
Reputation: 864
You could use a list comprehension to achieve the desired print of your deck of cards.
[f"{card.rank} of {card.suit}" for card in deck]
This statement would create a python list that contains string representations of the cards in your deck. Now we can turn this list of strings into one single string by using the string.join()
method, which concatenates the strings in the list and delimits them with the preceding string to join.
"\n".join([f"{card.rank} of {card.suit}" for card in deck])
If you print this you would get:
Two of Hearts
Three of Hearts
Four of Hearts
Five of Hearts
Six of Hearts
Seven of Hearts
Eight of Hearts
Nine of Hearts
Ten of Hearts
Jack of Hearts
Queen of Hearts
King of Hearts
Ace of Hearts
Two of Diamonds
Three of Diamonds
Four of Diamonds
Five of Diamonds
Six of Diamonds
Seven of Diamonds
Eight of Diamonds
Nine of Diamonds
Ten of Diamonds
Jack of Diamonds
Queen of Diamonds
King of Diamonds
Ace of Diamonds
Two of Spades
Three of Spades
Four of Spades
Five of Spades
Six of Spades
Seven of Spades
Eight of Spades
Nine of Spades
Ten of Spades
Jack of Spades
Queen of Spades
King of Spades
Ace of Spades
Two of Clubs
Three of Clubs
Four of Clubs
Five of Clubs
Six of Clubs
Seven of Clubs
Eight of Clubs
Nine of Clubs
Ten of Clubs
Jack of Clubs
Queen of Clubs
King of Clubs
Ace of Clubs
And your complete code is now:
suits = ['Hearts','Diamonds','Spades','Clubs']
ranks = ['Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace']
values = {'Two':2, 'Three':3,'Four':4,'Five':5,'Six':6,'Seven':7,'Eight':8,'Nine':9,'Ten':10,'Jack':10,'Queen':10,'King':10,'Ace':(1,11)}
playing = True
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def __str__(self):
print(f"{self.rank} of {self.suit}")
class Deck:
def __init__(self):
self.deck = []
for suit in suits:
for rank in ranks:
self.deck.append(Card(suit, rank))
def __str__(self):
return "\n".join([f"{card.rank} of {card.suit}" for card in self.deck])
deck = Deck()
print(deck)
Upvotes: 1
Reputation: 3829
Within a method, return
can only be executed once, then control returns to the calling code, so you can't have a return
inside a loop. One solution is to build the entire string to be printed, then return that.
If you change your code in class Deck
to:
def __str__(self):
return "\n".join(f"{card.rank} of {card.suit}" for card in self.deck)
It will return a string containing the entire deck of cards so that your print functions correctly.
Upvotes: 3