Homework 7: Shawn and Todd’s Election Extravaganza
Due: Tuesday April 14, 2020 at 9:00PM EDT.

Setup and Handin
Setup
- This is our first time using Pycharm! Yay! You have a choice: you can either create a new project in Pycharm for ALL your files, or create a new project for each homework. Just make sure to include
testlight.py
into each project you create.
- Pycharm Installation and Project Setup
- Python Testing and Clarity Guide (including
testlight.py
download instructions)
Handin
- Download your file and make sure it is called
hw7_code.py
. Hand in your work on Gradescope, making sure to use your anonymous account.
Remember your resources!
The Assignment
If you know how to solve any of these problems using techniques you’ve learned outside of 111, don’t! Make sure to only use Python concepts we’ve talked about in class.
Create a new Python file called hw7_code.py
.
Sheriff Todd’s Election
An election is happening in the out-west Far Far Away region, and Sheriff Todd needs help counting the votes. Deputy Shawn is making a mess in the election between Shr Ek and Don Key, and he needs your help to ensure a peaceful transition of power!
For the following, you can assume a vote is just the name of a candidate (though capitalization might be inconsistent!)
-
Task: Write a function name_matches
that takes a vote
(string) and a name
(string) and returns a boolean indicating whether the vote is for the given name, regardless of how the vote and name have been capitalized (that is, ignore case).
Note: You can lowercase a string s
in Python by writing s.lower()
(where s
gets replaced by the string you want to lowercase). As in Pyret, you have Boolean operators and
, or
, and not
.
-
Task: Write a function any_votes_for
that takes a name
(string) and votes
(list of votes) and returns a boolean indicating whether any votes were for the given name (case insensitive).
-
Task: Write a function count_votes_for
that takes a name
(string) and a votes
, a list of votes, and returns the number of votes that were for the given name (case insensitive).
-
Task: Write a function got_more_votes
that takes two names, name_one
and name_two
, and votes
, a list of votes, and returns the name that got more votes (case insensitive). If there is a tie, return the string “Tie”
.
-
Task: Write a function record_vote
that takes in votes
, a list of votes, and new_vote
, a new vote, and adds the vote to the end of the list. This function should not return anything!
-
Task: Write a function percentage_votes
that takes a name and a list of votes and returns the percentage of votes that match (case insensitive) the given name. You should return the percent in decimal form (i.e. if the name matches 90% of the votes, return 0.9). Please round to the nearest tenth. Don’t forget to consider the case where someone has no votes (or where there are no votes)!
Rounding help!
You can round a number in Python using the round
function. The round
function has two arguments, the first being the number to round and the second representing how many decimal places to have. Here are a few examples:
# If you'd like to round to the nearest whole number
# Note: this will still produce a decimal not an Int
round(1.3446, 0) # produces 1.0
round(1.5111, 0) # produces 2.0
round(1.7934, 0) # produces 2.0
# If you'd like to round to the nearest tenth
round(1.3446, 1) # produces 1.3
round(1.5111, 1) # produces 1.5
round(1.7934, 1) # produces 1.8
# If you'd like to round to the nearest hundreth
round(1.3446, 2) # produces 1.34
round(1.5111, 2) # produces 1.51
round(1.7934, 2) # produces 1.79
round(1.799, 2) # produces 1.8
-
Task: Write a function test_votes
to test your vote functions. In particular, think about how to test record_vote
. Run test_votes()
to make sure all your tests pass and your functions work as expected.
Note: Any time you are returning a name, it may be returned lowercased or uppercased. Our test suite is case insensitive, so returning "Credo"
will be treated the same as "credo"
and "CREDO"
. Same applies for functions that return lists. ["Cre","Credo"]
will be treated the same as ["cre","CREDO"]
.
Sorting Lists in Python
Here we have a lot of information to help with these questions. They’ll be quite difficult to do without reading these first.
String slicing
To do many of the following problems, you will need to do something called string slicing. String slicing is the Python equivalent of Pyret’s string-substring
, but winds up being a lot more powerful.
Let’s say you have the string str = "Beep!"
. Just like in Pyret, strings in Python are 0-indexed:
- The “B” is at index 0
- The "e"s are at indices 1 and 2
- The “p” is at index 3
- The “!” is at index 4
To access the characters at those indices, use the notation: str[index]
. For example,
>>> str[0]
"B"
>>>str[4]
"!"
If you want to slice a string into a substring of more than one character, use the notation: str[start:end]
where start
represents the first index of the substring (inclusive) and end
represents the last index of the substring (exclusive). For example,
>>> str[0:5]
"Beep!"
>>> str[1:4]
"eep"
>>> str[2:3] # note that this is equivalent to str[2]
"e"
>>> str[2:2] # no characters in range, so this outputs the empty string
""
That’s all you need to know for this assignment, but Python has a few additional shortcuts for string slicing that might be useful in the long run:
-
If you leave off the start or end index, Python assumes you want to start at 0 and end at the end of the string:
>>> str[:3] # equivalent to str[0:3]
"Bee"
>>> str[3:] # equivalent to str[3:5]
"p!"
>>> str[:] # equivalent to str[0:5]
"Beep!"
-
Negative numbers let you index from the end of a string
>>> str[-1] # equivalent to str[4]
"!"
>>> str[-5] # equivalent to str[0]
"B"
>>> str[-3:-1] # equivalent to str[2:4]
"ep"
Basic sorting
Python has a useful and customizable sorting function that operates on lists. In this section, we will explore how to use it.
The simplest version of the function is sorted(lst: list)
, which takes in a list and sorts it in ascending order.
- Lists of integers are sorted numerically
- Lists of strings are sorted alphabetically
- Lists of booleans are sorted with all Falses before all Trues
For example:
>>> sorted([1,5,3,1])
[1,1,3,5]
>>> sorted(["bc", "abc", "d", "aa", "aaa"])
['aa', 'aaa', 'abc', 'bc', 'd']
>>> sorted([False, True, True, False, True])
[False, False, True, True, True]
To sort a list in descending order, add the input reverse=True
to the function call. Here are the examples from above but sorted in reverse:
>>> sorted([1,5,3,1], reverse=True)
[5,3,1,1]
>>> sorted(["bc", "abc", "d", "aa", "aaa"], reverse=True)
['d', 'bc', 'abc', 'aaa', 'aa']
>>> sorted([False, True, True, False, True], reverse=True)
[True, True, True, False, False]
Note: Notation like reverse=True
is used for optional inputs to a function, a concept we did not see in Pyret. Since an optional input might not be provided, we need the <name>=
part to indicate which optional parameter is being used.
Custom sorting
In most cases, default sorting is enough. However, what if you want to sort a list in a specific, custom way? To do so, add the input key=my_fun
where my_fun
represents a function that takes in a single list element. my_fun
is called on each element in the list, and its output determines the sort order.
Let’s take a look at a concrete example. The following function takes in a string and returns its length:
def key_fun(elem: str):
return len(elem)
With key_fun
defined, we can do the following to sort the list by string length:
>>> sorted(["Bridgette", "does", "love", "sorting", "lists"], key=key_fun)
['does', 'love', 'lists', 'sorting', 'Bridgette']
(Note that since string length is an integer, sorted
defaults to sorting the elements in increasing order)
Emergency Organization
Just as the results of the election are about to go out, Deputy Shawn drops all of the ballots on the floor.
For all of the following functions, you can assume that all names have at least three letters. This means that none of your tests cases should have names less than three letters.
- Task: Write a function
first_three_letters(name: str, votes: list)
that takes in a candidate name and all votes and returns a list of all votes for candidates with the same first three letters in their name as name
(regardless of capitalization).
- Task: Write a function
test_first_three
to test first_three_letters
.
- Task: Write a function
sort_a(votes: list)
that returns votes
sorted alphabetically by the first letter in candidate’s names.
- Task: Write a function
test_a
to test sort_a
.
- Task: Write a function
sort_b(votes: list)
that returns votes
sorted alphabetically by the second letter in candidate’s names. You can assume all strings in votes
will be at least two characters long.
- Task: Write a function
test_b
to test sort_b
.
Theme Song
30 minutes of Wild Western Music by multiple artists
Brown University CSCI 0111 (Spring 2020)
Do you have feedback? Fill out this form.
Homework 7: Shawn and Todd’s Election Extravaganza
Due: Tuesday April 14, 2020 at 9:00PM EDT.

