Vin Breau Vin Breau - 5 months ago 14
Python Question

How to approach implementing 'class Card' as required by Python textbook

I'm currently working through John Zelle's Python Programming: An Introduction to Computer Science and hit a snag in Chapter 10. I'm having a conceptual issue in understanding the why and how of this exercise and require some assistance on how to approach the problem. The exercise asks me to create a program that displays n number of cards using a class named

Card
and requires the following methods. It should also be callable from within an app that generates n number of random cards:


  1. __init__(self, rank, suit):

  2. getRank(self)

  3. getSuite(self)

  4. BJValue(self)

  5. __str__(self)



As ridiculously easy as this should be, I hit a wall trying to implement this class. I created a simple app that would generate a deck of 52 cards, prompts the user for the number of cards they want, and then populates the hand with those cards. I just can't see where I would benefit from a card specific class once the hand is generated. Here's my working code so far:

import random

class Card:
def __init__(self, rank, suite):
self.rank = rank
self.suite = suite

def getRank(self):
return self.rank

def getSuite(self):
return self.suite

def BJValue(self):
if self.rank == 'Ace':
return 1
elif self.rank == 'Jack' or self.rank == 'Queen' or self.rank == 'King':
return 10
else:
return int(self.rank)

def __str__(self):
return ('{0} of {1}'.format(self.rank, self.suite))


def shuffled_deck():
deck = []
for suite in ['Clubs', 'Diamonds', 'Hearts', 'Spades']:
for num in ['Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King']:
deck.append([num, suite])
random.shuffle(deck)
return deck


def main():
deck = shuffled_deck()
hand = []
print('>> Card Generator v1 <<')
while True:
try:
n = int(input('Please enter the number of cards to display (1-7): '))
except ValueError:
print('Invalid input, please enter a number!\n')
else:
if n < 1 or n > 7:
print('Please enter a number between 1-7!\n')
else:
break
print('Your hand is:')
for i in range(n):
hand.append(deck[i])



main()


So once I've generated the hand of random n cards, I can't see how I would benefit from using the Card class, or even where to implement it. Since n is a random number between 1-7, I would need n number of variables to store each card object and then assign each variable to an instance of
Card
. I could show each card in the hand with
hand[i]
where i iterates through to
range(n)
without the need of a special
Card
class, but that's not what's expected from this project. I'm looking for advice on how to think about this issue so that I can make use of this required class.

Answer

It looks like the only thing you need to change in your code is to change the line:

deck.append([num, suite])

to

deck.append(Card(num, suite))

This makes the deck variable a list of 52 Card objects. That's useful because Card objects have some built-in functionality that a list of two items (like [num, suite]) doesn't.


Two examples: if you add the line

print hand

after your code, your current code would print something like

[["Jack", "Clubs"], ["9", "Spades"]]

while your new code would print

[Jack of Clubs, 9 of Spades]

(The line print "\n".join(map(str, hand))) might be closer to what you want in practice). You can also get the total blackjack value of your hand with the line:

sum(c.BJValue() for c in hand)