Day 9 - Tests for tables
Skills: 1, 2
Pre-reading: 4.1.5, DRAFT:29.1
Intro (15 mins)
- In the last few classes, we've shown table operations that take functions as
arguments; some of those are complex, and benefit from being written with our
full design process (e.g.,
calc-distance
, or the function to obfuscate item names), but others, likesubtract-1
seem a bit unnecessary. It would be nice if we could write:t = table: x-coord :: Number, y-coord :: Number
row: 1, 2
row: 3, 4
end
transform-column(t, "x-coord", n - 1) - But if we try to run this, we get an error --
n
is not defined. What we want, instead ofn
, is a way of referring to the column value that is being transformed. When we defined a function, this is the argument:fun subtract-1(n :: Number) -> Number:
doc: "subtracts 1 from input"
n - 1
where:
subtract-1(10) is 9
subtract-1(0) is -1
subtract-1(-3.5) is -4.5
end - For simple functions, we can do this with
lam
, which creates an unnamed function:transform-column(t, "x-coord", lam(n): n - 1 end)
- Another oddity about the last few classes is that while we've followed our design process for helper functions, we haven't actually written functions that take tables and produce tables, and (for the most part), haven't written tests on tables.
- For example, let's design a function that transforms a table, modifying a
"price"
column by discounting it by 20%, but only for prices that are below 100.fun apply-discounts(t :: Table) -> Table:
doc: "transforms 'price' column by reducing 20%, if value is below 100"
transform-column(t, "price", lam(price :: Number):
if price < 100: price * 0.8 else: price end
end)
where:
test-table =
table: price
row: 50
row: 120
row: 80
row: 40
end
apply-discounts(test-table) is
table: price
row: 50 * 0.8
row: 120
row: 80 * 0.8
row: 40 * 0.8
end
end - Note how we created an example table within our
where:
block, and in the test, rather than computing the actual numbers, wrote the expressions for the rows that should have changed. This makes it easier to understand the behavior.
Class Exercise (40 mins)
- Design a function that takes a table that has a "price" column and adds a new column "tax", which is the sales tax rate where you are multiplied by the price. You can assume there is not already a tax column.
- Create a function to carry out the "obfuscation" exercise from last class, and
write tests for it. Note, your test tables should only need an
"item"
column! - Create a function to carry out the employee total earnings calculation from last time, and again write tests.
Wrap-up (5 mins)
lam
allows us to more concisely use operations that expect functions as inputs, liketransform-column
,build-column
,filter-with
,order-by
, etc.- Table functions should follow the same design process, and include tests, just like other functions!