← Back to Blake's Home

Lesson 22: Sets, Abstraction & Exam Practice

Filling the last Year 11 gaps — then putting everything to the test

May 2026 ~90 min Year 11 Gaps + Exam Prep SE-11-08 · SE-11-09 · SE-12-07
🎓

Three full Year 12 modules — done.

Secure Software Architecture, Programming for the Web, and Software Automation are all complete. Before exam prep begins in earnest, there are two small things from Year 11 that never got covered: Sets and Abstraction. We'll close those gaps today, then do some real HSC practice.

1. Warm-Up: OOP Pillar Check ~5 min

Quick recall — no notes. The four pillars of OOP. Name as many as you can.

Show the four pillars
Encapsulation — bundling data and methods together inside a class, and controlling access with private/public.

Inheritance — a child class inherits attributes and methods from a parent class.

Polymorphism — the same method name works differently depending on which class is calling it.

Abstraction — hiding the complex implementation details and exposing only what the caller needs.
🔒

Encapsulation

Bundling + access control. You've got this.

🧬

Inheritance

Child classes. You've got this.

🎭

Polymorphism

Same method, different behaviour. You've got this.

🪄

Abstraction

Today's gap. Let's fix it.

2. Sets — The Data Structure You Didn't Know About ~22 min

SE-11-08 — Data Structures

What is a Set?

A Set is an unordered collection of unique values. That's the whole idea:

  • No duplicates — adding the same value twice does nothing
  • No guaranteed order — you can't index into a Set like a List
  • Extremely fast membership testing — checking "is X in this?" is O(1)

In Python, you make a Set with curly braces — but unlike a Dict, there are no colons:


# Creating a Set
tags = {"python", "web", "security", "python"}   # duplicate "python" is silently dropped
print(tags)   # {'python', 'web', 'security'}   — order may vary

# Empty set — must use set(), not {} (that makes an empty dict)
empty = set()

# Adding and removing
tags.add("automation")
tags.discard("web")    # safe remove — no error if missing
tags.remove("web")     # also removes, but raises KeyError if missing

# Membership check — O(1), much faster than a List for large data
print("security" in tags)   # True
        

Why does order not matter? Sets are backed by a hash table — the same structure as Dict keys. That's why membership checking is O(1) instead of O(n) like a List. The trade-off: you can't have duplicates, and order is not defined.

Set vs List vs Dict — Pick the Right Tool

Blake, in Lesson 2 you chose a Dict when a Set was the better fit. Here's how to think about it:

List

List

  • Ordered
  • Allows duplicates
  • Index access (list[0])
  • O(n) membership

Use when: you care about order, or you need duplicates, or you need index access.

Dict

Dict

  • Key → Value pairs
  • Keys unique, values not
  • O(1) key lookup
  • Preserves insertion order (Python 3.7+)

Use when: you need to map one thing to another (name → score, username → role).

Set

Set

  • Unique values only
  • Unordered
  • O(1) membership
  • Set math operations

Use when: you need deduplication, fast membership checks, or math on groups.

Volcanic Pantheon example: You track which users have visited each shrine page. If you use a List, the same visitor gets counted multiple times. Swap to a Set — duplicates vanish automatically. Then len(visitors_set) gives you the unique count instantly.

Set Operations — the Superpower

This is where Sets shine. You can do set math with simple operators:


admins   = {"blake", "luis", "admin"}
students = {"blake", "kai", "mia", "jordan"}

# Union — everyone in either group
print(admins | students)      # {'blake', 'luis', 'admin', 'kai', 'mia', 'jordan'}

# Intersection — only people in BOTH groups
print(admins & students)      # {'blake'}

# Difference — in admins but NOT in students
print(admins - students)      # {'luis', 'admin'}

# Symmetric difference — in one or the other, but not both
print(admins ^ students)      # {'luis', 'admin', 'kai', 'mia', 'jordan'}
        

Real Scenario: Permission System

Your Volcanic Pantheon site has protected pages. A user can view a page only if their permission set contains the required permissions. How do you check?


