Day 14 - Operating over tables & lists
Skills: None
Pre-reading: 5.1.6
FIXME
Lambda Functions and Combining Lists and Tables
Focus: Introduce anonymous functions (lambda) and show how to combine list and table operations to solve analysis problems with new examples.
1. Introduction & Warm-Up (10 minutes)
- Recap:
- Brief review of list operations and the idea of transforming data.
- Do Now:
- “Given a list of email addresses, how would you extract the username (the part before the '@')? Write down your thoughts.”
- Discussion:
- Share a couple of ideas without full code yet.
2. Lambda: Anonymous Functions (15 minutes)
- Motivating Example – Extracting Usernames:
- We want to convert a list of emails to a list of usernames.
- New Example List:
emails = [list: "alice@cafe.com", "bob@domain.org", "charlie@cafe.com"]
- Using a Named Helper Function (Review):
fun extract-username(email :: String) -> String:
string-split(email, "@").get(0)
end
usernames = L.map(extract-username, emails) - Introducing Lambda:
- Replace the helper with an anonymous function:
usernames = L.map(lam(email): string-split(email, "@").get(0) end, emails)
- Replace the helper with an anonymous function:
- Interactive Exercise:
- Ask: “What would be the output of the lambda version? Write it down.”
- Discuss and verify.
- Discussion:
- Benefits of using lambda for simple, one‑off functions.
3. Combining Lists and Tables (20 minutes)
- Scenario: A local bookstore tracks sales in a table. You want to compute statistics based on the genres of books sold.
- Example Table:
book-sales =
table: title, genre, copies-sold, price
row: "Mystery at Midnight", "Mystery", 20, 12.99
row: "Space Adventures", "Sci-Fi", 15, 15.50
row: "The Last Detective", "Mystery", 25, 11.50
row: "Future World", "Sci-Fi", 10, 18.00
row: "Romance in Paris", "Romance", 30, 9.99
end - Task 1: Extract a List of Copies Sold for a Specific Genre
- Plan:
- Filter the table for rows where genre is, say, "Mystery".
- Extract the "copies-sold" column.
- Implementation:
fun is-mystery(r :: Row) -> Boolean:
r["genre"] == "Mystery"
end
mystery-sales = filter-with(book-sales, is-mystery)
copies = mystery-sales.get-column("copies-sold")
avg-mystery = S.mean(copies) - Interactive Do Now:
- “How many mystery books were sold on average?” (Students compute
avg-mystery
.)
- “How many mystery books were sold on average?” (Students compute
- Plan:
- Task 2: Combining List Functions with Tables – Analyzing Email Domains
- Suppose the bookstore has a customer table:
customers =
table: name, email
row: "Alice", "alice@reader.com"
row: "Bob", "bob@novel.org"
row: "Charlie", "charlie@reader.com"
row: "Dana", "dana@books.net"
end - Plan:
- Extract the email column.
- Use
L.map
andstring-split
to get domain names (the part after '@'). - Find the distinct domains.
- Implementation:
import lists as L
email-list = customers.get-column("email")
domains = L.map(lam(email): string-split(email, "@").get(1) end, email-list)
unique-domains = L.distinct(domains) - Interactive Discussion:
- “Which domain appears most frequently? How might you count the frequency?”
- Suggest using
L.filter
or comparing lengths.
- Suppose the bookstore has a customer table:
- Do Now (Group Activity):
- TODO: PROVIDE A BIGGER TABLE FOR THESE
- Propose multiple task plans for the question: “How many customers with a '.com' email bought more than 10 copies of a book?”
- Groups discuss different approaches (filtering the table first versus extracting and then filtering a list) and share their plans.
4. Wrap-Up & Reflection (5 minutes)
- Recap Key Points:
- Lambda (anonymous functions) let you succinctly express functions, which can
be useful when using functions like
L.map
, etc. - Combining list and table operations enables flexible data analysis.
- Lambda (anonymous functions) let you succinctly express functions, which can
be useful when using functions like