def make_account(balance, p):
    def withdraw(amount):
        nonlocal balance
        if balance >= amount:
            balance = balance - amount
            return balance
        else:
            return "Insufficient funds"
    def deposit(amount):
        nonlocal balance
        balance = balance + amount
        return balance
    def dispatch(m, q):
        if p == q:
            return (withdraw if m == "withdraw"
                    else deposit if m == "deposit"
                    else "Unknown request: make_account")
        else:
            return lambda q: "Incorrect Password"
    return dispatch

a = make_account(100, "eva")
a("withdraw", "eva")(50)  # withdraws 50
print(a("withdraw", "ben")(40))  # incorrect password
def make_joint(linked_acc, linked_pw, joint_pw):
    def joint(message, input_pw):

        # Check authentication for joint account
        if input_pw != joint_pw:
            return lambda x: "Wrong joint account password"
        else:
            access_linked = linked_acc(message, linked_pw)

            # Check authentication for linked account
            if access_linked(0) == "Incorrect Password":
                # access_linked(0) does deposit / withdrawal of 0
                # to test for "Incorrect Password" message.
                return lambda x: "Wrong linked account password"
            else:
                # All authentication passed, return accessed
                # account to user
                return access_linked
    return joint

peter_acc = make_account(100, "open sesame")
peter_acc("withdraw", "open sesame")(10)  # Withdraws 10
peter_acc("withdraw", "ben")(40)  # Incorrect Password

# Make Joint Account
paul_acc = make_joint(peter_acc, "open sesame", "rosebud")

print(paul_acc("withdraw", "rosebud")(50))  # Withdraws 50, should return 40

# expected: 40
