;; 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-intermediate-reader.ss" "lang")((modname 12-tree) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) ; An [Assn K V] is (make-assn K V) ; Interp. (make-assn k v) associates key k with value v (define-struct assn (key val)) ; Examples: (define abc123 (make-assn "abc123" 0.8)) (define def456 (make-assn "def456" 0.9)) (define ghi789 (make-assn "ghi789" 1.0)) (define abc123* (make-assn "abc123" 1.0)) (define def456* (make-assn "def456" 1.0)) ; A GradeTable is [List-of [Assn String Number]] ; INVARIANT: The strings are unique. ; Interp. list of NetIDs associated with their grades. ; gt-lookup : String GradeTable -> Number ; Looks up the grade of the given NetID, or 0 if not found. ; ; Examples: ; - (gt-lookup abc {abc: 0.8, def: 0.9}) => 0.8 ; - (gt-lookup def {abc: 0.8, def: 0.9}) => 0.9 ; - (gt-lookup ghi {abc: 0.8, def: 0.9}) => 0 ; ; Strategy: struct decomp (define (gt-lookup netid gt) (cond [(empty? gt) 0] [else (if (has-key? netid (first gt)) (assn-val (first gt)) (gt-lookup netid (rest gt)))])) (check-expect (gt-lookup "abc123" (list abc123 def456)) 0.8) (check-expect (gt-lookup "def456" (list abc123 def456)) 0.9) (check-expect (gt-lookup "ghi789" (list abc123 def456)) 0) ; has-key? : String [Assn String V] -> Boolean ; Is the given key the key of the given association? ; ; Examples: ; - (has-key? "a" (make-assn "a" 1)) => true ; - (has-key? "a" (make-assn "b" 1)) => false ; ; Strategy: struct decomp (define (has-key? k assn) (string=? k (assn-key assn))) (check-expect (has-key? "a" (make-assn "a" 1)) true) (check-expect (has-key? "a" (make-assn "b" 1)) false) ; gt-update : String Number GradeTable -> GradeTable ; Associates the given NetID with the given grade in the grade table, changing ; or adding it as necessary. ; ; Examples: ; - (gt-update abc 0.8 {}) => {abc: 0.8} ; - (gt-update ghi 1.0 {abc: 0.8, def: 0.9}) => {abc: 0.8, def: 0.9, ghi: 1.0} ; - (gt-update abc 1.0 {abc: 0.8, def: 0.9, ghi: 1.0}) ; => {abc: 1.0, def: 0.9, ghi: 1.0} ; ; Strategy: struct decomp (define (gt-update netid grade gt) (cond [(empty? gt) (list (make-assn netid grade))] [else (if (has-key? netid (first gt)) (cons (make-assn netid grade) (rest gt)) (cons (first gt) (gt-update netid grade (rest gt))))])) (check-expect (gt-update "abc123" 0.8 '()) (list abc123)) (check-expect (gt-update "def456" 0.9 (list abc123)) (list abc123 def456)) (check-expect (gt-update "ghi789" 1.0 (list abc123 def456)) (list abc123 def456 ghi789)) (check-expect (gt-update "abc123" 1.0 (list abc123 def456 ghi789)) (list abc123* def456 ghi789)) (check-expect (gt-update "def456" 1.0 (list abc123 def456 ghi789)) (list abc123 def456* ghi789)) ;;;;; Now for a different representation: a binary tree ; A GradeTable is one of: ; - (make-empty-gt) ; - (make-node GradeTable String Number GradeTable) ; ; INVARIANT: for every node (make-node l k v r), all the keys in l are ; string? k. ; ; Interp. A mapping from NetIDs to grades, where: ; - (make-empty-gt) is an empty mapping, and ; - (make-node l k v r) is the mapping that associates k with v, as well as ; all the associations in mappings l and r. (define-struct node (left key val right)) (define-struct empty-gt ()) #| (define (process-gt gt) (cond [(empty-gt? gt) ...] [else ... (process-gt (node-left gt)) ... ... (node-key gt) ... ... (node-val gt) ... ... (process-gt (node-right gt)) ...])) |# ; empty-grade-table : GradeTable ; The empty grade table. (define empty-grade-table (make-empty-gt)) (define GT0 empty-grade-table) (define GT1 (make-node GT0 "def456" 0.9 GT0)) (define GT2 (make-node (make-node GT0 "abc123" 0.8 GT0) "def456" 0.9 GT0)) (define GT3 (make-node (make-node GT0 "abc123" 0.8 GT0) "def456" 0.9 (make-node GT0 "ghi789" 1.0 GT0))) (define GT3/l (make-node (make-node GT0 "abc123" 1.0 GT0) "def456" 0.9 (make-node GT0 "ghi789" 1.0 GT0))) (define GT3/c (make-node (make-node GT0 "abc123" 0.8 GT0) "def456" 1.0 (make-node GT0 "ghi789" 1.0 GT0))) (define GT3/r (make-node (make-node GT0 "abc123" 0.8 GT0) "def456" 0.9 (make-node GT0 "ghi789" 1.1 GT0))) ; lookup-grade : String GradeTable -> Number ; Looks up the grade of the given NetID, or 0 if not found. ; ; Examples: ; - (lookup-grade abc {abc: 0.8, def: 0.9}) => 0.8 ; - (lookup-grade def {abc: 0.8, def: 0.9}) => 0.9 ; - (lookup-grade ghi {abc: 0.8, def: 0.9}) => 0 ; ; Strategy: struct decomp (define (lookup-grade netid gt) (cond [(empty-gt? gt) 0] [else (cond [(string? netid (node-key gt)) (lookup-grade netid (node-right gt))] [else (node-val gt)])])) (check-expect (lookup-grade "def456" GT0) 0) (check-expect (lookup-grade "def456" GT1) 0.9) (check-expect (lookup-grade "abc123" GT1) 0) (check-expect (lookup-grade "ghi789" GT1) 0) (check-expect (lookup-grade "def456" GT2) 0.9) (check-expect (lookup-grade "abc123" GT2) 0.8) (check-expect (lookup-grade "ghi789" GT2) 0) (check-expect (lookup-grade "def456" GT3) 0.9) (check-expect (lookup-grade "abc123" GT3) 0.8) (check-expect (lookup-grade "ghi789" GT3) 1) ; update-grade : String Number GradeTable -> GradeTable ; Associates the given NetID with the given grade in the grade table, changing ; or adding it as necessary. ; ; Examples: ; - (update-grade abc 0.8 {}) => {abc: 0.8} ; - (update-grade ghi 1.0 {abc: 0.8, def: 0.9}) ; => {abc: 0.8, def: 0.9, ghi: 1.0} ; - (update-grade abc 1.0 {abc: 0.8, def: 0.9, ghi: 1.0}) ; => {abc: 1.0, def: 0.9, ghi: 1.0} ; ; Strategy: struct decomp (define (update-grade netid grade gt) (cond [(empty-gt? gt) (make-node (make-empty-gt) netid grade (make-empty-gt))] [else (cond [(string? netid (node-key gt)) (make-node (node-left gt) (node-key gt) (node-val gt) (update-grade netid grade (node-right gt)))] [else (make-node (node-left gt) netid grade (node-right gt))])])) (check-expect (update-grade "def456" 0.9 GT0) GT1) (check-expect (update-grade "abc123" 0.8 GT1) GT2) (check-expect (update-grade "ghi789" 1.0 GT2) GT3) (check-expect (update-grade "abc123" 1.0 GT3) GT3/l) (check-expect (update-grade "def456" 1.0 GT3) GT3/c) (check-expect (update-grade "ghi789" 1.1 GT3) GT3/r)