Homework 3: Row, Row, Row

Due: Tuesday, September 28, 2021 at 9:00PM ET.

Setup and Handin

Setup

  • Task: Create a file in Pyret called hw3-code.arr. You will write your solution in here. You will need to copy and paste the following at the top of the file.
    ​​​​provide *
    ​​​​provide-types * 
    ​​​​include shared-gdrive("dcic-2021", "1wyQZj_L0qqV9Ekgr9au6RX2iqt2Ga8Ep")
    ​​​​include tables
    
  • You will be graded on the quality of your tests for each function.
    What does this mean?
    • High-quality tests cover the simple/basic cases for each parameter, values at/around any boundaries mentioned in the problem statement, common cases, and potentially subtle cases (e.g., strings with two uses of a character where a function is looking for one use).
    • You do not need to include tests for erroneous inputs (such as negative numbers if only positives make sense for the problem).
  • Do not put your name anywhere in the file.

Handin

  • Download both your solutions file and your test file (instructions about creating the test file are in Part 2) and make sure they are called hw3-code.arr and hw3-tests-examples.arr respectively. Hand in your work on Gradescope.

Remember your resources!

Useful Functions
  • not is a builtin function that takes a Boolean, and inverts it: not(true)false and not(false)true
  • == is an equality test; 3 == 3true and 3 == 4false.

The Assignment

Part 1: Nicknames

Learning Goals:

  • To practice writing functions using string functions and boolean operators
  • To practice using documentation to find useful built-in functions

Annie, Erick, Ashley, and Ryan decide to give each other nicknames. Each nickname is formatted as a String in a specific way by pairing a real name and a nickname with diamond brackets and a comma. There are some strict conditions for which nicknames are allowed!

Requirements for a valid nickname pair String:

  • The first and last characters of the String must be < and > respectively
    Hints
    • What characters (by position) of the String are we looking at? Which string library function can look at specific positions/characters in a String?
  • The String must have a comma as its middle character (with the same number of characters on either side)
    Hints
    • What does this tell us about the length of the string? Can it be even? Here's a function to check if a number is odd or not, but you don't need to use it.
      ​​​​​​fun is-odd(n :: Number) -> Boolean:
      ​​​​​​​​  doc: "Checks if a number is odd"
      ​​​​​​​​  not(num-modulo(n, 2) == 0)
      ​​​​​​end
      
    • How can we check that the middle character (by position) is a comma? Start by finding the index of the middle character.
    • The function num-floor() might be useful.
  • The name and/or nickname must contain the letter "a" somewhere in it (case sensitive)
    Hints
    • Take a look at Homework 2 and see how you checked if a String was contained in another String.
  • The name or nickname CANNOT contain the sequence "curse" (case sensitive) (Annie, Erick, Ashley, and Ryan are very superstitious!)
    Hints
    • Something like "<acu,rse>" would be valid because the comma interrupts the sequence, but something like "<ashley,curser>" would be invalid.

Task: Write the function nickname-check in the file hw3-code.arr. nickname-check will take in a String (the name-nickname pair), and output a Boolean that indicates whether or not the input pair is allowed. Make sure to include a doc string, input/output type annotations, and a where block.

Note: Being able to look in language documentation for useful operations is an important skill, which is why we aren't telling you exactly which String operations to use. We want you to look at the String documentation to find useful operations for solving this problem. However, limit yourself to operations with input and output types that we have used this semester (Number, String, Boolean). Don't use operations that return List, as we haven't covered that yet.

Part 2: Practice Writing Comprehensive Tests

Learning Goal:

  • To practice developing a comprehensive set of tests for a function

After Homework 2, business is picking up, and Pedro is looking to expand his staff! He wants to purchase software to help him score resumes based on the candidate's current job title. There are several products available, and Pedro doesn't know which one to pick. He decides to create a collection of tests that describe the decisions he wants the software to make. He'll run his tests against the various tool options as a way to rule out products that don't suit his needs.

