ATM Machine
February 26, 2019
Today’s exercise asks you to simulate an ATM machine:
- Prompt for userid and password. If userid and password are not in the database, reprompt.
- Display balance.
- Present a menu asking to deposit, withdraw or exit. If user selects withdraw or deposit, perform the indicated transaction and goto Step 2. Deny withdrawals that would overdraw the account.
- Exit the program.
Your task is to write a program to simulate an ATM machine. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Your suggested solution has a large chunk missing (comparing with the ideone version, looks like a section in angle brackets has disappeared).
@matthew: Thanks. I think it’s fixed now. On the other hand, last night when I edited the exercise it looked right, too. WordPress has been playing with their editor lately, improving it. Things may change tomorrow.
Here’s a solution in Python.
database = { 'user1': ['password1', 20], 'user2': ['password2', 100], 'user3': ['password3', 0], } while True: user = input('user> ') password = input('password> ') entry = database.get(user) if entry is None or entry[0] != password: print('login error') continue menu = ( '[q] quit\n' '[d] deposit\n' '[w] withdraw' ) while True: balance = entry[1] print('balance: {}'.format(balance)) print(menu) option = input('choice> ') if option == 'q': break elif option == 'd': amount = int(input('amount> ')) entry[1] += amount elif option == 'w': amount = int(input('amount> ')) if amount > balance: print('insufficient funds') else: entry[1] -= amountExample:
Scheme version for completeness:
(import (chicken io) simple-md5 srfi-69) (define account-db (make-hash-table)) (define (prompt-for-line prompt) (print* prompt) (read-line)) (define (get-value prompt) (let ((v (string->number (prompt-for-line prompt)))) (if (and v (>= v 0)) v (begin (print "Invalid amount.") (get-value prompt))))) (define (make-account-dispatcher value) (define (dispatch) (print "\nYou currently have " value " CHF.\n\n" "Options:\n" "- [D]eposit funds\n" "- [W]ithdraw funds\n" "- e[X]it") (case (string->symbol (prompt-for-line "> ")) ((D d) (let ((v (get-value "Amount to deposit: "))) (set! value (+ value v)) (dispatch))) ((W w) (let ((v (get-value "Amount to withdraw: "))) (if (> v value) (print "Insufficient funds!") (set! value (- value v))) (dispatch))) ((X x) (print "Don't forget your card.")) (else (print "Invalid option.") (dispatch)))) dispatch) (define (make-login username password) (cons username (string->md5sum (string-append username password)))) (define (get-login) (make-login (prompt-for-line "Username --> ") (prompt-for-line "Password --> "))) (define (add-account login funds) (hash-table-set! account-db login (make-account-dispatcher funds))) (define (open-account) (print "Assign name and password for new account:") (add-account (get-login) 0) (print "Account created. You may now log in.")) (define (atm) (print "\nWelcome to E-Corp ATM\n" "=====================\n") (let ((login (get-login))) (if (hash-table-exists? account-db login) ((hash-table-ref account-db login)) (print "** Error: Invalid account.")) (atm))) (add-account (make-login "user1" "pass1") 10) (add-account (make-login "user2" "pass2") 20) (add-account (make-login "user3" "pass3") 30) (atm)Example output: