instagram

Students use the Design Recipe to define operations on tables, developing a structured approach to answering questions by transforming tables.

Lesson Goals

Students will be able to…​

  • write functions that consume a Row and perform a lookup to produce a column

  • write functions that consume a Row and compute to produce an Image

  • write functions that consume a Row and compute to produce a Boolean

Student-facing Lesson Goals

  • I can define functions that look up values from a row

  • I can define functions that compute images values from a row

  • I can define functions that compute a boolean from a row

Materials

Preparation

  • Make sure all materials have been gathered

  • Decide how students will be grouped in pairs

  • Computer for each student (or pair), with access to the internet

  • Student workbook, and something to write with

  • All students should log into CPO.

Language Table

Types

Functions

Values

Number

+, -, *, /, num-sqrt

4, -1.2, 2/3, pi

String

string-length, string-repeat, string-contains

"hello", "91"

Boolean

<, <>, <=, >=, <, >, ==, <>, >=

true, false

Image

star, triangle, circle, square, rhombus, ellipse, regular-polygon, radial-star, bar-chart, pie-chart, box-plot, scatter-plot, bar-chart-summarized, pie-chart-summarized

🔵🔺🔶

Table

.row-n, .order-by, .filter, .build-column

Glossary
contract

a statement of the name, domain, and range of a function

purpose statement

a concise, detailed description of what a function does with its inputs

🔗Warmup 5 minutes

Let’s review using .row-n and value definitions…​

Open the Row Functions Starter File, save a copy, and click "Run".

Scroll until you see the definition for cat-row. What will you get back if you evaluate cat-row in the Interactions Area?

We’ve defined a few rows for you already: young-row, fixed-row, and of course cat-row. Take a few minutes to define three more rows on the lines below:

  • Define old-row to be an animal that is greater than 5 years old

  • Define dog-row to be an animal that is a dog

  • Define unfixed-row to be an animal whose fixed column is false

🔗Computing Images from Rows 20 minutes

Overview

Primary: Students use different representations of functions to define Row-based functions.

Secondary: Students discover functions that consume other functions, and compose a scatter plot function with a function they’ve defined.

Launch

By now you’ve had a chance to explore functions on their own, thinking of them in terms of several different representations:

  • A mapping between Domain and Range

  • A list of discrete input values and output values

  • A symbolic definition

Now it’s time to use those representations to help us work with Tables!

The shelter wants to print nametags for all the animals, with their names written in red letters. Turn to The Animals Table in your Student Workbook.

Suppose you had a stack of blank nametags, and you needed to fill them out. In careful detail, exactly what would you do for each row?

This would be pretty repetitive! Just as we saw when making green triangles in Defining Functions, there’s got to be a better way! In this lesson, we’ll learn a step-by-step process that helps us define functions, called the Design Recipe.

The Design Recipe uses multiple representations of functions in a specific order, to help us solve problems. Let’s look at an example to see how this works!

Investigate

Step 1: Contract and Purpose

  • Scroll down in the starter file until you find the Contract for nametag.

  • What is the Domain of this function? The Range?

  • The Purpose Statement is a way of describing the function in detail. What is the Purpose Statement for this function?

Step 2: Write Examples

# nametag :: Row -> Image
# consumes an animal, and draws the name in 15px red letters
examples:
  nametag(cat-row)   is text(        "Miaulis", 20, "red")
  nametag(young-row) is text(           "Nori", 20, "red")

  nametag(cat-row)   is text(  cat-row["name"], 20, "red")
  nametag(young-row) is text(young-row["name"], 20, "red")
end
  • Look at the first two examples. Can you explain what these examples do?

  • These examples show us exactly what should be produced for the two Rows representing "Miaulis" and "Nori". But these examples only tell us part of the story! Where does the computer get those names from?

  • Now look at the last two examples. How are they related to the first?

  • The last two examples are the missing part of the puzzle. We get those names by looking up the "name" column in the Row!

  • In the previous lesson, we learned that representations of functions have to match. Look at the Examples carefully - there is one mistake, where the Examples don’t quite match the Contract and Purpose. Can you find the bug?

Make sure students have changed the 20 to 15, matching the Purpose Statement.

Step 3: Define the Function

Those last two examples provide the pattern that allows us to write our definition. Everything stays the same except the Row itself. Just as we did for gt, we can circle and label the the Rows. In this case, r or animal would be a pretty good name for the Row that represents an animal in our table:

fun nametag(r): text(r["name"], 15, "red")
end

Have students try this function on some of the animals they defined, by typing nametag(unfixed-row), nametag(dog-row), etc. Then have them find find the contract for image-scatter-plot in their Contracts pages.

  • How many things are in the Domain of this function? What is the type of the first thing? The second? The third?

  • The fourth argument is something you’ve never seen before! What do you think it means?

  • Type image-scatter-plot(animals-table, "pounds", "weeks", nametag) into the Interactions Area.

  • What did you get? Does this help you explain what the fourth argument is?

  • Try changing the color of the nametag. Remember: all the representations for the same function need to match! How many places do we need to change the color?

Note: the optional lesson If Expressions goes deeper into basic programming constructs, using image-scatter-plot to motivate more complex (and exciting!) plots.

Scatter plots allow us to display two dimensions of data: one on the x-axis and the other on the y-axis. This is useful if we want to explore a relationship between how much an animals weighs and how long it takes to be adopted! But what if we wanted to also see the impact of an animal’s age? We could make a different scatter plot, using age as our x-axis. But maybe we want to combine all three into a single plot, and see three dimensions?

  • Copy and paste the entire Design Recipe (Contract and Purpose, Examples, and Definition) for nametag, so you have a second copy below the first.

  • Now, change this second copy to a function named age-dot, which consumes a Row and draws a solid blue circle using the age as the radius.

  • When you’re done, click "Run" and make sure your examples pass!

  • Then type image-scatter-plot(animals-table, "pounds", "weeks", age-dot) into the Interactions Area.

