;===== ; CS 111 - Week 4 Lecture 1 - 2025-09-16 ;===== (require 2htdp/image) (require 2htdp/universe) ;===== ; slightly-edited FROM WEEK 2 LECTURE 2 ;===== ;----- ; signature: cyan-star: number -> image ; purpose: expects the distance between a 5-pointed ; star's points, and returns a solid cyan star image ; of that size (check-expect (cyan-star 30) (star 30 "solid" "cyan")) (check-expect (cyan-star 50) (star 50 "solid" "cyan")) (define (cyan-star star-size) (star star-size "solid" "cyan") ) ;===== (END of part copied over from Week 2 Lecture 2) ;===== ;FROM WEEK 3 LECTURE 2 - then REFACTORED a bit! ;===== (define WIDTH 400) (define HEIGHT 200) ; I decide that these named constants might make this ; more readable: (define CENTER-X (/ WIDTH 2)) (define CENTER-Y (/ HEIGHT 2)) (define BACKDROP (empty-scene WIDTH HEIGHT)) ;===== ; signature: cyan-star-scene: number -> scene ; purpose: expects a desired star size (distance in pixels ; between its points) and returns a scene of size ; WIDTH by HEIGHT with a cyan star of that size centered ; within it (check-expect (cyan-star-scene 50) (place-image (cyan-star 50) CENTER-X CENTER-Y BACKDROP)) (check-expect (cyan-star-scene 150) (place-image (cyan-star 150) CENTER-X CENTER-Y BACKDROP)) (define (cyan-star-scene star-size) (place-image (cyan-star star-size) CENTER-X CENTER-Y BACKDROP) ) (cyan-star-scene 50) (cyan-star-scene 150) ;===== (END of part copied over from Week 3 Lecture 2 and then REFACTORED) ;===== ; cond expression ;===== ; syntax: ;===== ; (cond ; [boolean-expr1 result-expr1] ; [boolean-expr2 result-expr2] ; [boolean-expr3 result-expr3] ; ... ; [else result-expr-else] ; ) ; ; * the [bool-expr result-expr] parts can be called ; branches or clauses ; * the second expr in each clause can be of any type ; (but it must have a value) ; ;===== ; semantics (meaning): ;===== ; * evaluate each clause's boolean expression in order ; until it finds one with the value #true -- ; that clause's 2nd expression becomes the value of the cond ; expression ; ; * once a clause starting with a #true boolean expression ; is found, the rest of the clauses are IGNORED, skipped! ; * at most one branch will be "taken", at most one ; clause will have its 2nd expression evaluated ; ; * so the ORDER of the clauses matters! ; ; * if you include an [else ...] clause and it is reached, ; else is always considered #true and the else clause's ; 2nd expression will be the value of the cond expression ; ;===== ; CS 111 Class Style: ;===== ; * start each [boolean-expr result-expr] clause in ; a cond expression on its own line ; ; * INDENT the start of each [boolean-expr result-expr] ; clause in a cond expression under its (cond ; ; * (for a long clause, indent its continuation line(s) ; so it is clear which clause it is continuing) ; ; * as always, ASK me if you have any questions about CS 111 ; class style! ;===== ; kind of inspired by the song "Yes, We Have No Bananas", ; I decide I want a function that expects a quantity ; of bananas, and returns a slightly-grammatical ; report of that quantity ;===== ; signature: banana-report: number -> string ; purpose: expects an integer quantity of bananas ; and returns a string reporting that quantity of ; bananas (saying no bananas if 0 or fewer, one banana ; if 1, and the given quantity as a number with bananas ; if more than 1) ;===== ; do you see that you should have a test for each ; branch, and sometimes more, as we'll see later? (check-expect (banana-report -7) "yes, we have no bananas!") (check-expect (banana-report 0) "yes, we have no bananas!") (check-expect (banana-report 1) "yes, we have one banana!") (check-expect (banana-report 2) "yes, we have 2 bananas!") (check-expect (banana-report 400) "yes, we have 400 bananas!") (define (banana-report num-bananas) (cond [(<= num-bananas 0) "yes, we have no bananas!"] [(= num-bananas 1) "yes, we have one banana!"] [else (string-append "yes, we have " (number->string num-bananas) " bananas!")] ) ) (banana-report -7) (banana-report 1) (banana-report 400) ;==== ; I decide I'd like to write a function to use with ; cyan-star-scene and big-bang to use with big-bang's ; stop-when clause, ; to help big-bang end gracefully whenever the world ; size gets "unreasonable" ; say: a star size of 0 or less, ; and maybe if the star size exceeds the HEIGHT, that's ; too big; ;===== ; remember: big-bang's stop-when clause ; expects the name of a function that ; expects the current world value's type and returns ; a boolean ; and when big-bang's ticker ticks, it calls the function ; from a stop-when clause with the current world value, ; and if that function returns #true, big-bang ends ; ; (get it? asking big-bang to stop when its function is #true...) ; ;===== ; recall the MATH notation for intervals: ; ( or ) means up to but NOT including that value ; [ or ] means INCLUDING that value ; ; so, for example: [1, HEIGHT) means all values between ; 1 and HEIGHT, *including* 1 but *not* including HEIGHT ;===== ; signature: bad-star-size?: number -> boolean ; purpose: expects a star size, and returns #true if it ; is OUTSIDE the the desired star size range of ; [1, HEIGHT) and it returns #false otherwise ;----- ; CS 111 Class Style: when your function is dealing with ; numeric intervals, need a test for each interval, ; PLUS a test for each BOUNDARY value between intervals ;----- ; so, we need at least FIVE tests here (3 intervals, and 2 boundaries ; in-between): (check-expect (bad-star-size? -5) #true) (check-expect (bad-star-size? 1) #false) (check-expect (bad-star-size? (- HEIGHT 1)) #false) (check-expect (bad-star-size? HEIGHT) #true) (check-expect (bad-star-size? (+ HEIGHT 167)) #true) ; (just for your reference, I am including the ; versions we refactored from during class -- ; that is not required!) (define (bad-star-size? star-size) ; (cond ;; ; version 1 - 3-branch version ;; ;; [(< star-size 1) #true] ;; [(>= star-size HEIGHT) #true] ;; [else #false] ; ; ; refactored version 2 - ; ; combining the #true cases into one branch using or ; ; [(or (< star-size 1) ; (>= star-size HEIGHT)) #true] ; [else #false] ; ; ) ; refactored version 3 - realizing a single boolean expression ; can work here for this boolean function (or (< star-size 1) (>= star-size HEIGHT)) ) (bad-star-size? (+ HEIGHT 167)) "=====" "thanks to stop-when clause, these big-bang calls end" " gracefully! (but you should close the World window...)" (big-bang 50 (to-draw cyan-star-scene) (on-tick sub1) (stop-when bad-star-size?) ) (big-bang 100 (to-draw cyan-star-scene) (on-tick add1) (stop-when bad-star-size?) )