user_permissions    = {"view_shrine", "leave_comment", "view_gallery"}
required_for_page   = {"view_shrine", "view_gallery"}

# Does the user have ALL required permissions?
# Intersection should equal the required set
can_access = required_for_page.issubset(user_permissions)
print(can_access)   # True

# Or equivalently:
can_access = required_for_page <= user_permissions   # <= means "is subset of"
        

Challenge: Right Tool, Right Job

For each scenario, say whether you'd use a List, Dict, or Set, and why in one sentence.

  1. Storing the sequence of moves in a chess game (order matters, duplicates possible)
  2. Mapping each student's name to their latest grade
  3. Tracking which IP addresses have visited your site (want unique IPs only, fast lookup)
  4. Finding which students are enrolled in both Software Engineering AND English Advanced
Show answers
  1. List — order matters (move sequence), duplicates allowed (same move can repeat).
  2. Dict — key (name) maps to a value (grade).
  3. Set — uniqueness enforced automatically, O(1) "have we seen this IP?" check.
  4. Set — intersection of two Sets gives exactly who's in both.

3. Abstraction — The Last Pillar ~20 min

SE-11-09 — OOP Paradigm

The One-Line Definition

Abstraction means hiding how something works and exposing only what it does.

You already use abstraction every day without knowing it:

  • You call list.sort() without knowing it uses Timsort internally
  • You call model.fit(X, y) without knowing it runs gradient descent
  • You open a file with open() without knowing how the OS handles file descriptors

All of those are abstracted APIs — the complexity is hidden, a clean interface is exposed.

Abstraction vs Encapsulation — they're NOT the same

Encapsulation: bundling data and methods together and controlling who can access them (public/private). It's about structure.

Abstraction: hiding the implementation and exposing a clean interface. It's about design.

Encapsulation is how you implement abstraction — but they answer different questions.

From Lesson 19: You Already Wrote Abstraction

Remember the MLPipeline class from Lesson 19? That was abstraction in action. The caller didn't need to know about StandardScaler, or that fit() calls two things internally. They just called pipeline.train(X, y).


# Lesson 19 — the caller uses this simple interface:
pipeline = MLPipeline(LinearRegression())
pipeline.train(X_train, y_train)
result = pipeline.evaluate(X_test, y_test)

# The IMPLEMENTATION is hidden — they don't see this complexity:
def train(self, X, y):
    X_scaled = self.scaler.fit_transform(X)   # hidden
    self.model.fit(X_scaled, y)               # hidden
    self._is_trained = True                   # hidden
        

The test: if a caller can use your class without reading your implementation, you've achieved abstraction. A good abstraction means the internal logic could be completely rewritten and the caller wouldn't need to change a line.

Abstract Base Classes — Enforcing an Interface

Python's abc module lets you define an abstract base class (ABC). An ABC says: "any class that inherits from me must implement these methods." It's like a contract.

This is how Python enforces abstraction at the design level.


from abc import ABC, abstractmethod

class AuthProvider(ABC):
    """Anyone who implements authentication must provide these two methods."""

    @abstractmethod
    def login(self, username: str, password: str) -> bool:
        pass   # No implementation here — just the contract

    @abstractmethod
    def logout(self, username: str) -> None:
        pass


# A concrete class that fulfils the contract:
class JWTAuth(AuthProvider):
    def login(self, username, password):
        # Real JWT verification logic here
        return verify_jwt(username, password)

    def logout(self, username):
        invalidate_token(username)


# A different concrete class — same interface, different internals:
class SessionAuth(AuthProvider):
    def login(self, username, password):
        # Session-based login logic
        return check_session_db(username, password)

    def logout(self, username):
        clear_session(username)


# If you forget to implement login() or logout(), Python raises a TypeError at runtime:
class BrokenAuth(AuthProvider):
    pass   # Missing both methods

auth = BrokenAuth()   # TypeError: Can't instantiate abstract class BrokenAuth
        
Volcanic Pantheon connection: You currently have one auth system — SHA-256 in the browser. If you ever moved to server-side auth, you'd want an AuthProvider ABC so you could swap implementations without breaking the rest of the site.

