CSC 270 - Survey of Programming Languages: Scheme (Racket)
Lecture 8 - More On Processing Lists
Programs That Produce Lists
- Remember the program wage?
;; wage : number ? number
;; to compute the total wage (@ $12 per ;; hour of someone who worked for h
;; hours
(define (wage h)
(* 12 h))
- The program's most obvious limitation is that it only calculates
the wage for one employee.
- Let's plan a program that can calculate wage for many employees,
where we will place the hours that they worked on a list.
- The contract and header will be:
;; find-wages : list-of-numbers -->
;;list-of-numbers
;; to create a list of weekly wages from a
;; list of weekly hours (hourlist)
(define (find-wages hourslist) ...)
Developing find-wages
- Let's look at some sample input-output combinations:
Input list | Output list |
empty | empty |
cons 28 empty) | cons 336 empty) |
(cons 40 (cons 28 empty) | (cons 480 (cons 336 empty) |
- Because the program consumes a list, we can use the same template
as before:
(define (find-wages hourlist)
(cond
[(empty? hourlist) ...]
[ else... (first hourlist) ...
(find-wages (rest hourlist))
...]
)
)
- If the list is empty, then the output list
(with the wages listed in it) will also be empty.
(define (find-wages hourlist)
(cond
[(empty? hourlist) empty]
[ else... (first hourlist) ...
(find-wages (rest hourlist))
...]
)
)
- If the list is NOT empty, then we use the
program to process the list that contains eveything except the
first item.
(define (find-wages hourlist)
(cond
[(empty? hourlist) empty]
[ else... (first hourlist) ...
(find-wages (rest hourlist))
...]
)
)
- If the list is NOT empty, we want to do two things with the first item:
- compute the weekly wage for this worker
- construct a list consisting of this worker's wage
and whatever wages follow.
- If we reuse wage we can find the first item on the new list:
(wage (first hourlist))
- To construct the new list with this at the beginning:
(cons (wage (first hourlist))
(find-wages (rest hourlist)))
The find-wages program
;; find-wages : list-of-numbers à
;;list-of-numbers
;; to create a list of weekly wages from a
;; list of weekly hours (hourlist)
(define (find-wages hourslist)
(cond
[(empty? hourlist) empty]
[ else (cons (wage (first hourlist))
(find-wages (rest hourlist)))]
)
)
Lists That Contain Structures
An Inventory List
- This allows us to define an inventory list more realistically:
- An inventory is either
EMPTY
or
(cons inrec inlist)
where ir is an inventory record and inlist is our inventory list
Constructing an Inventory List
Rewriting Our Inventory Program
- Let's rewrite the program which
sums up our inventory and start by writing the contract and header:
;; sum : inventory --> number
;; to compute the sum of prices
;; on inlist
(define (sum inlist) ...)
- We'll use the same sample prices as before, which produces answers
of 0, 17.95 and 40.
- Let's start with the same template as before:
(define (sum inlist)
(cond
[empty? inlist)...]
[else ...(first inlist)... )
(sum(rest inlist)) ...]
)
)
- If the inventory list is empty, the sum is 0:
(define (sum inlist)
(cond
[empty? inlist) 0]
[else ...(first inlist)... )
(sum(rest inlist)) ...]
)
)
- If the list is not empty, we need to add the
first item's price to the rest of the list:
(define (sum inlist)
(cond
[(empty? inlist) 0]
[else (+ (make-inrec(first inlist))
(sum (rest inlist)))]
)
)
- We are only adding the price of the first item,
not the entire structure:
;; sum : inventory ? number
;; to compute the sum of prices
;; on inlist
(define (sum inlist)
(cond
[(empty? inlist) 0]
[else (+ (inrec-price(first inlist))
(sum (rest inlist)))]
)
)
Another example: creating a list with less expensive items
Sample Input and Output for extract1
- Our input list might be:
(cons (make-inrec 'dagger .95)
(cons (make-inrec 'Barbie 17.95)
(cons (make-inrec 'key-chain .55)
(cons (make-inrec 'robot 22.05)
empty)))
- This would produce the output list:
(cons (make-inrec 'dagger .95)
(cons (make-inrec 'key-chain .55)
empty)))
extract1 - Some Examples
(first inlist)
= (make-inrec 'dagger .95)
(rest inlist)
= (cons (make-inrec 'Barbie 17.95)
(cons (make-inrec 'key-chain .55)
(cons (make-inrec 'robot 22.05)
empty)))
- Assuming that extract1 works correctly, we know that
(extract1 (rest inlist))
= (cons (make-inrec 'keychain .55)
empty)
Writing extract1
- Our template is:
(define (extract1 inlist)
(cond
[(empty? inlist) ...]
[else
(cond
[(<= (inrec-price(first inlist)) 1.00) ...]
[else ...]
)]
)
)
- If the input list is empty, so is the output list.
Our template becomes:
(define (extract1 inlist)
(cond
[(empty? inlist) empty]
[else
(cond
[(<= (inrec-price(first inlist)) 1.00) ...]
[else ...]
)]
)
)
- If the first item is more than $1.00, then the
output list consists of whatever our program determines from
the rest of the list. Our template becomes:
(define (extract1 inlist)
(cond
[(empty? inlist) empty]
[else
(cond
[(<= (inrec-price(first inlist)) 1.00) ...]
[else (extract1(rest inlist))]
)]
)
)
- If the first item is $1.00 or less, then the output list
consists of this item followed whatever our program determines from
the rest of the list. Our template becomes:
(define (extract1 inlist)
(cond
[(empty? inlist) empty]
[else
(cond
[(<= (inrec-price(first inlist)) 1.00)
(cons (first inlist)
(extract1 (rest inlist)))]
[else (extract1 (rest inlist))]
)]
))
[Back to the Notes Index]