;;; Program: ;;; dvds.ss ;;; Author: ;;; Samuel A. Rebelsky ;;; Version: ;;; 1.0 of February 2001 ;;; Summary: ;;; A sample collection of DVDs along with some utilities to work with ;;; collections of DVDs. ;;; Design: ;;; Each DVD is a list of the form ;;; (title studio genres note) ;;; where each element of the list, except genres, is a string ;;; and genres is a non-empty list of strings. ;;; A collection of DVDs is simply a list of DVDs ;;; Contents: ;;; Sample Data ;;; samsdvds ;;; a sample list of DVDs ;;; DVD Manipulation ;;; (dvd-title dvd) ;;; Get the title of a dvd. ;;; (dvd-studio dvd) ;;; Get the studio of a dvd. ;;; (dvd-genres dvd) ;;; Get the genres associated with a DVD. ;;; (dvd-notes dvd) ;;; Get the notes associated with a DVD. ;;; (dvd->html dvd) ;;; Generate some nice HTML for a DVD. ;;; (dvd? value) ;;; See if a value seems to be a DVD. ;;; (genres->html lst) ;;; Convert a list of genres to HTML. ;;; Manipulating Collections of DVDS ;;; (dvds->html dvds) ;;; Convert a list of DVDs to HTML. ;;; (find-dvd-by-title title dvds) ;;; Find a DVD with the given title (or get #f if no such DVD exists). ;;; History: ;;; Thursday, 15 February 2001 [Version 1.0] ;;; Created. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Sample Data ;;; Value: ;;; sample-dvds ;;; Type: ;;; A list of DVDs (see above for the definition of a DVD). ;;; Purpose: ;;; A sample list of DVDs for use in testing. (define sample-dvds (list (list "Tim Burton's the Nightmare Before Christmas" "Disney" (list "animated" "holiday") "Also includes early Tim Burton films and other cool stuff.") (list "How the Grinch Stole Christmas" "Warner Brothers" (list "animated" "holiday") "Also includes Horton Hears a Who") (list "Chicken Run" "Dreamworks" (list "animated" "childrens") "") (list "The Wizard of Oz" "Warner Brothers" (list "classic" "childrens") "Includes outtakes") (list "The Road to El Dorado" "Dreamworks" (list "animated" "childrens") "Special Edition") (list "Tarzan" "Disney" (list "animated" "childrens") "Collector's Edition - Two Discs") (list "Titan A.E." "Fox" (list "animated" "sf") "") )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DVD Manipulation ;;; Procedures: ;;; dvd-title ;;; dvd-studio ;;; dvd-notes ;;; Parameters: ;;; dvd, a list that represents a DVD ;;; Purpose: ;;; Extract some aspect of the DVD (title, associated studio, ;;; notes on the DVD) ;;; Produces: ;;; A string containing the requested information. ;;; Preconditions: ;;; The list that represents the DVD must be in the format ;;; specified above. (Unverified) ;;; Postconditions: ;;; The value returned is a string. ;;; Does not modify the DVD. (define dvd-title (lambda (dvd) (list-ref dvd 0))) (define dvd-studio (lambda (dvd) (list-ref dvd 1))) (define dvd-notes (lambda (dvd) (list-ref dvd 3))) ;;; Procedures: ;;; dvd-genres ;;; Parameters: ;;; dvd, a list that represents a DVD ;;; Purpose: ;;; Extracts the list of genres associated with the DVD. ;;; Produces: ;;; A list of genres. ;;; Preconditions: ;;; The list that represents the DVD must be in the format ;;; specified above. [Unverified] ;;; Postconditions: ;;; The value returned is a list of strings. ;;; Does not modify the DVD. (define dvd-genres (lambda (dvd) (list-ref dvd 2))) ;;; Procedure: ;;; dvd->html ;;; Parameters: ;;; A list that represents a DVD. ;;; Purpose: ;;; Generate some nice HTML for the DVD. This HTML can then ;;; be inserted within the body of a page (e.g., by a CGI script). ;;; Preconditions: ;;; The list must be in the appropriate format (see above). ;;; (unverified) ;;; Postcondtions: ;;; Returns valid HTML. (define dvd->html (lambda (dvd) (string-append "

" (dvd-title dvd) "" " from " (dvd-studio dvd) "." "
" (string #\newline) "Genres: " (genres->html (dvd-genres dvd)) "

" (string #\newline) (if (string=? (dvd-notes dvd) "") "" (string-append "
" (dvd-notes dvd) "
" (string #\newline)))))) ;;; Procedure: ;;; genres->html ;;; Parameters: ;;; genres, a list of strings ;;; Purpose: ;;; Build a simple text string for a list of genres ;;; Produces: ;;; A string ;;; Preconditions: ;;; genres must be a non-empty list of strings ;;; Postconditions: ;;; Returns a string (define genres->html (lambda (genres) ; If only one genre, just use it (if (null? (cdr genres)) (car genres) ; Otherwise, join the first, a comma, and the rest (string-append (car genres) ", " (genres->html (cdr genres)))))) ;;; Predicate: ;;; dvd? ;;; Parameters: ;;; Any one value ;;; Purpose: ;;; Determine if that value seems to represent a DVD (according ;;; to the specifications above). ;;; Produces: ;;; A Boolean value, true (#t) if the value seems to represent a ;;; DVD and false (#f) if it does not. ;;; Preconditions: ;;; (none) ;;; Postconditions: ;;; The value is likely to be information on a DVD, but may not. (define dvd? (lambda (value) (and (list? value) ; It must be a list (= (length value) 4) ; of four elements (string? (list-ref value 0)) ; The title, a string (string? (list-ref value 1)) ; The studio, a string (list? (list-ref value 2)) ; The list of genres (not (null? (list-ref value 2))) ; which is non-empty (string? (list-ref value 3)) ; The notes, a string ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Manipulating Collections of DVDS ;;; Procedure: ;;; dvds->html ;;; Parameters: ;;; dvds, a list of DVDs ;;; Purpose: ;;; Generate some nice HTML (e.g., a list) for the DVDs. ;;; Produces: ;;; A string. ;;; Preconditions: ;;; Each element of dvds must have the appropriate form (described ;;; above). (Unverified) ;;; Postconditions: ;;; Does not modify the list or any element of the list. ;;; Returns valid HTML. (define dvds->html (lambda (dvds) (if (null? dvds) "" (string-append "" (string #\newline))))) ;;; Helper: ;;; help-dvds->html ;;; Purpose: ;;; Convert a list of DVDS to HTML without worrying about the ;;; surrounding ul tags. Intended only as a helper for dvds->html ;;; Notes: ;;; Preconditions and postconditions are as in dvds->html (define help-dvds->html (lambda (dvds) (if (null? dvds) "" (string-append "
  • " (dvd->html (car dvds)) "
  • " (string #\newline) (help-dvds->html (cdr dvds)))))) ;;; Procedure: ;;; find-dvd-by-title ;;; Parameters: ;;; title, he title of a DVD ;;; dvds, a list of DVDs ;;; Purpose: ;;; Find a DVD with the given title. ;;; Produces: ;;; d, a DVD with the given title, if one is in the list. ;;; #f otherwise ;;; Preconditions: ;;; The title must be a string. ;;; Each DVD in the list must be in the appropriate form. ;;; Postconditions: ;;; Does not modify the list. ;;; If the procedure returns #f, there is no DVD, d, in the list ;;; for which (string=? title (dvd-title d)) holds. ;;; If the procedure returns another value, d ;;; d is an element of dvds ;;; (string=? title (dvd-title d)) holds (define find-dvd-by-title (lambda (title dvds) (cond ; If there are no DVDs, there can't be a DVD with the given title. ((null? dvds) #f) ; If the DVD we're looking for is at the front of the list, use it. ((string=? title (dvd-title (car dvds))) (car dvds)) ; Otherwise, look through the remaining DVDs (else (find-dvd-by-title title (cdr dvds)))))) ;;; Procedure: ;;; find-dvds-by-studio ;;; Parameters: ;;; studio, a string ;;; dvds, a list of DVDs ;;; Purpose: ;;; Find all the DVDs from a particular studio. ;;; Produces: ;;; matches, a list of DVDs. ;;; Preconditions: ;;; Each element of dvds is in the appropriate form (see above). ;;; studio is a string. ;;; Postconditions: ;;; Does not modify the list of DVDs. ;;; matches may be empty. ;;; For every element, e, of matches, the following holds: ;;; (string=? studio (dvd-studio e)) ;;; Any element of dvds for which that expression holds appears ;;; somewhere in matches. ;;; No other elements are in matches. (define find-dvds-by-studio (lambda (studio dvds) (cond ; No DVDs left, no matching DVDs left ((null? dvds) null) ; We match the first DVD. Add it to any other matches ((string=? studio (dvd-studio (car dvds))) (cons (car dvds) (find-dvds-by-studio studio (cdr dvds)))) ; Otherwise, just look for any other matches (else (find-dvds-by-studio studio (cdr dvds)))))) ;;; Procedure: ;;; find-dvds-by-genre ;;; Parameters: ;;; genre, a string ;;; dvds, a list of DVDs ;;; Purpose: ;;; Find all the DVDs in a particular genre. ;;; Produces: ;;; matches, a list of DVDs. ;;; Preconditions: ;;; Each element of dvds is in the appropriate form (see above). ;;; genre is a string. ;;; Postconditions: ;;; Does not modify the list of DVDs. ;;; matches may be empty. ;;; All the elements of matches are in the appropriate genre. ;;; All the elements of dvds that are in the appropriate genre ;;; are in matches. ;;; No other elements are in matches. ;;; Note: ;;; The member procedure is a built-in Scheme procedure that ;;; can be used to determine if a value is in a list. (It ;;; does other things, too, but that's how I'm using it here.) ;;; Note that we wrote a simlar procedure in the first recursion ;;; lab. (define find-dvds-by-genre (lambda (genre dvds) (cond ; No DVDs left, no matching DVDs left ((null? dvds) null) ; We match the first DVD. Add it to any other matches ((member genre (dvd-genres (car dvds))) (cons (car dvds) (find-dvds-by-genre genre (cdr dvds)))) ; Otherwise, just look for any other matches (else (find-dvds-by-genre genre (cdr dvds))))))