Overview
To help stay within your weekly budget, you want a program that determines which store(s) you should visit to minimize your grocery bill. Your shopping list is a table of the items and quantities you need, and you have pricing data from three nearby food stores. You'll develop a program that helps you decide where to shop this week, trading off lowest price against convenience.
Learning objectives
After this assignment, you should be able to:
- Practice writing tables programs, on both single and multiple tables
- Practice breaking down tables problems into plans
- Practice creating testing strategies for table-based programs
- Practice using LLMs for various software tasks
AI and collaboration policy for this assignment
AI is allowed on some problems. Tasks that allow it are explicitly marked. If a task carries no such marker, do it by hand.
Setup
- Make a copy of
hw3-code.arr. - Use this Gemini Gem for the AI-permitted parts of this assignment.
- Make a copy of the written answer worksheet and submit the link to it in the worksheet submission form (you can do this before filling anything in).
- NEW 9/30: Make a new Pyret file named
hw3-tests-examples.arrand put all of yourchecktests for the required functions in that file. This way, the part of the autograder that inspects your tests can get them in isolation of your functions. That file will not run on its own (since the function defintions are missing), but that's okay -- the autograder combines your tests with our implementations behind the scenes.
The CS111 tables documentation lists the table operations that are in the dcic2024 context.
Do not put your name in your Pyret/.arr files, so we can grade it anonymously.
Part 1Understanding the Data and Developing a Testing Strategy
We're going to capture a shopping list as a table with two columns: the name of the item, and the number of that item you need to buy.
item | quantity
avocado | 4
olive oil | 1
salt | 1
For this assignment, you have access to three stores: MegaMart, Farmstand, and Corner Market (these load automatically in the hwk3-code.arr starter file). For each one, you have a table of the current prices of the items it carries. Each table has two columns: the name of the item and the price per unit:
item | price
corn | .75
olive oil | 6.99
bread | 3.49
Overall, we're going to write programs to determine the lowest cost of your list under two different strategies: one where you shop at the single store that yields the lowest total bill, and one where you visit up to three stores, buying each item at the store where it costs least. The key functions for these are total-costs and where-to-buy. Each takes a shopping table and the three stores' pricing tables. total-costs returns a table with one row per store showing the total price of the shopping list at that store. where-to-buy returns a table of the shopping items and which store to buy each one at.
Describe a set of scenarios that should be tested for each of total-costs and where-to-buy. Put these in your worksheet.
Note: For a reminder of what testing and code plans look like, see the class notes from the airplane-cabin exercise
Part 2Developing the Code
Now we'll write the code for these functions. The tasks below name the functions our test cases will look for. You're welcome to create helper functions as part of any of these.
Write a program in-stock that takes the name of an item and a product table and returns a boolean indicating whether the store carries the named item.
Write a program where-cheapest that takes the name of an item and three store tables and returns the name of the store that offers the item for the least amount.
To avoid looking in all three store tables every time you compare prices, it may make more sense to add columns to your shopping list showing the price of each item at each store. We want a function build-price-columns that takes a shopping table and three store tables and returns an extended shopping table with a column of prices for each store. You may assume every store sells every item on your list — raise an error "item not found" if an item is missing from an individual store.
Details that we didn't get to on Friday
To do this, you need a table operator for adding a column to a table:
build-column ( t :: Table, # the table to add the column to
colname :: String, # the name of the new column
col-func :: (Row -> Value) ) # compute the new column value
-> Table col-func is a function that takes a row and produces the value that you want to put into the cell in the new column. For example:
Here's the example we would have done in class with the gradebook:
# add col for exam average
fun exam-avg(r :: Row) -> Boolean:
(r["exam1"] + r["exam2"]) / 2
end
build-column(gradebook, "avg", exam-avg)Develop the plan for build-price-columns and write it in your worksheet.
Implement your plan for build-price-columns in your Pyret file.
Using build-price-columns, write a program price-gap that takes the name of an item, a shopping table, and three store tables and returns the difference between the highest and lowest cost for the item across the stores. Include the quantity needed in the calculation — if the shopping table says you need 4 avocados, price-gap should return the cost difference for 4 avocados, not for a single one.
You're sufficiently interested in saving money that you decide to purchase each item at whichever of the three stores offers the best price. Write a program where-to-buy that takes a shopping table and three store product tables and extends the shopping table with a new column listing which store offers the cheapest price on that item. Items you'll buy from the same store should end up in consecutive rows.
Rather than focus on the price of individual items, you instead want to know which store would offer the lowest total price for everything you need. Write a program total-costs that takes a shopping table and three store product tables. It returns a new table with two columns, "store" (string) and "total" (number) — one row per store, each showing the total cost of your grocery bill if you bought everything at that one store.
Rather than build one wide shopping table with a column per store, we could instead make a tall table: all the rows from the three store tables, plus a column naming which store each row came from. Such a table might look like:
item | price | store
corn | .75 | corner-market
olive oil | 6.99 | corner-market
bread | 3.49 | megamart
milk | 3.69 | megamart
corn | 1.00 | farmstand
Ultimately, we want a function named where-cheapest-tall that takes the name of an item and three product tables and returns the name of the store with the cheapest price on that item, using a tall table like the one above instead of the wide table. Write a plan for this function as a prose bulleted list. Put it in your worksheet.
Some AI permitted: once you have the plan, implement the code. You may use Gemini to help figure out how to combine the three product tables into the tall table; your solution should work on any set of three product tables, not just the specific ones we've given you.
Part 3Design Questions
For this assignment, we told you to assume that every item you wanted to buy was available in every store. This isn't realistic. If we relaxed that assumption, what changes would you have to make to your functions? Contrast the changes needed when store prices are in wide format versus tall format. Put your response in the worksheet.
What other assumptions does your program make? Pick two and talk about what would need to be different about your code to relax them. We're not asking you to edit the code — we're asking you to describe what would need to change.
Grading
Working code is one way of showing that you understood something, not the only one. The rubric covers:
- your code passes our tests
- you wrote your own examples and tests, and they cover more than the easy case
- your code follows the design and clarity guidelines
- your written answers are complete and specific
- you show the particular thing this assignment is teaching — including reusing your own earlier work where the handout points you at it
Follow the directions as written. Where a task asks for a specific number of items, or a specific format, that is part of what is graded.
Handin
Hand in these files, together, in one submission:
hw3-code.arrhw3-tests-examples.arr
Make sure you have put links to any required chat transcripts at the top of your file. Submit to Gradescope. You may submit as many times as you like before the deadline; we grade the last submission.
Include the config file that came with hw3-code.arr.
Comments or concerns?
If you have comments or concerns, submit them on the anonymous feedback form. Sign in with your Brown Google account to open it; your email address is not recorded.