Skip to content

Problem 2: Joint Account (100pts)

Problem

Suppose that our banking system requires the ability to make joint accounts, which enables an additional password for for original account. Please help to define the function make_joint that takes three arguments.

  1. A password-protected withdraw function, like the one generated by make_withdraw.
  2. Any registered password for withdraw function.
  3. The additional password you want to enable to access the original account.

If the old password is incorrect or the account is already locked, make_joint should propagate the error. Otherwise, it returns a withdraw function that provides additional access to the original account using either the new or old password. Both functions draw from the same balance. Incorrect passwords provided to either function will be stored and cause the functions to be locked after three wrong attempts.

假设我们的银行系统需要具备创建联名账户的能力,这使得原始账户可以启用额外的密码。请帮助定义函数 make_joint,它接受三个参数:

  1. 一个受密码保护的 withdraw 函数,就像由 make_withdraw 生成的那种。
  2. withdraw 函数的任何一个已注册密码。
  3. 您想要启用以访问原始账户的附加密码。

如果旧密码不正确或账户已被锁定,make_joint 应传播(返回)错误信息。 否则,它返回一个新的 withdraw 函数,该函数允许使用新密码旧密码访问原始账户。 这两个函数都从同一个余额中取款。 提供给任一函数的不正确密码都将被存储,并在三次错误尝试后导致这些函数被锁定。

def make_joint(withdraw, old_pass, new_pass):
    """Return a password-protected withdraw function that has joint access to
    the balance of withdraw.

    >>> w = make_withdraw(100, 'hax0r')
    >>> w(25, 'hax0r')
    75
    >>> make_joint(w, 'my', 'secret')
    'Incorrect password'
    >>> j = make_joint(w, 'hax0r', 'secret')
    >>> w(25, 'secret')
    'Incorrect password'
    >>> j(25, 'secret')
    50
    >>> j(25, 'hax0r')
    25
    >>> j(100, 'secret')
    'Insufficient funds'

    >>> j2 = make_joint(j, 'secret', 'code')
    >>> j2(5, 'code')
    20
    >>> j2(5, 'secret')
    15
    >>> j2(5, 'hax0r')
    10

    >>> j2(25, 'password')
    'Incorrect password'
    >>> j2(5, 'secret')
    "Your account is locked. Attempts: ['my', 'secret', 'password']"
    >>> j(5, 'secret')
    "Your account is locked. Attempts: ['my', 'secret', 'password']"
    >>> w(5, 'hax0r')
    "Your account is locked. Attempts: ['my', 'secret', 'password']"
    >>> make_joint(w, 'hax0r', 'hello')
    "Your account is locked. Attempts: ['my', 'secret', 'password']"
    """
    "*** YOUR CODE HERE ***"

Hints

Hint1: The solution is short (less than 10 lines) and contains no string literals! The key is to call withdraw with the right password and amount, then interpret the result. You may assume that all failed attempts to withdraw will return some string (for incorrect passwords, locked accounts, or insufficient funds), while successful withdrawals will return a number.

Hint2: You can use type(value) == str to test if some value is a string.

  • 解决方案很短(少于 10 行)并且不包含字符串字面量!关键在于使用正确的密码和金额调用 withdraw,然后解释结果。您可以假设所有取款失败的尝试都会返回某个字符串 (对于不正确的密码、锁定的账户或资金不足),而成功的取款将返回一个数字。

  • 您可以使用 type(value) == str 来测试某个值是否为字符串。

  • 你可能需要定义一个辅助函数。

  • 写了超过 10 行很正常。

  • 列表不需要使用 nonlocal(当然你写 nonlocal 也不会报错)

Solutions