Courseiva

PCAP Object-Oriented Programming Practice Question

A team is developing a banking system in Python. They have a base class Account with attributes account_number and balance, and a method __init__(self, account_number, balance) that initializes these attributes. They then create a subclass SavingsAccount that adds an attribute interest_rate. In SavingsAccount's __init__, they assign self.interest_rate = rate but do not call super().__init__. When they instantiate SavingsAccount('12345', 1000, 0.02) and attempt to print(balance), an AttributeError occurs: 'SavingsAccount' object has no attribute 'balance'. What is the most appropriate fix to ensure that the SavingsAccount includes balance and account_number without code duplication?

⚠ Common exam trap

The trap is that candidates see 'no code duplication' and jump to option B (manually assign the attributes) because it looks explicit and safe, missing that the question is testing the cooperative super().__init__ pattern as the idiomatic, non-duplicating fix.

Answer choices

Why each option matters

Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.

Correct answer & explanation

✓

Call super().__init__(account_number, balance) as the first line in SavingsAccount.__init__, then assign self.interest_rate = rate.

In Python, the subclass SavingsAccount overrides __init__ but never invokes the parent's initializer, so account_number and balance are never set on the instance. Calling super().__init__(account_number, balance) as the first line of SavingsAccount.__init__ runs Account's initializer, which assigns those attributes, and then the subclass can safely set self.interest_rate = rate. This is the canonical cooperative-initialization pattern and avoids duplicating the parent's assignment logic.

Answer analysis

Option-by-option breakdown

For each option: why learners choose it and why it is or isn't the right answer here.

  • ✗

    Remove the __init__ method from SavingsAccount entirely and rely on the default __init__ from Account.

    Why it's wrong here

    If SavingsAccount omits its own __init__, it inherits Account.__init__ which accepts exactly two parameters. Constructing SavingsAccount with three arguments (account_number, balance, rate) raises TypeError because there is no parameter for rate and no way to store it. Even if the object could be created, self.interest_rate would be undefined, causing AttributeError when used in methods that depend on it. Therefore removing __init__ is not a viable solution.

  • ✗

    Manually assign self.account_number and self.balance in SavingsAccount.__init__ before assigning interest_rate.

    Why it's wrong here

    Manually copying the base-class parameter assignments into SavingsAccount.__init__ duplicates logic and creates a maintenance burden: any change in Account's initialization, such as adding validation or computing derived fields, would need to be mirrored by hand. This violates the DRY principle and increases the risk of subtle bugs when the two classes drift apart. While it may produce a working object for the current trivial case, it fails to leverage the base class contract and is not robust.

  • ✓

    Call super().__init__(account_number, balance) as the first line in SavingsAccount.__init__, then assign self.interest_rate = rate.

    Why this is correct

    Calling super().__init__(account_number, balance) immediately at the start of SavingsAccount.__init__ delegates construction of base-class attributes to Account, preserving its invariants and any additional logic it performs. After the delegate call, assigning self.interest_rate = rate adds the subclass-specific attribute. This is the canonical cooperative-inheritance pattern and ensures the object is fully initialized before it is used.

  • ✗

    Define balance as a class attribute in Account with a default value and remove it from __init__.

    Why it's wrong here

    Defining balance as a class attribute with a default value shared across all instances is fundamentally incorrect because balance is mutable, per-account state. A class attribute is accessed via the class, so all SavingsAccount instances would share the same balance value, and mutations on one account would be visible on every other. Furthermore, removing balance from __init__ means it cannot be set at creation time per instance, breaking the required constructor contract. This would produce a system that cannot correctly track distinct accounts.

About these practice questions

One of 421 original PCAP practice questions on Courseiva, each with a full explanation and wrong-answer analysis — not exam dumps or protected exam content. Learn why practice questions differ from exam dumps →

How Courseiva writes practice questions · Editorial policy

JA

Written and reviewed by Johnson Ajibi, MSc IT Security

Senior Network & Security Engineer · founder of Courseiva

Last reviewed September 2026 · checked against the official Python Institute exam blueprint

This PCAP practice question is part of Courseiva's free Python Institute certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the PCAP exam.