Python Programming for the Absolute Beginner, 3rd Edition

In the real world, interesting objects are usually made up of other, independent objects. For example, a drag racer can be seen as a single object that's composed of individual objects such as a body, tires, and an engine. Other times, you may see an object as a collection of other objects. For example, a zoo can be seen as a collection of animals. Well, you can mimic these kinds of relationships among objects in OOP. You could write a Drag_Racer class that has an attribute engine which references an Engine object. Or, you could write a Zoo class that has an attribute animals which is a list of different Animal objects. Combining objects like this allows you to create more complex objects from simpler ones.

Introducing the Playing Cards Program

The Playing Cards program uses objects to represent individual playing cards that you might use in a game of Blackjack or Go Fish (depending upon your tastes . . . and your tolerance for losing money). The program goes on to represent a hand of cards through an object that is a collection of card objects. Figure 9.4 shows the results of the program.

Figure 9.4: Each Hand object is a collection of Card objects.

Creating the Card Class

The first thing I do in the program is create a Card class for objects that represent playing cards. Here's the code for the Card class:

# Playing Cards # Demonstrates combining objects # Michael Dawson - 4/9/03 class Card(object): """ A playing card. """ RANKS = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] SUITS = ["c", "d", "h", "s"] def __init__(self, rank, suit): self.rank = rank self.suit = suit def __str__(self): rep = self.rank + self.suit return rep

Each Card object has a rank attribute, which represents the rank of the card. The possible values are listed in the class attribute RANKS. "A" represents an ace, "2" through "10" represent their corresponding numeric values, "J" represents a jack, "Q" represents a queen, and "K" represents a king.

Each card also has a suit attribute, which represents the suit of the card. The possible values for this attribute are listed in the class attribute SUITS. "c" represents clubs, "d" means diamonds, "h" stands for hearts, and "s" represents spades. So, an object with the rank attribute of "A" and a suit attribute of "d" represents the ace of diamonds.

The special method __str__() simply returns the concatenation of the rank and suit attributes so that an object can be printed.

Creating the Hand Class

The next thing I do in the program is create a Hand class for objects, which is a collection of Card objects:

class Hand(object): """ A hand of playing cards. """ def __init__(self): self.cards = [] def __str__(self): if self.cards: rep = "" for card in self.cards: rep += str(card) + " " else: rep = "<empty>" return rep def clear(self): self.cards = [] def add(self, card): self.cards.append(card) def give(self, card, other_hand): self.cards.remove(card) other_hand.add(card)

A new Hand object has an attribute cards that is intended to be a list of Card objects. So each single Hand object has an attribute that is a list of possibly many other objects.

The special method __str__() returns a string that represents the entire hand. The method loops through each Card object in the Hand object and concatenates the Card object's string representation. If the Hand object has no Card objects, the string "<empty>" is returned.

The clear() method clears the list of cards by assigning an empty list to an object's cards attribute.

The add() method adds an object to the cards attribute.

The give() method removes an object from the Hand object and appends it to another Hand object by invoking the other Hand object's add() method. Another way to say this is that the first Hand object sends the second Hand object a message to add a Card object.

Using Card Objects

In the main part of the program, I create and print five Card objects:

# main card1 = Card(rank = "A", suit = "c") print "Printing a Card object:" print card1 card2 = Card(rank = "2", suit = "c") card3 = Card(rank = "3", suit = "c") card4 = Card(rank = "4", suit = "c") card5 = Card(rank = "5", suit = "c") print "\nPrinting the rest of the objects individually:" print card2 print card3 print card4 print card5

The first Card object created has a rank attribute equal to "A" and a suit attribute of "c". When I print the object, it's displayed on the screen as Ac. The remaining objects follow the same pattern.

Combining Card Objects Using a Hand Object

Next, I create a Hand object, assign it to my_hand, and print it:

my_hand = Hand() print "\nPrinting my hand before I add any cards:" print my_hand

Since the object's cards attribute is an empty list, printing the object displays the text <empty>.

Next, I add the five Card objects to my_hand and print it again:

my_hand.add(card1) my_hand.add(card2) my_hand.add(card3) my_hand.add(card4) my_hand.add(card5) print "\nPrinting my hand after adding 5 cards:" print my_hand

This time, the text Ac 2c 3c 4c 5c is displayed.

Then, I create another Hand object, your_hand. Using my_hand's give() method, I transfer the first two cards from my_hand to your_hand. Then, I print both hands:

your_hand = Hand() my_hand.give(card1, your_hand) my_hand.give(card2, your_hand) print "\nGave the first two cards from my hand to your hand." print "Your hand:" print your_hand print "My hand:" print my_hand

As you'd expect, your_hand is displayed as Ac 2c while my_hand appears as 3c 4c 5c.

Finally, I invoke my_hand's clear() method and print it one last time:

my_hand.clear() print "\nMy hand after clearing it:" print my_hand raw_input("\n\nPress the enter key to exit.")

As it should, the text <empty> is displayed.

Категории