Paper 2 OOP Answers
These answers correspond to Paper 2 OOP Drills.
Verification note: every Python code block in this answer file has been executed locally.
Answer 1: Define Class
Model answer:
class Book:
def __init__(self, title, copies):
self.title = title
self.copies = copies
def available(self):
return self.copies > 0
book = Book("Algorithms", 3)
print(book.title)
print(book.available())Expected output:
Algorithms
TrueMark points:
- defines class
Book; - defines
__init__(self, title, copies); - stores
titleas an instance attribute usingself; - stores
copiesas an instance attribute usingself; - defines
available(self); - uses the correct condition
copies > 0; - returns the correct Boolean result.
Common weak answer:
- assigning
title = titlewithoutself, which creates only a local variable.
Answer 2: Create Objects
Model answer:
class Book:
def __init__(self, title, copies):
self.title = title
self.copies = copies
b1 = Book("Algorithms", 3)
b2 = Book("Networks", 0)
b3 = Book("Databases", 2)
print(b1.title)
print(b2.title)
print(b3.title)Expected output:
Algorithms
Networks
DatabasesMark points:
- creates first object with correct values;
- creates second object with correct values;
- creates third object with correct values;
- stores them in separate variables or equivalent references;
- prints all three titles in the required order.
Common weak answer:
- reusing one variable and then trying to print earlier objects after their reference has been overwritten.
Answer 3: Getter Setter
Model answer:
class Student:
def __init__(self, name, mark):
self.name = name
self._mark = mark
def get_mark(self):
return self._mark
def set_mark(self, mark):
if mark >= 0 and mark <= 100:
self._mark = mark
return True
return False
s = Student("Amy", 60)
print(s.get_mark())
print(s.set_mark(75))
print(s.get_mark())
print(s.set_mark(120))
print(s.get_mark())Expected output:
60
True
75
False
75Mark points:
- stores
_markas an instance attribute; - defines
get_mark; - defines
set_mark; - checks that the mark is within
0to100inclusive; - updates only when valid;
- returns a Boolean status.
Common weak answer:
- setting the mark before validation, so invalid input changes the object state.
Answer 4: Inheritance
Model answer:
class Person:
def __init__(self, name, email):
self.name = name
self.email = email
class Student(Person):
def __init__(self, name, email, class_name):
super().__init__(name, email)
self.class_name = class_name
def summary(self):
return self.name + " " + self.class_name + " " + self.email
s = Student("Amy", "amy@example.com", "24S1")
print(s.summary())Expected output:
Amy 24S1 amy@example.comMark points:
- defines superclass
Person; - stores shared
name; - stores shared
email; - defines subclass
Student; - uses inheritance syntax;
- calls
super().__init__or otherwise correctly initializes superclass attributes; - stores
class_name; - returns the expected summary.
Common weak answer:
- defining
Studentseparately without inheriting fromPerson.
Answer 5: Override Method
Model answer:
class Notification:
def send(self):
return "generic"
class EmailNotification(Notification):
def send(self):
return "email sent"
class SMSNotification(Notification):
def send(self):
return "sms sent"
items = [EmailNotification(), SMSNotification()]
for item in items:
print(item.send())Expected output:
email sent
sms sentMark points:
- defines superclass method;
- defines
EmailNotificationas a subclass; - overrides
sendinEmailNotification; - defines
SMSNotificationas a subclass; - overrides
sendinSMSNotification; - creates subclass objects;
- calls the same method name on each object;
- produces different outputs.
Common weak answer:
- giving the subclasses different method names, such as
send_emailandsend_sms, which does not demonstrate the same method call.
Answer 6: Object List
Model answer:
class Book:
def __init__(self, title, copies):
self.title = title
self.copies = copies
def available_titles(books):
titles = []
for book in books:
if book.copies > 0:
titles.append(book.title)
return titles
books = [Book("Algorithms", 3), Book("Networks", 0), Book("Databases", 2)]
print(available_titles(books))Expected output:
['Algorithms', 'Databases']Mark points:
- stores objects in a list;
- loops through the object list;
- accesses each object’s
copies; - checks
copies > 0; - accesses each matching object’s
title; - appends matching titles;
- returns the expected list.
Common weak answer:
- filtering dictionaries or strings instead of the required objects.
Answer 7: Class Diagram to Code
Model answer:
class Device:
count = 0
def __init__(self, code, name):
self.code = code
self.name = name
Device.count = Device.count + 1
def label(self):
return self.code + " " + self.name
d1 = Device("D01", "Laptop")
d2 = Device("D02", "Tablet")
print(d1.label())
print(d2.label())
print(Device.count)Expected output:
D01 Laptop
D02 Tablet
2Mark points:
- defines class
Device; - defines class attribute
count; - defines
__init__withcodeandname; - stores
codeas an instance attribute; - stores
nameas an instance attribute; - updates
Device.countthrough the class; - defines
label; - returns the correct label string;
- creates two
Deviceobjects with the required values; - produces all expected outputs.
Common weak answer:
- writing
self.count = self.count + 1. That can create or update an instance attribute instead of maintaining one shared class attribute.
Answer 8: Encapsulated Validation
Model answer:
class BankAccount:
def __init__(self, balance):
self._balance = balance
def deposit(self, amount):
if amount > 0:
self._balance = self._balance + amount
return True
return False
def get_balance(self):
return self._balance
account = BankAccount(100)
print(account.deposit(50))
print(account.get_balance())
print(account.deposit(-20))
print(account.get_balance())Expected output:
True
150
False
150Mark points:
- stores
_balance; - defines
deposit; - checks amount is positive;
- updates balance for valid deposit;
- rejects invalid deposit;
- defines
get_balance; - preserves balance after invalid input.
Common weak answer:
- adding the amount before checking whether it is positive.
Answer 9: Implementation Independence
Model answer:
class Wallet:
def __init__(self, opening_balance):
self._transactions = [opening_balance]
def deposit(self, amount):
if amount > 0:
self._transactions.append(amount)
return True
return False
def withdraw(self, amount):
if amount > 0 and amount <= self.get_balance():
self._transactions.append(-amount)
return True
return False
def get_balance(self):
return sum(self._transactions)
wallet = Wallet(100)
print(wallet.get_balance())
print(wallet.deposit(40))
print(wallet.withdraw(30))
print(wallet.withdraw(200))
print(wallet.get_balance())Expected output:
100
True
True
False
110The calling code still uses deposit(amount), withdraw(amount), and get_balance(). This shows implementation independence: the internal representation changed to transaction records, but the public interface stayed the same.
Mark points:
- initialises
_transactionsas a list containing the opening balance; - keeps the public method names
deposit,withdraw, andget_balance; - accepts only positive deposits and appends accepted deposits;
- accepts withdrawals only when positive and sufficient funds are available;
- records accepted withdrawals as negative transaction amounts;
- calculates the balance from the transaction list;
- produces the expected output, including rejection of the invalid withdrawal.
Common weak answer:
- continuing to store only one
_balancenumber. The question requires a changed internal representation while preserving the public interface.
Answer 10: Display Method
Model answer:
class Item:
def __init__(self, code, name, price):
self.code = code
self.name = name
self.price = price
def __str__(self):
return self.code + " " + self.name + " $" + format(self.price, ".2f")
item = Item("P01", "Pen", 1.5)
print(item)Expected output:
P01 Pen $1.50Mark points:
- defines class
Itemand its constructor; - stores all three instance attributes;
- defines
__str__(self); - formats price to two decimal places;
- returns the exact required string.
Common weak answer:
- returning the raw price with one decimal place, such as
$1.5, when the required display is$1.50.