;=====
; CS 111 - Week 2 Lecture 2 - 2026-09-03
;
; In-class examples, cleaned up after class!
;
; last modified: 2026-09-03

;=====
; say that, for some problem I am seeking to solve,
;    the maximum safe temperature is 80 degrees --
;    I might define a named constant for that:

(define MAX-SAFE-TEMP 80)

;-----
; now MAX-SAFE-TEMP is a simple expression of type number:

MAX-SAFE-TEMP

;-----
; ...and MAX-SAFE-TEMP can be used anywhere an expression of
;     type number can be used:

(< 50 MAX-SAFE-TEMP)

;-----
; FUN FACT: relational operators < > <= >= = expect
;    TWO or more number expressions, and return #true
;    if all of them satisfy that relational operation
;    in the order written, and return #false if they do not

(< 50 MAX-SAFE-TEMP 100)         ; will be #true

(> 50 MAX-SAFE-TEMP)             ; will be #false

(>= MAX-SAFE-TEMP MAX-SAFE-TEMP) ; will be #true

(= MAX-SAFE-TEMP                 ; will be #false
   (+ 1 MAX-SAFE-TEMP))

;=====
; I want to use the HTDP 2nd edition text's image module,
;     so I need to use require to get access to its functions

(require 2htdp/image)

;-----
; and another example of a named constant:
;     what if I have a desire to use a dayglo-bright
;     fuchsia 50-pixel-per-side hexagon image several times?

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

; now DAYGLO-HEX is a simple expression of type image

DAYGLO-HEX

; beside expects 2 or more image arguments
;    and returns an image of those given arguments
;    side-by-side

(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
;
; (check-expect desired-expression
;               expected-value-expression)

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

;-----
; fun fact: Racket has built-in predicate
;   functions ...
;   [predicate function or predicate is a function
;       that returns a boolean value...!]
;   such as functions like:
;       number? image? string? boolean?
;       *   each of these expects one argument of
;           ANY type and returns whether its data type
;           IS that type or not

(number? 3)
(image? 3)
(number? "3")
(boolean? #true)
(string? "3")

;-----
; I expect that (number? 3.4) will return #true

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

;-----
; I expect that (number? "3.4") will have the value #false,
;     since "3.4" is of type string, not type number

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

;-----
; I expect that (number? #true) will have the value #false,
;     since #true is of type boolean, not type number

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

;-----
; this test below fails -- (number? "13") will not return #true.
;
; 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 Mathematicsh has functions:
;=====
; In mathematics...
;
; f(x) = 3x
;
; f(4) = 3 * 4 = 12
; f(10) = 3 * 10 = 30

;-----
; 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 defines a parameter variable for each argument
;     the new function is to expect when it is used as
;     the operation for a compound expression.
;
; when you USE that function as the operation of a compound expression,
;     each parameter variable will be set to the value of the
;         corresponding argument expression,
;     and the body-expression will be computed accordingly,
;     and the resulting value will be the function's return value

;-----
; 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 each time it is used

;-----
; CLASS STYLE: INDENT the function body's expression by at LEAST 2 spaces

;-----
; SO: let's write Math's function:
;
;     f(x) = 3x
;
; ...as a Racket function:

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

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

;-----
; and now, the Math expressions:
;
;     f(4)
;     f(10)
;     f(2 + 4)
;
; ...would be written in Racket as:

(f 4)
(f 10)
(f (+ 2 4))

;=====
; SCOPE of an identifier:
;     the PART(s) of a program where an identifier
;     has meaning
; scope of a named constant and of a function?
;     scope is from where it is defined to the end
;     of the .rkt file
; scope of a parameter variable?
;     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: develop a function signature comment for the new
;         function
;
;     *   reminder: CLASS STYLE: in a function signature comment,
;         only use *type* names for the expected argument(s) and
;         return type for your function-to-be!
;
; Here, I decide 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: develop a function purpose statement comment
;
;     *   reminder: CLASS STYLE: write in the form of:
;
;     ; purpose: expects ... and returns ...
;
;     *   and DESCRIBE what it expects,
;         and DESCRIBE what it returns

; purpose: expects a number and returns three times
;    the given number

;=====
; STEP 3: write a function header,
;         with a body of ... FOR NOW
;
;     *	  grab the function name from its signature comment
;
;     *   class style:
;         for each expected argument type in its signature comment,
;         decide on a DESCRIPTIVE, NON-MISLEADING parameter variable name
;         *   and do not use an exact type name -- that can be confusing!

;(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 4)
              12)

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

;=====
; STEP 5: replace the ... in the function's body with
;         an expression USING the parameter variable(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 as the operation in compound expressions!

(triple 24)

(triple MAX-SAFE-TEMP)

;=====
; ANOTHER example of writing a function using the design recipe
;=====
; I want a function to generate a cyan star
;    of a specified size

;-----
; signature: cyan-star: number -> image
; purpose: expects the desired distance between
;    the points of a star and returns an image
;    of a cyan star of that size

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

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

(check-expect (cyan-star 4)
              (star 4 "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")
)

;-----
; trying out my new function cyan-star:

(cyan-star 100)

; silly, but it works:

(cyan-star MAX-SAFE-TEMP)