All Four Pillars — Together

Here's a quick example that uses all four in one class hierarchy:


from abc import ABC, abstractmethod

# ABSTRACTION: defines the interface — "what" without "how"
class Shape(ABC):
    @abstractmethod
    def area(self) -> float:
        pass

    @abstractmethod
    def perimeter(self) -> float:
        pass

    def describe(self):                   # concrete method — shared by all
        return f"Area: {self.area():.2f}, Perimeter: {self.perimeter():.2f}"


# INHERITANCE: Circle and Rectangle inherit from Shape
class Circle(Shape):
    def __init__(self, radius: float):
        self._radius = radius             # ENCAPSULATION: private attribute

    def area(self):
        return 3.14159 * self._radius ** 2

    def perimeter(self):
        return 2 * 3.14159 * self._radius


class Rectangle(Shape):
    def __init__(self, w: float, h: float):
        self._w = w
        self._h = h

    def area(self):
        return self._w * self._h

    def perimeter(self):
        return 2 * (self._w + self._h)


# POLYMORPHISM: same method name, different behaviour
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
    print(shape.describe())   # calls each class's own area() + perimeter()
        

Spot the Pillar

Match each numbered line to its OOP pillar (Encapsulation, Inheritance, Polymorphism, Abstraction):

  1. @abstractmethod on area() in the base class
  2. self._radius = radius (note the underscore)
  3. class Circle(Shape):
  4. shape.describe() calling different area() for each type in the loop
Show answers
  1. Abstraction — defining the interface without the implementation.
  2. Encapsulation — making the attribute private, controlling access.
  3. Inheritance — Circle inherits from Shape.
  4. Polymorphism — same describe() call, different area() results.

4. HSC Exam Practice ~38 min

SE-12-07 — Evaluate & Optimise

HSC Action Verbs — What the Marker Wants

Every HSC question uses a specific verb. Getting the verb wrong loses marks even if your content is correct.

Verb What it means Typical marks Example
describe Give features/characteristics. What it is, what it does. 1–3 "Describe what hashing is."
explain Make something clear. Show cause-and-effect or how/why. 2–4 "Explain how a SQL injection attack works."
assess Weigh up evidence. Consider both sides. Make a judgement. 4–6 "Assess the impact of ML on employment."
design/develop Produce a plan, diagram, or code. Show the artefact. 3–6 "Design a class diagram for this system."

For "assess" questions (4+ marks), use PEEL:
Point — state your claim.
Evidence — give a specific example or case study.
Explanation — explain why the evidence supports your point.
Link — tie it back to the question.

Secure Software Architecture 3 marks
Explain

Explain how parameterised queries prevent SQL injection attacks. In your answer, refer to how user input is handled differently to a regular query.

Approx. 5–6 lines

Show worked answer

In a regular (vulnerable) SQL query, user input is concatenated directly into the query string. This means an attacker can enter input like ' OR '1'='1, which is interpreted as part of the SQL command, giving them unauthorised access.

Parameterised queries separate the SQL structure from the data. The query is compiled first with placeholders (e.g., ? or %s), and user input is passed in as a separate parameter. The database treats the input purely as data — it is never interpreted as SQL syntax, so injected commands cannot execute.

Mark allocation: 1 mark — identifies the vulnerability in direct concatenation. 1 mark — explains how placeholders separate structure from data. 1 mark — explains why input cannot execute as SQL.

Programming for the Web 4 marks
Describe

Describe the roles of the client and the server in a client-server web application. In your answer, include examples of tasks performed by each.

Approx. 6–8 lines

Show worked answer

Client: The client is the user's device (typically a browser). It is responsible for sending requests to the server (e.g., clicking a link sends an HTTP GET request), rendering the HTML/CSS/JavaScript response, and handling user interaction. The client runs code that executes on the user's machine — JavaScript, for example, can update the page without reloading it.

Server: The server listens for requests, processes business logic (e.g., querying a database, verifying authentication), and returns a response — typically HTML, JSON, or other data. The server runs code that the user cannot see or modify, making it the appropriate place for sensitive operations such as password verification, database access, and API key handling.

