TeachScheme, ReachJava Adelphi University Tuesday afternoon July 13, 2010
Recall left/right arrow animation Could obviously have picture move up or down, rather than left or right Could have circle of radius that increases or decreases etc. How about a picture that moves up, down, left, or right? Problem: need to "remember" both x and y coordinates July TeachScheme, ReachJava 2010
Definition by parts Sometimes several related data need to be passed around together, e.g. name, SSN, and salary of employee x and y coordinates of 2-D point name, length, and favorite food of boa-constrictor Scheme allows you to define a new data type with several "parts" July TeachScheme, ReachJava 2010
A predefined struct There's a built-in type named posn, which has two parts x and y. Built-in functions ; make-posn : number(x) number(y) -> posn ; posn-x : posn -> number ; posn-y : posn -> number ; posn? : anything -> boolean July TeachScheme, ReachJava 2010
For those who know Java… make-posn is a constructor. posn-x and posn-y are getter methods. posn? is like instanceof Posn. There are also setter methods, but we'll get to them later. July TeachScheme, ReachJava 2010
Using posns "Examples of the posn type:" (make-posn 3 5) (make-posn 12 -7) (define here (make-posn 14 9)) (check-expect (posn-x here) 14) (check-expect (posn-y here) 9) July TeachScheme, ReachJava 2010
Writing functions on posns Almost any function that takes in a posn looks like (define (function-on-posn where) ) (the "skeleton" step of the recipe) July TeachScheme, ReachJava 2010
Writing functions on posns Almost any function that takes in a posn looks like (define (function-on-posn where) ; where posn ) (the "inventory" step of the recipe) July TeachScheme, ReachJava 2010
Writing functions on posns Almost any function that takes in a posn looks like (define (function-on-posn where) ; where posn ; (posn-x where) number ; (posn-y where) number ) (the "inventory" step of the recipe, continued) July TeachScheme, ReachJava 2010
Using posns Write a function right-of-100? which takes in a posn and tells whether its x coordinate is greater than 100 Work this out together July TeachScheme, ReachJava 2010
Creating posns Write a function diagonal-posn which takes in a number and produces a posn whose x and y coordinates are both that number Work this out together July TeachScheme, ReachJava 2010
Exercises on posns Write a function above-main-diagonal? which takes in a posn and tells whether it is above the diagonal line "x=y" (note that positive x is to the right, and positive y is down, as usual in computer graphics) Write a function posn=? which takes in two posns and tells whether they have the same x coordinate and the same y coordinate Write a function swap-x-y which takes in a posn and returns a posn whose x coordinate is the y coordinate of the given posn, and vice versa. July TeachScheme, ReachJava 2010
Optional exercises on posns Write a function distance which takes in two posns and returns their Euclidean distance, which is given by the formula sqrt((x1-x2) 2 + (y1-y2) 2 ) Write a function scale-posn which takes in a posn and a number and produces a posn by multiplying each coordinate of the given posn by the number Write a function add-posns which takes in two posns and produces a posn whose x coordinate is the sum of their x coordinates, and likewise for the y coordinates July TeachScheme, ReachJava 2010
Animations with posn models Write an animation of a picture that moves up, down, left, and right in response to the corresponding arrow keys July TeachScheme, ReachJava 2010
Model & handlers Model is a posn representing center of picture We'll need a redraw handler ; calendar-at-posn : posn -> image and a key handler ; handle-key : posn key -> posn July TeachScheme, ReachJava 2010
Draw handler ; calendar-at-posn : posn -> image (check-expect (calendar-at-posn (make-posn )) (place- image calendar BACKGROUND)) (check-expect (calendar-at-posn (make-posn 215 6)) (place- image calendar BACKGROUND)) (define (calendar-at-posn where) ; where posn ; (posn-x where) number ; (posn-y where) number (place-image calendar (posn-x where) (posn-y where) BACKGROUND)) July TeachScheme, ReachJava 2010
Key handler: contract & examples ; handle-key : posn key -> posn (check-expect (handle-key (make-posn 12 47) "v") (make-posn 12 47)) (check-expect (handle-key (make-posn 12 47) "up") (make-posn 12 46)) (check-expect (handle-key (make-posn 12 47) "down") (make-posn 12 48)) (check-expect (handle-key (make-posn 12 47) "left") (make-posn 11 47)) (check-expect (handle-key (make-posn 12 47) "right") (make-posn 13 47)) (check-expect (handle-key (make-posn 12 47) "home") (make-posn 12 47)) July TeachScheme, ReachJava 2010
Key handler: skeleton & inventory ; handle-key : posn key -> posn (define (handle-key old-place key) (cond [(key=? key "left") …] [(key=? key "right") …] [(key=? key "up") …] [(key=? key "down") …] [else old-place] )) July TeachScheme, ReachJava 2010
Key handler: skeleton & inventory ; handle-key : posn key -> posn (define (handle-key old-place key) (cond [(key=? key "left") (add-posns old-place (make-posn -1 0))] [(key=? key "right") (add-posns old-place (make-posn 1 0))] [(key=? key "up") (add-posns old-place (make-posn 0 -1))] [(key=? key "down") (add-posns old-place (make-posn 0 1))] [else old-place] )) July TeachScheme, ReachJava 2010
Or more briefly… ; handle-key : posn char-or-symbol -> posn (define (handle-key old-place key) (add-posns old-place (cond[(symbol=? key "left") (make-posn -1 0))] [(symbol=? key "right") (make-posn 1 0)) [(symbol=? key "up") (make-posn 0 -1)) [(symbol=? key "down") (make-posn 0 1)) [else (make-posn 0 0)] )) July TeachScheme, ReachJava 2010
Running the animation (big-bang (make-posn (/ WIDTH 2) (/ HEIGHT 2)) (check-with posn?) (on-draw calendar-at-posn) (on-key handle-key)) July TeachScheme, ReachJava 2010
Exercises Write an animation of a picture that, every second, teleports to a random location within the window, but ignores key & mouse events Write an animation of a picture that moves randomly up, down, left, or right by a pixel each 0.1 second July TeachScheme, ReachJava 2010
Structs posn is an example of a "structure type": it's made of two parts (x and y), each of which is a number. Another pre-defined structure type is color; it has three parts (red, green, and blue), each of which is a number (define my-color (make-color )) (triangle 50 "solid" my-color) (check-expect (color-red my-color) 50) July TeachScheme, ReachJava
Structs What if you need to "package up" something other than two or three numbers? July TeachScheme, ReachJava
Defining our own structs 1)Choose a name for the new data type 2)Choose names and types for each of its parts 3)Write a define-struct (next slide) to tell Scheme about it 4)Write contracts for the constructor and accessor methods 5)Write examples of the new data type 6)Write a function template for the new data type 7)Start writing functions on the new data type July TeachScheme, ReachJava 2010
Syntax Rule: Defining a Struct To define a structure named foo with fields snark and boojum, (define-struct foo (snark boojum)) This defines a new data type foo and several functions: ; make-foo : snark-type boojum-type -> foo ; foo-snark : foo -> snark-type ; foo-boojum : foo -> boojum-type ; foo? : anything -> boolean July TeachScheme, ReachJava 2010
Example: posn (if it weren't pre-defined) ; A posn consists of two numbers (x and y) (define-struct posn (x y)) ; make-posn : number number -> posn ; posn-x : posn -> number ; posn-y : posn -> number ; posn? : anything -> boolean "Examples of the posn data type:" (make-posn 3 5) (make-posn 12 -7) (define here (make-posn 14 9)) (check-expect (posn-x here) 14) (check-expect (posn-y here) 9) July TeachScheme, ReachJava 2010
Real example: dogs ; A dog has a string(name), number(age), number(weight), and a boolean(asleep?) (define-struct dog (name age weight asleep?)) ; make-dog : string num num boolean -> dog ; dog-name : dog -> string ; dog-age : dog -> number ; dog-weight : dog -> number ; dog-asleep? : dog -> boolean July TeachScheme, ReachJava 2010
Real example: dogs "Examples of the dog data type:" (make-dog "Ludo" 6 78 true) (make-dog "Thibaut" 4 74 false) (define this-dog (make-dog "Rover" 8 45 false)) (check-expect (dog-name this-dog) "Rover") (check-expect (dog-age this-dog) 8) (check-expect (dog-weight this-dog) 45) (check-expect (dog-asleep? this-dog) false) July TeachScheme, ReachJava 2010
Type-based coding patterns Almost any function that takes in a dog looks like (define (function-on-dog the-dog) ) (the "skeleton" step of the recipe) July TeachScheme, ReachJava 2010
Type-based coding patterns Almost any function that takes in a dog looks like (define (function-on-dog the-dog) ; the-dog a dog ) (the "inventory" step of the recipe) July TeachScheme, ReachJava 2010
Type-based coding patterns Almost any function that takes in a dog looks like (define (function-on-dog the-dog) ; the-dog a dog ; (dog-name the-dog) a string ; (dog-age the-dog) a number ; (dog-weight the-dog) a number ; (dog-asleep? the-dog) a boolean ) (the "inventory" step of the recipe, continued) July TeachScheme, ReachJava 2010
Type-based coding patterns #| (define (function-on-dog the-dog) ; the-dog a dog ; (dog-name the-dog) a string ; (dog-age the-dog) a number ; (dog-weight the-dog) a number ; (dog-asleep? the-dog) a boolean ) |# This header-plus-inventory, commented out, can be used as a template, copying and pasting it as a starting point for any function that takes in a dog. July TeachScheme, ReachJava 2010
A function on dogs Write a function fits-in-lap? which takes in a dog and the weight capacity of a lap, and tells whether the dog will fit in the lap in question Work this out together July TeachScheme, ReachJava 2010
Your turn Write a function movable? which takes in a dog. If the dog is awake, it's movable. If the dog is asleep but under 20 pounds, it's movable. Otherwise it's not. (Hint: it's shorter and simpler if you don't use a cond.) Write a function birthday which takes in a dog and returns a dog with the same name, weight, and sleep status, but one year older. July TeachScheme, ReachJava 2010
Inventors and Factories define-struct is like an inventor. Specifies once what's in a particular model of cell phone, but doesn't actually manufacture them. Then invents something else, and doesn't manufacture them either…. make-posn is like a cell-phone factory. Each factory "knows" how to build one kind of thing (cell phones, posns, dogs, etc.) Factory doesn't exist until the thing is invented. Can be used over and over to build many cell- phones/posns/dogs/whatever. July TeachScheme, ReachJava 2010
Defining another animal Define a data structure fish which has a string(color), a number(weight) and a boolean(salt-water?). Remember the steps: 1)Choose a name for the new data type 2)Choose names and types for each of its parts 3)Write a define-struct to tell Scheme about it 4)Write contracts for the constructor and accessor methods 5)Write examples of the new data type 6)Write a function template for the new data type 7)Start writing functions on the new data type July TeachScheme, ReachJava 2010
Animations with user-defined structures Worked exercise in textbook Modifications: exercises and If you finish these, look at exercises July TeachScheme, ReachJava
Definition by choices New data type: animal ; An animal is either a dog or a fish. Scheme doesn't enforce this; it's up to the programmer. July TeachScheme, ReachJava 2010
A function on animals Write a function fits-in-crate? which takes in an animal (either a dog or a fish) and the weight capacity of a crate, and tells whether the animal can be shipped in that crate. Hint: fish are never shipped in crates, regardless of weight. July TeachScheme, ReachJava 2010
How to write this? The input type, animal, is one of two sub-categories (dog or fish), so… we need at least two test cases, one of each type (in fact, we'll need three dogs — under, over, and borderline — and at least one fish) the function body will probably be a cond with two cases, with questions "dog?" and "fish?" July TeachScheme, ReachJava 2010
Function template for animals Almost any function on animals will look like (define (function-on-animal the-animal) ) July TeachScheme, ReachJava 2010
Function template for animals Almost any function on animals will look like (define (function-on-animal the-animal) (cond [(dog? the-animal) ] [(fish? the-animal) ])) July TeachScheme, ReachJava 2010
Function template for animals Almost any function on animals will look like (define (function-on-animal the-animal) (cond [(dog? the-animal) ; the-animal a dog ] [(fish? the-animal) ; the-animal a fish ])) July TeachScheme, ReachJava 2010
Function template for animals #| (define (function-on-animal the-animal) (cond [(dog? the-animal) ; the-animal a dog ; (dog-name the-animal) a string ; (dog-age the-animal) a number ; (dog-weight the-animal) a number ; (dog-asleep? the-animal) a boolean ] [(fish? the-animal) ; the-animal a fish ; (fish-color the-animal) a string ; (fish-weight the-animal) a number ; (fish-salt-water? the-animal) a boolean ])) |# July TeachScheme, ReachJava 2010
Function template for animals Again, we can copy and paste this as a starting point for any function on animals. In practice, much of it is irrelevant to any given function, so we can delete those lines. July TeachScheme, ReachJava 2010
My answer to fits-in-crate? ; fits-in-crate? : animal number -> boolean (define (fits-in-crate? the-animal max-weight) ; max-weight a number (cond [(dog? the-animal) ; (dog-weight the-animal) a number (<= (dog-weight the-animal) max-weight) ] [(fish? the-animal) false ])) "Examples of fits-in-crate?:" (check-expect (fits-in-crate? (make-dog "Bob" 3 58 true) 50) false) (check-expect (fits-in-crate? (make-dog "Dave" 2 65 true) 65) true) ; borderline (check-expect (fits-in-crate? (make-dog "Eddie" 7 35 false) 50) true) (check-expect (fits-in-crate? (make-fish "orange" 0.03 false) 5) false) July TeachScheme, ReachJava 2010
Another exercise Write a function underweight? which takes in an animal and tells whether or not it's underweight — which means under 30 pounds for a dog, and under 0.1 pounds for a fish. July TeachScheme, ReachJava 2010
Lab exercise Open shapes-lab.scm (in Examples folder) Do the exercises in it July TeachScheme, ReachJava 2010
Are we done yet? Fill out end-of-day survey Eat Sleep Come back for another day July TeachScheme, ReachJava 2010