Skip to content

Problem 1: Password Protected Account (100pts)

Problem

In the lecture, we learned how to use functions to create mutable objects. Below is a function make_withdraw which produces a function that can withdraw money from an account:

在讲座中,我们学习了如何使用函数来创建可变对象。下面是一个函数 make_withdraw,它生成一个可以从账户中取款的函数:

def make_withdraw(balance):
    """Return a withdraw function with BALANCE as its starting balance.
    >>> withdraw = make_withdraw(1000)
    >>> withdraw(100)
    900
    >>> withdraw(100)
    800
    >>> withdraw(900)
    'Insufficient funds'
    """
    def withdraw(amount):
        nonlocal balance
        if amount > balance:
           return 'Insufficient funds'
        balance = balance - amount
        return balance
    return withdraw

Write a version of the make_withdraw function that returns password-protected withdraw functions. That is, make_withdraw should take a password argument (a string) in addition to an initial balance. The returned function should take two arguments: an amount to withdraw and a password.

A password-protected withdraw function should only process withdrawals when input password is correct. Upon receiving an incorrect password, the function should:

  1. Store that incorrect password in a list, and
  2. Return the string 'Incorrect password'.

If a withdraw function has been called three times with incorrect passwords <p1>, <p2>, and <p3>, then it is locked. All subsequent calls to the function should return:

"Your account is locked. Attempts: [<p1>, <p2>, <p3>]"

The incorrect passwords may be identical or different:

编写一个返回受密码保护的取款函数的 make_withdraw 函数版本。也就是说,make_withdraw 除了初始余额外,还应接受一个密码参数(一个字符串)。返回的函数应该接受两个参数:取款金额和密码。

受密码保护的 withdraw 函数只应在输入的密码正确时处理取款。当接收到不正确的密码时,该函数应:

  1. 将该不正确密码存储在一个列表中,并且
  2. 返回字符串 'Incorrect password'。

如果一个取款函数已被不正确密码 <p1><p2><p3> 调用了三次,则它被锁定。此后所有对该函数的调用都应返回:

"Your account is locked. Attempts: [<p1>, <p2>, <p3>]"

不正确的密码可能是相同或不同的:

def make_withdraw(balance, password):
    """Return a password-protected withdraw function.

    >>> w = make_withdraw(100, 'hax0r')
    >>> w(25, 'hax0r')
    75
    >>> error = w(90, 'hax0r')
    >>> error
    'Insufficient funds'
    >>> error = w(25, 'hwat')
    >>> error
    'Incorrect password'
    >>> new_bal = w(25, 'hax0r')
    >>> new_bal
    50
    >>> w(75, 'a')
    'Incorrect password'
    >>> w(10, 'hax0r')
    40
    >>> w(20, 'n00b')
    'Incorrect password'
    >>> w(10, 'hax0r')
    "Your account is locked. Attempts: ['hwat', 'a', 'n00b']"
    >>> w(10, 'l33t')
    "Your account is locked. Attempts: ['hwat', 'a', 'n00b']"
    >>> type(w(10, 'l33t')) == str
    True
    """
    "*** YOUR CODE HERE ***"

Hints

You may find Python string formatting syntax useful. A quick example:

>>> ten, twenty, thirty = 10, 'twenty', [30]
>>> '{0} plus {1} is {2}'.format(ten, twenty, thirty)
'10 plus twenty is [30]'
>>> ten, twenty, thirty = 10, 'twenty', [30]
>>> '{0} plus {1} is {2}'.format(ten, twenty, thirty)
'10 plus twenty is [30]'
  • 还可以使用 f-string 来格式化字符串。

Solutions