;; CD Store ;; Problem 1 ;; a cd is a (make-cd string string number number string) (define-struct cd (title artist price copies genre)) ;; example (make-cd "Messiah" "Handel" 17.98 100 "classical") ;; Problem 2 ;; make-cd: string string number number string -> cd ;; cd-title: cd -> string ;; cd-srtist: cd -> string ;; cd-price: cd -> number ;; cd-copies: cd -> number ;; cd-genre: cd -> string ;; cd?: anything -> boolean ;; Problem 3 ;; an inventory (list-of-cd) is either ;; empty, or ;; (cons cd inventory) ;; Example (define classical (cons (make-cd "Messiah" "Handel" 17.98 100 "classical") (cons (make-cd "Motets" "Brueckner" 16.98 40 "classical") empty))) ;; Problem 4 ;;; cd-fcn: cd ... -> ?? ;;; ?? ;(define (cd-fcn acd) ; (cd-title acd) ; (cd-artist acd) ; (cd-price acd) ; (cd-copies acd) ; (cd-genre acd)) ; ;;; inventory-fcn: inventory ... -> ?? ;;; ?? ;(define (inventory-fcn alocd) ; (cond [(empty? alocd) ...] ; [(cons? alocd) ...(cd-fcn (first alocd)) ; ...(inventory-fcn (rest alocd)...)])) ;; Problem 5 ;; copies-in-stock: string string inventory -> number ;; consumes the title and artist and an inventory and produces ;; the number of the given cd that are in stock (define (copies-in-stock title artist alocd) (cond [(empty? alocd) 0] [(cons? alocd) (cond [(target-cd? title artist (first alocd)) (cd-copies (first alocd))] [else (copies-in-stock title artist (rest alocd))])])) ;; target-cd?: string string cd -> boolean ;; consumes a title and artist and returns true if the ;; given cd has that title and artist (define (target-cd? title artist acd) (and (string=? (cd-title acd) title) (string=? (cd-artist acd) artist))) ;; Tests (check-expect (target-cd? "Sounds of Silence" "Simon and Garfunkel" (make-cd "Happy Birthday" "Hamel" .50 10 "general")) false) (check-expect (target-cd? "Messiah" "Handel" (make-cd "Messiah" "Handel" 17.98 100 "classical")) true) (check-expect (copies-in-stock "Messiah" "Handel" classical) 100) (check-expect (copies-in-stock "Messiah" "Handel" empty) 0) ;; Problem 6 ;; restock: string number inventory -> inventory ;; consumes a title, a number of new copies, and an inventory ;; The function produces an inventory in which the named CD ;; has the given number of additional copies (define (restock title new-copies alocd) (cond [(empty? alocd) empty] [(cons? alocd) (cons (add-cds title new-copies (first alocd)) (restock title new-copies (rest alocd)))])) ;; add-cds: string number cd -> cd ;; consumes a cd title and the number of additional copies ;; and produces a cd. The produced cd has the number of copies ;; increased by new-copies if the title of the cd matches the ;; title given, otherwise the cd returned is the same as the ;; original (define (add-cds title new-copies acd) (cond [(string=? (cd-title acd) title) (make-cd (cd-title acd) (cd-artist acd) (cd-price acd) (+ new-copies (cd-copies acd)) (cd-genre acd))] [else acd])) ;; tests (check-expect (add-cds "Messiah" 12 (make-cd "Messiah" "Handel" 17.98 100 "classical")) (make-cd "Messiah" "Handel" 17.98 112 "classical")) (check-expect (add-cds "Yesterday" 55 (make-cd "Messiah" "Handel" 17.98 100 "classical")) (make-cd "Messiah" "Handel" 17.98 100 "classical")) (check-expect (restock "Motets" 15 classical) (cons (make-cd "Messiah" "Handel" 17.98 100 "classical") (cons (make-cd "Motets" "Brueckner" 16.98 55 "classical") empty))) ;; Problem 7 ;; titles-by: string inventory ->list-of-string ;; consumes an artist's name and an inventory and produces a ;; list of titles of cd's by that artist (define (titles-by an-art alocd) (cond [(empty? alocd) empty] [(cons? alocd) (cond [(target-artist? an-art (first alocd)) (cons (cd-title (first alocd)) (titles-by an-art (rest alocd)))] [else (titles-by an-art (rest alocd))])])) ;; target-artist?: string cd -> boolean ;; produces true if the cd is by the given artist, ;; produces false otherwise (define (target-artist? an-art acd) (string=? an-art (cd-artist acd))) ;; tests (check-expect (target-artist? "Handel" (make-cd "Messiah" "Handel" 17.98 200 "classical")) true) (check-expect (titles-by "Handel" classical) (cons "Messiah" empty)) (check-expect (titles-by "Handel" empty) empty) ;; Problem 8 ;; blues-sale: inventory -> inventory ;; consumes an inventory and produces an inventory in which ;; each blues CD is discounted by 10% (define (blues-sale alocd) (cond [(empty? alocd) empty] [(cons? alocd) (cons (discount-if-blues (first alocd)) (blues-sale (rest alocd)))])) ;; discount-if-blues: cd -> cd ;; consumes a cd. If that cd is a blues CD, then the ;; cd that is returned is discounted by 10%. Otherwise, ;; the cd that is returned is the same as the original (define (discount-if-blues acd) (cond [(string=? "blues" (cd-genre acd)) (make-cd (cd-title acd) (cd-artist acd) (* .9 (cd-price acd)) (cd-copies acd) (cd-genre acd))] [else acd])) ;; tests (check-expect (discount-if-blues (make-cd "Messiah" "Handel" 17.98 200 "classical")) (make-cd "Messiah" "Handel" 17.98 200 "classical")) (check-expect (blues-sale classical) classical) ;; problem 9 ;; category-stock: string inventory -> inventory ;; consumes a music category and an inventory. It produces an ;; inventory of all cd's from the original inventory that are ;; of the named category and have more than 0 copies in stock (define (category-stock category alocd) (cond [(empty? alocd) empty] [(cons? alocd) (cond [(more-than-0-genre? category (first alocd)) (cons (first alocd) (category-stock category (rest alocd)))] [else (category-stock category (rest alocd))])])) ;; more-than-0-genre?: string cd -> boolean ;; consumes a name of a category and a cd and returns ;; true if the cd is of that category and has more ;; than 0 copies in stock (define (more-than-0-genre? category acd) (and (string=? (cd-genre acd) category) (> (cd-copies acd) 0))) ;; tests (check-expect (more-than-0-genre? "blues" (make-cd "Messiah" "Handel" 17.98 200 "classical")) false) (check-expect (more-than-0-genre? "blues" (make-cd "Blues Brothers" "Blues Brothers" 12.95 123 "blues")) true) (check-expect (category-stock "blues" classical) empty) ;; Problem 10 ;; unique-categories: inventory -> list-of-string ;; consumes an inventory and produces a list of all music ;; categories contained in the inventory, with no duplicates (define (unique-categories alocd) (cond [(empty? alocd) empty] [(cons? alocd) (cond [(category-present? (cd-genre (first alocd)) (unique-categories (rest alocd))) (unique-categories (rest alocd))] [else (cons (cd-genre (first alocd)) (unique-categories (rest alocd)))]) ])) ;; category-present?: string list-of-string -> boolean ;; consumes a category and a list-of-categories and returns true if the ;; named category appears in the list (define (category-present? category alos) (cond [(empty? alos) false] [(cons? alos) (cond [(string=? (first alos) category) true] [else (category-present? category (rest alos))])])) ;; tests (check-expect (category-present? "blues" (cons "classical" (cons "rock" (cons "jazz" empty)))) false) (check-expect (category-present? "blues" empty) false) (check-expect (unique-categories classical) (cons "classical" empty))