Lisp Project #2, The Bank
Due: Monday, February 21
Write a Lisp program that interprets an input file detailing the creation
of bank accounts, withdrawals and deposits to and from those accounts,
and printing of the balances of accounts. The data of each account
should be stored in a structure. The structures should be organized
into an association list, keyed by the account owner's name.
You must provide a function named MAIN, which takes a single argument,
the name of the input file.
For extra credit (a full grade increase to any programming assignment),
store the data not in an association list, but in a binary search tree,
sorted by the account owner's name.
Additional extra credit (a half grade increase to any programming assignment)
will be awarded to any program not using any global variables, but one, the
association list of accounts.
The input file:
Each line of the input file will be of one of five types (and formats)
-
new name initial-balance: Opens a new bank account,
where name is a single symbol, the name of the owner of the account.
initial-balance is a number, the amount of money initially in the
account. The function should print the message: "Account opened for
name
in the amount of initial-balance."
-
draw name amount: Attempts to make a withdrawl from
the account belonging to name. If no such account exists,
print "No account exists for an owner named name." If the
withdrawl amount exceeds the current balance in that account, print "Insufficient
funds to withdrawl amount from name's account. Current
balance is current-balance", where current-balance is the
amount of money currently in that account. In all other cases, debit
the appropriate account by the given amount, and print the message:
"Account for name is debitted amount, leaving a balance of
current-balance."
-
deposit name amount: If there is an account belonging to
name,
credit the account by amount, and print "Account for
name
is creditted amount, leaving a balance of current-balance."
If there is no such account, print the message, "No account exists for
an owner named name."
-
print name: If there is an account belonging to name,
print "The account belonging to name currently has a balance of
current-balance.
The transactions on this account are", and then a series of indented lines,
each line of the form, "DEPOSIT amount balance" or "DEBIT amount
balance", where balance was the balance of the account just
after the corresponding transaction was completed. The transactions
should be listed from oldest (top) to most recent (bottom).
-
printall s-expression: s-expression will be
a single s-expression that evaluates to T or NIL. The s-expression
will contain the symbols NAME and BALANCE. Your program should evaluate
the s-expression on each account currently in the system, giving NAME the
name of the account (a string), and BALANCE, the curernt balance of that
account. For each account for which the s-expression does not evaluate
to NIL, the program should print "The account name with balance
current-balance satisfies the given s-expression."
Lisp you will need:
defstruct
nth
read
open
symbol-name
string<
You might also want to use FORMAT, to generated formatted output for
your tables.
Recommended course of action:
Write a simple version of MAIN that simply opens the file of the
given name, and reads the contents of the file, one symbol at a time, printing
those symbols. For example, say I created a file "D:/Matt/test.txt"
containing:
new bob 100
deposit bob 150
then called (main "D:/Matt/test.txt"), this should generate the output:
NEW
BOB
100
DEPOSIT
BOB
150
Next, try implementing the system using an association list. There
is info
on association lists on CMU's on-line
version of ClTl2. The key operators with association lists (or
"a-lists") are ACONS and ASSOC. Here is a simple explanation of their
workings:
acons key datum a-list
acons constructs a new association list by adding the pair (key . datum)
to the old a-list.
assoc item a-list &key :test :test-not :key
assoc-if predicate a-list
assoc-if-not predicate a-list
Each of these searches the association list a-list. The value is the
first pair in the a-list such that the car of
the pair satisfies the test, or nil if there is no such pair in the
a-list.
You'll want to keep the transactions for each account in a list, probably,
to facilitate the PRINT operator.
Sample Input
new bob 100
deposit bob 150
new sue 300
draw sue 50
draw bob 70
new tom 500
print bob
new emma 400
printall (> balance 199)
deposit bob 100
printall (and (> balance 199) (string< name "PPP"))
Sample Output
Account opened for BOB in the amount of $100.
Account for BOB is creditted $150, leaving a balance of $250.
Account opened for SUE in the amount of $300.
Account for SUE is debitted $50, leaving a balance of $250.
Account for BOB is debitted $70, leaving a balance of $180.
Account opened for TOM in the amount of $500.
The account belonging to BOB currently has a balance of $180.
The transactions on this account are:
Trans Amt Bal
DEPOSIT 100 100
DEPOSIT 150 250
DEBIT 70 180
Account opened for EMMA in the amount of $400.
The following accounts satisfy the given s-expression, (> BALANCE
199):
EMMA, SUE, TOM
Account for BOB is creditted $100, leaving a balance of $280.
The following accounts satisfy the given s-expression,
(AND (> BALANCE 199) (STRING< NAME "PPP")):
EMMA, BOB