hw8.py (plain text)


"""CS 61A HW 08
Name:
Login:
TA:
Section:
"""


#### Core Questions
#### Q1
class Amount(object):
    """An amount of nickels and pennies.

    >>> a = Amount(3, 7)
    >>> a.nickels
    3
    >>> a.pennies
    7
    >>> a.value
    22
    >>> a.pennies += 6
    >>> a.pennies
    13
    >>> a.value
    28
    """

    "*** YOUR CODE HERE ***"


class MinimalAmount(Amount):
    """An amount of nickels and pennies with no more than four pennies.

    >>> a = MinimalAmount(3, 7)
    >>> a.nickels
    4
    >>> a.pennies
    2
    >>> a.value
    22
    >>> a.pennies += 6
    >>> a.pennies # Doesn't stay minimal!
    8
    >>> a.value
    28
    """

    "*** YOUR CODE HERE ***"


#### Q2 (and part of Q3)
class Bank:
    """A Bank capable of creating accounts."""

    "*** YOUR CODE HERE ***"


class Account:
    """ An account in a particular bank.

    >>> third_national = Bank()
    >>> second_federal = Bank()
    >>> acct0 = third_national.make_account(1000)
    >>> acct0.withdraw(100)
    >>> acct1 = third_national.make_account(2000)
    >>> third_national.total_holdings()
    2900
    >>> second_federal.total_holdings()
    0
    >>> acct1.deposit(300)
    >>> acct1.balance()
    2300
    >>> third_national.total_holdings()
    3200
    >>> acct1.total_holdings()
    Traceback (most recent call last):
       ...
    AttributeError: 'Account' object has no attribute 'total_holdings'
    >>> acct1.bank().total_holdings()
    3200
    """

    "*** YOUR CODE HERE ***"


#### Q3
class SecurityError(BaseException):
    """Exception to raise if there is an attempted security violation."""
    pass


class SecureAccount(Account):
    """An account that provides password security.
    >>> third_national = Bank()
    >>> acct3 = third_national.make_secure_account(1000, "The magic woid")
    >>> acct3.deposit(1000, 'The magic woid')
    >>> acct3.balance('The magic woid')
    2000
    >>> acct3.balance('Foobar')
    Traceback (most recent call last):
       ...
    hw8.SecurityError: wrong passphrase or account
    >>> acct3.balance()
    Traceback (most recent call last):
       ...
    hw8.SecurityError: passphrase missing
    """

    "*** YOUR CODE HERE ***"


#### Q4
class MissManners(object):
    """A container class that only forward messages that say please.

    >>> some_bank = Bank()
    >>> a = some_bank.make_account(100)
    >>> m = MissManners(a)
    >>> m.ask('balance')
    'You must learn to say please.'
    >>> m.ask('please balance')
    100
    >>> m.ask('please deposit', 20)
    >>> m.ask('balance')
    'You must learn to say please.'
    >>> m.ask('please show me the balance')
    'Thanks for asking, but I know not how to show me the balance'
    >>> m.ask('please balance')
    120
    """

    "*** YOUR CODE HERE ***"


#### Reinforcement Questions
#### Q5
class Monitor:
    """A general-purpose wrapper class that counts the number of times each
    attribute of a monitored object is accessed.

    >>> B = Bank()
    >>> acct = B.make_account(1000)
    >>> mon_acct = Monitor(acct)
    >>> mon_acct.balance()
    1000
    >>> for i in range(10): mon_acct.deposit(100)
    >>> mon_acct.withdraw(20)
    >>> mon_acct.balance()
    1980
    >>> mon_acct.access_count('balance')
    2
    >>> mon_acct.access_count('deposit')
    10
    >>> mon_acct.access_count('withdraw')
    1
    >>> mon_acct.access_count('clear')
    0
    >>> L = list(mon_acct.attributes_accessed())
    >>> L.sort()
    >>> L
    ['balance', 'deposit', 'withdraw']
    """

    "*** YOUR CODE HERE ***"


#### Extra for Experts
#### Q6
class ArgumentMonitor:
    """A general-purpose wrapper class that counts the number of times each
    method of a monitored object is called with each unique argument list.

    >>> B = Bank()
    >>> acct = B.make_account(1000)
    >>> mon_acct = ArgumentMonitor(acct, ['balance', 'withdraw', 'deposit'])
    >>> mon_acct.balance()
    1000
    >>> for i in range(10): mon_acct.deposit(100)
    >>> mon_acct.withdraw(20)
    >>> mon_acct.withdraw(10)
    >>> mon_acct.balance()
    1970
    >>> d = mon_acct.argument_counts('balance')
    >>> d[()]
    2
    >>> d = mon_acct.argument_counts('deposit')
    >>> list(d.items())
    [((100,), 10)]
    >>> d = mon_acct.argument_counts('withdraw')
    >>> d[(10,)]
    1
    >>> d[(20,)]
    1
    """

    def __init__(self, obj, operations):
        """An ArgumentMonitor that monitors the methods named in
        operations for obj."""
        "*** YOUR CODE HERE ***"

    "*** YOUR CODE HERE ***"