;; **************************************** ;; * Csu 211 : 1/30/2008 ;; * Lecture #9.1 Code ;; * Structures and More Conditionals ;; **************************************** ;; A Clock is (make-clock H M S) where H, M, and S are Numbers ;; representing the current time (define-struct clock (h m s)) ;; incr-clock: Clock -> Clock ;; Increment the seconds of the given clock and update minutes ;; and hours accordingly (define (incr-clock clk) (incr-min (clock-h clk) (clock-m clk) (+ (clock-s clk) 1))) ;; incr-min: Number Number Number -> Clock ;; If seconds is over 59, increment minutes and set sec. to 0 (define (incr-min h m s) (cond [(> s 59) (incr-hour h (+ m 1) 0)] [else (make-clock h m s)])) ;; incr-hour: Number Number Number -> Clock ;; If minutes is over 59, increment hours and set min. to 0 (define (incr-hour h m s) (cond [(> m 59) (fix-hour (+ h 1) 0 s)] [else (make-clock h m s)])) ;; fix-hour: Number Number Number -> Clock ;; If hours is > 23 then set hours to 0 (define (fix-hour h m s) (cond [(> h 23) (make-clock 0 m s)] [else (make-clock h m s)])) ;; two-digit: Number -> String ;; Convert the given number to a two digit String; if it is ;; only one digit then we add another "0" to the front (define (two-digit n) (string-append (cond [(< n 10) "0"] [else ""]) (number->string n))) ;; Test Normal Time (equal? (incr-clock (make-clock 5 6 7)) (make-clock 5 6 8)) ;; Test Minute update (equal? (incr-clock (make-clock 5 6 59)) (make-clock 5 7 0)) ;; Test Hour update (equal? (incr-clock (make-clock 5 59 59)) (make-clock 6 0 0)) ;; Test Hour wrapping (equal? (incr-clock (make-clock 23 59 59)) (make-clock 0 0 0)) ;; clock->scene: Clock -> Scene ;; Draw an image of the clock into an empty scene (define (clock->scene clk) (place-image (text (clock->string (clock-h clk) (clock-m clk) (clock-s clk)) 36 'black) 0 0 (empty-scene 320 55))) ;; clock->string: Number Number Number -> String ;; Create a String representation of the given clock (define (clock->string h m s) (string-append (am/pm-hour h) ":" (two-digit m) "." (two-digit s) (am/pm h))) ;; am/pm-hour: Number -> String ;; Convert 24-hour into 12-hour (am/pm) ;; 0 or 12 -> "12" ;; h>12 -> "n-12" ;; else -> "n" (define (am/pm-hour h) (two-digit (cond [(or (= h 0) (= h 12)) 12] [(> h 12) (- h 12)] [else h]))) ;; am/pm: Number -> String ;; return "am" if h < 12, "pm" otherwise (define (am/pm h) (cond [(< h 12) " am"] [else " pm"])) ;; Setup the Drawing/Ticking for the Clock display (big-bang 320 55 1 (make-clock 0 59 55)) (on-redraw clock->scene) (on-tick-event incr-clock)