(2025 Spring) Lecture Note (4)
(2025 Spring) Lecture Note (4)
class Card(object):
"""A Blackjack card."""
pass
card = Card()
card.face = "Ace"
card.suit = "Spades"
card.value = 11
__str__()
__eq__()
By specifying "object" as shown, ...
the Card class inherits the attributes and methods
of the object class.
class Card
__doc__
This is not required in Python 3. face
• All classes in Python 3 inherit from object suit
implicitly. value
...
class Card(object): __str__()
"""A Blackjack card.""" __eq__()
pass ...
We do not really need the value attribute, since the value can be computed
from the face attribute.
class Card(object):
"""A Blackjack card."""
method of Card
def value(self):
if type(self.face) == int:
return self.face
elif self.face == "Ace":
return 11 self refers to the object itself
else:
inside the method
return 10
def value(self):
if type(self.face) == int:
return self.face
elif self.face == "Ace":
return 11 if type(card1.face) == int:
else: return card1.face
return 10 elif card1.face == "Ace":
return 11
else:
return 10
6
The value() method works like this
How?
Class Card(object):
"""A Blackjack card."""
def __init__(self, face, suit):
self.face = face
self.suit = suit
class Card(object):
"""A Blackjack card."""
def __init__(self, face, suit):
self.face = face
self.suit = suit
Class Card(object):
"""A Blackjack card."""
def __init__(self, face, suit):
assert face in FACES and suit in SUITS
self.face = face
self.suit = suit Check if the face and suit values are
valid. Otherwise, it throws an
AssertionError.
def mysqrt(x):
assert x >= 0.0
return math.sqrt(x)
print(mysqrt(1))
print(mysqrt(-1))
12
Better syntax for printing a card?
>>> card_string(card1)
'an Ace of Spades'
>>> card_string(card2)
'a 2 of Clubs'
>>> card1.string()
'an Ace of Spades'
>>> card2.string()
'a 2 of Clubs'
How?
class Card(object):
"""A Blackjack card."""
...
def string(self):
article = "a "
if self.face in [8, "Ace"]:
article = "an "
return (article + str(self.face) +
" of " + self.suit)
How?
class Card(object):
"""A Blackjack card."""
"""Already defined __init__ and value methods"""
def __str__(self):
article = "a "
if self.face in [8, "Ace"]:
article = "an "
return (article + str(self.face) + " of " + self.suit)
hen = make_chicken(True)
chick1 = make_chicken()
chick1.layer.move(120, 0)
chick2 = make_chicken()
chick2.layer.move(800, 200)
18
How about this?
hen = Chicken(True)
chick1 = Chicken()
chick1.move(120, 0)
chick2 = Chicken()
chick2.move(800, 200)
Looks better!
Then, how?
19
More elegant way to make a Chicken
class Chicken(object):
"""Graphic representation of a chicken."""
def __init__(self, hen = False):
layer = Layer()
# make all the parts
self.layer = layer
self.body = body
self.wing = wing
self.eye = eye
...
class Chicken(object):
"""Graphic representation of a chicken."""
def move(self, dx, dy):
self.layer.move(dx, dy)
We only need one method: drawing a card from the top of the deck:
class Deck(object):
"""A deck of cards."""
def __init__(self):
"""Create a deck of 52 cards and shuffle them."""
self.cards = []
for suit in SUITS:
for face in FACES:
self.cards.append(Card(face, suit))
random.shuffle(self.cards)
def draw(self):
"""Draw the top card from the deck."""
return self.cards.pop() # returns the last
for j in range(num_players):
hands.append([])
for i in range(num_cards):
for j in range(num_players):
card = deck.draw()
hands[j].append(card)
print("Player", j+1, "draws", card)
for j in range(num_players):
print ("Player %d's hand (value %d):" %
(j+1, hand_value(hands[j])))
for card in hands[j]:
print (" ", card)
You may need to use the comparison operators: ==, !=, <, etc.
24
To make “==” more useful ...
class Card(object):
"""A Blackjack card."""
...
def __eq__(self, rhs):
return (self.face == rhs.face and
self.suit == rhs.suit)
def __ne__(self, rhs):
return not self == rhs
25
Blackjack with a graphical interface (GUI)
These are Hand objects that represent the hand on the table.
while True:
if t.ask('Want more card? (y/n)'):
t.set_message('You said Yes')
else:
t.set_message('You said No')
28
More generally - Event Loop!
while True:
e = t.canvas.wait()
if e == None:
sys.exit(1)
d = e.getDescription()
if d == "keyboard":
k = e.getKey()
d = d + '-' + k Handles an event
if k == 'p':
t.player.add(Card("King", "Clubs"))
if k == 'q':
t.close()
elif d == "mouse click":
d = d + '-' + str(e.getMouseLocation())
t.set_message(d)
29
Separating tasks (event handlers) from the loop
while True:
e = t.canvas.wait()
if e == None:
sys.exit(1)
d = e.getDescription()
if d == "keyboard":
k = e.getKey()
d = d + '-' + k
onKey(k) Event Handler
elif d == "mouse click":
onMouseClick() Event Handler
elif ...
With this separation, you are only to provide event handlers in GUI
programming.
https://gist.github.com/kassane/f233
GUI application framework 0ef44b070f4a5fa9d59c770f68e9
The program waits for an event to happen and execute an event handler.