You are going to help Pedro design a good set of tests that capture his goals. You are NOT writing any functions for this part.

Pedro wants to give each product a string (consisting of a job title) and get back a number (representing a score of that title against Pedro's needs).

  • Scores are determined by words that appear in a job title. Here are the scores associated with the specific jobs that Pedro is tracking: (the higher the score, the better it matches his criteria)
    • 5 for “marketing”, 4 for “artist”, 3 for “media”, 2 for “writer”, and 1 for “editor”
    • Job titles with none of these terms score 0
  • Capitalized keywords should be matches (e.g. "Marketing associate" matches), but the keyword should not be a part of another word (e.g. "editorial assistant" does not match)
  • If there are two (or more) keywords in the job title, output the score for the higher of the keywords

Your job is to capture these goals in a set of tests, such as

resume-ranker("editor") is 1

where resume-ranker is a function provided in the software product that Pedro is testing.

We are providing a custom version of Pyret that has the code for the different software products. Pyret will run your tests against each of the products.

Task: Click this link to access the custom Pyret version. DO NOT click "Begin Implementation".

Pyret/Examplar not loading?

Try removing permissions for Pyret@Brown from your Google account. You can do this by going to Manage your Google Account, searching "apps" in the search bar on top of the page, and removing permissions for Pyret@Brown. Then, revisit the link, log in, and re-allow permissions. If you have any questions, post in Ed or come to hours!


Task: Fill in the check block with your tests (Reminder: you aren't writing resume-ranker, only tests). As you add tests and hit "Run", the report in the interactions window will show you how many unsatisfactory software products you've ruled out.

What's going on here?

We have seven different versions of that function behind the scenes (one from each competing software company). You are going to enter your tests in this custom version of Pyret that has access to the seven versions. This version of Pyret will give you a report indicating whether your tests express what Pedro wants, as well as how many of the versions you have ruled out.

What's the goal?

Your goal is to eliminate as many of the products as you can. There is one product that satisfies all of Pedro's requirements. The other six are each off in some way. As your tests get more comprehensive, you'll knock out more of the unsatisfactory ones.

Do I need to knock out all of the unsatisfactory products?

You don't have to knock out all of the unsatisfactory products to do well on this. This is our first exercise that focuses on designing good tests. This week, we're trying to build up your experience writing tests. Aim to knock out at least four, and see if you can get all the way to knocking out all six.


Task: Download your tests file. If it downloads as a .zip file, unzip it to retrieve the Pyret file. Make sure your file is called hw3-tests-examples.arr. This will be submitted along with hw3-code.arr to Gradescope. If you also see a downloaded file called hw3-code-ignore.arr, feel free to disregard this file.

Part 3: More sophisticated ad matching

Learning Goals:

  • To give you practice accessing data from tables
  • To help you understand the benefit of bundling small pieces of data into one larger piece of data

In Homework 2, we wrote a show-ad function to help Pedro match ads to users. It had the following header:

fun show-ad(age :: Number, town :: String, hobby :: String, has-car :: Boolean) -> Boolean:
  doc: "figure out whether or not to show this customer the ad"
 ...
end

In reality, ad-matching systems check dozens of pieces of information about users, not just four. Does that mean real ad systems have functions with 40-50 parameters? No!

Instead, real ad systems bundle multiple pieces of information about a user together to make it easier to handle. This week, we look at tables to do that bundling. The information about one user would then be a row in the table.

We want to update our show-ad function to work with individual rows, rather than separate pieces of information. Specifically, we wantshow-ad to look like:

fun show-ad(user-info :: Row) -> Boolean: 
  ...
end

where the user-info is a row from a table of user data which has columns for age, town, hobby, and has-car.

Part 3A: Rewriting show-ad to use Rows

Note: It is extremely important that you make sure to use the CS0111 Table documentation, not the official Table documentation. This includes the documentation for Rows, which is necessary for this assignment.

Note: To help you rewrite show-ad, we are providing our solutions to its helper functions from hwk 2. They are in a file called hw3-helper.arr, which is available in the Files area on Canvas. Do not look at hw3-helper.arr before you turn in Homework 2. We can tell when you look at something, and we'll be checking to see who peeks.

How do I open hw3-helper.arr?

Download this file from Canvas. You can open it in a plain-text editor (e.g. TextEdit, WordPad) to copy and paste into your hw3-code.arr file. If you want to see it in Pyret, navigate to code.pyret.org and hit "View in Google Drive". Once You're in the Google Drive folder, drag and drop the file in, right click on it > Open with > Pyret.


The helper code contains the table CUSTOMERS:

CUSTOMERS = table: age :: Number, town :: String, hobby :: String, has-car :: Boolean 
  row: 21, "oatman", "swimming", false 
  row: 21, "kingman", "swimming", true 
  row: 21, "kingman", "swimming", false  
  row: 21, "providence", "swimming", true  
  row: 18, "oatman", "swimming", true  
  row: 21, "oatman", "reading", true
end

Task: Using these global variables and helpers, write a new version of show-ad which takes in a Row and outputs a Boolean. You may assume that the input Row comes from the provided table (and thus has its column names).

As a reminder, show-ad returns true when within-5 and hobby-relates and in-range are all true; otherwise, it returns false.

Hint: To get a particular cell of a Row, use square bracket notation like this: my-row["column-name"].

Task: Make sure to include tests for show-ad in a where block. To get an input Row to call show-ad on, you can get any Row from the global variable CUSTOMERS by using row-n. For example, CUSTOMERS.row-n(0) will give you:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Clarified 9/27: Given that we haven't gotten to discuss this issue much in lecture yet, we will not grade the quality of your where block on hwk3. It is still a good idea for you to try to write one to get a sense of the structure, but you won't be graded on it. We'll come back to this in hwk4.

Part 3B: Excluding what the ad doesn't care about

Learning Goals:

  • To start to look at how to handle blank or missing data in tables

Sometimes, an ad company doesn't have the information for all of the cells for a given users. In this case, some cells of the table might be blank. For the purposes of this assignment, we consider a String to be blank if it is an empty string (which we write as "") and a Number to be blank if it is negative.

Task: Modify the relevant helper functions (for show-ad) to handle blank values for the hobby and age columns. The challenge here is to figure out when and how to handle these blanks. You do not need to handle blank cases for anything besides hobby and age.

Make sure to add relevant tests using blank values to the where blocks for any helper functions you edit and to show-ad to document this functionality. Since none of the rows in CUSTOMERS have blank values, you can add some rows to our definition of CUSTOMERS and access those with row-n.

Task: Could you do something similar to using "" for a blank String or a negative number for a blank Number in order to handle blank values for the column has-car? Why or why not? Are there other downsides to taking this approach? Write a comment under show-ad answering these questions.

Part 4: What Your Car Won't Tell You

Learning Goals:

  • To learn about ways data are gathered about us beyond web browsing
  • To think about the implications of data tracking

Web browsers aren't the only kinds of tools that are gathering data about us. Data-enabled devices have access to a lot of data about us. What is getting collected, and what control might we have over this collection?

Task: Read the article “Your Car Knows When You Gain Weight” on how the objects we use are also collecting data on us, and who has the rights to use those data. (You can use this guide to access the New York Times through a free academic pass if needed.)

Task: Go to this separate gradescope assignment to answer several questions regarding this article.

There is no right or wrong answer here. For this assignment, we are having you practice being concrete in talking about the context of computing technology and identifying potential impacts of data collected by objects around us.

Task: Please add a comment at the bottom of your code file with the approximate number of hours you spent on this homework. This will be used only to average how long the homeworks are taking students this semester, and it is completely anonymous. Thank you for working to help us improve this class as we grow!

Theme Song

Row Row Row Your Boat by Eliphalet Oram Lyte


Brown University CSCI 0111 (Fall 2021)
Do you have feedback? Fill out this form.