Assigned | Thursday, 1 February |
Due | Wednesday, 7 February, 11:59 p.m. |
Targeted advertising is a real-world example of how data, computation, and social impacts come together. With this assignment, we want you to develop a basic understanding of how these systems work.
Contents
- Assignment guidelines
- Introduction: Representing ads
- Part 1: Targeted ads
- Part 2: Pyret style and testing check
- Part 3: Differences and limitations
- Part 4: Personal data and privacy
- Challenge exercise
- Check block (autograder compatibility)
- Submitting the assignment
Assignment guidelines
Create a new file named
asmt02.arr
on code.pyret.org (CPO). Do not put your name in your assignment or the filename; we want to grade anonymously.As always, your friendly coaches and professor are here to help with this assignment! Check coaching hours and your professor’s office hours.
Introduction: Representing ads
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 first step in processing something with a program is to represent that thing in terms of focused, discrete pieces of data. For this assignment, we will use three pieces of information to represent an ad:
- the age of person it targets,
- the location of the event, and
- the kinds of activities it involves.
We’ll start by thinking about the simplest form of matching ads: writing explicit conditional expressions to see whether a person is in the target audience for a single, fixed ad. Therefore, we can store the information about the ad in three constants:
TARGET-AGE = 25 TARGET-TOWN = "Poughkeepsie" TARGET-HOBBIES = "running, biking, walking, swimming"
Task: Copy and paste these definitions into the top of your code.
Part 1: Targeted ads
Next, let’s help the ad agency figure out what customers are good
matches for Winifred’s ad. To decide if someone is a good
potential customer for Winifred 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.
Exercise 1: Age
Let’s start by writing a function to see if any potential customer is within five years of the ad’s target age.
Task: Define the function
fun within-five(age :: Number) -> Boolean: ... end
It should return true
if the input,
age
, is within five years of TARGET-AGE
and
false
if not.
You may want to refer to 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
.
Exercise 2: Interest
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 for the ad.
Task: Define the function
fun hobby-relates(hobby :: String) -> Boolean: ... end
It should return true
when the input
hobby is contained in TARGET-HOBBIES
(that is,
it’s a substring) and false
otherwise.
You may want to refer to the
String
documentation.
Exercise 3: Location
Winifred also wants to match a person to the ad based on their
location, since they need to be able to get to 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 is-nearby(town :: String) -> Boolean: ... end
It should return true
if the input
is "Hyde
Park"
, "Pleasant
Valley"
, "Poughkeepsie"
,
or "LaGrange"
,
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 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 (so they can walk) or if they can drive to the target town from another town in the area.
Solving this problem gives us a chance to practice using functions to write other functions.
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 nearby and the person also has a car.
Otherwise, the function
should return false
.
Do not repeat the code you already wrote
in is-nearby
!
Exercise 4: Combining criteria (coach-free)
Now it’s time to put all the criteria together to determine whether the 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
- their age is within five years of the target age (inclusive),
- their town is the
TARGET-TOWN
or they have a car and their town is nearby, and - their hobby is contained in
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!
Part 2: Pyret style and testing check
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.
Starting with this assignment, 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.
Task: Take a moment to go back through the functions you’ve written:
- Did you write a docstring for each function?
- Do you have examples that demonstrate the functions work as intended?
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!
Part 3: Differences and limitations (coach-free)
Let’s think a bit about the approach we just implemented for matching ads to people.
Task: Respond to the following questions:
- How do you think these functions differ from how real ads are targeted?
- Think about the way we set up the code and the programming
operations that we used:
- What are the limitations of our current code/operations for evaluating ads?
- What would you want to be able to do in code to do a better job of targeting ads?
You can put your answers in a multi-line comment
#|
Like
this
one!
|#
Task:
In a check
block (just like a where
block but
not attached to any particular function), write two examples
using show-ad
, demonstrating a situation in which the
function would output false
(because of a
limitation of the function), even though the ad would otherwise seem a
good match for the person.
A check
block is like a where
, except
it’s not attached to the definition of a particular function.
For example,
check: show-ad(...) is false ... end
Part 4: Personal data and privacy (coach-free)
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. 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
- your profile and
- assumptions that the search engine makes about you based on your browing history, users that are similar to you, etc.
3 points Identify three pieces of information that are inferred about you by Google and two ways that Google inferred that information. Your answer should look like “X likely comes from a search I made and Y piece of information. Z likely comes from A and B.”
-
4 points 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
- one possible use which is beneficial or benign, and
- one which you believe is problematic, unethical, or harmful.
Your answer could look like “Google knows I like hybrid alternative vehicles; one benefit is X and one harm is Y.”
Reference at least two of the following criteria somewhere in your response:
- Intent/purpose (academic research vs targeted ads)
- If the data is public, does that mean it can be used in any way?
- Timing (e.g., data set from a decade ago)
- Attributes collected (e.g., those protected by law from discrimination such as religion, race, age, or disability)
- Inference potential: What might this information help companies infer about you?
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.
Challenge exercise (coach-free)
In reality, ad-matching systems check dozens of pieces of information
about users, not just four like show-ad
did. 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. For example, the information about one user could be a row in a larger table of potential customers. When you’re working with tables, refer to the CMPU 101 Table documentation rather than the Pyret documentation.
Our goal is to update the show-ad
function to work with
individual rows, rather than separate pieces of information.
Specifically, we want the inputs of show-ad2
to look like:
fun show-ad2(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
.
Task: Since you’ll be working with tables, at the top of your file, add the line
include shared-gdrive("dcic-2021", "1wyQZj_L0qqV9Ekgr9au6RX2iqt2Ga8Ep")
Task: Copy this table definition into your program:
CUSTOMERS = table: age, town, hobby, has-car row: 21, "Poughkeepsie", "swimming", false row: 29, "LaGrange", "swimming", true row: 25, "Hyde Park", "swimming", false row: 27, "Beacon", "swimming", true row: 93, "Poughkeepsie", "swimming", true row: 20, "Poughkeepsie", "reading", true end
Task:
Using these constants and helpers, write show-ad2
that
takes a user Row and returns a Boolean. This new version
of show-ad
should extract needed data about the user from
the given Row.
As a reminder, show-ad2
returns true
when the customer’s age is
within 5 of TARGET-AGE
, the customer lives
in TARGET-TOWN
itself or within the surrounding area and
has a car, and TARGET-HOBBIES
contains the customer’s
favorite hobby. The output is false
otherwise.
Be sure to write tests for show-ad2
in
its where
block.
Note: Figure out how to use the previous functions that you’ve written as helpers for this problem. You only need to write a bit of additional code for this problem. Think about how to break the problem down in a way that you can reuse the functions you’ve already written.
Check block (autograder compatibility)
Task:
Copy the following check
block into the
bottom of your program:
check "Functions exist and have correct inputs": within-five(0) hobby-relates("") is-nearby("") in-range("", true) show-ad(0, "", "", true) end
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 did the challenge exercise, you can add these lines to the
check
block:
t1 = table: age, town, hobby, has-car row: 0, "", "", false end show-ad2(t1.row-n(0))
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:
Submitting the assignment
- Download your file (File → Download) and ensure
it’s named
asmt02.arr
. - Upload your assignment on Gradescope.
Most of the functions (in Part 1 and the challenge exercise) 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 and tests (Part 2) and reading your answers for Part 3 and Part 4.
Note: You can submit as many times as you want before the deadline. Only your latest submission will be graded.