Homework 6: Classes

  • Due: Thursday 10/22 @ 11:59pm
  • Points: 1
  • Download: hw06.zip

To receive credit, you must solve each problem and then complete a short checkoff interview about your solution. You may use Preceptor for the interview or come to office hours to be interviewed by a member of the course staff. Staff will be doing in-person checkoffs for up to 3 business days after the assignment deadline (including any approved extension). If a checkoff happens more than 3 business days after the regular deadline, staff may ask to confirm your extended deadline via Flextensions. You will submit a Provenance bundle that includes a record of how you used VS Code, including interactions with Preceptor. Please do not use AI tools other than Preceptor for this assignment.

Readings: This homework relies on the following readings from Composing Programs:

Required Questions

Survey

Q1: Mid-Semester Feedback

As part of this assignment, fill out the Mid-Semester Feedback form.

Once you finish the survey, you will be presented with a passphrase. Put this passphrase, as a string, on the line that says passphrase = 'REPLACE_THIS_WITH_PASSPHRASE' in the Python file for this assignment. For example, if the passphrase is abc, then the line should be passphrase = 'abc'.

python3 -m pytest -k midsem_survey

OOP

Q2: Free Checking

Let's improve the Account class from lecture, which models a bank account that can process deposits and withdrawals.

class Account:
    """An account has a balance and a holder.

    >>> a = Account('John')
    >>> a.deposit(10)
    10
    >>> a.balance
    10
    >>> a.interest
    0.02
    >>> a.time_to_retire(10.25)  # 10 -> 10.2 -> 10.404
    2
    >>> a.balance                # time_to_retire should not change the balance
    10
    >>> a.time_to_retire(11)     # 10 -> 10.2 -> ... -> 11.040808032
    5
    >>> a.time_to_retire(100)
    117
    """
    max_withdrawal = 10
    interest = 0.02

    def __init__(self, account_holder):
        self.balance = 0
        self.holder = account_holder

    def deposit(self, amount):
        self.balance = self.balance + amount
        return self.balance

    def withdraw(self, amount):
        if amount > self.balance:
            return "Insufficient funds"
        if amount > self.max_withdrawal:
            return "Can't withdraw that amount"
        self.balance = self.balance - amount
        return self.balance

First, add a time_to_retire method to the Account class. This method takes an amount and returns the number of years until the current balance grows to at least amount, assuming that the bank adds the interest (the current balance multiplied by the interest rate) to the balance at the end of each year.

Important: Calling time_to_retire should not change the account balance.

    def time_to_retire(self, amount):
        """Return the number of years until balance would grow to amount."""
        assert self.balance > 0 and amount > 0 and self.interest > 0
        "*** YOUR CODE HERE ***"

Second, implement the FreeChecking class, which is like Account except that it charges a withdrawal fee withdraw_fee after free_withdrawals withdrawals. If a withdrawal is unsuccessful, no fee is charged, but it still counts toward the number of free withdrawals remaining.

class FreeChecking(Account):
    """A bank account that charges for withdrawals, but the first two are free!

    >>> ch = FreeChecking('Jack')
    >>> ch.balance = 20
    >>> ch.withdraw(100)  # First one's free, even though it was unsuccessful
    'Insufficient funds'
    >>> ch.withdraw(3)    # Second withdrawal is also free
    17
    >>> ch.balance
    17
    >>> ch.withdraw(3)    # Now there is a fee, since free_withdrawals is 2
    13
    >>> ch.withdraw(3)
    9
    >>> ch2 = FreeChecking('John')
    >>> ch2.balance = 10
    >>> ch2.withdraw(3)   # No fee
    7
    >>> ch.withdraw(3)    # ch still charges a fee
    5
    >>> ch.withdraw(5)    # Not enough to cover fee + withdraw
    'Insufficient funds'
    """
    withdraw_fee = 1
    free_withdrawals = 2

    "*** YOUR CODE HERE ***"
python3 -m pytest -k checking

Q3: Cucumber

Cucumber is a card game. Cards are positive integers (no suits). A Cucumber game has a number of players, numbered 0 through players - 1: 0, 1, 2, and 3 in a 4-player game.

A Round is created with its starter player and the Cucumber game it is played in. In each Round, the players each play one card, starting with the starter and in ascending order (player 0 follows player 3 in a 4-player game). If the card played is as high as or higher than the highest card played so far, the player who played it takes control. Once every player has played one card, the round is complete, and its winner is the last player who took control. If a player tries to play out of turn or after the round is over, the card is not played, and play returns an error message instead, which play_round prints.

Complete the Round class, adding instance attributes as needed.

