ATM Machine

February 26, 2019

Since I’ve been writing Awk all day at work, I’ll write this solution in Awk. We keep a file bank that has userid, password and balance in three space-separated fields:

$ cat bank
phil correcthorse 1000
sue horsebattery 1000
john batterystaple 500

Here’s the program:

$ cat atm
BEGIN {
    while (getline < "bank") {
        password[$1] = $2
        balance[$1] = $3 }
    userid = getuserid()
        printf "Your balance is %.2f\n", balance[userid]
    while ((cmd = getcommand()) != "Q") {
        if (cmd == "D") {
            balance[userid] += getamount()
        } else if (cmd == "W") {
            amt = getamount()
            if (amt <= balance[userid]) {
                balance[userid] -= amt
            } else { print "Can't overdraw account" }
        } else { print "Unrecognized command" }
        printf "Your balance is %.2f\n", balance[userid] }
    print "Thank you for your custom."
    for (userid in password) {
        if (userid !~ /^ *$/)
            print userid, password[userid], balance[userid] > "bank" } }

function getuserid(    userid, passwd) {
    userid = ""; passwd = "hello"
    while (passwd != password[userid]) {
        printf "%s ", "Enter userid:"; getline userid
        printf "%s ", "Enter password:"; getline passwd }
    return userid }

function getcommand(    cmd) {
    cmd = "X"
    while (cmd !~ /[dDwWqQ]/) {
        printf "Enter command: D)eposit, W)ithdrawl or Q)uit: "
        getline cmd }
    return toupper(cmd) }

function getamount(   amt) {
    amt = "X"
    while (amt !~ /[1-9][0-9]*\.?[0-9]*/) {
        printf "Enter amount: "; getline amt }
    return amt }</pre>
And here it is in action:
$ awk -f atm
Enter userid: phil
Enter password: correcthorse
Your balance is 1000.00
Enter command: D)eposit, W)ithdrawl or Q)uit: d
Enter amount: 500
Your balance is 1500.00
Enter command: D)eposit, W)ithdrawl or Q)uit: w
Enter amount: 300
Your balance is 1200.00
Enter command: D)eposit, W)ithdrawl or Q)uit: w
Enter amount: 2000
Can't overdraw account
Your balance is 1200.00
Enter command: D)eposit, W)ithdrawl or Q)uit: q
Thank you for your custom.

There is nothing tricky here, just straight forward coding on a simple algorithm. You can run the program at https://ideone.com/szzB46.

Advertisements

Pages: 1 2

4 Responses to “ATM Machine”

  1. matthew said

    Your suggested solution has a large chunk missing (comparing with the ideone version, looks like a section in angle brackets has disappeared).

  2. programmingpraxis said

    @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.

  3. Daniel said

    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] -= amount
    

    Example:

    user> user4
    password> password4
    login error
    user> user2
    password> password2
    balance: 100
    [q] quit
    [d] deposit
    [w] withdraw
    choice> d
    amount> 5
    balance: 105
    [q] quit
    [d] deposit
    [w] withdraw
    choice> w
    amount> 200
    insufficient funds
    balance: 105
    [q] quit
    [d] deposit
    [w] withdraw
    choice> q
    user> 
    
  4. Tim said

    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:

    $ csi atm.scm
    
    Welcome to E-Corp ATM
    =====================
    
    Username --> user1
    Password --> pass1
    
    You currently have 10 CHF.
    
    Options:
    - [D]eposit funds
    - [W]ithdraw funds
    - e[X]it
    > d
    Amount to deposit: 123
    
    You currently have 133 CHF.
    
    Options:
    - [D]eposit funds
    - [W]ithdraw funds
    - e[X]it
    > w
    Amount to withdraw: 12
    
    You currently have 121 CHF.
    
    Options:
    - [D]eposit funds
    - [W]ithdraw funds
    - e[X]it
    > x
    Don't forget your card.
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: