Programming, problem solving, and algorithms

CPSC 203, 2025 W2

January 22, 2026

Announcements

Your current toolkit

  • Representation — how we encode meaning (binary, types, RGB)
  • Collections — how we group things (lists, tuples, dicts)
  • Control flow — how we make decisions and repeat (if/else, loops)
  • Functions — how we name and reuse logic
  • Abstraction — how we hide complexity
  • Efficiency — how we measure cost (summations, timing analysis)

Every problem we solve uses some combination of these.

The pattern: learn a new tool, use it to solve a harder problem.

Today: dataclassesbracelets

Data Classes

Defining our own types

So far we’ve used built-in types: int, float, str, list, tuple

What if we want to represent something more complex?

  • A bead with a radius and a color?
  • A bracelet with beads arranged in a circle?
  • A song with a title and duration?
  • A playlist with a name and songs?

Python lets us define our own types using dataclasses.

A bead bracelet

A colorful beaded bracelet.

What data describes a bead?

What data describes a bracelet?

Dataclasses in Python

A dataclass bundles related data together into a custom type.

This creates a new type called Bead with two attributes.

Creating Bead objects

Your turn: Beads

What would these print?

02:00

Adding behavior: methods

A dataclass can also have methods.

Adding behavior: more methods

Add a draw method:

Calling methods

Questions?

Now that you know about dataclass how would you design a Bracelet?

The Bracelet

A bracelet contains a list of beads and has a radius.

This is composition: a Bracelet contains Beads.

Creating a Bracelet

Does it fit?

The beads fit on the bracelet if the sum of their diameters is less than or equal to the circumference. We refer to the extra string as slack.

How much slack?

Adding beads safely

We only want to add a bead if it fits!

Drawing the bracelet

The full picture

@dataclass
class Bead:
    radius: float
    colour: tuple[int, int, int]

    def diameter(self) -> float: ...
    def draw(self, ax, x: float, y: float) -> None: ...

@dataclass
class Bracelet:
    radius: float
    beads: list[Bead]

    def circumference(self) -> float: ...
    def slack(self) -> float: ...
    def string_bead(self, bead: Bead) -> bool: ...
    def remove_bead(self, index: int) -> Bead: ...
    def draw(self) -> None: ...

Your turn: Experiment

Try the Bracelet Activity on PrairieLearn!

20:00

Design Strategies

  1. Identify the objects in your problem (nouns)

  2. List the data each object needs (attributes)

  3. List the operations each object supports (methods)

  4. Decide which object is responsible for what

  5. Implement and test incrementally

What you learned

  • Dataclasses let us define custom types with attributes
  • Methods are functions that belong to a class
  • Composition: objects can contain other objects
  • Design: who owns what data and behavior matters!