Class 5 — Wednesday, September 9
[list: ...], L.map, and one function of your own.
[DCIC] 5.1 — From Tables to Lists and [DCIC] 5.2 — Processing Lists go out today and are due before class on Monday 09/14. Nothing below assumes you have read them.
Outline
- Starting code — copy this before anything else; the first line is new
- A flag from a list of colors — pairs from here on, and I will say when to switch
- One function of your own, examples before the body — the same recipe as last week, on a list
- Paste your file into the Journal — last two minutes, both of you
1. Starting code
Put this code (including the first conditional version of stripe) into a fresh Pyret session:
import lists as L
unit = 20
fun stripe(u, color):
if u < 10:
rectangle(u * 6, u, "solid", color)
else:
rectangle(u * 6, u, "outline", color)
end
endThat first line is new and it is not optional. Everything we use today lives in a library that Pyret does not load until you ask it to. Without that line the rest of this page fails with an error that does not mention the import — so if you ever see L is unbound, this is why.
2. A flag from a list of colors
Pairs from here to the end of class. You will both get a turn at the keyboard — I will say when to switch, so you do not have to watch the clock.
A list is one value. It holds things in order, and you write it with [list:, the things, and a ]:
colors = [list: "red", "black", "blue"]L.map takes a function and a list, and gives back a list — as long as the one it started with, with the function applied to every element:
fun default-stripe(c):
stripe(unit, c)
end
L.map(default-stripe, colors)Run that line. You get three stripes in a row, not a flag. L.map hands back a list, and Pyret draws a list side by side. Stacking is a second step.
L.fold does the stacking. Give it above, an empty picture to start from, and your list:
L.fold(
above,
empty-image,
L.map(default-stripe, colors))You just handed above to L.fold the same way you handed default-stripe to L.map. On Monday you write L.fold yourself.
Your flag
Pick a flag of horizontal stripes and put it on the screen, with its colors written down once. Whoever is not typing picks the flag.
Three stripes is a normal flag, and a color may repeat — Austria is [list: "red", "white", "red"].
Done looks like: one [list: ...] line naming the stripes from top to bottom, one L.map, one L.fold, and a flag on the screen. above is typed exactly once in your file, as an argument.
Your stripes come out see-through, because stripe outlines anything from 10 up and unit is 20. Change unit to 9 to fill them in.
Lambda: Anonymous Functions ([DCIC] 5.1 — From Tables to Lists §5.1.5)
Change your code so that instead of the named function default-stripe it uses a lambda function.
L.map(
lam(c): #= definition of default-stripe here =# end,
colors)lam(c): ... end is a function with no name. Lambdas are handy when a function is needed exactly once, and thinking up a name for it would be the only hard part.
If you finish early, add a fourth stripe to your flag without touching the L.map line or the L.fold line.
Break at 2:50–3:00
3. One function of your own, examples before the body
The new thing today is the list. The old thing from the last week, how to design functions, is still important: examples first, worked out, and the body written last.
L.filter takes a function and a list too, but that function has to answer true or false, and what comes back is a list of just the elements it said true about. It is never longer than the list you handed it. That is [DCIC] 5.1 — From Tables to Lists §5.1.4.
Write this one:
fun outlined(units :: List<Number>) -> List<Number>:
doc: "the units that stripe draws as an outline rather than solid"
...
where:
...
endFour examples in the where: block, before you write the body. One of them is the empty list.
Done looks like: four examples that pass, one of them containing 10, one of them [list: ] (the empty list), and the body written last.
[list: ] is a list
A list with nothing in it is a perfectly good value and you can write it down: [list: ], with nothing between the colon and the bracket.
As an example it is worth more than any other. Every operation on a list has to do something when there is nothing there. Getting it right in the where: block is the basis of your understanding of the function.
L.filter today
Then write this one instead. It is the same recipe with L.map, which you did get to.
fun stripe-widths(units :: List<Number>) -> List<Number>:
doc: "the width stripe draws for each unit"
...
where:
...
endA stripe’s width is u * 6, so stripe-widths([list: 4, 20]) is [list: 24, 120]. Add three examples, and one of them is still [list: ].
If you finish early, put stripe and outlined together on your own machine:
L.map(
lam(u): stripe(u, "red") end,
outlined([list: 4, 10, 20, 9]))Two stripes, both outlined, and nothing new was needed to get them.
4. Paste your file into the Journal
Select all, copy, and paste it into your Journal on Brightspace — both of you, not just whoever was typing.
If you would rather have Pyret save to your Google Drive, that is on Getting your work off the lab machine. Drive is an option but the Journal paste is a must.