Overview
Students analyze the behavior of a piecewise function
Learning Objectives
Students learn the concept of piecewise functions
Students learn about conditionals (how to write piecewise functions in code)
Evidence Statements
Students will understand that functions can perform different computations based on characteristics of their inputs
Students will begin to see how Examples indicate the need for piecewise functions
Students will understand that condcond statements capture pairs of questions and answers when coding a piecewise function
Product Outcomes
Materials
Computers w/ DrRacket or WeScheme
Student workbook
Pens/pencils for the students, fresh whiteboard markers for teachers
Class posters (List of rules, basic skills, course calendar)
Language Table (see below)
Preparation
"Luigi’s Pizza" [LuigisPizza.rkt from source-files.zip | WeScheme] preloaded on students’ machines, and on the projector
REQUIRED: Hand out Luigi’s Pizza Worksheet.
To get started with this lesson, complete Luigi’s Pizza Worksheet.
The code for the costcost function is written below:
; cost : String -> Number
; given a Topping, produce the cost of a pizza with that topping
(EXAMPLE (cost "cheese") 9.00)
(EXAMPLE (cost "pepperoni") 10.50)
(EXAMPLE (cost "chicken") 11.25)
(EXAMPLE (cost "broccoli") 10.25)
(define (cost topping)
(cond
[(string=? topping "cheese") 9.00]
[(string=? topping "pepperoni") 10.50]
[(string=? topping "chicken") 11.25]
[(string=? topping "broccoli") 10.25]
[else 00.00]))
Up to now, all of the functions you’ve seen have done the same thing to their inputs:
green-trianglegreen-triangle always made green triangles, no matter what the size was.
safe-left?safe-left? always compared the input coordinate to -50, no matter what that input was.
update-dangerupdate-danger always added or subtracted the same amount
and so on...
This was evident when going from EXAMPLEs to the function definition: circling what changes essentially gives away the definition, and the number of variables would always match the number of things in the Domain.Turn to page Page 23, fill in the Contract and EXAMPLEs for this function, then circle and label what changes.
It may be worthwhile to have some EXAMPLEs and definitions written on the board, so students can follow along.
The costcost function is special, because different toppings can result in totally different expressions being evaluated. If you were to circle everything that changes in the example, you would have the toppings circles and the price. That’s two changeable things, but the Domain of the function only has one thing in it - therefore, we can’t have two variables.
Of course, priceprice isn’t really an independent variable, since the price depends entirely on the toppingtopping. For example: if the topping is "cheese""cheese" the function will simply produce 9.009.00, if the topping is "pepperoni""pepperoni" the function will simply produce 10.5010.50, and so on. The price is still defined in terms of the topping, and there are four possible toppings - four possible conditions - that the function needs to care about. The costcost function makes use of a special language feature called conditionals, which is abbreviated in the code as condcond.
- Each conditional has at least one clause. Each clause has a Boolean question and a result. In Luigi’s function, there is a clause for cheese, another for pepperoni, and so on. If the question evaluates to truetrue, the expression gets evaluated and returned. If the question is falsefalse, the computer will skip to the next clause.
Look at the costcost function:
How many clauses are there for the costcost function?
Identify the question in the first clause.
Identify the question in the second clause.
Square brackets enclose the question and answer for each clause. When students identify the questions, they should find the first expression within the square brackets. There can only be one expression in each answer.
- The last clause in a conditional can be an elseelse clause, which gets evaluated if all the questions are falsefalse.
In the costcost function, what gets returned if all the questions are false? What would happen if there was no elseelse clause? Try removing that clause from the code and evaluating an unknown topping, and see what happens.
ElseElse clauses are best used as a catch-all for cases that you can’t otherwise enumerate. If you can state a precise question for a clause, write the precise question instead of elseelse. For example, if you have a function that does different things depending on whether some variable xx is larger than 55, it is better for beginners to write the two questions (> x 5)(> x 5) and (<= x 5)(<= x 5) rather than have the second question be elseelse. Explicit questions make it easier to read and maintain programs. When you use elseelse, someone has to read all the previous questions to know what condition elseelse corresponds to: they can’t just skim all the questions to find the one that matches their situation. This might be counterintuitive to those with prior programming experience, but it does help make code more readable and understandable.
Functions that use conditions are called piecewise functions, because each condition defines a separate piece of the function. Why are piecewise functions useful? Think about the player in your game: you’d like the player to move one way if you hit the "up" key, and another way if you hit the "down" key. Moving up and moving down need two different expressions! Without condcond, you could only write a function that always moves the player up, or always moves it down, but not both.