Q.
Suppose that our banking system requires the ability to make joint accounts. Define a function
make_jointthat takes three arguments.
A password-protected
withdrawfunction,The password with which that
withdrawfunction was defined, andA new password that can also access the original account.
The
make_jointfunction returns awithdrawfunction that provides additional access to the original account using either the new or old password. Both functions draw down the same balance. Incorrect passwords provided to either function will be stored and cause the functions to be locked after three wrong attempts.Hint: The solution is short (less than 10 lines) and contains no string literals! The key is to call
withdrawwith the right password and interpret the result. You may assume that all failed attempts towithdrawwill return some string (for incorrect passwords, locked accounts, or insufficient funds), while successful withdrawals will return a number.Use
type(value) == strto test if some value is a string:
Solution
def make_withdraw(balance, password):
"""Return a password-protected withdraw function.
>>> w = make_withdraw(100, 'hax0r')
>>> w(25, 'hax0r')
75
>>> w(90, 'hax0r')
'Insufficient funds'
>>> w(25, 'hwat')
'Incorrect password'
>>> w(25, 'hax0r')
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']"
"""
incorrect_password_list = []
count = 0
def withdraw(amount, input_passwd):
nonlocal count
if count < 3:
if input_passwd == password:
nonlocal balance
if amount < balance:
balance -= amount
return balance
else:
return "Insufficient funds"
else:
nonlocal incorrect_password_list
incorrect_password_list.append(input_passwd)
count += 1
return "Incorrect password"
else:
return "Your account is locked. Attempts: ['{0}', '{1}', '{2}']".format(incorrect_password_list[0], incorrect_password_list[1], incorrect_password_list[2])
return withdraw
def make_joint(withdraw, old_passwd, new_passwd):
"""
>>> 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'
"""
value = withdraw(0, old_passwd)
if type(value) == str:
return "Incorrect password"
else:
def joint_withdraw(balance, input_passwd):
if (input_passwd == old_passwd) or (input_passwd == new_passwd):
return withdraw(balance, old_passwd)
return joint_withdraw
My question:
Apart from test cases mentioned in docstring of above solution make_joint, below additional test cases are yet to pass, Please provide an hint to modify make_joint to satisfy these given additional test cases(below).
>>> 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']"
Let's just focus on these lines:
What happens when the
input_passwdis neither theold_passwdnor thenew_passwd? Your function gives does nothing, and gives no response.Note that you already have code to respond to incorrect passwords. How can you define
joint_withdrawto reuse that functionality?Fix that problem in the way that I hinted, and you should be able to get
j2(5, 'hax0r')to work.