teachscheme, reachjava stephen bloch, adelphi university, garden city, ny john clements, cal poly,...
TRANSCRIPT
TeachScheme, ReachJava
Stephen Bloch, Adelphi University, Garden City, NY
John Clements, Cal Poly, San Luis Obispo, CA
Kathi Fisler, Worcester Polytechnic Institute, Worcester, MA
Matthew Flatt, University of Utah, Salt Lake City, UT
Shriram Krishnamurthi, Brown University, Providence, RI
Viera K. Proulx, Northeastern University, Boston, MA
Supported by NSF grant #0618543
Related work by Matthias Felleisen, Robby Findler,Kathy Gray, Eli Barzilay, et al
June 28 2009 TeachScheme, ReachJava 2009 2
What is a problem?
• What is the meaning of life?– Not an objective question
• How old am I?– An objective question, which requires
information you don’t have
• What is the smallest prime number?– An objective, fully-specified question, but once
it’s answered once, it’s over
June 28 2009 TeachScheme, ReachJava 2009 3
What is a problem?
• What is the Celsius equivalent of 45F?– Again, once it’s answered, it’s over
• What is the Celsius equivalent of 87F?– Ditto, but closely related
• What is the Celsius equivalent of ___ in Fahrenheit?– Generalizes infinitely many questions
June 28 2009 TeachScheme, ReachJava 2009 4
What is a problem?
Question: has a single answerProblem: large (or infinite) family of
questions, sharing some features & differing in others
Program: general rule for solving a problem, with input for the features that differ
Computation: a program working on particular input to produce particular results
June 28 2009 TeachScheme, ReachJava 2009 5
Introductions
• Who are you?
• What kind of school? students?
• Background in teaching CS
• Background in Scheme, Java, etc?
June 28 2009 TeachScheme, ReachJava 2009 6
This week
• You’re primarily students, not teachers
• Get “the student experience” of this approach — only faster
• Time on Friday to talk pedagogy
June 28 2009 TeachScheme, ReachJava 2009 7
What is “computer science”?
• “microscope science” — about microbes• “telescope science” — about stars
It’s not about the tool, it’s about what you can study using the tool!
• “computer science” — about information and the manipulation thereof
June 28 2009 TeachScheme, ReachJava 2009 8
What is a beginning CS course about?1) How to use Microsoft Office et al
2) Survey of the CS profession
3) A language that will get students jobs
4) Concepts, habits, & methodologies of programming
Four completely different courses, each valuable for different reasons and audiences
#3 useful for students about to graduate, or about to get internships and summer jobs
#4 more useful as a first course. Let's call it "CS1"…
June 28 2009 TeachScheme, ReachJava 2009 9
What is CS1 about?
June 28 2009 TeachScheme, ReachJava 2009 10
What you teachblah algorithm blah variable blah function
blah data type blah object blah re-use blah methodology blah testing blah design blah composition blah refinement blah abstraction
June 28 2009 TeachScheme, ReachJava 2009 11
What they hearblah ; blah { blah ) blah ] blah return blah this.x = x;
blah public static void main (String[] args) blah /* blah // blah <int> blah if ( blah JOptionPane blah class Posn(int x,y)
June 28 2009 TeachScheme, ReachJava 2009 12
Programming languages:a necessary evil
• Necessary: to write real programs that really run on real computers
• Evil: distract students from the important stuff
• Will be obsolete in a few years anyway
June 28 2009 TeachScheme, ReachJava 2009 13
How to minimize language & IDE?
• Introduce features one at a time
• Avoid "black magic"; never ask students to write anything they can't understand now
• Introduce features only as necessary to teach an important concept
• Corollary: any feature that doesn't help teach a CS1 concept shouldn't be mentioned in CS1
• Corollary: need enforced language subsets so students don't accidentally use language features they haven't seen
• For GUI, robotics, networking, etc. need interface between student code (in subset) and library code (in full language)
June 28 2009 TeachScheme, ReachJava 2009 14
What Java do we need? When?
• Realistically, most of us must cover a certain amount of Java by the end of CS2
• Not obvious that the best way to do this is Java from start of CS1
• Instead, teach concepts & habits first, then complicated language
June 28 2009 TeachScheme, ReachJava 2009 15
Alternatives to Java-first
• Leading alternatives: Alice, Python, Scheme
• All three: start w/simpler syntax while students master concepts
• Difference: Alice & Python usually taught imperatively; Scheme usually functionally
• (Functional-first Python: has potential)
June 28 2009 TeachScheme, ReachJava 2009 16
Why functional?• Simple, familiar semantic model
– 3+4*5 => 3+20 => 23
• Ease of writing test suites– each test is usually one stmt, rather than
"set up", "call method", "check side effects"– tests order-independent– no worry about aliasing, equals() vs. ==, etc.– If testing is easy, students may actually do it!
June 28 2009 TeachScheme, ReachJava 2009 17
But what about OOP?
• Students need to learn OOP, and an OO language, by 2nd or 3rd semester
• OOP is a terrific way to organize multi-KLOC programs
• First-term students don't write multi-KLOC programs
• OOP's benefits aren't apparent in first term; students see only the overhead
• (Challenge: write a short, OO C++/Java program that wouldn't be simpler without OO)
June 28 2009 TeachScheme, ReachJava 2009 18
Main points of TSRJ• Multi-language approach to CS1/CS2
– Start in Scheme, develop concepts & habits
– Switch to Java after 2-4 months
• Step-by-step design recipe in both languages– concrete questions & products at each step
– test-first methodology
– strong emphasis on data types
– shape of data determines shape of code & test cases
• DrScheme development environment– beginner-friendly
– interactive testing and experimentation
– enforces language subsets w/appropriate messages
June 28 2009 TeachScheme, ReachJava 2009 19
Let’s try DrScheme
• DrScheme• Interactions pane (bottom half)• Literal expressions
– 7– "hello world"– copy and paste picture from Web browser– true
• Try www.adelphi.edu/sbloch/book/pictures/
June 28 2009 TeachScheme, ReachJava 2009 20
Operating on pictures
• (reflect-vert paste-picture-from-Web)• Same with reflect-horiz, rotate-cw, rotate-ccw,
rotate-180• (image-above picture1 picture2)• Same with image-beside, overlay
– These three actually accept two or more pictures.
• Syntax rule: ( operation pic1 … )• Terminology: expression, function, argument,
value, literal
June 28 2009 TeachScheme, ReachJava 2009 21
Composing functions
> (image-beside (reflect-horiz ))
Exercise: write expressions to produce
June 28 2009 TeachScheme, ReachJava 2009 22
Scheme syntax
• All expressions fully parenthesized;no order of operations to memorize
• All functions (both built-in and user-defined) are prefix, inside parentheses
• Some functions have arity 1, some 2, some"2 or more", etc. as appropriate.
June 28 2009 TeachScheme, ReachJava 2009 23
Definitions pane
• Editable and savable
• "Run" button evaluates all expressions in order, replacing old Interactions
• Try7"hello world"copied image from Web(image-above (rotate-cw picture) (rotate-ccw picture))
June 28 2009 TeachScheme, ReachJava 2009 24
The Stepper
• Type several nested expressions into Definitions pane
• Click "Step" button at top
• See each sub-expression replaced with its value, one by one
• Valuable for students who never really "got" algebra
June 28 2009 TeachScheme, ReachJava 2009 25
Variable definitions
• (define calendar )
• (image-above calendar (reflect-vert calendar))
• Define another variable to hold a different picture copied from the Web; write some expressions using both.
• Note no declared data type;data have types, variables don't
June 28 2009 TeachScheme, ReachJava 2009 26
Building images from scratch• (rectangle 34 21 "solid" "blue")• (circle 18 "outline" "green")• (ellipse 34 55 "outline" "purple")• (triangle 22 "solid" "pink")• (star 7 20 10 "solid" "blue")• (text "Hello there" 18 "blue") • Try your own variations
• (define blue-star (star 7 20 10 "solid" "blue"))• Try modifying & combining these using image-above,
overlay, reflect-vert, rotate-cw, surround, etc.
June 28 2009 TeachScheme, ReachJava 2009 27
Terminology
• Three kinds of literals: image (pasted from Web browser), number, and string.
• Data types
June 28 2009 TeachScheme, ReachJava 2009 28
Function contracts
; reflect-vert : image -> image
; reflect-horiz, rotate-cw, rotate-ccw, rotate-180 : similar
; image-beside : image image … -> image
; image-above, overlay : similar
; rectangle : number(width) number(height) string(solid/outline) string(color) -> image
Summarizes what a function takes in and returns, in a brief, standard notation
Note semicolon for comment-to-end-of-line
June 28 2009 TeachScheme, ReachJava 2009 29
More image functions
; crop-bottom : image number(pixels) -> image
; crop-top, crop-left, crop-right : similar
; image-width : image -> number
; image-height : similar
; place-image : image(foreground) number(x) number(y) image(background) -> image
; text : string(text) number(size) string(color) -> image
June 28 2009 TeachScheme, ReachJava 2009 30
Defining functions
> (define (mirror picture)
(image-beside picture (reflect-horiz picture)))
(mirror calendar)
(mirror (rotate-cw (triangle 10 "solid" "blue")))
• Note no declared parameter or return types; again, data have types
• Try (mirror calendar hacker) -- wrong number of arguments!
• Try (mirror 7) -- wrong type of argument!
June 28 2009 TeachScheme, ReachJava 2009 31
Exercise
Define a function four-square that takes in an image and produces a 2x2 arrangement of it like
June 28 2009 TeachScheme, ReachJava 2009 32
Worked Exercise
Define a function counterchange that takes in two images and produces a 2x2 arrangement like
My answer:
(define (counterchange topleft topright)
(image-above (image-beside topleft topright)
(image-beside topright topleft)))
June 28 2009 TeachScheme, ReachJava 2009 33
Testing functions• With English descriptions:
– (mirror calendar) "should be a calendar on the left, and a right-left-reflected calendar on the right"
• With check-expect:– (check-expect (mirror calendar)
(image-beside calendar (reflect-horiz calendar)))
• Put either or both in Definitions window; hit Run & see what happens.
• Try with wrong function definition!
June 28 2009 TeachScheme, ReachJava 2009 34
Design recipes
We could write counterchange in an ad-hoc way, but in general we use…
Step-by-step recipes to get from English-language description to working, tested code
One recipe for functions, one for data types, one for abstractions, one for event-driven animations…
June 28 2009 TeachScheme, ReachJava 2009 35
How to accomplish anything
1) Figure out what you want to do
2) Do it
3) Check that you did it right
June 28 2009 TeachScheme, ReachJava 2009 36
How to write a function/method
• Figure out what you want to do• Contract: Specify name, inputs, outputs• Data definition: Identify any new data types in the problem• Examples: Write test cases with expected answers
• Do it• Skeleton: Write boilerplate code for function definition• Inventory: Write available expressions, their types, and
(later) their values for a non-trivial test case• Body: Fill in details based on problem to solve
• Check that you did it right• Testing: Run test cases
June 28 2009 TeachScheme, ReachJava 2009 37
The design recipe in practicecontract:
; counterchange : image (topleft) image(topright) -> image
data definition: problem only involves images, which are predefined
test cases:
(check-expect (counterchange calendar schemelogo)
(image-above (image-beside calendar schemelogo)
(image-beside schemelogo calendar)))
(check-expect (counterchange book (ellipse 30 10 "outline" "pink"))
(image-above (image-beside book (ellipse 30 10 "outline" "pink"))
(image-beside (ellipse 30 10 "outline" "pink") book))
June 28 2009 TeachScheme, ReachJava 2009 38
The design recipe in practiceskeleton: (inserted before examples)
(define (counterchange topleft topright) )
inventory:(define (counterchange topleft topright) ; topleft an image ; topright an image )
body: (fill in something real, using expressions from inventory)(define (counterchange topleft topright) ; topleft an image ; topright an image (image-above (image-beside topleft topright) (image-beside topright topleft)))
testing: hit "Run" and see whether answers match
June 28 2009 TeachScheme, ReachJava 2009 39
The result; counterchange : image (topleft) image(topright) -> image
(check-expect (counterchange calendar schemelogo)
(image-above (image-beside calendar schemelogo)
(image-beside schemelogo calendar)))
(check-expect (counterchange book (ellipse 30 10 "outline" "pink"))
(image-above (image-beside book (ellipse 30 10 "outline" "pink"))
(image-beside (ellipse 30 10 "outline" "pink") book))
(define (counterchange topleft topright) ; topleft an image ; topright an image (image-above (image-beside topleft topright) (image-beside topright topleft)))
June 28 2009 TeachScheme, ReachJava 2009 40
Testing again
• Change the definition so that it's wrong; run the tests again and see what happens.
June 28 2009 TeachScheme, ReachJava 2009 41
Design recipes as pedagogy• Note "test-first" methodology (a la XP); identify special cases
before writing code
• Use as grading rubric: partial credit for each step
• First steps are in comments; non-threatening,avoids "blank page syndrome"
• Each step has concrete questions and concrete products
• I don't help with step N until I see step N-1
• Same steps apply in Java, C++, etc.(but more complicated)
• Know-it-all students usually try to skip the recipe…until Chapter 12 of HtDP…
June 28 2009 TeachScheme, ReachJava 2009 42
Exercises
Write contracts and test cases, but no definitions, for
1) a function named copies-beside that takes in a number and an image, and produces that many copies of the image side by side
2) a function named pinwheel that takes in an image & produces a 2x2 rotated thing like
3) a function named checkerboard2 that takes in two color names & produces a 2x2 checkerboard in those colors
June 28 2009 TeachScheme, ReachJava 2009 43
Exercises
Write skeletons & definitions for pinwheel and checkerboard2 (you don't know how to do copies-beside yet)
Do all the steps to define lollipop, which takes in two numbers and a color name, and creates a picture of a lollipop w/specified radius, stick length, and color
June 28 2009 TeachScheme, ReachJava 2009 44
Discussion break
• How is this different from what you've done in the past?
• How much explaining would it take for your students?
• I have a lot of mathophobic students, so I start with images rather than numbers and algebra. The prefix notation doesn't throw them, because they don't already "know" the "right" notation for operating on images.
June 28 2009 TeachScheme, ReachJava 2009 45
Animation
(run-animation 50 50 calendar 0.5(on-tick rotate-cw))
; run-animation : number(width) number(height) image number(tick-interval) handler … -> boolean
Every tick-interval, applies handler to old image to get new image
Try some variations: different widths, heights, images, tick-intervals, "on-tick" handlers
June 28 2009 TeachScheme, ReachJava 2009 46
A more complex animation
• Write an animation of an image that moves 5 pixels to the right every second
• We'll need a function that takes in an image and returns the same image 5 pixels to the right
• Follow the design recipe!
June 28 2009 TeachScheme, ReachJava 2009 47
move-right-5
; move-right-5 : image -> image
June 28 2009 TeachScheme, ReachJava 2009 48
move-right-5
; move-right-5 : image -> image
(check-expect (move-right-5 calendar)(image-beside (rectangle 5 0 "solid" "white") calendar))
(check-expect (move-right-5 (circle 3 "solid" "red"))(image-beside (rectangle 5 0 "solid" "white") (circle 3 "solid" "red")))
June 28 2009 TeachScheme, ReachJava 2009 49
move-right-5
; move-right-5 : image -> image
(define (move-right-5 old-pic)
)
(check-expect (move-right-5 calendar)(image-beside (rectangle 5 0 "solid" "white") calendar))
(check-expect (move-right-5 (circle 3 "solid" "red"))(image-beside (rectangle 5 0 "solid" "white") (circle 3 "solid" "red")))
June 28 2009 TeachScheme, ReachJava 2009 50
move-right-5
; move-right-5 : image -> image
(define (move-right-5 old-pic); old-pic an image)
(check-expect (move-right-5 calendar)(image-beside (rectangle 5 0 "solid" "white") calendar))
(check-expect (move-right-5 (circle 3 "solid" "red"))(image-beside (rectangle 5 0 "solid" "white") (circle 3 "solid" "red")))
June 28 2009 TeachScheme, ReachJava 2009 51
move-right-5
; move-right-5 : image -> image
(define (move-right-5 old-pic); old-pic an image(image-beside (rectangle 5 0 "solid" "white") old-pic))
(check-expect (move-right-5 calendar)(image-beside (rectangle 5 0 "solid" "white") calendar))
(check-expect (move-right-5 (circle 3 "solid" "red"))(image-beside (rectangle 5 0 "solid" "white") (circle 3 "solid" "red")))
June 28 2009 TeachScheme, ReachJava 2009 52
Running the animation
(run-animation 500 50 calendar 1(on-tick move-right-5))
June 28 2009 TeachScheme, ReachJava 2009 53
Other kinds of event handlers
• tick-handler : image -> imageSpecify with on-tick
• mouse-handler : image number(x) number(y) event -> imageSpecify with on-mouse
• key-handler : image key -> imageSpecify with on-key
• I'm lying: they're actually more general than this.• Note: on-tick, on-mouse, and on-key all take in a function
name as an argument.
June 28 2009 TeachScheme, ReachJava 2009 54
Another animation
Write an animation of a calendar that moves with the mouse on a 500x300 yellow background.
Need a mouse-handling function
Contract must be
; handle-mouse : image num(x) num(y) event -> image
We don't know what an "event" is yet; ignore it.
June 28 2009 TeachScheme, ReachJava 2009 55
calendar-at-mouse
; calendar-at-mouse : image num(x) num(y) event -> image
June 28 2009 TeachScheme, ReachJava 2009 56
calendar-at-mouse
; calendar-at-mouse : image num(x) num(y) event -> image
(check-expect (calendar-at-mouse schemelogo 47 218 "dummy")(place-image calendar 47 218 (rectangle 500 300 "solid" "yellow")))
(check-expect (calendar-at-mouse stick-figure 350 12 "event")(place-image calendar 350 12 (rectangle 500 300 "solid" "yellow")))
June 28 2009 TeachScheme, ReachJava 2009 57
calendar-at-mouse
; calendar-at-mouse : image num(x) num(y) event -> image
(check-expect (calendar-at-mouse schemelogo 47 218 "dummy")(place-image calendar 47 218 (rectangle 500 300 "solid" "yellow")))
(check-expect (calendar-at-mouse stick-figure 350 12 "event")(place-image calendar 350 12 (rectangle 500 300 "solid" "yellow")))
(define (calendar-at-mouse old-pic x y event)
)
June 28 2009 TeachScheme, ReachJava 2009 58
calendar-at-mouse
; calendar-at-mouse : image num(x) num(y) event -> image
(check-expect (calendar-at-mouse schemelogo 47 218 "dummy")(place-image calendar 47 218 (rectangle 500 300 "solid" "yellow")))
(check-expect (calendar-at-mouse stick-figure 350 12 "event")(place-image calendar 350 12 (rectangle 500 300 "solid" "yellow")))
(define (calendar-at-mouse old-pic x y event); old-pic an image; x a number; y a number; event whatever)
June 28 2009 TeachScheme, ReachJava 2009 59
calendar-at-mouse
; calendar-at-mouse : image num(x) num(y) event -> image
(check-expect (calendar-at-mouse schemelogo 47 218 "dummy")(place-image calendar 47 218 (rectangle 500 300 "solid" "yellow")))
(check-expect (calendar-at-mouse stick-figure 350 12 "event")(place-image calendar 350 12 (rectangle 500 300 "solid" "yellow")))
(define (calendar-at-mouse old-pic x y event); old-pic an image; x a number; y a number; event whatever(place-image calendar x y (rectangle 500 300 "solid" "yellow")))
June 28 2009 TeachScheme, ReachJava 2009 60
calendar-at-mouse
; calendar-at-mouse : image num(x) num(y) event -> image
(define BACKGROUND (rectangle 500 300 "solid" "yellow"))
(check-expect (calendar-at-mouse schemelogo 47 218 "dummy")(place-image calendar 47 218 BACKGROUND))
(check-expect (calendar-at-mouse stick-figure 350 12 "event")(place-image calendar 350 12 BACKGROUND))
(define (calendar-at-mouse old-pic x y event); old-pic an image; x a number; y a number; event whatever(place-image calendar x y BACKGROUND))
June 28 2009 TeachScheme, ReachJava 2009 61
Running the animation
(run-animation 500 300 calendar 999(on-mouse calendar-at-mouse))
June 28 2009 TeachScheme, ReachJava 2009 62
Numbers
• Remember, my students are numerophobic. We haven't seen an arithmetic operator yet.(Week 4 of a non-major course)
• Arithmetic operators follow the same syntax rule as every other function:(operation argument …)
• The +, -, *, / operations accept 2 or more arguments• Example: 3 + 4*5 + 6 becomes
(+ 3 (* 4 5) 6)• Other built-in functions with obvious names: sqrt, cos,
sin, abs, …
June 28 2009 TeachScheme, ReachJava 2009 63
Examples of arithmetic
• 3+4 becomes (+ 3 4)• 3+(4*5) becomes (+ 3 (* 4 5))• 1+2+3+4+5 becomes (+ 1 2 3 4 5)• 3x-7 becomes (- (* 3 x) 7)
(presumably x is an already-defined variable)• 3*4+5/6 becomes (+ (* 3 4) (/ 5 6))
(but you have to know order of operations to understand the former; the latter is unambiguous)
June 28 2009 TeachScheme, ReachJava 2009 64
Exercise
Convert the following from "standard" algebraic notation to Scheme notation:
• 3+cos(0)• 2/(x+1)• (-b+√(b2-4ac))/2a
where a, b, c are variables
June 28 2009 TeachScheme, ReachJava 2009 65
Writing functions on numbers
; cube : number -> number
(define (cube num); num a number(* num num num))
(check-expect (cube 0) 0)(check-expect (cube 5) 125)(check-expect (cube -6) -216)(check-expect (cube (/ 2 3)) (/ 8 27))
June 28 2009 TeachScheme, ReachJava 2009 66
Kinds of numbers• Try (cube (cube (cube 1234567890)))• Integers behave correctly• Try (+ (/ 2 3) (/ 3 4))• Fractions behave correctly (can choose output in
either fraction or repeating-decimal form)• Abbreviations: -4 = (- 4), 2/3 = (/ 2 3), etc. as long
as there are no spaces
June 28 2009 TeachScheme, ReachJava 2009 67
Kinds of numbers• Try (sqrt 2)• Result is marked as inexact, as are results of subsequent
computations using it
• Note (sqr (sqrt 2)) ≠ 2
• (check-expect (sqr (sqrt 2)) 2) will fail!
• (check-within (sqr (sqrt 2)) 2 0.001) passes the test
• Use check-within whenever function result might be inexact.
June 28 2009 TeachScheme, ReachJava 2009 68
Exercises
• Define a function f that takes in two numbers x and y and returns 3x-2y
• Define a function discriminant that takes in three numbers a, b, and c and returns
b2 - 4ac
• As usual, follow the design recipe!
June 28 2009 TeachScheme, ReachJava 2009 69
Animations revisited
• Previous animations computed the "new image" from the "old image"
• Often makes more sense to compute on something other than an image -- a "model"
• "Model" can be an image or a number (or really any data type you choose)
June 28 2009 TeachScheme, ReachJava 2009 70
Kinds of event handlers• tick-handler : model -> model
Specify with on-tick• mouse-handler : model number(x) number(y) event -> model
Specify with on-mouse• key-handler : model key -> model
Specify with on-key• redraw-handler : model -> image
Specify with on-redraw unless model is an image, in which case you can skip it
• run-animation : number(width) number(height) model number(tick-interval) handler … -> boolean
• Note: on-tick, on-mouse, on-key, and on-redraw all take in a function name as an argument.
June 28 2009 TeachScheme, ReachJava 2009 71
Animations with numeric models
Write an animation of a blue circle that grows in radius by 1 pixel per half second
Need a tick handler and a redraw handler
Follow the design recipe for both
There happens to already be an add1 function which will work as the tick handler
June 28 2009 TeachScheme, ReachJava 2009 72
Growing-circle animation
; blue-circle-of-size : number -> image
(check-expect (blue-circle-of-size 0)(circle 0 "solid" "blue"))
(check-expect (blue-circle-of-size 12)(circle 12 "solid" "blue"))
(define (blue-circle-of-size r)(circle r "solid" "blue"))
(run-animation 200 200 0 1/2(on-tick add1) (on-redraw blue-circle-of-size))
June 28 2009 TeachScheme, ReachJava 2009 73
Exercise: parametric equations
Write an animation that displays a small dot atx coordinate 100+50*cos(t/20) andy coordinate 100+30*sin(t/20)where t is the number of time steps so far.
(Set the tick interval fairly short, e.g. 1/10 second.)
Hint: write helper functions x(t) and y(t).
Play with the formulae and see what different patterns you can get.
June 28 2009 TeachScheme, ReachJava 2009 74
Exercise
Write an animation that displays a digital counter, in 18-point blue numerals. It should start at 0 and increase by 1 every second.
Hint: there's a built-in function number->string that converts a number to its decimal representation. Then use text to convert the string to an image.
June 28 2009 TeachScheme, ReachJava 2009 75
Discussion break
• How is this different from what you've done in the past?
• How much explaining would it take for your students?
June 28 2009 TeachScheme, ReachJava 2009 76
Animations with numeric models
• Can now assign animations in which model is a number
• Examples: radius, x coordinate, or y coordinate, number of sides, …
• Model can increase & decrease in response to ticks, mouse actions, & keyboard actions
June 28 2009 TeachScheme, ReachJava 2009 77
Animations with randomness
• (random 8) returns a random integer from 0 through 7
• Use this to write more fun and unpredictable animations
June 28 2009 TeachScheme, ReachJava 2009 78
Strings
; string-append : string … -> string; string-length : string -> number; substring : string number [number] -> string; string->number : string -> number; number->string : number -> string
Can now write animations with strings as the model (e.g. adding or chopping characters)
June 28 2009 TeachScheme, ReachJava 2009 79
Booleans
; = : number number -> boolean
; >, <, >=, <= : similar
; string=? : string string -> boolean
; image=? : image image -> boolean
; not : boolean -> boolean
; and : boolean … -> boolean
; or : boolean … -> boolean
June 28 2009 TeachScheme, ReachJava 2009 80
A Boolean-valued function; 18-to-25? : number -> boolean
(define (18-to-25? age); age a number(and (>= age 18) (<= age 25)))
(check-expect (18-to-25? 17) false)(check-expect (18-to-25? 18) true)(check-expect (18-to-25? 22) true)(check-expect (18-to-25? 25) true)(check-expect (18-to-25? 26) false)
June 28 2009 TeachScheme, ReachJava 2009 81
Stopping an Animation
• There's another kind of handler:
(stop-when function)
where function has contract model -> boolean
June 28 2009 TeachScheme, ReachJava 2009 82
Stopping an Animation
Example: a growing disk that stops growing when the radius reaches 100
; model is a number representing radius; over-100? : number -> boolean(define (over-100? r) (> r 100))
(run-animation 200 200 0 1/4(on-tick add1)(on-redraw blue-circle-of-size)(stop-when over-100?))
June 28 2009 TeachScheme, ReachJava 2009 83
Conditionals
(cond[boolean-expr-1 answer-1][boolean-expr-2 answer-2]…[boolean-expr-n answer-n])
tries each boolean-expr in turn. As soon as one of them evaluates to true, it evaluates and returns the corresponding answer.
June 28 2009 TeachScheme, ReachJava 2009 84
Functions with conditionals
Write a function reply that takes in one of the strings "good morning", "good afternoon", or "good night", and returns "I need coffee!", "I need a nap!", or "Bed time!" respectively.
June 28 2009 TeachScheme, ReachJava 2009 85
Functions with conditionalsContract & data analysis
; reply : string -> string
Data analysis: the input falls into three categories: "good morning", "good afternoon", and "good night".
The output likewise falls into three categories: "I need coffee!", "I need a nap!", or "Bed time!"
June 28 2009 TeachScheme, ReachJava 2009 86
Functions with conditionalsTest cases
Need a test case for each category of input, and each category of output. Conveniently, they match up one-to-one in this example.
(check-expect (reply "good morning")"I need coffee!")
(check-expect (reply "good afternoon")"I need a nap!")
(check-expect (reply "good night")"Bed time!")
June 28 2009 TeachScheme, ReachJava 2009 87
Functions with conditionalsSkeleton & inventory
Since there are three categories of input (and output), we'll probably need a 3-branch cond:
(define (reply greeting)
; greeting ; a string(cond [ question answer ] [ question answer ] [ question answer ]) )
June 28 2009 TeachScheme, ReachJava 2009 88
Functions with conditionalsBody
Fill in either all three answers, or all three questions, whichever is easier. In this case, the answers.
(define (reply greeting)
; greeting ; a string(cond [ question "I need coffee!" ] [ question "I need a nap!" ] [ question "Bed time!" ]))
June 28 2009 TeachScheme, ReachJava 2009 89
Functions with conditionalsBody
Then do the other of (questions, answers).
(define (reply greeting)
; greeting ; a string(cond [ (string=? greeting "good morning") "I need coffee!" ] [ (string=? greeting "good afternoon") "I need a nap!" ] [ (string=? greeting "good night") "Bed time!" ]))
June 28 2009 TeachScheme, ReachJava 2009 90
Functions with conditionalsError-checking
Quibble: this isn't idiot-proof. What happens if input isn't one of the three recognized inputs?
Answer: ugly error message.Solution: revise data analysis (and everything that depended
on it)Input is "good morning", "good afternoon", "good night", or
anything else. Output is "I need coffee!", "I need a nap!", "Bed time!", or "Huh?"
Add one more test case(check-expect (reply "buenas noches") "Huh?")
June 28 2009 TeachScheme, ReachJava 2009 91
Functions with conditionalsError-checking
Add one more cond case:
(define (reply greeting)
; greeting ; a string(cond [ (string=? greeting "good morning") "I need coffee!" ] [ (string=? greeting "good afternoon") "I need a nap!" ] [ (string=? greeting "good night") "Bed time!" ] [ else "Huh?" ]))
June 28 2009 TeachScheme, ReachJava 2009 92
Isomorphism
The shape of the data determines the shape of the code and tests.
Say this ten times before bed.
June 28 2009 TeachScheme, ReachJava 2009 93
Another example; pepper-scale : number -> string ("serrano", "cayenne",
"thai", "habanero"); Scoville 5000-25000 -> serrano; Scoville 30000-50000 -> cayenne; Scoville 65000-90000 -> thai; Scoville 100000-up -> habanero; Data analysis: input is a number, but falls into 4
categories:; 5000-25000, 30000-50000, 65000-90000, 100000-up.; Output is likewise four categories: "serrano",
"cayenne", "thai"., "habanero"
June 28 2009 TeachScheme, ReachJava 2009 94
Another example; Test cases therefore need to include all 4 categories plus borderlines.
(check-expect (pepper-scale 5000) "serrano")(check-expect (pepper-scale 16500) "serrano")(check-expect (pepper-scale 25000) "serrano")(check-expect (pepper-scale 30000) "cayenne")(check-expect (pepper-scale 42000) "cayenne")(check-expect (pepper-scale 50000) "cayenne")(check-expect (pepper-scale 65000) "thai")(check-expect (pepper-scale 85000) "thai")(check-expect (pepper-scale 90000) "thai")(check-expect (pepper-scale 100000) "habanero")(check-expect (pepper-scale 120000) "habanero")
June 28 2009 TeachScheme, ReachJava 2009 95
Another example: skeleton & inventory
There are four categories, hence a four-branch cond:
(define (pepper-scale scoville); scoville a number(cond [ q a ] [ q a ] [ q a ] [ q a ]))
June 28 2009 TeachScheme, ReachJava 2009 96
Another example: body
Fill in the answers
(define (pepper-scale scoville); scoville a number(cond [ q "serrano" ] [ q "cayenne" ] [ q "thai" ] [ q "habanero" ]))
June 28 2009 TeachScheme, ReachJava 2009 97
Another example: bodyFill in the questions
(define (pepper-scale scoville); scoville a number(cond [ (and (>= scoville 5000) (<= scoville 25000)) "serrano" ] [ (and (>= scoville 30000) (<= scoville 50000)) "cayenne" ] [ (and (>= scoville 65000) (<= scoville 90000)) "thai" ] [ (>= scoville 100000) "habanero" ]))
June 28 2009 TeachScheme, ReachJava 2009 98
Another example; rough-age : number -> string ("child", "teenager", or "adult")
; Data analysis: input is a number, but falls into 3 categories:
; under 13, 13-19, and over 19.
; Output is likewise three categories: "child", "teenager", "adult".
; Test cases therefore need to include all 3 categories plus borderlines.
(check-expect (rough-age 7) "child")
(check-expect (rough-age 13) "teenager")
(check-expect (rough-age 16.3) "teenager")
(check-expect (rough-age 19) "teenager")
(check-expect (rough-age 20) "adult")
June 28 2009 TeachScheme, ReachJava 2009 99
Functions with conditionals; rough-age : number -> string ("child", "teenager", or "adult"); Data analysis: input is a number, but falls into 3 categories:; under 13, 13-19, and over 19.
(define (rough-age age); age a number(cond [(< age 13) "child"] [(and (>= age 13) (<= age 19)) "teenager"] [(> age 19) "adult"]))
(check-expect (rough-age 7) "child")(check-expect (rough-age 13) "teenager")(check-expect (rough-age 16.3) "teenager")(check-expect (rough-age 19) "teenager")(check-expect (rough-age 20) "adult")
June 28 2009 TeachScheme, ReachJava 2009 100
We could have written…
(define (rough-age age); age a number(cond [(< age 13) "child"] [(<= age 19) "teenager"] [else "adult"]))
by relying on the fall-through behavior of the conditional.Advantage: less typing.Advantage: save a few nanoseconds of run time (maybe).
Disadvantage: you can't tell when a particular branch will happen just by looking at that condition; you have to also look at all the previous ones
Disadvantage: branches of conditional can no longer be reordered without changing function behavior.
Disadvantage: the isomorphism to the input data type is less clear. Use else only when you really mean "anything else".
June 28 2009 TeachScheme, ReachJava 2009 101
Animations with conditionals
Can now assign animations that decide among a finite set of cases, e.g.
• slide show of a sequence of pictures
• stop light that cycles red, green, yellow, red…
June 28 2009 TeachScheme, ReachJava 2009 102
So far we've…• covered the first six weeks of my non-majors'
programming course
• learned four syntax rules– function call
– variable definition
– function definition
– conditional
• gotten some practice writing, composing, and re-using functions, following a concrete step-by-step recipe
• learned to write interactive animations with model/view framework and callbacks (will do the same in Java)