Synthesize

Each step in the Design Recipe helps us write the next one.

  • If we can’t write our Contract and Purpose, it means we haven’t thought through the problem enough. Better to find this out before we write the rest of our function!

  • If we’re having trouble writing our Examples, we can check our Contract and Purpose for hints.

  • If we’re having trouble writing the Definition, we can check our Examples for hints.

These steps also help us check our work. If any two representations don’t match, it means there’s likely a bug somewhere.

🔗Computing Booleans from Rows 15 minutes

Overview

Students use different representations of functions to write functions that produce true and false by asking questions of Rows.

Launch

Let’s try solving some other word problems using the Design Recipe, starting from scratch.

Turn to The Animals Dataset. For the first 10 rows in the table, write true next to the animals that are cats and false next to all the ones which aren’t.

Investigate

How could we describe this work to the computer, so that we can define a function and make it do the work for us? Complete the following sentence: For each Row, I…​

Step 1: Contract and Purpose

Since we’re asking if an animal is a cat, we’ll call our new function is-cat. What type of data is going in? What type is coming out?

Turn to The Design Recipe - Compute in your Student Workbook, and fill out the Contract and Purpose Statement for this function. Make sure your Purpose Statement includes all the details you need!

Step 2: Write Examples

Using the dog-row and cat-row values defined earlier, write examples for this function. If you’re not sure what work to do, look back at the purpose statement! Ultimately, we want to write examples that show their work. But if you get stuck, you can always start with examples that just show the answer.

	examples:
		is-cat(dog-row) is false
		is-cat(cat-row) is true

		is-cat(dog-row) is dog-row["species"] == "cat"
		is-cat(cat-row) is cat-row["species"] == "cat"
	end

Step 3: Define the Function

The last two examples are what we want, because we can see the pattern! Just as with nametag, the only thing changing is the Row itself. Once we circle and label the Rows, we’re ready to define the function:

fun is-cat(r): r["species"] == "cat" end
  • Scroll further down in the file, until you find the Contract for is-cat.

  • Add the examples from your workbook. We’ve already provided one to get you started, but it doesn’t show the work being done.

  • Try using this function in the Interactions Area with some of your predefined animals!

  • On The Design Recipe - Compute, practice the Design Recipe by completing is-young. When you’ve finished, type it into Pyret and try it out!

Common Misconceptions

It’s extremely likely that students will struggle with this Boolean expression:

dog-row["species"] == "cat"

That’s because they are confusing false with wrong. It’s absolutely correct that this expression will produce false, because the species of the dog row isn’t "cat". But this doesn’t make the example wrong! Remember, the first example said that false is the answer we expect.

Synthesize

There are lots of Boolean-producing functions that would be handy to write. We might want functions that tell us if an animal is old, if it’s male, or if it was adopted in under a week.

What are some other Boolean-producing functions that would be useful?

🔗Defining Lookup Functions 10 minutes

Overview

Students use different representations of functions to define Lookup functions.

Launch

Turn to The Animals Dataset. For the _next 10 rows in the table, write the value in the fixed column over in the margin.

Investigate

Step 1: Contract and Purpose

Turn to The Design Recipe - Lookup in your Student Workbook, and write the Contract and Purpose Statement.

Have students share back their Purpose Statements, and discuss.

Since we’re looking up the fixed column, we’ll call our new function lookup-fixed. What type of data was going in? What type was coming out? This gives us the Contract:

# lookup-fixed :: Row -> Boolean # consumes an animal, and tells whether it is fixed

Write two examples for this function, using the fixed-row and unfixed-row that you defined earlier.

Have students share back their examples.

	examples:
		lookup-fixed(fixed-row)   is true
		lookup-fixed(unfixed-row) is false

		lookup-fixed(fixed-row)   is fixed-row["fixed"]
		lookup-fixed(unfixed-row) is unfixed-row["fixed"]
	end

Looking at the rows that include the lookup, what is changing? Circle and label the changing part, then use that pattern to define the function.

fun lookup-fixed(r): r["fixed"] end
  • Scroll further down in the file, until you find the Contract for lookup-fixed.

  • Add the two examples that show the pattern, and click "Run"

  • Try using this function in the Interactions Area with some of your predefined animals!

  • Optional: On The Design Recipe - Lookup, practice the Design Recipe by completing lookup-name. When you’ve finished, type it into Pyret and try it out!

Common Misconceptions

Ironically, students are likely to struggle with lookup functions that only look up a column ("but it doesn’t do any work!"). This may come from a misunderstanding that a column lookup is doing work!

Synthesize

Students may ask "why would I need this, if I can already see all the values in the Row?"

The big idea here is that functions provide a standard way to compose computations. Every wall plug has a standard shape, which allows us to plug all sorts of appliances, lamps, etc into any room in the house. Having a standard like function-name(argument1, argument2, …​) allows us to stack functions together and do all kinds of sophisticated analysis.

These materials were developed partly through support of the National Science Foundation, (awards 1042210, 1535276, 1648684, and 1738598). CCbadge Bootstrap:Data Science by the Bootstrap Community is licensed under a Creative Commons 4.0 Unported License. This license does not grant permission to run training or professional development. Offering training or professional development with materials substantially derived from Bootstrap must be approved in writing by a Bootstrap Director. Permissions beyond the scope of this license, such as to run training, may be available by contacting contact@BootstrapWorld.org.