Setup and Handin
Setup
testlight.py
into each project you create.testlight.py
download instructions)Handin
hw7_code.py
. Hand in your work on Gradescope, making sure to use your anonymous account.Remember your resources!
The Assignment
If you know how to solve any of these problems using techniques you’ve learned outside of 111, don’t! Make sure to only use Python concepts we’ve talked about in class.
Create a new Python file called
hw7_code.py
.Sheriff Todd’s Election
An election is happening in the out-west Far Far Away region, and Sheriff Todd needs help counting the votes. Deputy Shawn is making a mess in the election between Shr Ek and Don Key, and he needs your help to ensure a peaceful transition of power!
For the following, you can assume a vote is just the name of a candidate (though capitalization might be inconsistent!)
Task: Write a function
name_matches
that takes avote
(string) and aname
(string) and returns a boolean indicating whether the vote is for the given name, regardless of how the vote and name have been capitalized (that is, ignore case).Note: You can lowercase a string
s
in Python by writings.lower()
(wheres
gets replaced by the string you want to lowercase). As in Pyret, you have Boolean operatorsand
,or
, andnot
.Task: Write a function
any_votes_for
that takes aname
(string) andvotes
(list of votes) and returns a boolean indicating whether any votes were for the given name (case insensitive).Task: Write a function
count_votes_for
that takes aname
(string) and avotes
, a list of votes, and returns the number of votes that were for the given name (case insensitive).Task: Write a function
got_more_votes
that takes two names,name_one
andname_two
, andvotes
, a list of votes, and returns the name that got more votes (case insensitive). If there is a tie, return the string“Tie”
.Task: Write a function
record_vote
that takes invotes
, a list of votes, andnew_vote
, a new vote, and adds the vote to the end of the list. This function should not return anything!Task: Write a function
percentage_votes
that takes a name and a list of votes and returns the percentage of votes that match (case insensitive) the given name. You should return the percent in decimal form (i.e. if the name matches 90% of the votes, return 0.9). Please round to the nearest tenth. Don’t forget to consider the case where someone has no votes (or where there are no votes)!Rounding help!
You can round a number in Python using the
round
function. Theround
function has two arguments, the first being the number to round and the second representing how many decimal places to have. Here are a few examples:Task: Write a function
test_votes
to test your vote functions. In particular, think about how to testrecord_vote
. Runtest_votes()
to make sure all your tests pass and your functions work as expected.Note: Any time you are returning a name, it may be returned lowercased or uppercased. Our test suite is case insensitive, so returning
"Credo"
will be treated the same as"credo"
and"CREDO"
. Same applies for functions that return lists.["Cre","Credo"]
will be treated the same as["cre","CREDO"]
.Sorting Lists in Python
Here we have a lot of information to help with these questions. They’ll be quite difficult to do without reading these first.
String slicing
To do many of the following problems, you will need to do something called string slicing. String slicing is the Python equivalent of Pyret’s
string-substring
, but winds up being a lot more powerful.Let’s say you have the string
str = "Beep!"
. Just like in Pyret, strings in Python are 0-indexed:To access the characters at those indices, use the notation:
str[index]
. For example,If you want to slice a string into a substring of more than one character, use the notation:
str[start:end]
wherestart
represents the first index of the substring (inclusive) andend
represents the last index of the substring (exclusive). For example,That’s all you need to know for this assignment, but Python has a few additional shortcuts for string slicing that might be useful in the long run:
If you leave off the start or end index, Python assumes you want to start at 0 and end at the end of the string:
Negative numbers let you index from the end of a string
Basic sorting
Python has a useful and customizable sorting function that operates on lists. In this section, we will explore how to use it.
The simplest version of the function is
sorted(lst: list)
, which takes in a list and sorts it in ascending order.For example:
To sort a list in descending order, add the input
reverse=True
to the function call. Here are the examples from above but sorted in reverse:Note: Notation like
reverse=True
is used for optional inputs to a function, a concept we did not see in Pyret. Since an optional input might not be provided, we need the<name>=
part to indicate which optional parameter is being used.Custom sorting
In most cases, default sorting is enough. However, what if you want to sort a list in a specific, custom way? To do so, add the input
key=my_fun
wheremy_fun
represents a function that takes in a single list element.my_fun
is called on each element in the list, and its output determines the sort order.Let’s take a look at a concrete example. The following function takes in a string and returns its length:
With
key_fun
defined, we can do the following to sort the list by string length:(Note that since string length is an integer,
sorted
defaults to sorting the elements in increasing order)Emergency Organization
Just as the results of the election are about to go out, Deputy Shawn drops all of the ballots on the floor.
For all of the following functions, you can assume that all names have at least three letters. This means that none of your tests cases should have names less than three letters.
first_three_letters(name: str, votes: list)
that takes in a candidate name and all votes and returns a list of all votes for candidates with the same first three letters in their name asname
(regardless of capitalization).test_first_three
to testfirst_three_letters
.sort_a(votes: list)
that returnsvotes
sorted alphabetically by the first letter in candidate’s names.test_a
to testsort_a
.sort_b(votes: list)
that returnsvotes
sorted alphabetically by the second letter in candidate’s names. You can assume all strings invotes
will be at least two characters long.test_b
to testsort_b
.Theme Song
30 minutes of Wild Western Music by multiple artists