Module 3
Object Oriented Programming
Unit 5
More on Classes
Learning Outcomes
- Create a Python program which uses a constructor and abstract class.
- Describe the concepts of polymorphism, aggregation and composition.
- Name variables according to the namespace within which they exist.
Pratical Activity - Inheritance
Review chapter 18 of the 'Think Python' book to help you better understand this week’s concepts. Use card.py to understand the chapter's contents. Review the code by using the guidance in the book.
For the following program, draw a UML class diagram that shows these classes and the relationships among them.
Code:
class PingPongParent:
pass
class Ping(PingPongParent):
def __init__(self, pong):
self.pong = pong
class Pong(PingPongParent):
def __init__(self, pings=None):
if pings is None:
self.pings = []
else:
self.pings = pings
def add_ping(self, ping):
self.pings.append(ping)
pong = Pong()
ping = Ping(pong)
pong.add_ping(ping)

Write a Deck method called deal_hands
that takes
two parameters, the number of hands and the number of cards per
hand. It should create the appropriate number of Hand objects,
deal the appropriate number of cards per hand, and return a list
of Hands.
import random
class Card:
def __init__(self, suit=0, rank=2):
self.suit = suit
self.rank = rank
suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7',
'8', '9', '10', 'Jack', 'Queen', 'King']
def __str__(self):
return '%s of %s' % (Card.rank_names[self.rank],
Card.suit_names[self.suit])
class Deck:
def __init__(self):
self.cards = []
for suit in range(4):
for rank in range(1, 14):
card = Card(suit, rank)
self.cards.append(card)
def __str__(self):
res = []
for card in self.cards:
res.append(str(card))
return '\n'.join(res)
def add_card(self, card):
self.cards.append(card)
def pop_card(self):
return self.cards.pop()
def shuffle(self):
random.shuffle(self.cards)
def deal_hands(self, num_hands, cards_per_hand):
if (num_hands * cards_per_hand) > len(self.cards):
raise ValueError('Not enough cards')
hands = []
for i in range(num_hands):
hand = Hand(f'Hand {i+1}')
for j in range(cards_per_hand):
card = self.pop_card()
hand.add_card(card)
hands.append(hand)
return hands
class Hand(Deck):
def __init__(self, label=''):
self.cards = []
self.label = label
def __str__(self):
return f"{self.label}: {', '.join(str(card) for card in self.cards)}"
def move_cards(self, hand, num):
for i in range(num):
hand.add_card(self.pop_card())
if __name__ == '__main__':
deck = Deck()
deck.shuffle()
# Expected Output: Deals 3 hands of 5 cards each
hands = deck.deal_hands(3, 5)
for hand in hands:
print(hand)
e-Portfolio Activity: Polymorphism
Write a Python program with polymorphism that is usable within the summative assessment for the humanoid robot.
class Shape:
def __init__(self, name):
self.name = name
def calculate_area(self):
return 0
def display_info(self):
print(f"{self.name} Area: {self.calculate_area()}")
class Circle(Shape):
def __init__(self, radius):
super().__init__("Circle")
self.radius = radius
def calculate_area(self):
return 3.14 * self.radius * self.radius
class Square(Shape):
def __init__(self, side):
super().__init__("Square")
self.side = side
def calculate_area(self):
return self.side * self.side
if __name__ == '__main__':
circle = Circle(4)
circle.display_info()
square = Square(3)
square.display_info()
Reflection
- Unit 5 involved numerous activities. I prioritised completing the UML-related tasks, as they will be beneficial for the upcoming Unit 7 assignment.
- In addition to these activities, I began defining the features of my humanoid robot.