;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-beginner-reader.ss" "lang")((modname lect11-12) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) ; A book is: ; (make-book [string] [string] [number] [boolean]) (define-struct book (title author pages copyR?)) ; Examples of the data: (make-book "The Soul of Wit" "Shorty" 0 false) (define b1 (make-book "The Cat in the Hat" "Seuss" 31 true)) ; Template for any book-handling function: ; (define (func-for-book a-book) (... (book-title a-book) ... (book-author a-book) ... (book-pages a-book) ... (book-copyR? a-book)) ) ; Note that 'define-struct' automagically creates ; functions for us: ; Constructor: ; make-book: string, string, number, boolean -> book ; Selectors: ; book-title : book -> string ; book-author : book -> string ; book-pages : book -> number ; book-copyR? : book -> boolean ; Predicate: ; book? : ANY -> boolean ; book->string : book -> string ; Convert a book into a nice printable format for users. ; (define (book->string a-book) (string-append (book-title a-book) ", by " (book-author a-book) " (" (number->string (book-pages a-book)) "pp)" (if (book-copyR? a-book) " (c)" ""))) (check-expect (book->string b1) "The Cat in the Hat, by Seuss (31pp) (c)") (check-expect (book->string (make-book "The Soul of Wit" "Shorty" 0 false)) "The Soul of Wit, by Shorty (0pp)") ;;;;;;;;;;;;;; ; derive-from : book, string, number -> book ; Create a brand new book, based on an original. ; The result's author will be the original author & the new-author, ; and the result has pages added to the original. ; (define (derive-from a-book new-author pages-added) (make-book (string-append "Son of " (book-title a-book)) (string-append (book-author a-book) " and " new-author) (+ (book-pages a-book) pages-added) false)) (check-expect (derive-from (make-book "The Soul of Wit" "Shorty" 0 false) "Dr Barland" 10) (make-book "Son of The Soul of Wit" "Shorty and Dr Barland" 10 false)) (check-expect (derive-from b1 "John Madden" 20) (make-book "Son of The Cat in the Hat" "Seuss and John Madden" 51 false)) ; recall: ;(make-book "The Cat in the Hat" "Seuss" 31 true) ;;;;;;;;;;;;;;;;;;;;;;;; union-of-structs ;;;;;;;;;;;;;;;;;; ;;;;;;;;;; ; A DVD is: ; (make-dvd [string] [number] [symbol]) ; where `time` is the running time in minutes (non-negative) ; and title is non-empty string. ;;;;;;;;;;;; (define-struct dvd (title time rating)) ; Examples of the data: (define fave (make-dvd "Once" 100 'PG-13)) (define botr (make-dvd "Bored of the Rings" 4892 'R)) (define dvd0 (make-dvd " " 0 'G)) ;;;;;;;;;;;;;;;;;;;;;;;;; ; A lib-item is either ; - a book, or ; - a dvd. ; examples of the data: (make-dvd "Once" 100 'PG-13) (make-book "The Cat in the Hat" "Seuss" 31 true) ;; Functions which handle lib-items: (define (func-for-lib-item ali) ; ali for "a lib item" (cond [(book? ali) (...(book-title ali) ...(book-author ali) ...(book-pages ali) ...(book-copyR? ali))] [(dvd? ali) (...(dvd-title ali) ...(dvd-time ali) ...(dvd-rating ali))])) ;; time-to-waste : lib-item -> number ;; Return how long the lib-item takes to be experienced (in hours) (define (time-to-waste ali) ; ali for "a lib item" (cond [(book? ali) (* 2 (book-pages ali)) ] [(dvd? ali) (+ 5 (dvd-time ali))])) (check-expect (time-to-waste (make-book "The Soul of Wit" "Shorty" 0 false)) 0) (check-expect (time-to-waste (make-book "The Cat in the Hat" "Seuss" 31 true)) 62) (check-expect (time-to-waste (make-dvd "Bored of the Rings" 480 'R)) 485) ;;;;;;;;;;;; next data definiton: struct of structs ;;;;;;;;;;;;;; ; A bookshelf is: ; (make-bookshelf [string] [book] [book]) ; (define-struct bookshelf (label bk1 bk2)) (define shelf1 (make-bookshelf "fiction" b1 (make-book "The Soul of Wit" "Shorty" 0 false))) (define shelf2 (make-bookshelf "crappy" (derive-from b1 "John Madden" 20) (derive-from (make-book "The Soul of Wit" "Shorty" 0 false) "Dr Barland" 10))) ; template for bookshelf: (define (func-for-bookshelf a-shelf) (... (bookshelf-label a-shelf) ... (bookshelf-bk1 a-shelf) ... (bookshelf-bk2 a-shelf))) ; shelf-time-to-waste : booksehlf -> number ; How much time spent reading everything on the shelf? (define (shelf-time-to-waste a-shelf) (+ (time-to-waste (bookshelf-bk1 a-shelf)) (time-to-waste (bookshelf-bk2 a-shelf)))) ; When dealing with a struct whose fields are other complicated types, ; extract the book and shelf-title (like you do for any struct), ; but *don't* start pulling out all each books' fields -- ; that's taking it too far! Instead, defer the entire book to a helper ; (like time-to-waste, here). (check-expect (shelf-time-to-waste shelf1) (+ 62 0)) (check-expect (shelf-time-to-waste shelf2) (+ 102 20)) ;;;;;;; last example: a struct-of-unions ; A lib-shelf is ; (make-lib-shelf [lib-item] ; [lib-item] ; [lib-item]) (define-struct lib-shelf (li1 li2 li3)) ; Examples of the data: (make-lib-shelf (make-book "The Cat in the Hat" "Seuss" 31 true) (make-dvd "Once" 100 'PG-13) botr) (define (func-for-lib-shelf als) (...(lib-shelf-li1 als) ...(lib-shelf-li2 als) ...(lib-shelf-li2 als)) ; just call functions that handle a lib-item on these fields -- ; DON'T go and (for each of the three) try to have a ; cond-with-two-branches. Defer to helpers.