;=====
; posted examples for Week 2 Lecture 2 - 2025-09-04
;     Cleaned up after class!
; last modified: 2025-09-04

(require 2htdp/image)

;-----
; defining another named constant
; *   intended to represent a maximum safe temperature
;     for some situation

(define MAX-SAFE-TEMP 80)

;-----
; and once defined, the named constant is a simple
;    expression whose data type is the data type of
;    its value

MAX-SAFE-TEMP

; ...and it can be used accordingly

(< 50 MAX-SAFE-TEMP)

;-----
; and here's one more named constant,
;    in case I might be using a fuchsia hexagon 
;    of this size, style, and color several times

(define DAYGLO-HEX (regular-polygon 50 6 "solid" "fuchsia"))

DAYGLO-HEX

(beside DAYGLO-HEX DAYGLO-HEX)

;=====
; check-expect - one of a FAMILY of TESTING
;     functions provided by DrRacket!
;=====
; check-expect expects TWO arguments,
;     an expression to be tested,
;     and an expression whose value is what I HOPE
;         the value of the first expression is
; and it returns nothing,
;     BUT has several side-effects:
;     *   if all the check- expressions in the Definitions window passed,
;         prints a message at the end of the Interactions
;         windows saying how many tests passed
;     *   if any failed, a pop-up window gives info
;         about those failures

;-----
; TYPICALLY, we use it with a first argument that is using a function
;     we want to test, especially one we are creating.
; BUT just to demonstrate its usage:

(check-expect (number? 13)
              #true)

(check-expect (number? "13")
              #false)

; this one fails -- UNCOMMENT it to see the pop-up window
;     that results
;
;(check-expect (number? "13")
;              #true)

;=====
; writing your own operations --
;     creating your own functions
;=====
; we know Math has functions:
;    f(x) = 3x
;
;    we can then say:
;    f(1) = 3*1 = 3
;    f(33) = 3 * 33 = 99

;-----
; what is BSL Racket syntax for this?
;
; (define (desired-funct-name desired-param1 desired-param2 ... )
;     body-expression
; )
;
; this DEFINES desired-funct-name to be a new function,
;    and for each of its parameters it expects an argument,
;    and when you use that function, each parameter
;    is given the value of the corresponding argument,
;    and the body-expression is computed (and it hopefully
;    uses those parameters!) and its value is the value for
;    that function

;-----
; IMPORTANT class terms:
;-----
; function header and function body:
;
; (define (desired-funct-name desired-param1 desired-param2 ... ) ; <- function HEADER
;     body-expression)                                            ; <- function BODY
;
; *   function header defines the name of the function and name(s) of
;     its parameter variable(s)
; *   function body determines WHAT the function DOES when it is used

;-----
; CLASS STYLE: indent the function body's expression

;-----
; so, we could write Math's f(x) = 3x in Racket using:

(define (f x)   
    (* 3 x)     
)

(f 1)
(f 33)

;-----
; (So,
;
;  (define (f x)   ; is the function header,
;                  ; defining a function named f with one parameter named x
;
;      (* 3 x)     ; this is the function body,
;   )              ; including the expression computing the function's value
;                  ;     when it is used in a compound expression

;----
; so:
;    (f 1)  ; uses function f, making parameter x have the value 1
;           ;    in f's body expression
;    (f 33) ; also uses function f, now making parameter x have the value 33
;           ;    in f's body expression

;=====
; SCOPE of an identifier:
;     the PART(s) of a program where an identifier
;     has meaning
; named constant and for a function?
;     scope is from where it is defined to the end
;     of the .rkt file
; parameter?
;     scope of a parameter is JUST the body of its
;     function

;=====
; DESIGN RECIPE - answers the question: where do you start
;    in writing a function?
;
; It is a methodical approach to writing a function.
;=====

;=====
; let's rewrite the function f above to make it more readable,
;    and demo the design recipe!

; =====
; first version of the design recipe:
;=====
; *   STEP 0: THINK about what you want to do?
;             what kind of data is involved?
;
;     *   you often do not type anything yet as part of this

;=====
; *   STEP 1: write a signature comment for the new function
;
;     *   reminder: CLASS STYLE: only use *type* names for the
;         expected arguments and return type for your function-to-be!
;
; Here, I decided that triple is a more-descriptive name than f!
;     and it expects one argument of type number,
;     and it returns a value of type number:

; signature: triple: number -> number

;=====
; *   STEP 2: write a purpose statement comment for the
;             new function

; purpose: expects a number, and returns that number
;    multiplied by 3

;=====
; *   STEP 3: write the function header, with a body of
;             ... for NOW
;     *	  grab the function name from its signature comment  
;     *	  class	style: decide on a DESCRIPTIVE,	NON-MISLEADING
;     	  name for a parameter for each	of the expected
;     	  argument types in its	signature comment
;     	  (and do NOT use an exact type name)

;(define (triple a-num)
;   ...
;)

;=====
; *   STEP 4: write at least TWO (and sometimes more)
;             check- expressions/TESTS for your function-in-progress
;
; test: an example call of your function, with specific argument(s)
;       you choose, AND what that example call's value SHOULD be,
;       if it works -- and in Racket, you can use a check-expect
;       expression whose arguments are this example call and its
;       expected value for each test
; (there are several other possible check- functions for testing
;       also -- we'll get to some of those later)

(check-expect (triple 1)
              3)

(check-expect (triple 66)
              (* 3 66))

;=====
; *   STEP 5: replace the ... in the function's body with
;             an expression USING the parameter(s) that does
;             what you want
;
; (in class, I commented out the earlier version and repasted
;     it here, with the actual body expression replacing the ... --
; to EMPHASIZE that we write the tests BEFORE completing the
;     function body --
; but when you are using the design recipe, it is FINE to just
;     go up and REPLACE the ... in Step 3's result)

(define (triple a-num)
   (* 3 a-num)
)

; *   STEP 6: run and debug as needed (going back to earlier
;             steps if/as needed)

;-----
; and now that you have defined a function triple,
;     you can use triple in compound expressions!

(triple MAX-SAFE-TEMP)

;=====
; ANOTHER example of writing a function using the design recipe
;=====
; say I am going to have a need for different-sized cyan
;    stars

;-----
; 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

; note: check- functions ARE "special" -- it IS fine
;    to put them BEFORE the function definition expression!

(check-expect (cyan-star 30)
              (star 30 "solid" "cyan"))

(check-expect (cyan-star 50)
              (star 50 "solid" "cyan"))

(define (cyan-star star-size)
   ; body expression WAS ..., but after I wrote the tests I replaced it with:
  
   (star star-size "solid" "cyan")
)

(cyan-star 50)
(cyan-star 18)

; silly, but it works:

(cyan-star MAX-SAFE-TEMP)