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 # Related work by Matthias Felleisen, Robby Findler, Kathy Gray, Eli Barzilay, et al
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava What is a problem? Question: has a single answer Problem: 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 TeachScheme, ReachJava Introductions Who are you? What kind of school? students? Background in teaching CS Background in Scheme, Java, etc?
June TeachScheme, ReachJava This week You’re primarily students, not teachers Get “the student experience” of this approach — only faster Time on Friday to talk pedagogy
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava What is CS1 about?
June TeachScheme, ReachJava What you teach blah 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 TeachScheme, ReachJava What they hear blah ; blah { blah ) blah ] blah return blah this.x = x; blah public static void main (String[] args) blah /* blah // blah blah if ( blah JOptionPane blah class Posn(int x,y)
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava Let’s try DrScheme DrScheme Interactions pane (bottom half) Literal expressions –7 –"hello world" –copy and paste picture from Web browser –true Try
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Composing functions > (image-beside (reflect-horiz )) Exercise: write expressions to produce
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Definitions pane Editable and savable "Run" button evaluates all expressions in order, replacing old Interactions Try 7 "hello world" copied image from Web (image-above (rotate-cw picture) (rotate-ccw picture))
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava Building images from scratch (rectangle "solid" "blue") (circle 18 "outline" "green") (ellipse "outline" "purple") (triangle 22 "solid" "pink") (star "solid" "blue") (text "Hello there" 18 "blue") Try your own variations (define blue-star (star "solid" "blue")) Try modifying & combining these using image-above, overlay, reflect-vert, rotate-cw, surround, etc.
June TeachScheme, ReachJava Terminology Three kinds of literals: image (pasted from Web browser), number, and string. Data types
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava Exercise Define a function four-square that takes in an image and produces a 2x2 arrangement of it like
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava How to accomplish anything 1)Figure out what you want to do 2)Do it 3)Check that you did it right
June TeachScheme, ReachJava 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 TeachScheme, ReachJava The design recipe in practice contract: ; 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 "outline" "pink")) (image-above (image-beside book (ellipse "outline" "pink")) (image-beside (ellipse "outline" "pink") book))
June TeachScheme, ReachJava The design recipe in practice skeleton: (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 TeachScheme, ReachJava 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 "outline" "pink")) (image-above (image-beside book (ellipse "outline" "pink")) (image-beside (ellipse "outline" "pink") book)) (define (counterchange topleft topright) ; topleft an image ; topright an image (image-above (image-beside topleft topright) (image-beside topright topleft)))
June TeachScheme, ReachJava Testing again Change the definition so that it's wrong; run the tests again and see what happens.
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava Animation (run-animation 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava move-right-5 ; move-right-5 : image -> image
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava move-right-5 ; move-right-5 : image -> image (define (move-right-5 old-pic) ; old-pican 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 TeachScheme, ReachJava move-right-5 ; move-right-5 : image -> image (define (move-right-5 old-pic) ; old-pican 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 TeachScheme, ReachJava Running the animation (run-animation calendar 1 (on-tick move-right-5))
June TeachScheme, ReachJava Other kinds of event handlers tick-handler : image -> image Specify with on-tick mouse-handler : image number(x) number(y) event -> image Specify with on-mouse key-handler : image key -> image Specify 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava calendar-at-mouse ; calendar-at-mouse : image num(x) num(y) event -> image
June TeachScheme, ReachJava calendar-at-mouse ; calendar-at-mouse : image num(x) num(y) event -> image (check-expect (calendar-at-mouse schemelogo "dummy") (place-image calendar (rectangle "solid" "yellow"))) (check-expect (calendar-at-mouse stick-figure "event") (place-image calendar (rectangle "solid" "yellow")))
June TeachScheme, ReachJava calendar-at-mouse ; calendar-at-mouse : image num(x) num(y) event -> image (check-expect (calendar-at-mouse schemelogo "dummy") (place-image calendar (rectangle "solid" "yellow"))) (check-expect (calendar-at-mouse stick-figure "event") (place-image calendar (rectangle "solid" "yellow"))) (define (calendar-at-mouse old-pic x y event) )
June TeachScheme, ReachJava calendar-at-mouse ; calendar-at-mouse : image num(x) num(y) event -> image (check-expect (calendar-at-mouse schemelogo "dummy") (place-image calendar (rectangle "solid" "yellow"))) (check-expect (calendar-at-mouse stick-figure "event") (place-image calendar (rectangle "solid" "yellow"))) (define (calendar-at-mouse old-pic x y event) ; old-pican image ; xa number ; ya number ; eventwhatever )
June TeachScheme, ReachJava calendar-at-mouse ; calendar-at-mouse : image num(x) num(y) event -> image (check-expect (calendar-at-mouse schemelogo "dummy") (place-image calendar (rectangle "solid" "yellow"))) (check-expect (calendar-at-mouse stick-figure "event") (place-image calendar (rectangle "solid" "yellow"))) (define (calendar-at-mouse old-pic x y event) ; old-pican image ; xa number ; ya number ; eventwhatever (place-image calendar x y (rectangle "solid" "yellow")))
June TeachScheme, ReachJava calendar-at-mouse ; calendar-at-mouse : image num(x) num(y) event -> image (define BACKGROUND (rectangle "solid" "yellow")) (check-expect (calendar-at-mouse schemelogo "dummy") (place-image calendar BACKGROUND)) (check-expect (calendar-at-mouse stick-figure "event") (place-image calendar BACKGROUND)) (define (calendar-at-mouse old-pic x y event) ; old-pican image ; xa number ; ya number ; eventwhatever (place-image calendar x y BACKGROUND))
June TeachScheme, ReachJava Running the animation (run-animation calendar 999 (on-mouse calendar-at-mouse))
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Examples of arithmetic 3+4 becomes (+ 3 4) 3+(4*5) becomes (+ 3 (* 4 5)) becomes ( ) 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 TeachScheme, ReachJava Exercise Convert the following from "standard" algebraic notation to Scheme notation: 3+cos(0) 2/(x+1) (-b+√(b 2 -4ac))/2a where a, b, c are variables
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Kinds of numbers Try (cube (cube (cube ))) 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 TeachScheme, ReachJava 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)) ) passes the test Use check-within whenever function result might be inexact.
June TeachScheme, ReachJava 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 b 2 - 4ac As usual, follow the design recipe!
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 /2 (on-tick add1) (on-redraw blue-circle-of-size))
June TeachScheme, ReachJava Exercise: parametric equations Write an animation that displays a small dot at x coordinate *cos(t/20) and y coordinate *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 TeachScheme, ReachJava 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 TeachScheme, ReachJava Discussion break How is this different from what you've done in the past? How much explaining would it take for your students?
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Animations with randomness (random 8) returns a random integer from 0 through 7 Use this to write more fun and unpredictable animations
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Booleans ; = : number number -> boolean ; >, =, <= : similar ; string=? : string string -> boolean ; image=? : image image -> boolean ; not : boolean -> boolean ; and : boolean … -> boolean ; or : boolean … -> boolean
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Stopping an Animation There's another kind of handler: (stop-when function) where function has contract model -> boolean
June TeachScheme, ReachJava 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 /4 (on-tick add1) (on-redraw blue-circle-of-size) (stop-when over-100?))
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava Functions with conditionals Contract & 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 TeachScheme, ReachJava Functions with conditionals Test 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 TeachScheme, ReachJava Functions with conditionals Skeleton & 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 TeachScheme, ReachJava Functions with conditionals Body 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 TeachScheme, ReachJava Functions with conditionals Body 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 TeachScheme, ReachJava Functions with conditionals Error-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 TeachScheme, ReachJava Functions with conditionals Error-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 TeachScheme, ReachJava Isomorphism The shape of the data determines the shape of the code and tests. Say this ten times before bed.
June TeachScheme, ReachJava Another example ; pepper-scale : number -> string ("serrano", "cayenne", "thai", "habanero") ; Scoville > serrano ; Scoville > cayenne ; Scoville > thai ; Scoville up -> habanero ; Data analysis: input is a number, but falls into 4 categories: ; , , , up. ; Output is likewise four categories: "serrano", "cayenne", "thai"., "habanero"
June TeachScheme, ReachJava 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 ) "habanero") (check-expect (pepper-scale ) "habanero")
June TeachScheme, ReachJava 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 TeachScheme, ReachJava Another example: body Fill in the answers (define (pepper-scale scoville) ; scoville a number (cond [ q "serrano" ] [ q "cayenne" ] [ q "thai" ] [ q "habanero" ] ))
June TeachScheme, ReachJava Another example: body Fill in the questions (define (pepper-scale scoville) ; scoville a number (cond [ (and (>= scoville 5000) ( = scoville 30000) ( = scoville 65000) ( = scoville ) "habanero" ] ))
June TeachScheme, ReachJava 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 TeachScheme, ReachJava 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) ( 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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 TeachScheme, ReachJava 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)