Writing these small procedures makes use of the program development process covered earlier. Refer to that handout to help with the steps in the process of creating your programs.
During the demonstration in class today, we will collaboratively develop some of the specifications, algorithms, and code, for the functions that work on your contact list. The rest is up to you. Get an early start for best results.
Below we will develop the procedures for a similar problem - creating a banking database.
You will be using the Scheme functions you already know from the previous labs for this lab. The only somewhat new function is let*. The syntax for let* is identical to that of let. The difference is that let* forces a sequential evaluation of the local variables and can therefore be used when the value of one local variable depends on the value(s) of other local variable(s).
When using let, the order of variable binding is not guaranteed to be sequential (the interpreter/compiler can perform them in any order chosen). let* can be used everywhere let can be used, but it makes the interpreter or compiler do a bit more work to guarantee the order of evaluation.
An example of the use of let* can be found in the Scheme code for the sample final exam in the change-each-value procedure. Look at the difference between this procedure and the others that use let (example: print-all-category) in the file valuable.scm.
Syntax of let*:
(let* (( < variable > < value > ) + ; 1 or more variables and values
)
< statements > )
There is also a do* function. Do* does exactly what do does, with the exception that the (local) loop variables are guaranteed to be bound (assigned values) sequentially, in the same way that variables are bound with let*, as compared to let.
This example shows the design and implementation of procedures for a database of bank accounts. We will create the basic procedures necessary create the database and to manipulate the data in the database. Your bank account database should have the following structure:
( (ID-number Balance Name Address Phone-Number) (ID-number Balance Name Address Phone-Number) (ID-number Balance Name Address Phone-Number) ... )
This structure is an association list containing an arbitrary number of sub-lists, where each sub- list contains information about one bank account. Each sub-list is composed of the following items:
(
("2141" 100.00 "Fred Flintstone" "1 Rocky Wy., Bedrock" "244-412-3912")
("3988" 144.12 "Betty Rubble" "2 Graphite Ln., Bedrock" "244-412-3114")
("1211" 981.00 "Greg Granite" "3 Geode St., Red Rock" "244-412-3912")
)
In this example, the database contains three sub-lists. The first has data for Fred Flintstone. He has $100 in his account, lives at 1 Rocky Way in Bedrock, has a phone number of 244-412-3912, and his ID number is 2141. Similarly, Betty has $144.12, lives at 2 Graphite Lane in Bedrock, has a phone number of 244-412-3114, and has a ID number of 3988.
To manipulate the bank account database, you will need to create the bank data structure and write the following functions.
Create the global variable *bank* and initialize it to the empty list with:
(define *bank* (list))
The description: The add-account-silent procedure adds a ID number, starting balance, name, address, and phone number to the A-List *Bank*.
Procedure name: add-account-silent
Arguments: (5) ID balance name address phone
Side Effects: add a new sublist to *bank* with the new information
Input/Output: none specified.
Result: none specified.
(define (add-account-silent ID balance name address phone)
(set! *bank*
(cons (list ID balance name address phone) *bank*)))
;;;;;; The MAKE-DEPOSIT procedure example ; Description ; make-deposit takes as input an ID number and a ; deposit amount, and changes the corresponding account balance to ; contain the sum of the old balance and the new amount. ; To start the definition, we need: ; Procedure: MAKE-DEPOSIT ; Arguments: ID deposit ; Input/Output: none specified ; Side Effects: none specified ; Pseudocode algorithm: ; get the current balance of the account (from the database) ; calculate the new balance by adding the current balance to the deposit amount ; save the new balance back to the database ; Code in Scheme ; We must start to define the function with its name & arguments: ; In Scheme syntax that is: ; (define (make-deposit id deposit) ; ..... ) ; The code for most of the functions is included below.
;;;;;;;;;;;;;;;;; Creating a Banking Database
; ECS15, Nancy Reed
; The form of the Association list for the bank
;(
; (ID-number Balance Name Address Phone-number)
; (ID-number Balance Name Address Phone-number)
; (ID-number Balance Name Address Phone-number)
; ......
; )
; ID-number -> string
; Balance -> number
; Name -> string
; Address -> string
; Phone-number -> string
;;;;;; Data structure necessary:
;; 1. Global variable *bank*
(define *bank* (list))
;; 2. add-account-silent procedure (arguments: ID, balance, name, address, phone)
(define (add-account-silent id balance name address phone)
(set! *bank* (cons (list id balance name address phone) *bank*)))
; Some data to start with
(add-account-silent "2141" 100.00 "Fred Flintstone" "1 Rocky Wy., Bedrock"
"244-412-3912")
(add-account-silent "3988" 944.12 "Betty Rubble" "2 Graphite Ln., Bedrock"
"244-412-3114")
(add-account-silent "1242" 991.41 "Wilma Flintstone" "1 Rocky Wy., Bedrock"
"244-412-3912")
;; 3. Get-account procedure (arguments: ID)
(define (get-account id)
(assoc id *bank*))
;; 4. Display-accounts procedure (arguments: Alist-of-data)
(define (display-accounts accounts)
(cond
((null? accounts)
(display "End of accounts.")
(newline))
(else
; display info in the first sublist
(let*
((sublist (car accounts))
(id (car sublist))
(balance (cadr sublist)) ; cadr = car cdr
(name (caddr sublist))
(address (cadddr sublist))
(phone (car (cddddr sublist))) )
(display ; display in columns
(string-append
id (make-string (- 10 (string-length id)) #\space)
"$" (number->string balance)
(make-string (- 10 (string-length
(number->string balance))) #\space)
name (make-string (- 20 (string-length name)) #\space)
address (make-string (- 25 (string-length address)) #\space)
phone))
(newline)
; recursive call on the rest of the list
(display-accounts (cdr accounts))) ) ) )
;; 5. Change-name procedure (arguments: ID, new-name)
(define (change-name ID newname)
(display "This function is left as an exercise for the reader")
)
;; 6. Make-deposit function (arguments: ID, deposit-amount)
(define (make-deposit id deposit)
; modify balance of account with id=ID so it is old balance + deposit
(let*
((sublist (assoc id *bank*))
(newbalance (+ deposit (cadr sublist))))
(set-car! (cdr sublist) newbalance) ) )
; 7. Make-withdrawal function (arguments: ID, withdrawal-amount)
; NOTE: Make sure there is enough $, or else issue a warning message
(define (make-withdrawal id amount)
(let*
((balance-list (cdr (assoc id *bank*)))
(balance (car balance-list)))
(cond
((> amount balance)
(newline)
(display "Error, not enough money in account."))
(else
(set-car! balance-list (- balance amount))))))
Go to the index of
lectures for ECS15 - Fall 1997 .
Go to the homepage for ECS15 - Fall 1997 .

© Nancy E. Reed, 1997 -- nereed@ucdavis.edu