;; 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-reader.ss" "lang")((modname lect03a) (read-case-sensitive #t) (teachpacks ((lib "universe.ss" "teachpack" "2htdp") (lib "image.ss" "teachpack" "2htdp"))) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ((lib "universe.ss" "teachpack" "2htdp") (lib "image.ss" "teachpack" "2htdp"))))) ;;;;; lect03a.rkt ; symbols: ; examples: 'jack 'queen 'red 'yellow 'green 'amy 'george ... ; Can often be used as an enumerated type, ; or like a string that I'll never want to call substring/string-ref/string-concat etc. ; The *only* useful function involving symbols: symbol=? symbol? ; ; symbol=? : symbol, symbol -> boolean ; symbol? : ANY -> boolean ; ; integer? : ANY -> boolean ;;; Review: (define (root1 a b c) (/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a))) ; parameter (a,b,c) is a variable-name ; argument (4,7,3) is a *value* that get passed in to a function ;;; Review: ;;; If you have a union-type ;;; ("A Blargh is either: ;;; - a char, *or* ;;; - an int, *or* ;;; - a boolean"), ;;; your code that processes a Blargh will naturally start with ???? ;;;;;;; Exercise, to check your review/understanding: ;; Write a function to compute income tax, according to: ;; income [0,$10,000) -- no tax ;; income [$10,000, $25,000) -- 10% of the amount above $10,000 ;; income [$25,000,+infinity) -- 25% of the amount above $25,000 plus $1500 (check-expect (income 0) 0) (check-expect (income 3000) 0) (check-expect (income 10000) 0) (check-expect (income 15000) 500) (check-expect (income 24999.99) 1499.999) (check-expect (income 25000) 1500) (define (income x) (cond [(< x 10000) 0] [(and (<= 10000 x) (< x 25000)) (* 0.10 (- x 10000))] [(<= 25000 x) (+ (* 0.25 (- x 25000)) 1500)])) ;; The TEMPLATE for functions that consume a `rank`: ;;; Since we're handling data that can be integer OR character, ;;; we'll use "cond", which is like if-else-if: #;(define (func-for-ranks r) (cond [(integer? r) ...] [(symbol? r) ...])) (check-expect (rank->string 5) "5") (check-expect (rank->string 10) "10") (check-expect (rank->string 'queen) "Q") ; rank->string : rank -> string ; (define (rank->string r) (cond [(integer? r) (number->string r)] [(symbol? r) (string (char-upcase (string-ref (symbol->string r) 0)))])) ;;;;;;;;;;;;;;;;;;;;;;;;;;; Hour 3 ;;;;;;;;;;;;;;;;;;;;; ; Exercise: write a function that takes in rank, and returns ...? ; Let's see how much we can write w/o even knowing WTF ("what the function?") ; A rank is either: ; - an integer (2..10) ; or - a symbol ('jack, 'queen, 'king, 'ace) ; Btw, we can write: ; rank? ANY -> boolean ; (define (rank? any) (or (and (integer? any) (<= 2 any 10)) (symbol? any))) ; ; The design recipe: ; http://htdp.org/2003-09-26/Book/curriculum-Z-H-7.html#node_sec_4.4 ; --- per (abstract) data type: ; - data def'n ; - examples of data ; - template (incl. any case analysis) ; ; --- per function: ; - contract (types), purpose (prose), header (`define`)/stub ; - test-cases (check-expect) ; - complete function-body ; - union data?: case analysis (cond-questions, 1 per data variant) ; - ... ; - answer for each cases ; - run the tests (trivial) ;;;;;;;;;;;;;;;;; Next stage: define-struct (product type) ; ; My data definition: ; (define-struct card (r s)) ; r : rank ; s : symbol ; Examples of the data: ; (define 4s (make-card 4 'spades)) (define qh (make-card 'queen 'hearts)) ; When I define-struct, racket creates four functions for me: ; make-card -- constructor ; card-rank -- accessor ; card-suit -- accessor ; card? -- predicate ; have-a-heart : rank -> card ; Return a card of the given rank, in hearts. ; (define (have-a-heart r) (make-card r 'hearts)) (check-expect (have-a-heart 10) (make-card 10 'hearts)) (check-expect (have-a-heart 'ace) (make-card 'ace 'hearts))