class Cucumber:
    """A game of Cucumber that records the winner of each completed round.

    Each (who, card) pair in cards indicates who plays and what card they play.

    >>> g = Cucumber(4)
    >>> g.play_round(3, [(3, 4), (0, 8), (1, 8), (2, 5)])
    >>> g.winners
    [1]
    >>> g.play_round(1, [(3, 5), (1, 4), (2, 5), (0, 8), (3, 7), (0, 6), (1, 7)])
    It is not your turn, player 3
    It is not your turn, player 0
    The round is over, player 1
    >>> g.winners
    [1, 3]
    >>> g.play_round(3, [(3, 7), (2, 5), (0, 9)]) # Round is never completed
    It is not your turn, player 2
    >>> g.winners
    [1, 3]

    >>> h = Cucumber(3)
    >>> h.play_round(2, [(2, 5), (0, 6), (1, 4), (2, 9)])
    The round is over, player 2
    >>> h.winners
    [0]
    """
    def __init__(self, num_players):
        self.winners = []
        self.players = num_players

    def play_round(self, starter, cards):
        r = Round(starter, self)
        for who, card in cards:
            error = r.play(who, card)
            if error is not None:
                print(error)
        if r.winner is not None:
            self.winners.append(r.winner)


class Round:
    """One round of Cucumber."""
    def __init__(self, starter, game):
        self.starter = starter
        self.next_player = starter
        self.winner = None
        "*** YOUR CODE HERE ***"

    def play(self, who, card):
        """Play card for player who, or return an error string if who can't play."""
        if self.is_complete():
            return f'The round is over, player {who}'
        if who != self.next_player:
            return f'It is not your turn, player {who}'
        self.next_player = _____
        if _____:
            "*** YOUR CODE HERE ***"
        if self.is_complete():
            "*** YOUR CODE HERE ***"

    def is_complete(self):
        """Return whether every player has played once in this round."""
        "*** YOUR CODE HERE ***"
python3 -m pytest -k Cucumber

Submit

Run Provenance: Prepare Submission Bundle from the VS Code command palette to create your submission zip, and upload that zip to Gradescope. For a refresher on how to do this, refer to Lab 00.

Optional Questions

These questions are optional. If you don't complete them, you will still receive credit for this assignment. They are great practice, so do them anyway!

Q4: Cat

Below is the implementation of a Pet class. Each pet has two instance attributes (name and owner), as well as one instance method (talk).

class Pet:

    def __init__(self, name, owner):
        self.name = name
        self.owner = owner

    def talk(self):
        print(self.name)

Implement the Cat class, which inherits from Pet. To complete the implementation, override or implement the following methods:

__init__

Set the Cat's name and owner attributes, and also add 2 new attributes:

  1. is_hungry — should be set to False
  2. fullness — should be set to whatever the fullness parameter is

Hint: You can call the __init__ method of Pet (the superclass of Cat) to set a cat's name and owner using super().

talk

Print out a cat's greeting, which is "<name of cat> says meow!".

get_hungry

Decrement a cat's fullness level by 1. When fullness reaches zero, is_hungry becomes True. If this is called after fullness has already reached zero, print the message "<name of cat> is hungry."

eat

This method is called when the cat eats some food. If the cat is hungry, then after calling this method both of the following should be true:

  1. The cat's fullness value is set to whatever Cat.default_fullness is.
  2. The cat's is_hungry value is False.

Also print out the food the cat ate. For example, if a cat named Thomas ate fish, print 'Thomas ate a fish!'

Otherwise, if the cat wasn't hungry, print '<name of cat> is not hungry.'

class Cat(Pet):
    default_fullness = 5

    def __init__(self, name: str, owner: str, fullness: int = default_fullness):
        """
        >>> cat = Cat('Thomas', 'Tammy')
        >>> cat.name
        'Thomas'
        >>> cat.owner
        'Tammy'
        >>> cat.fullness  # use default fullness value
        5
        >>> cat.is_hungry
        False
        >>> cat2 = Cat('Meow Meow', 'Yoobin', 3)
        >>> cat2.fullness  # use fullness value that was passed in
        3
        """
        "*** YOUR CODE HERE ***"

    def talk(self) -> None:
        """
        >>> Cat('Thomas', 'Tammy').talk()
        Thomas says meow!
        >>> Cat('Meow Meow', 'ThuyAnh').talk()
        Meow Meow says meow!
        """
        "*** YOUR CODE HERE ***"

    def get_hungry(self) -> None:
        """
        >>> cat = Cat('Thomas', 'Tammy', 2)
        >>> cat.is_hungry
        False
        >>> cat.fullness
        2
        >>> cat.get_hungry()
        >>> cat.is_hungry
        False
        >>> cat.fullness
        1
        >>> cat.get_hungry()
        >>> cat.is_hungry
        True
        >>> cat.fullness
        0
        >>> cat.get_hungry()
        Thomas is hungry.
        >>> cat.is_hungry
        True
        >>> cat.fullness
        0
        """
        "*** YOUR CODE HERE ***"

    def eat(self, food: str) -> None:
        """
        >>> cat = Cat('Crookshanks', 'Hermione', 1)
        >>> cat.eat('tuna')
        Crookshanks is not hungry.
        >>> cat.is_hungry
        False
        >>> cat.fullness
        1
        >>> cat.get_hungry()
        >>> cat.eat('tuna')
        Crookshanks ate a tuna!
        >>> cat.is_hungry
        False
        >>> cat.fullness
        5
        """
        "*** YOUR CODE HERE ***"
python3 -m pytest -k cat

Back to Top

Accessibility Nondiscrimination

Copyright ©2026, Regents of the University of California and respective authors.

This site is built following the Berkeley Class Site template, which is generously based on the Just the Class, and Just the Docs templates.

View all course offerings