Welcome to Discussion 2! Today we will examine the topics of privacy and power through a role play activity. A company that collects health data is deciding what kind of privacy policy to implement. Each of you will represent a stakeholder and decide what kind of privacy policy that stakeholder would support. Then, you will try to convince the CEO (your TA) to select your preferred policy.
Here are the SRC Discussion slides
Here are the stakeholder roles
β
In this lab, youβll be using everything youβve learned about tables (and some of what youβve learned about lists) to create a data visualization tool. Specifically, youβll use a dataset of active Providence business licenses published by the Rhode Island government to mark locations on a map.
A key goal of this lab is to give you practice breaking large problems into separate tasks, each of which gets handled with its own collection of functions, expressions, and operators. As you work on the problems, practice writing out the lists of tasks and using those to guide your work.
Before you start working with the data, take a look at the Providence Business License dataset. The first sheet (inside the file) is the original dataset, and the second sheet is a pruned version with only the columns youβll need for this lab. Load the pruned sheet into Pyret by pasting the following code into the definitions window:
We have provided you with a function table-to-map(t :: Table) -> Image
, which takes in a table and plots rows as dots on a map of Providence, based on their "x"
, "y"
, and "color"
columns. Treat table-to-map
like a built-in function; you can call it just like you called filter-by
or any other built-in function in previous labs.
To use table-to-map
to map the locations of the businesses listed in pvd-businesses
, you will need to convert the longitude and latitude values in the table to x- and y-coordinate values. Only locations that fit within the bounds of the Providence map can be included (table-to-map
will account for this automatically). Weβve defined the following values for you in the stencil.arr
file that the setup code includes:
LAT-MIN
- the minimum latitude that fits the mapLAT-MAX
- the maximum latitude that fits the mapLON-MIN
- the minimum longitude that fits the mapLON-MAX
- the maximum longitude that fits the mapHEIGHT
- the height of the mapWIDTH
- the width of the mapTry typing LAT-MIN
or any of these values in the interactions window, you should see they are predefined values that you can use in your functions.
Use these values to write functions that scale latitudes to y
values and longitudes to x
values relative to the map dimensions. You must proportionally scale the businesses' (long
, lat
) coordinates to (x
, y
) coordinates in order for the rows to be read by the table-to-map
function correctly.
To make things easier for you, we've included scaling formulas!
TASK: Use these scaling functions to add columns named x
and y
to the pvd-businesses
table with these scaled values.
TASK: Add a column labeled color
and set each rowβs color to "black." After adding these columns, the computed table can then be used as an input to table-to-map
.
HINT: Think about whether the output for this column is dependent on each specific row. How can we generate this column using build-column
?
Complete the tasks and pass the transformed table into table-to-map
. The output should look something like this:
Now that you have a map of Providence (albeit not a very pretty one), we need to put it to good use. Your friend Sofia has taken you up on your invitation to visit and has just arrived in Providence. She wants to know what she should do while she's here!
Write a function generate-tourist-map(needs-hotel :: Boolean, has-car :: Boolean, stays-up-late :: Boolean, eats-out :: Boolean, businesses :: Table) -> Image
that takes in a series of Booleans and the original pvd-businesses
table and returns a map marked with the places that Sofia might want to visit.
needs-hotel
: If this Boolean is true
, Soia needs a hotel to stay at! Mark all of the inns on the map with a color of your choice.has-car
: If true
, Sofia has decided to drive and will need to find places with parking. Mark all places with parking with a second color.stays-up-late
: If true
, Sofia is ready for a night out! Mark all places with extended hours (Look at the column entitled extended-hours
) with a third color.eats-out
: If true
, Sofia has given up on cooking for himself and wants to eat out. Mark all eateries with a fourth color.Remember that your generate-tourist-map
function should take in the original pvd-businesses table, not the modified one made in Part 1.
If a place has more than one relevant characteristic, it should be colored according to the characteristic that's most important to Sofia. Any non-relevant places should be colored black. Starting with the most important characteristic, Sofia cares first about hotels, then eating out, then places that have parking, and lastly, places that stay open late.
Depending on the values of the parameters (needs-hotel
, has-car
, stays-up-late
, eats-out
), the computed colors for places will be different. Think about how you can accomplish this behavior with a nested function.
NOTE: Look at the list of predefined colors in the Pyret Documentation to see what options you have.
It turns out that your game-enthusiast friend Sofia wants nothing more than to buy and play Monopoly. However, before she can buy Monopoly, Sofia would like a doughnut (everyone gets hungry!). Good thing Sofia is a big advocate for local businesses and wants to visit all the local doughnut shops in Providence!
How do we distinguish local shops from those in national chains? One way is to find all the doughnut shops and see which ones have names that appear many times in the dataβ-local shops will have fewer entries in the list. A frequency-bar chart would show us this answer visually, but what if we had to compute this information from a list of names of doughnut shops, rather than read it off of a frequency-bar-chart?
By imporating lists as L, we can use a collection of operations on tables and lists.
L.member
L.distinct
L.map
L.filter
L.length
get-column
(tables)filter-with
(tables)order-by
(tables)TASK: Write an expression that gets the list of all donut shops from the original table.
Something to keep in mind: There are two spellings for the tasty dessert of interest: donut and doughnut. Be aware of this when you are looking for businesses.
TASK: Based on inspecting the list of donut shops, determine which shops are local or a chain. We'll consider a doughnut shop to be local if it has no more than 2 locations in the pvd-businesses
table.
Filter out the chain donut shops to create a list called donuts-lst
of names of local doughnut shops.
Remember to write out your list of tasks first and use that to guide your work.
TASK: Filter the original pvd-businesses
table to only include donut shops (both local and chain).
TASK: On this filtered table, add a color column where local stores are red and chain stores are black.
TASK: Using the table-to-map
function and your updated table, create a map that highlights all of the donut shops in their correct colors.
Now that Sofia got her doughnut, she is ready to purchase Monopoly. Unsatisfied with how few stores sell them in Providence, Sofia decides to open her own game store. After conducting a survey of existing options, she's created a list of the most popular board games. With Monopoly, Sofia can finally have fun!
Write a function create-token(token-colors :: List<String>) -> List<Image>
that takes in a list of strings representing valid colors and produces a list of game tokens of these colors. Each token should have this shape, but with its index-specific color and a yellow star:
Each token should also have a randomly generated size, such that its radius is between 15-35 units.
HINT: Take a look at the List operations from part 3.1.
Discuss why you think lists are being used in this problem as opposed to tables. When would it be preferable to use tables over lists?
Sofia has discovered that the ideal token size has a radius within 20-30. She wants to discard all of the token images that are outside of that range and make display signs out of the rest.
Write a function generate-token-signs(token-images :: List<Image>) -> List<Image>
that takes in the output list from create-token
. This function should remove all of the tokens that lie outside of the size range and put the remaining token on square backgrounds. This is what an output list item should look like:
HINT: look at the image-width
function in the documentation when making the function
Sofia finally bought her new token! Hooray! As a gift, she has provided you with a $5 gift card for her game store! Business at Sofia's store is booming, all thanks to you.
Brown University CSCI 0111 (Spring 2022)
Do you have feedback? Fill out this form.