Inlab: Design Recipe
Keep in mind that the design recipe we will be applying to just about ALL future functions we write consists of four parts:
- The type signature (aka "contract"), which tells us how many and what types of inputs a function takes, and what type of data it returns. Note that the types we currently know about include Numbers (Integers & Fractions), Strings, Symbols, Booleans, and Images. E.g.,
draw-clock :: Number Number Number -> Image
. - The purpose statement, which is a short description of what the function does. E.g., "draws a colored, digital clock face given the time in hours, minutes, and seconds."
Examples that demonstrate how the function should work on specified inputs. Examples are best written using one of the
check-
functions (e.g.,check-expect
,check-within
,check-range
) so that DrRacket can automatically test them for us. A test fordraw-clock
might look liks this:(check-expect (draw-clock 9 5 18) (beside (text "9" 20 'red) (text ":" 20 'black) (text "05" 20 'blue) (text ":" 20 'black) (text "18" 20 'green)))
A template for our function. For now, a function template will simply tell us the name of the function and the local variables that will hold its inputs. The body of the function will start out as an arbitrary value that has the same type as its expected output. E.g., the following is a template for
draw-clock
:(define (draw-clock hours minutes seconds) (empty-scene 100 100))
A simpler function, such as
k2f
(a conversion function from Kelvin to Fahrenheit), may appear simply as:(define (k2f k) 0)
Here's the completed design recipe for draw-clock
:
; draw-clock :: Number Number Number -> Image
; draws a colored, digital clock face given the time in hours, minutes, and seconds
(check-expect (draw-clock 9 30 18)
(beside (text "9" 20 'red)
(text ":" 20 'black)
(text "30" 20 'blue)
(text ":" 20 'black)
(text "18" 20 'green)))
(define (draw-clock hours minutes seconds)
(empty-scene 100 100))
Recap: Signature, Purpose, Examples, Template. Recite until memorized. Remember: for each function you need to implement, you will be writing down these things BEFORE you start work on its body. For every program that consists of more than one function, it is also likely that you will be writing out the design recipes for all of the functions BEFORE any single function is completely implemented!
Of course, actually implementing the function body itself is also part of the design process, but we will now be saving that for last.
Practice Exercises
Let's practice designing a number of functions. For each function, come up with at least 3 different tests. Take it slow -- the goal here is to apply the design recipe, not at all to jump into the implementation!
We'll start with some you've seen before:
Design the function
hd-ready?
, which takes an image and determines if the ratio of its width to its height is equal to 16:9. The function will returntrue
if so, otherwise it will returnfalse
.Design the function
dot-product
, which takes the x and y components of two vectors as four successive numerical inputs and computes the dot product of the two vectors. The dot product of two vectors with components [x1, y1] and [x2, y2] is simply x1 × x2 + y1 × y2.Design the function
pig-latin
, which takes a word as a string and returns the (somewhat simplified) "Pig Latin" version of it. The Pig Latin version of a word is just the word minus its first character, followed by the first character prepended to the string "ay". E.g., Pig Latin for "feeling" is "eeling-fay", and Pig Latin for "happy" is "appy-hay". Your function should insert the dash ('-'), as shown.
And next:
Design the function named
n->text
, which takes a numbern
in the range 0-60, a Boolean value,padding
, a numericalsize
and a symbol,color
, and returns an image ofn
as text with sizesize
and colorcolor
. Ifpadding
is true and the number is smaller than 10, there should be a 0 prepended to the number before it is drawn as a textual image.Use the above function to implement
draw-clock
, for which we already provide a design in the introductory section. Make sure you include a completed design in your code, however.Design the function named
draw-seconds
, which takes a numerical valueelapsed
, which contains the elapsed time in seconds, and usesdraw-clock
to draw a digital clock with the appropriate number of hours, minutes, and seconds.
For these next two, you'll need to use check-within
instead of check-expect
, because you'll be dealing with inexact numbers:
Design a function named
ppi
, which computes the PPI of a display given numerical inputshres
,asp
, anddiag
, which are respectively the horizontal resolution of the display, its aspect ratio (e.g., 16/9), and its diagonal size.Design a function named
width
, which takes two numerical inputsasp
anddiag
, and computes the width of a display with aspect ratioasp
(e.g., 16/9) and diagonal sizediag
.