CS 5010: Guided Practice 4.3 — Solution
Here is one solution:
;; inventory-total-value : Inventory -> Integer ;; GIVEN: a Inventory ;; RETURNS: the value of all the copies on hand of all the books in the ;; given Inventory ;; (inventory-total-value inv1) = 390 (begin-for-test (check-equal? (inventory-total-value empty) 0 "value of the empty inventory should have been 0") (check-equal? (inventory-total-value inv1) 390 "simple test")) ;; STRATEGY: Use template for Inventory on books (define (inventory-total-value books) (cond [(empty? books) 0] [else (+ (book-inventory-value (first books)) (inventory-total-value (rest books)))]))
;; books-out-of-stock : Inventory -> Inventory ;; GIVEN: a list of books ;; RETURNS: a list of the books that are out of stock in the given Inventory ;; Example: ;; (books-out-of-stock inv1) = ;; (list ;; (make-book "Shakespeare" "Hamlet" 0 2) ;; (make-book "Shakespeare" "Macbeth" 0 10)) ;; STRATEGY: Use template for Inventory on books (define (books-out-of-stock books) (cond [(empty? books) empty] [else (if (book-out-of-stock? (first books)) (cons (first books) (books-out-of-stock (rest books))) (books-out-of-stock (rest books)))])) (check-equal? (books-out-of-stock inv1) (list (make-book "Shakespeare" "Hamlet" 0 2) (make-book "Shakespeare" "Macbeth" 0 10))) ;; book-out-of-stock? : Book -> Boolean ;; returns true iff the given book is out of stock ;; EXAMPLE: ;; (book-out-of-stock? (make-book "Felleisen" "HtDP/1" 20 7)) = false ;; (book-out-of-stock? (make-book "Felleisen" "HtDP/1" 0 7)) = true ;; STRATEGY: Use template for Book on b (define (book-out-of-stock? b) (= (book-on-hand b) 0)) (begin-for-test (check-false (book-out-of-stock? (make-book "Felleisen" "HtDP/1" 20 7))) (check-true (book-out-of-stock? (make-book "Felleisen" "HtDP/1" 0 7)))) ;; (check-equal? ... true) would have been fine, too. Look at the ;; Help Desk page for check-equal? to see some other useful checks.
Note how our program follows the data definition: the inventory contains books, so books-out-of-stock? calls book-out-of-stock?
Note that the design of the help function
book-out-of-stock?
, with its deliverables,
was needed to make this a good solution.
Writing
(if (= (book-on-hand (first lob)) 0) ... ...)
matches the template, but is undesirable because it violates
the principle of one-function-one-task, by forcing
books-out-of-stock
to know about both the
representation of an inventory AND how being out of stock
is represented for a book.
These are not the only reasonable contracts for these functions.
In inventory-total-value
, we could have replaced
Integer
with any numeric type that includes Integer, but
then any function that calls inventory-total-value
could
not assume that the value returned by
inventory-total-value
was an integer.
We could not replace it with NonNegInteger
, since the
data definition for BookStatus
allows the price field to
be negative (!).