Mark allocation: 1 mark each — client role, client example, server role, server example.

Software Automation 5 marks
Assess

Assess the impact of machine learning and automation on employment. In your answer, consider both negative and positive effects on individuals and society.

Approx. 10–12 lines

Show worked answer (PEEL structure)

Negative — job displacement: Automation eliminates repetitive roles. Amazon's warehouse robotics reduced picker headcount significantly, and self-checkout kiosks displaced retail cashiers. These workers, often low-income, may lack the skills to transition quickly, increasing short-term unemployment and economic inequality.

Positive — job creation and safety: Automation also creates roles — ML engineers, data annotators, robot maintenance technicians. In high-risk industries such as mining and manufacturing, cobots handle dangerous tasks, reducing workplace injuries. Workers with disabilities benefit from AI-powered assistive technology that enables participation in the workforce.

Overall judgement: The net impact depends heavily on reskilling investment. Without government and industry support for displaced workers, automation risks widening inequality. With it, automation has the potential to improve safety, productivity, and accessibility across society.

Mark allocation: 1–2 marks — describes negative impact with example. 1–2 marks — describes positive impact with example. 1 mark — makes a supported overall judgement.

Major Project 3 marks
Describe

Describe the difference between functional and non-functional requirements. Give ONE example of each for a student mark-tracking web application.

Approx. 4–6 lines

Show worked answer

Functional requirements define what the system shall do — specific, observable behaviours. Example: "The system shall allow a student to enter a mark for each assessment task and store it persistently."

Non-functional requirements define the quality of how the system does it — performance, security, usability. Example: "The system shall load the dashboard in under two seconds on a standard school network connection."

Mark allocation: 1 mark — defines functional requirement. 1 mark — defines non-functional requirement. 1 mark — gives a correct and distinct example of each.

OOP & Data Structures 4 marks
Explain

Explain the concept of abstraction in object-oriented programming. In your answer, describe how abstract base classes support abstraction and give ONE benefit of using them.

Approx. 6–8 lines

Show worked answer

Abstraction is the OOP principle of hiding the implementation details of a class and exposing only the interface that callers need. The caller knows what a method does, not how it does it. This reduces complexity and makes systems easier to use and maintain.

Abstract base classes (ABCs) support abstraction by defining methods that subclasses must implement. Using Python's abc module, a method decorated with @abstractmethod cannot be inherited without providing an implementation — Python raises a TypeError if a concrete subclass skips it. This enforces a consistent interface across all subclasses.

Benefit: ABCs enable substitutability — any subclass can be swapped for another without changing the calling code, as long as both implement the same interface. This supports modular, maintainable software.

Mark allocation: 1 mark — defines abstraction. 1 mark — explains how ABCs work. 1 mark — gives a concrete benefit. 1 mark — quality/depth of explanation.

5. Wrap-Up & Homework ~5 min

What We Covered

  • Sets — unordered, unique, O(1) membership, set math. Use when you need deduplication or group operations.
  • Abstraction — the 4th OOP pillar. Hiding implementation, exposing interface. ABCs enforce contracts across subclasses.
  • HSC Exam Technique — action verbs (describe / explain / assess), PEEL for extended responses, mark allocation thinking.

All four OOP pillars — complete.

Encapsulation, Inheritance, Polymorphism, Abstraction. The Year 11 OOP gap is closed.

Sets are now in your toolkit alongside List and Dict. You know when to use each.

Homework

Pick one of the following:

  1. Sets in Volcanic Pantheon: Find one place in your site where you're using a List when a Set would be better (e.g., tracking unique visitors, unique tags, visited pages). Refactor it. Write a comment explaining why Set is the right choice there.
  2. Abstract your auth: Create an AuthProvider ABC with login() and logout() methods. Write one concrete subclass that represents your current client-side SHA-256 approach. Write a second concrete subclass that represents a hypothetical server-side JWT approach. You don't need working code — just the class structure and method stubs.
  3. Exam practice: Write your own response to Q3 (the automation/employment assess question) without looking at the worked answer. Aim for PEEL structure and a supported judgement at the end.