Assigned: Thursday, 8 September
Due: Wednesday, 14 September, 11:59 p.m.
Joe Dator, The New Yorker, 21 July 2014
Create a new file named asmt02.arr
on Pyret.
Do not put your name in your assignment; we want to grade anonymously.
You will be graded on following good Pyret style and having examples that cover a variety of situations. Read the Testing and Style Guidelines for details.
Try to write your tests before filling in your functions, so you can quickly tell if they are working correctly.
The Pyret documentation is accessible from the pirate button in the top left corner of code.pyret.org.
Your friendly coaches and professor are here to help with this assignment! Check coaching hours and my office hours.
Winifred is the owner of a sporting goods store in Poughkeepsie. Recently she’s seen advertisements for a competitor all over town. Afraid of losing business, Winifred hires the Vassar Bros. Ad Agency for help.
The agency recommends targeting people living nearby who would be able to get to a store in downtown Poughkeepsie. They decide specifically to target people with sporting interests in their twenties. The ad agency already has data on locals’ age, hobbies, town, and whether they have a car.
Task: Copy and paste these definitions into the top of your code:
TARGET-AGE = 25
TARGET-TOWN = "poughkeepsie"
TARGET-HOBBIES = "running, biking, walking, swimming"
These definitions are for global variables, which are variables (names) created outside of a function, which are accessible to all functions throughout the program. They are normally defined in the top of the program and are distinguished from local variables by having upper-case names.
Next, let’s help the ad agency figure out what customers fit Winifred’s criteria. We want to write a function that takes a person’s age, hobby, town, and car status and determines whether or not Winifred should send them an ad.
To do this, we first need to figure out more information about them.
To decide if someone is a good potential customer to advertise to, we’ll write a series of predicates – functions that return the Boolean values true
or false
. Make sure to write examples for each function before you try writing the function body.
Let’s start by writing a function to see if any potential customer is within five years of Winifred’s target age.
Task: Define the function
fun within-5(age :: Number) -> Boolean:
...
end
It should return true
if the input, age
, is within five years of TARGET-AGE
and false
if not.
(Check out the Number documentation!)
This should be an inclusive comparison, meaning that if the target age is exactly five years older or younger than the target, the function should return true
.
Since Winifred is looking for a variety of interests that customers might have, we want to see if a customer’s interest is one of her target hobbies.
Task: Define the function
fun hobby-relates(hobby :: String) -> Boolean:
...
end
It should return true
when the input hobby is contained in TARGET-HOBBIES
and false
otherwise.
(Check out the String documentation!)
Winifred wants to be able to see if a person’s town is within the general area of her store. However, TARGET-TOWN
only gives us a specific place! To solve this issue, we need to write a function to check if a certain location is in the target town or its surrounding area.
Task: Define the function
fun in-area(town :: String) -> Boolean:
...
end
It should return true
if the input is "hyde park"
, "pleasant valley"
, "poughkeepsie"
, or "lagrange"
(the towns around her store), and false
otherwise.
Hint: The input "park"
should return false
even though "hyde park"
is one of the towns. Consider: Why is this the case? What makes this different from the task above where we check if global variable TARGET-HOBBIES
contains a particular hobby?
Now we can find out if someone lives in the area, but Winifred knows that people can only get to her store if they live in the target town itself or if they can drive to the target town from another town in the area.
Task: Define the function
fun in-range(town :: String, has-car :: Boolean) -> Boolean:
...
end
The inputs represent a customer’s town and whether they have a car or not. The function should return true
if the input town is TARGET-TOWN
or if the input town is in the target area and the person also has a car. Otherwise, the function should return false
.
Hint: Can you reuse any of the functions that we already wrote?
Now it’s time to put all the criteria together to determine whether an ad should be shown to a potential customer or not!
Task: Define the function
fun show-ad(age :: Number, town :: String,
hobby :: String, has-car :: Boolean)
-> Boolean:
...
end
The inputs are information about a potential customer, and the output is true
when
TARGET-TOWN
or they have a car and their town is within the target area, and TARGET-HOBBIES
.Otherwise, the output is false
.
Hint: Consider previous tasks you have completed! Make sure to avoid redundant code or functions that do the same thing!
A different way of targeting ads is looking at keywords in the text of the advertisement rather than specific criteria like Winifred’s target definitions.
Task: Define the function
fun show-ad2(ad :: String, age :: Number) -> Boolean:
...
end
The input ad is the text of an ad and age
is a person’s age. The function should return true
if any of the following conditions are met:
Otherwise, it should return false
.
Remember that programs aren’t just written for computers to run; they’re also for people to read. Just as there is good style for writing an English essay, there is good style for writing a program.
Task: Take a moment to go back through the functions you’ve written:
If not, do so now!
Do any of your functions look like this?
if some-question:
true
else:
false
end
This is very common, especially if you’ve used other programming languages before. However, the if
–else
is redundant; you could just write some-question
and get the same result!
Task: Remove any redundant if
expressions!
Task: Copy the following check
block into the bottom of your program:
check "Functions exist and have correct inputs":
within-5(0)
hobby-relates("")
in-area("")
in-range("", true)
show-ad(0, "", "", true)
show-ad2("", 0)
end
A check
block is similar to a where
block, but not attached to an individual function. This check
block ensures that you’ve included all the required functions, named correctly, and that they handle inputs in the right order.
If you see this block appear in the interactions window after running it, then you are fine:
Instead, if you see one of these screens, please check your function names, input types, and input order:
Let’s think a bit about the two approaches we’ve implemented for matching ads to people, show-ad
and show-ad2
.
Task: Respond to the following questions:
You can put your answers in a multi-line comment
#|
Like
this
one!
|#
at the bottom of your program.
Task: In another multiline comment, write at least two test examples that demonstrate weaknesses of show-ad
and at least two test examples that demonstrate weaknesses of show-ad2
.
The output from each function for each input should be surprising given the input. That is, an ad could seem perfect for the customer, but the function would output false
because of a limitation of its design or vice versa. Remember that ad-text
could be a String containing multiple words!
Beyond teaching you technical skills around computing and data, CMPU 101 also wants to help you think about the broader societal issues surrounding them.
Task: Read the article “These Ads Think They Know You” on the kinds of information that advertisers are able to access and use when targeting ads to users. (You have free access to the New York Times as a Vassar student. Follow these directions to set up your account!)
Task: Answer the following prompts using your own Google ad-matching information or – to protect your privacy – the sample shown below (from a real person). Your answers can go in a multiline comment at the bottom of your program.
Information that a search engine has on you comes from a combination of
Identify one piece of ad-matching information of each type. Your answer should look like “X likely comes from the profile, Y likely comes from browsing history, etc.”
Pick one piece of ad-matching information that could have come from multiple sources. Give 2–3 concrete examples of online activities (e.g., “searched for X”) that might have associated that ad-matching label with the account.
Pick two pieces of ad-matching information, which can be the same or different from what you used in the last question. For each, describe
Reference at least two of the following criteria somewhere in your response:
There’s no right or wrong answer here. Our goal is to get you thinking about the context of the technical content of the course. Your answer should be clear and concise, with enough specifics to show that you are thinking about the question beyond a surface level.
This part is entirely optional and will not be graded, but you may find it rewarding to try!
When we use a search engine, ads related to those searches sometimes appear in the same window. That suggests that the content of our search terms (also known as “queries”) might be used to select ads. For this problem, you will work with a simple version of this setup.
Assume that an ad is an arbitrary String and that a query can have up to three words (such as “bike”, “store”, “vassar”). We want to rate an ad for how well it fits these three words. We will score each word against the ad. A word contributes a score of 1 if it (or a simple modification to it) appears in the ad; otherwise it contributes 0. The rating for an ad against the whole query is the sum of the ratings for each of the three query words divided by the length of the ad String (in characters).
For this question, we will consider modifications that make a word singular (by removing an “s” from the end, e.g., "helmets"
→ "helmet"
) or turn a gerund into a verb (by removing “ing” from the end, e.g., "skateboarding"
→ "skateboard"
). This means that any of the query words can score against an ad with or without an ending removed.
Task: Complete the following function:
fun rating(ad :: String,
wd1 :: String, wd2 :: String, wd3 :: String) -> Number:
...
end
Your work should emphasize two skills:
This question doesn’t earn any points. It is meant to let you fine-tune your skills at structuring code and developing good sets of examples to illustrate a problem.
Download your file (File → Download) and ensure it’s named asmt02.arr
.
Upload your assignment on Gradescope.
Part 1 will be automatically graded when you submit your assignment, but your final assignment grade will be determined by your instructor when they review your work, including checking the programming style (Part 2) and reading your answers for Part 3 and Part 4.
You can submit as many times as you want before the deadline. Only your latest submission will be graded.
This assignment is adapted from Kathi Fisler and colleagues at Brown University.