Due: Tuesday, July 9 at 6pm
To practice writing programs over tables
To practice writing example tables for testing functions
Collaboration Policy: This is an individual assignment. Your work must be your own, though you can certainly utilize Kathi, Will, and Tasha’s office hours for help.
Reminder: put the following lines at the top of your file to get all the needed table operations:
include tables |
include shared-gdrive("cs111-2018.arr", "1XxbD-eg5BAYuufv6mLmEllyg28IR7HeX") |
include gdrive-sheets |
For part of this assignment, you will again work with the Data Druid tool. Druid has been configured so that different students are asked to use different Druid versions on different problems. Since this is a SOLO assignment, you shouldn’t be discussing the problems with anyone anyway, but just letting you know that you won’t all be asked to do exactly the same work per problem (the work will, however, be similar across the whole assignment).
In class, we wrote several functions using gradebooks as an example. We talked a bit about how to test table functions, including functions that take rows as inputs and functions that produce entire tables as output.
For this section of the assignment, you are going to write test cases for two functions involving gradebook tables. To make sure that you create tables that have the right types in each cell, we will have you work again in the Data Druid tool. Please do these two problems in the order assigned below (it helps us with our analysis of how you are all doing learning to work with data tables).
Go to the Druid tool and produce test inputs for a function that computes letter grades within the gradebook. Download your finished tests (letter-grades-examples.arr) and upload them when you submit for this assignment.
Go to the Druid tool and produce test inputs for a function that identifies students who have inconsistent grades across assignments (details are in the Druid problem). Download your finished tests (inconsistent-grades-examples.arr) and upload them when you submit for this assignment.
For both of these exercises, you will get full points as long as you submit something reasonable and show a good attempt at the problem.
A couple of reminders on Druid exercises:
If the font size comes up small, you can increase it under the "Data Druid" menu at the upper left of the window.
If you press Run before there are any values in your file, you will get an error "roughnum constructor got unsuitable arg COMMENT". Ignore this. It goes away once you have a value in your file.
If you don’t see a report of how many predicates have been satisfied after you first hit run, then you have been assigned to do this problem without the checks. You’ll just write the set of individual rows that occur to you, then submit that file.
If you get an error that "the highlighted examples did not fit the problem specifications", it means that you have a row in which some entry is of the wrong type or is of an unexpected value.
If you get a "Pyret didn’t understand your program" error, you likely have a punctuation error in writing down your examples, as we have seen so far in the course.
Put your work for this set of exercises in a file named icecream.arr. At the top of the file, confirm that you worked on your own by including this statement: "I understand this is an individual assignment, the work below is my own"
A local ice cream store stores information about its current flavors in a Google Sheet. It wants to use data from the sheet to generate the menu for its new digital menu board. Your job is to write the programs they need to generate content for the menu board.
Here’s the link to the Google sheet. Create a Pyret file for this assignment, and load this sheet as your initial table. We’ll refer to this as the flavors table in describing subsequent problems.
Loading a Table from Google Sheets: the following lines show you how to load the above table into Pyret:
include gdrive-sheets |
|
# the long string below is the last part of the URL to the sheet |
flavors-sheet = load-spreadsheet("1drj1kiC3VVCe17wrrTpNUn0DSx9R0mhdNkan7znOdcE") |
|
flavor-data = load-table: name, core, add-in, base, style |
source: flavors-sheet.sheet-by-name("flavors", true) |
end |
The Problems
Imagine that you were asked to find the rows from the flavor-data table in which either the "Core Flavor" or "Add In" columns contain chocolate. Which rows should be included? Write a comment listing the flavor names whose rows should be in the output. No code is required for this question.
Write an expression that performs the computation from the previous question. Specifically, define a table named has-chocolate that contains the rows from the flavor-data table in which either the "Core Flavor" or "Add In" columns contains chocolate. Pyret’s string-contains function is useful here: it takes two strings and determines whether the first string contains the second as a substring (try it out in the interactions window to learn how it works).
Did you get the answer that you expected from question 1? If not, what was different? (You don’t have to have matched your expected answer necessarily – we’re asking you to think about expectations and results. You don’t lose points for your answers to these two questions being different as long as you had reasonable answers in each case and can articulate any differences between them.
Clearly, the ice cream folks are too busy scooping to keep their capitalization consistent. Two possible solutions here are to modify your has-chocolate program to look for either "chocolate" or "Chocolate", or you could (somehow) transform the table you read in to convert all the core flavors to lowercase after you load the table. What are the advantages and disadvantages of each approach? Put your answer in a block comment in your Pyret file. Don’t write code, just discuss the approaches.
Define a table named clean-flavors that puts the strings in the "Core Flavor" and "Add In" columns all in lowercase. Generate this table via a program (don’t create a new table by hand).
Pyret has an operation called transform-column that calls a function on every cell in a given column. The result of the function is the content of the cell in the returned table. For example, if you had a function named add5 that added 5 to a number, the following expression would give all students 5 extra points on exam1 in our gradebook problem:
transform-column(gradebook, "exam1", add5)
Look in Pyret’s strings documentation to find a function that will help you convert to lowercase.
The ice cream store frequently gets visitors with dietary restrictions. They want to list flavors that are either vegan or nut-free in separate sections of the menu. Define a table named nut-free-vegan-menu that contains two new columns of booleans:
The first indicates whether the item is vegan (which means it has "almond milk" or "coconut milk" as its base and does not use "marshmallows" as its add-in)
The second new column indicates whether the item is free of nuts (which means it does not use "almond milk" as its base or "peanuts" as its add-in).
Generate this table via a program (don’t create a new table by hand).
Use the Data Druid to develop a good set of rows to use in testing your code. Download your Druid file (vegan-ice-cream-examples.arr) and submit it along with this assignment (yes, you’ll end up with the same test inputs in two places, but having the inputs in a separate file will help us in grading your work).
TIP: If you want to combine the rows from your Druid tests into a table for testing your function, you can use the add-row function on tables. Here is an example:
# create an empty table with columns "a" and "b"
T = table: a, b end
# add-row takes a table and a row for that table and
# produces a table
Tfull =
T.add-row(T.row(3,4))
.add-row(T.row(5, 6))
.add-row(T.row(6, 7))
Some customers are concerned about the number of calories in their ice cream. The owner has asked you to develop a collection of input tables to use in testing that they are properly categorizing flavors as being high-calorie, medium-calorie, or (relatively) low-calorie.
Use the Data Druid to develop a good collection of tables for testing such a program. You do not have to implement the function, just submit your Druid file (calorie-ice-cream-examples.arr).
In order to generate the menu for the digital display board, the ice cream shop needs not just the names of the flavors, but also a description of each flavor that indicates the core flavor, add-in, and style of the flavor. Here are examples of the descriptions they want to see:
"black raspberry ice cream with chocolate chips" (for either hard or soft serve ice cream)
"simple strawberry ice cream" (for an item with no add-in)
"mango frozen yogurt with papaya" (for frozen yogurt)
Define a table called descriptions that includes a new column with the descriptions of each item, following these examples. Generate this table via a program (don’t create a new table by hand).
It’s time to generate the flavor menu! The shop may put menus for different styles of ice cream in different sections of its display, so it wants to be able to quickly generate a table of flavors that are available in a given style, with the rows sorted alphabetically by the name of the flavor.
Define a function flavor-by-style that takes a string for the style ("hard", "soft", or "froyo") and produces a table of the flavors from that style, sorted alphabetically by flavor.
Write expressions that use your function to get the tables for each style (these should appear in the interactions window when you run your program).
During a local vegan-eating festival, the owner wants to highlight the vegan options within each of the styles. You’ve now written some code to work with vegan options and some code to work with focusing on particular styles. Write an expression that produces a table containing the vegan hard-style rows.
In a comment, briefly discuss the extent to which you were able to reuse code you had already written, versus how much code you had to repeat. If you feel had to repeat code unnecessarily, describe how you might have set up the code differently up front to avoid the repetition.
You do NOT have to rewrite your code for the second part. Again, we are asking you to reflect on your work – what we are really measuring here are your observations and understanding, not whether your code was designed ideally the first time.
For questions that ask you to write code, you’ll be graded on (a) whether the code performs the expected computation, (b) whether you have a reasonable set of examples on functions (in a where block), and (c) whether your code as good structure and style. For style, we want to see doc strings on functions, types on columns and parameters, and useful names for any parameters or variables you create.
For questions that are more free-response, you’ll be graded on whether you can articulate a technical opinion in a precise manner. Good answers should state technical reasons, not just opinions like "this is better", or "I like it".
Remember to include the collaboration statement in the ice-cream file.
Submit five files, icecream.arr plus your four Druid files, through this Google form.