1b: How to Design Functions Flashcards
What are the learning goals of How to Design Functions (HtDF)?
(1) Be able to use the How to Design Functions (HtDF) recipe to design functions that operate on primitive data.
(2) Be able to read a complete function design and identify its different elements.
(3) Be able to evaluate the different elements for clarity, simplicity and consistency with each other.
(4) Be able to evaluate the entire design for how well it solves the given problem.
Why does the HtDF recipe seem like overkill?
Design methods often make simple problems harder to solve. Right now we are using simple problems to learn how to use the design method. This will pay you back later by making really hard problems much easier to solve.
What does the HtDF (how to define functions) RECIPE do in terms of design?
The HtDF recipe SYSTEMATIZES the design of a function. It tells us what to DO 1ST, & 2ND, & 3RD, all the way through the design of a function. It helps us know WHAT TO DO, and it also helps us be sure we end up with a HIGH QUALITY function.
Why do I ask for your patience here?
It may seems there is a lot going on. It may be overkill for those who have programmed before.
What are the steps to the HtDF recipe?
(1) Signature, purpose and stub (states the data type of each argument/parameter (string or number etc.), purpose is what do you want it to do in plain English and a stub as a wireframe scaffolding to run examples before the design is complete.
(2) Define examples, wrap each in (check-expect [function x] [ * 0 2 ] )
(3) Data Driven Template (type of data the function consumes, raw material you have to work with; number, string, boolean, image, etc.) and inventory of constants named properly to be used for easiness of use, clarify of understanding, and modifiability in the future. (define (f-n-for-type-name x) [body] )
(4) Code the function body.
(5) Test and debug until correct. “Run early and run often” should catch a lot of the bugs but if not this step should catch most of the issues.
What does the signature do?
It tells us what the input and output is in type.
What does the purpose do?
It describes in plain English what we want the function to do.
What is the summary of the HtDF recipe?
(1) Signature, purpose and stub.
(2) Define examples, wrap each in (check-expect).
(3) Data Driven Template and inventory of constant names.
(4) Code the function body.
(5) Test and debug until correct.
What does the stub do?
(define (double n) 0)
What does the check-expect do?
Makes sure the program runs, even if I get an error.
Why is the HTDF recipe NOT a waterfall process?
You don’t have to get step #1 exactly perfect before being able to move on to the next step. YOU can always comes BACK to it to clarify/modify if needed.
1) Signature, purpose, stub
2) Check Expect->Examples
3) Data Template and Inventory of Constants
4) Code the function body.
5) Test and debug until correct.
It happens often when you skip step 1 and go to examples to clarify what the signature (data type input and output) may be. It’s not carte blanche but there is some flexibility, structure process but not locked in waterfall.
Design a function CALLED image that consumes an image and produces the area of that image.
(require 2htdp/image) ->we need to tell Dr. Racket we want to use the image function.
1) signature: image -> number (natural)
purpose take an image, multiply its width by its height to get its area and print that.
stub (define (image_area a) 0)
[0 is the dummy value here because its a number]
2) check expect (image_area (rectangle 2 3 “solid” “red”)) (* 2 3))
3) data template and constants
(define (image_area a)
(…img))
(define (image_area a)
(* (image-width img) (image-height img)))
4) code the body.
5) Test and debug.
We may realize that images are ALWAYS SIZED in pixels. AND PIXELS are a NATURAL number (no 3.2 just 3).
Why should you use the most SPECIFIC correct type?
Saying floating point (i.e. a type of number) or natural is better than just saying number because IT MAKES IT EASIER to think about the function and to DEBUG as well.
Why are we going to start being LESS and LESS specific about the FUNCTION we design?
This is because design is the PROCESS of GOING from a poorly formed problem to a WELL structured solution. SO making the problem more specific is PART OF THE DESIGN process.
Design a function that consumes an image and determines whether the image is tall.
1) signature, purpose, stub
; image -> boolean (true/false yes/no)
; compare and image to another and see if it’s tall then produce a true
(require htdp2/image)
; (define (image_tall? img) True)
2) check expect examples (This function needs three examples).
(check-expect (image_tall? (rectangle 2 3 “solid” “red”) ) true)
(check-expect (image_tall? (rectangle 3 2 “solid” “red”) ) false)
(check-expect (image_tall? (rectangle 3 3 “solid” “red”) ) false)
3) data template and inventory of constants
(define (image_tall? img)
(if (…img) (…img) (…img)))
(define (image_tall? img)
(if (> (image-height img) (image-width img)) true false))
Dr. Racket highlights CODE COVERAGE and test coverage by highlighting False if you haven’t tested it.
4) code the body
5) test and debug