CS1602Introduction to Computation
Lab 9Part 4 Abstraction and OrganizationAI Level 1

Designing and Writing Classes

Six problems. Four write classes, one refactors existing dictionary code into a class, and the last asks you to judge whether a class is warranted at all — sometimes it is not.

Due:Homework 3 · Tue 17 Nov, 23:59
Contents

What this session is for

  • Write classes with __init__ and methods comfortably
  • Keep instance and class variables straight
  • See how encapsulation protects the validity of data
  • Develop a sense of when a class is the wrong answer

Problems

9-1 Rectangle

Implement Rectangle:

class Rectangle:
    def __init__(self, width: float, height: float) -> None: ...
    def area(self) -> float: ...
    def perimeter(self) -> float: ...
    def is_square(self) -> bool: ...
    def scale(self, factor: float) -> None: ...     # scale in place
r = Rectangle(3, 4)
r.area()       →  12
r.perimeter()  →  14
r.is_square()  →  False
r.scale(2); r.area()  →  48

Answer in your notes: did you make scale modify the object or return a new one, and why?

9-2 Stack

Implement Stack, last in first out (stacks came up in L7 with the call stack):

class Stack:
    def __init__(self) -> None: ...
    def push(self, item: int) -> None: ...
    def pop(self) -> int: ...
    def peek(self) -> int: ...
    def is_empty(self) -> bool: ...
    def size(self) -> int: ...

What should pop do on an empty stack? You have three options: return None, raise an exception, or require the caller to check first. All three are defensible — but pick one and justify it in your notes.

9-3 A counter

Implement WordCounter:

class WordCounter:
    def __init__(self) -> None: ...
    def add(self, word: str) -> None: ...            # increment the count
    def get(self, word: str) -> int: ...             # 0 for unseen words
    def total(self) -> int: ...                      # sum of all counts
    def most_common(self, n: int) -> list[tuple[str, int]]: ...

most_common sorts as in Lab 6: most frequent first, ties broken alphabetically.

9-4 Temperature: let encapsulation hold the line

Implement Temperature, storing Celsius internally:

class Temperature:
    def __init__(self, celsius: float) -> None: ...
    def celsius(self) -> float: ...
    def fahrenheit(self) -> float: ...
    def kelvin(self) -> float: ...
    def set_celsius(self, value: float) -> bool: ...   # True on success

Requirement: any value below absolute zero (−273.15 °C) must be refused, returning False and leaving the stored value unchanged.

Store it in self._celsius, with the single underscore.

Answer in your notes: without a class — if everyone simply kept a celsius variable and did the arithmetic themselves — what would go wrong?

9-5 Refactor: from dictionaries to a class

Here is some working code. Refactor it into a Gradebook class.

def add_score(book, name, subject, score):
    if name not in book:
        book[name] = {}
    book[name][subject] = score

def average(book, name):
    scores = book[name].values()
    return sum(scores) / len(scores)

def top_student(book):
    return max(book, key=lambda n: average(book, n))

gb = {}
add_score(gb, "Alex", "maths", 87)
add_score(gb, "Alex", "physics", 92)
add_score(gb, "Blake", "maths", 65)
print(average(gb, "Alex"), top_student(gb))

The class should offer add(name, subject, score), average(name) and top_student().

Fix the two problems in the original along the way (hint: what happens when you ask about a student who is not there? what does top_student do with no students at all?). Say what you fixed in your notes.

9-6 Class or not?

For each of these four, decide whether a class is warranted and give a one-sentence reason:

  1. converting Celsius to Fahrenheit
  2. representing a deck of cards that can be shuffled, dealt from, and counted
  3. deciding whether a string is a palindrome
  4. a chatbot that remembers the conversation so far and replies accordingly

Before you submit

  • Every class and method is annotated
  • 9-2 picks one behavior for an empty pop and justifies it
  • 9-3 tested with two objects to confirm the data does not leak
  • 9-4 tested with -300 to confirm it is refused
  • 9-5 fixes both problems in the original and says so
  • 9-6 gives a reason for all four, and not all four are “yes”
  • AI usage declaration written