|Problem Set 5: Wahoo! Auctions||
Out: 26 February 2007
Due: Wednesday, 14 March 2007
Collaboration Policy - Read Very Carefully
If you wish to be assigned a partner for this assignment, send me an email by 11:59 pm, Tuesday, 27 February. Otherwise, you may work on this assignment alone or with one partner of your choice.
Regardless of whether you work alone or with a partner, you are encouraged to discuss this assignment with other students in the class and ask and provide help in useful ways. You may consult any outside resources you wish including books, papers, web sites and people. If you use resources other than the class materials, indicate what you used along with your answer.Purpose
|Download: Download ps5.zip
to your machine and unzip it into your home directory
This file contains:
Fortunately, the University was able to get "Chapter 11" status from the Commonwealth, which gives it more power to control its own destiny by raising tuition and selling off assets. The Board of Transients has decided the time for drastic measures has arrived, and they will conduct an auction to raise money. To avoid paying fees to a commercial auction service, they have decided to exploit free labor from cs150 students to develop an auction service for them.
The auction service will be built using a database. A database is just a way of storing and manipulating a large amount of structured data. For this problem set, you will implement a database and use it to implement an auction service. Our database is controlled using Scheme procedures that are similar to the SQL commands used to control nearly all commercial databases. In the final course project, you will build a dynamic web site that uses SQL commands to interact with a database.
Data in a database is stored in tables. The fields of a table describe the data and are not mutable. The entries of a table are the data, and can be changed. We will represent a table using a cons pair where the car is a list of the table fields and the cdr is a list of the table entries. These definitions are found in database.scm:
(define (make-new-table fieldlist) (cons fieldlist null)) (define (make-table fieldlist entries) (cons fieldlist entries)) (define (table-fields table) (car table)) (define (table-entries table) (cdr table))For the Wahoo! Auctions service, we will need several different tables to keep track of the bidders, the items for sale, and the bids on those items. We use quoted symbols to describe the fields in a table. Those tables are defined in auction.scm:
(define bidders (make-new-table (list 'name 'email))) (define items (make-new-table (list 'item-name 'description))) (define bids (make-new-table (list 'bidder-name 'item-name 'amount)))
(define t1 (make-new-table (list 'name 'email))) (set-car! (table-fields t1) 'nom) (set-cdr! t1 t1)b. Suppose we then evaluate:
(define (length lst) (if (null? lst) 0 (+ 1 (length (cdr lst))))) (length t1)Explain why the evaluation of (length t1) never terminates.
Try evaluating the expressions in Question 2 in DrScheme. Also evaluate t1 and see if you can figure out what the printed value means.
The table-insert! procedure inserts an entry into a table. We follow the Scheme (and Yahoo!?) convention of using an ! at the end of the names of procedures that mutate state. You should follow this convention also.
You shouldn't need to change the definition of table-insert!, but you should be able to understand it (defined in database.scm):
(define (table-insert! table entry) (assert (= (length entry) (length (table-fields table)))) (if (null? (table-entries table)) (set-cdr! table (list entry)) (append! (table-entries table) (list entry))) (void)) ;;; don't evaluate to a valueThe expression (assert (= (length entry) (length (table-fields table)))) checks that the entry we are adding to the table has the right number of elements — there must be one element in the entry corresponding to each field in the table. The assert procedure will produce an error if the passed parameter is false. It is defined:
(define (assert pred) (if (not pred) (error "Assertion failed!")))We use (void) at the end of the procedure body to prevent an application of table-insert! from evaluating to a value. The procedure void takes no parameters, and produces no value.
b. Why does the definition of table-insert! need to do something different in the case where (table-entries table) is null?
Hint: try evaluating
(define lst null) (append! lst 3) lst
Our auction service will need procedures for adding bidders, posting items for sale and bidding on items. For now, define simple procedures that insert entries in the appropriate tables:
b. Describe the running time of your insert-bid! procedure. Your answer should use Θ notation, clearly explain what all variables you use mean, and include an explanation of why your answer is correct.
We have provided a table-display procedure in database.scm for printing out a table. (You don't need to understand the details of how table-display works.)
If you define add-bidder!, post-item! and insert-bid! correctly, you should obtain the following interactions:
> (table-display bidders)
name email ------------------------- -------------------------
> (add-bidder! "Tim Koogle" "email@example.com")
> (add-bidder! "Katie Couric" "firstname.lastname@example.org")
> (add-bidder! "Dave Matthews" "email@example.com")
> (table-display bidders)
name email ------------------------- ------------------------- Tim Koogle firstname.lastname@example.org Katie Couric email@example.com Dave Matthews firstname.lastname@example.orgDevelop similar tests for your post-item! and insert-bid! procedures, and make sure they also work correctly.
(define (make-string-selector match) (lambda (fval) (string=? fval match))) (define (get-bids item) (table-entries (table-select bids 'item-name (make-string-selector item))))The get-bids procedure evaluates to a list of bid entries that are the entries in the bids table whose item-name field matches the parameter item. If you're not sure how this works, try evaluating some expressions using make-string-selector by themselves.
If your table-select is working correctly, you should see interactions similar to these:
> (insert-bid! "Tim Koogle" "SEAS" 10000000)
> (insert-bid! "Dave Matthews" "CLAS" 2000000)
> (insert-bid! "Tiki Barber" "COMM" 79000000)
> (insert-bid! "Katie Couric" "CLAS" 37000000)
> (table-select bids 'item-name (lambda (pitem) (string=? pitem "CLAS")))
((bidder-name item-name amount) ("Dave Matthews" "CLAS" 2000000) ("Katie Couric" "CLAS" 37000000))
> (table-display (table-select bids 'item-name (lambda (pitem) (string=? pitem "CLAS"))))
bidder-name item-name amount ------------------------- ------------------------- ------------------------- Dave Matthews CLAS 2000000 Katie Couric CLAS 37000000
> (table-entries (table-select bids 'item-name (lambda (pitem) (string=? pitem "SEAS"))))
(("Tim Koogle" "SEAS" 10000000))
> (table-entries (table-select bids 'item-name (lambda (pitem) (string=? pitem "Rotunda"))))
> (table-entries (table-select bids 'amount (lambda (pamount) (> pamount 10000000))))
(("Tiki Barber" "COMM" 79000000) ("Katie Couric" "CLAS" 37000000)
(table-select bids 'amount (lambda (pamount) (<= pamount 10000000)))
(lambda (pbidder) (string=? pbidder "Katie Couric"))))
Selects can be nested. Here we use (table-select bids 'amount (lambda (pamount) (<= pamount 10000000))) to produce the table of all bids over 10000000, and then use another table-select to select the bids from that table where the bidder name is "Katie Couric". To make sure you understand table-select, produce a different expression that will evaluate to the same table by selecting the name first and then the amount.
Your get-highest-bid procedure should work like this:
> (get-highest-bid "SEAS")
("Tim Koogle" "SEAS" 10000000)
> (get-highest-bid "Rotunda")
You may want to use the printf procedure builtin to DrScheme to generate the output. For example,
will print out, bidder is now the high bidder for item: $amount.(printf "~a is now the high bidder for ~a: $~a~n" bidder item amount)
You should get interactions similar to these:
> (place-bid "Tim Koogle" "SEAS" 20000000)
Tim Koogle is now the high bidder for SEAS: $20000000
> (place-bid "Katie Couric" "SEAS" 18000000)
Bid amount does not exceed previous highest bid: (Tim Koogle SEAS 20000000)
> (place-bid "Katie Couric" "SEAS" 22000000)
Katie Couric is now the high bidder for SEAS: $22000000
> (place-bid "Dave Matthews" "AFC" 1000000)
Dave Matthews is now the high bidder for AFC: 1000000
> (place-bid "Dave Matthews" "Rotunda" 1000000)
The Rotunda is not for sale!
> (place-bid "Dave Evans" "SEAS" 10000000000)
Dave Evans is not an authorized bidder!
Here's an example:
> (place-bid "Tim Koogle" "SEAS" 18000000)
Tim Koogle is now the high bidder for SEAS: 18000000
> (place-bid "Katie Couric" "CLAS" 10000000)
Katie Couric is now the high bidder for CLAS: 10000000
Congratulations Tim Koogle! You have won the SEAS for $18000000. Please drop off the cash under Mr. Jefferson's statue. Congratulations Katie Couric! You have won the CLAS for $10000000. Please drop off the cash under Mr. Jefferson's statue. No bids on COMM.
Try some sample auctions to demonstrate your program. See if you can make enough money to save the University, but be careful not to sell off too many important assets — we will revisit the University in Charlottansville in Problem Set 6.