;; 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 lect05) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) ; What is the type of: symbol=? : symbol symbol -> boolean #| The Design Recipe (take 1 -- primitive types only) ------- per function: 4. tests 5. stub : signature, header, description, stub-body 7. complete the body-expression 8. watch your tests pass |# ; Task: `turn`, for changing a stop-light. ; ...wait, what data type to use? ; Data Definition: ; A slc ("stoplight color") is one of: ; - 'red, OR ; - 'yellow, OR ; - 'green, OR ; - 'flashing-yellow, OR ; - 'flashing-red (check-expect (turn 'red) 'green) (check-expect (turn 'green) 'yellow) (check-expect (turn 'yellow) 'red) (check-expect (turn 'flashing-red) 'flashing-red) (check-expect (turn 'flashing-yellow) 'flashing-yellow) ; turn : slc -> slc ; return the next color for a stop-light. ; (define (turn curr-color) (cond [(symbol=? curr-color 'red) 'green] [(symbol=? curr-color 'yellow) 'red] [(symbol=? curr-color 'green) 'yellow] [(symbol=? curr-color 'flashing-yellow) 'flashing-yellow] [(symbol=? curr-color 'flashing-red) 'flashing-red] [else (error 'turn "fell off cond?!")] )) ; Task: write penalty-for-running-a-light. (check-expect (penalty-for-running-a-light 'red) 50) (check-expect (penalty-for-running-a-light 'yellow) 0) (check-expect (penalty-for-running-a-light 'green) 0) ; ... ; penalty-for-running-a-light : slc -> non-negative-real ; Return the fine for running a stoplight, in USD. ; (define (penalty-for-running-a-light curr-color) (cond [(symbol=? curr-color 'red) 50] [(symbol=? curr-color 'yellow) 0] [(symbol=? curr-color 'green) 0] [(symbol=? curr-color 'flashing-yellow) 25] [(symbol=? curr-color 'flashing-red) 99] )) ; template (define (func-for-slc a-slc) (cond [(symbol=? a-slc 'red) ...] [(symbol=? a-slc 'yellow) ...] [(symbol=? a-slc 'green) ...] [(symbol=? a-slc 'flashing-yellow) ...] [(symbol=? a-slc 'flashing-red) ...] )) #| We actually just did several more steps of the design-recipe. 1. Choose data definition 2. Give some examples of the data 3. Template: a. If handling a union type, include a cond w/ one branch per option. Note that if we write five more functions involving stoplight-colors, we only need do steps 1-3 once. (And we'll copy/paste 3a over and over, for each functions.) |# ; Step 3, TEMPLATE, for the streetlight-color data type: ; ; func-for-slc : slc -> ??? ; #| (define chr (cond [(symbol=? a-slc 'red) ...] [(symbol=? a-slc 'yellow) ...] [(symbol=? a-slc 'green) ...] [(symbol=? a-slc 'flashing-yellow) ...] [(symbol=? a-slc 'flashing-red) ...])) |# ; Task: write penalty-for-running-a-light. ; Task: Write a function to return the tax-due, given taxable-income. ; (for single tax-payers; we'll stop after 3 brackets) ; ($9075 => 10%; $36900 => 15%; else 25% ) ; http://www.forbes.com/sites/kellyphillipserb/2013/10/31/irs-announces-2014-tax-brackets-standard-deduction-amounts-and-more/ ; A taxable income is: ; - real number <= 9075 ; - real number in (9075,36900] ; - real number in (36900,∞) ; examples of the data: 500 9076 200000000000 36899.9999 36900 36900.00001 -1 2.05 #| ; TODO: Step 4: develop test cases: (check-expect (tax 0) 0) (check-expect (tax 10) 1) (check-expect (tax 9075) 907.50) (check-expect (tax 9076) 907.65) (check-expect (tax 36900) (+ (* 0.10 9075) (* 0.15 (- 36900 9075))) ) (check-expect (tax 46900) (+ (* 0.10 9075) (* 0.15 (- 36900 9075)) (* 0.25 10000))) ; a taxable-income is either: ; - a number <= 9075, OR it's ; - a number > 9075 and is <= 36900, Or it's ; - a number > 36900. ; tax : number -> number ; return the tax-due, given taxable-income. ; (for single tax-payers; we'll stop after 4 brackets) #| (define (tax income) (cond [(<= income 9075) (* 0.10 income)] [(<= income 36900) (+ (* 0.10 9075) (* 0.15 (- income 9075)))] [else (let* {[tier2 (- 36900 9075)] [excess (- income 36900)]} (+ (* 0.10 9075) (* 0.15 tier2) (* 0.25 excess)))])) ; Update: ; a taxable-income-entry is either: ; - 'exempt (a claim that income is exempt-- tax-treaty?), OR it's ; - #false (represents no taxes filed!), OR it's ; - a number <= 9075, OR it's ; - a number > 9075 and is <= 36900, Or it's ; - a number > 36900. ; Examples of the data -- taxable-income-entry: 10000 37000.5 6000 'exempt #false ; template (define (function-for-tie a-tie) (cond [(symbol? a-tie) ...] [(false? a-tie) ...] [(and (number? a-tie) (<= a-tie 9075)) ...] [... ...] [... ...]))) ; (**) or, collapse the last three cases, and just say it's a "taxable-income" ; as previously defined? |# #| (define (func-for-taxable-income-entry a-tie) (cond [(symbol? a-tie) ...] [(boolean? a-tie) ...] [(<= a-tie 9075) ...] [.. ..] [.. ..]) ; DESIGN QUESTION: ; Should we make `tax2` call `tax` as a helper? ; I'd say, Answer: depending on our data-def'n: ; if we included 5 branches in 'taxable-income-entry', we should have 5 branches. ; Otherwise three. ; But that just begs the question: what is the right data-def'n -- ; should it have 'exempt,#f,number or should it have 5 branches? ; I tend towards the former. |# |#