;; 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-abbr-reader.ss" "lang")((modname week4_f_full) (read-case-sensitive #t) (teachpacks ((lib "image.ss" "teachpack" "2htdp"))) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ((lib "image.ss" "teachpack" "2htdp"))))) ; note the below is a repeat of Wednesday's notes, scroll down to "Friday" ; for new material ; a person is ; - (make-person number symbol) (define-struct person (ssn name)) ;; example people: (define Adam (make-person 1 'adam)) (define George (make-person 2 'george)) (define Jon (make-person 3 'jon)) (define Steve (make-person 4 'steve)) ; Simple version: ; a database is ; - empty ; - (make-db-node person ; database ; database) ; Better version: ; a database is ; - empty ; - (make-db-node person ; database[left] ; database[right]) ; INVARIANT: ; where everyone in left has a smaller ssn than person ; and everyone in right has a larger ssn than person (define-struct db-node (person left right)) (define mydb (make-db-node George (make-db-node Adam empty empty) (make-db-node Steve (make-db-node Jon empty empty) empty))) ; template: ; (cond [(empty? db) ...] ; [(db-node? db) ; ... (db-node-person db) ... ; ... (fun-for-db (db-node-left db)) ... ; ... (fun-for-db (db-node-right db)) ... ]) ; lookup2 : number database -> person or false ; returns person if ssn in database, false otherwise (define (lookup2 n db) (cond [(empty? db) false] [(db-node? db) (cond [(person-matches? (db-node-person db) n) (db-node-person db)] [(smaller? n (db-node-person db)) (lookup2 n (db-node-left db))] [else (lookup2 n (db-node-right db))] )])) (check-expect (lookup2 1 mydb) Adam) (check-expect (lookup2 6 mydb) false) ; helper functions: ; person-matches? : person number -> boolean ; returns whether person matches ssn (define (person-matches? per n) (= n (person-ssn per))) (check-expect (person-matches? Adam 1) true) (check-expect (person-matches? Adam 2) false) ; smaller? : number person -> boolean ; returns whether number is smaller than person's ssn (define (smaller? n per) (< n (person-ssn per))) (check-expect (smaller? 1 Adam) false) (check-expect (smaller? 2 Steve) true) (check-expect (lookup2 1 mydb) Adam) (check-expect (lookup2 2 mydb) George) (check-expect (lookup2 3 mydb) Jon) (check-expect (lookup2 4 mydb) Steve) (check-expect (lookup2 6 mydb) false) (check-expect (lookup2 2 empty) false) ; A sorted-list is either: ; - empty ; - (cons number[n] sorted-list[l]) ; INVARIANT: each number in 'l' is larger than 'n' ; insert : number sorted-list -> sorted-list ; inserts number into correct position in sorted list (define (insert n slon) (cond [(empty? slon) (list n)] [else (cond [(< n (first slon)) (cons n slon)] [else (cons (first slon) (insert n (rest slon)))] )] )) (check-expect (insert 4 (list 1 2 93)) (list 1 2 4 93)) (check-expect (insert 4 empty) (list 4)) ; --------- Friday -------------- ; Execise 1: you must exploit the invariant. This implies: ; a) Your code will be somewhat faster than if it didn't exploit the ; invariant ; b) Your code may break if the input violates the invariant ; (garbage-in, garbage-out) ; Exercise 2: ; Adding to a Binary Search Tree: ; How to add Jon to (make-db-node George empty empty) ; George has ssn of 2, Jon has ssn of 3. ; Output should be: ; (make-db-node George empty (make-db-node Jon empty empty)) ; return-min : database -> number ; returns the smallest ssn in the database, assuming all ssns < 1000 ; returns 1000 if no people (define (return-min db) (cond [(empty? db) 1000] [(db-node? db) (min (person-ssn (db-node-person db)) (return-min (db-node-left db)))]) ) (check-expect (return-min mydb) 1) (check-expect (return-min (make-db-node George empty empty)) 2) ; Odds and Ends ; Syntax and Semantics ; syntactic errors: ;(define (f x) (cond x)) ;(define (f x) (/ x (0))) ; does is look look rain ? ; Racket complains as soon as it sees these things (when you hit 'Run') ; run-time (semantic) errors: ;(define (f x) (/ x 0)) ;(define (f x) (cond [false x])) ; a clear request that has no answer: ; "If you cannot understand me, what is your name?" ; Racket vs. English: ; - rules of grammar are much simpler in Racket ; - interpretation (semantics) is driven by re-write rules