;; The first three lines of this file were inserted by DrScheme. 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 lect02c) (read-case-sensitive #t) (teachpacks ((lib "universe.ss" "teachpack" "2htdp"))) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ((lib "universe.ss" "teachpack" "2htdp"))))) ; A book is: ; (make-book [string] [string] [number] [boolean]) ; (define-struct book (title author pages copyR?)) ;(define (book->string a-book) ; ... (book-title a-book) ; ... (book-author a-book) ; ... (book-pages a-book) ; ... (book-copyR? a-book) ; ) ; Just so we compile [this function was written in lect02a:] (define (blend s1 s2) s1) ; 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)) ; 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 ; read-time: book -> number ; How long does it take to read `a-book`, in hours? ; #;(define (read-time a-book) -99) (check-expect (read-time (make-book "The Soul of Wit" "Shorty" 0 false)) 0) (check-expect (read-time b1) (+ 1 2/60)) ;;; AFTER making the test cases, we go back and write the code: ; read-time: book -> number ; How long does it take to read the book, in hours? ; (define (read-time a-book) (* (book-pages a-book) 2 1/60)) ; 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 ; (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) (book-copyR? a-book))) (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)) ;;;;; Sep.14 ;;;;;; ;; vandalize : book -> book ;; (define (vandalize a-book) (make-book (blend (book-title a-book) (book-author a-book)) (book-author a-book) (quotient (book-pages a-book) 2) (book-copyR? a-book))) (check-expect (vandalize b1) (make-book (blend "The Cat in the Hat" "Seuss") "Seuss" 15 true)) (check-expect (book-pages b1) 31) ;;;;; Sep.16 ;;;;;; ; A DVD is: ; (make-dvd [string] [number]) ; where `time` is the running time in minutes (non-negative) ; and title is non-empty string. (define-struct dvd (title time)) (define botr (make-dvd "Bored of the Rings" 4892)) (define dvd0 (make-dvd " " 0)) ; A lib-item is either ; - a book, or ; - a dvd. ;; Functions which handle lib-items: ;; time-to-waste : lib-item -> number ;; Return how long the lib-item takes to be experienced (in hours) (define (time-to-waste li) (cond [(book? li) (read-time li)] [(dvd? li) (/ (+ (dvd-time li) 5) 60)] [else (error 'time-to-waste "Expected a lib-item, got ~v." li)])) (check-expect (time-to-waste (make-book "The Soul of Wit" "Shorty" 0 false)) 0) (check-expect (time-to-waste (make-dvd "Bored of the Rings" 4892)) (/ (+ 4892 5) 60)) ;; Template for a function handling *any* type of lib-item: ;(define (fun-for-lib-item li) ; (cond [(book? li) ...(book-title li) ; ...(book-author li) ; ...(book-pages li) ; ...(book-copyR? li)] ; [(dvd? li) ...(dvd-time li) ; ...(dvd-title li)] ; [else (error 'fun-for-lib-item "Expected a lib-item, got ~v." li)])) ; li-title: lib-item -> string ; Return the title of *any* lib-item ; (whether a book, a dvd, or some variant we might add in the future). (define (li-title li) (cond [(book? li) (book-title li)] [(dvd? li) (dvd-title li)] [else (error 'li-title "Expected a lib-item, got ~v." li)])) ; ; Here's where we wish that we could use sub-classing, ; with the supertype lib-item having a single selector, ; rather than having to do a cond, and choose which selector ; to use (either book-title or dvd-title, depending). ; ... it turns out, plt-scheme does allow structs that inherit. ; (Separately, it also has an object system, too.) ; We won't explore those here though, since you already know O.O. ;;;; lect03c (Sep.18) ; A bookshelf is: ; (make-bookshelf [string] [book] [book]) ; (define-struct bookshelf (label b1 b2)) (define bs1 (make-bookshelf "fiction" b1 (make-book "Soul of Wit" "Shorty" 0 false))) ; total-read-time: bookshelf -> number ; How long does it take to read every ; book on the shelf, in hours? (define (total-read-time bs) (+ (read-time (bookshelf-b1 bs)) (read-time (bookshelf-b2 bs)))) (check-expect (total-read-time bs1) 62/60) ;;;; A template for any function ;;;; processing bookshelves: ;(define (total-read-time bs) ; ...(bookshelf-label bs) ; ...(bookshelf-b1 bs) ; ...(bookshelf-b2 bs)) ; ; A ls is ; (make-ls [lib-item] ; [lib-item] ; [lib-item]) (define-struct ls (li1 li2 li3)) ; Examples: (make-ls b1 botr b1) (define (ls->string a-ls) (string-append (li-title (ls-li1 a-ls)) ", " (li-title (ls-li2 a-ls)) ", " (li-title (ls-li3 a-ls)))) (check-expect (ls->string (make-ls b1 botr b1)) "The Cat in the Hat, Bored of the Rings, The Cat in the Hat")