;;; File: ;;; cd-utils.ss ;;; Author: ;;; Samuel A. Rebelsky ;;; Version: ;;; 1.0 of October 2000 ;;; Contents: ;;; Some simple utilities for working with a CD database. ;;; Written as part of the answer key for Exam 1 of CSCS151.02 2000F. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; General helper procedures ;;; Extract some bit of information about a CD. ;;; Parameters: ;;; A CD entry in the appropriate format. ;;; Preconditions: ;;; The CD entry is in the appropriate format. ;;; Postconditions: ;;; Does not modify the CD. ;;; Return value: ;;; Some part of the CD record. (define get-cd-artist (lambda (cd) (list-ref cd 0))) (define get-cd-title (lambda (cd) (list-ref cd 1))) (define get-cd-genre (lambda (cd) (list-ref cd 2))) (define get-cd-songs (lambda (cd) (list-ref cd 3))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Exam 1, Problem 4 ;;; Write and test a procedure, ;;; (search-cd category key database) ;;; that lets them search by artist, title, or genre and returns all ;;; matching records. For example, ;;; (search-cd 'artist "Van Morrison" samscds) ;;; should return all the CDs I have by Van Morrision. ;;; Extract a specified part of a CD ;;; Parameters: ;;; The entry for a CD ;;; A category (one of artist, title, and genre) ;;; Preconditions: ;;; The CD entry is in the appropriate format ;;; The category is one of the three symbols artist, title, genre ;;; Postconditions: ;;; Returns the specified part of the CD. (define get-category (lambda (cd category) (cond ((equal? category 'artist) (get-cd-artist cd)) ((equal? category 'title) (get-cd-title cd)) ((equal? category 'genre) (get-cd-genre cd)) (else (error "Invalid category"))))) ;;; Extract all CDs that match a key for a particular category. ;;; Parameters: ;;; A category (artist, title, or genre); a symbol. ;;; A string that represents the key to match. ;;; A list of CDs. ;;; Returns: ;;; A list of CDs that match the given criteria. ;;; Preconditions: ;;; Every CD in the list is in valid CD format. ;;; The category is one of artist, title, and genre. ;;; Postconditions: ;;; Does not affect the list of CDs. (define search-cd (lambda (category key cds) (cond ;;; If there are no CDs, there are no matches ((null? cds) null) ;;; If the first CD matches, keep it and recurse ((equal? key (get-category (car cds) category)) (cons (car cds) (search-cd category key (cdr cds)))) ;;; Otherwise, just recurse on the rest (else (search-cd category key (cdr cds)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Exam 1, Problem 5 ;;; Show how to use search-cd to find a CD matching a given artist ;;; and title. ;;; Extract all the CDs from a database that match a given artist ;;; and title. ;;; Parameters: ;;; An artist (a string) ;;; A title (a string) ;;; A list of CDs ;;; Returns: ;;; All CDs with the given artist and title. ;;; Preconditions: ;;; All CDs in the list are in the appropriate format. ;;; Postconditions: ;;; Does not affect the list. (define search-artist-title (lambda (artist title cds) (search-cd 'artist artist (search-cd 'title title cds)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Exam 1, Problem 6 ;;; Write and test a procedure, ;;; (search-songs song database) ;;; that lets someone search the database by song title. ;;; Extract all CDs that match a key for a particular category. ;;; Parameters: ;;; A song title (a string). ;;; A list of CDs. ;;; Returns: ;;; A list of CDs that match the given criteria. ;;; Preconditions: ;;; Every CD in the list is in valid CD format. ;;; Postconditions: ;;; Does not affect the list of CDs. (define search-songs (lambda (song cds) (cond ;;; If there are no CDs, there are no matches ((null? cds) null) ;;; If the first CD matches, keep it and recurse ((inlist? song (get-cd-songs (car cds))) (cons (car cds) (search-songs song (cdr cds)))) ;;; Otherwise, just recurse on the rest (else (search-songs song (cdr cds)))))) ;;; Determine if a string is in a list of strings. ;;; Parameters: ;;; A string. ;;; A potentially empty list of strings. ;;; Preconditions: ;;; None ;;; Postconditions: ;;; Does not affect the list. (define inlist? (lambda (str strlist) ;;; Nothing is in the null list. (if (null? strlist) #f ;;; str is in the list if it's the first element or part ;;; of the remainder.0 (or (equal? str (car strlist)) (inlist? str (cdr strlist))))))