Images
Grayscale
Write a function grayscale(filename) that takes in the name of an image file filename and returns a grayscaled version of that image. To grayscale an image, you can set each pixel's new R, G, B value to the average of all its current R, G, B values. Here's an example of what the original image might look like, and what the grayscaled version of this image would be.

Lists
Interesting List
Write a function make_interesting(num_list) that accepts a list of integers and returns a new list based on the given list. The new list should have each of the values in num_list as follows:
- if the integer in num_list is less than zero, the new list should not have this value;
- if the integer in num_list is greater than or equal to zero and odd, the new list should have this integer value with 10 added to it;
- if the integer in num_list is greater than or equal to zero and even, the new list should have this integer value unchanged.
- We'll consider the number 0 to be even.
Here are some sample calls to make_interesting and what should be returned.
>>> make_interesting([-2, 33, 14, 6, -13, 9, 2])
[43, 14, 6, 19, 2]
>>> make_interesting([1, 2, 3, 4, 5])
[11, 2, 13, 4, 15]
>>> make_interesting([-10, -20, -5])
[]
Collapse List
Write a function collapse(lst) that accepts a list of integers as a parameter and returns a new list containing the result of replacing each pair of integers with the sum of that pair. If the list stores an odd number of elements, the final element is not collapsed.
Here are some sample calls to collapse:
>>> collapse([7, 2, 8, 9, 4, 13, 7, 1, 9, 10])
[9, 17, 17, 8, 19]
>>> collapse([1, 2, 3, 4, 5])
[3, 7, 5]
Average Temps
Say you're given a list of lists, where each inner list contains the average temperatures from all 12 months of a year as floats. We want to find the average temperature for each year, and form a list of these annual averages.
Implement the function annual_temps(nested) that takes in a nested list of monthly temperature lists, and returns a (non-nested) list of the average temperatures from each year.
For example, given the following list:
month_values = [[1,2,3,4,5,6,7,8,9,10,11,12],
[3,0,0,0,0,0,0,0,0,0,0,0],
[12,0,0,0,0,0,0,0,0,0,0,0]]
annual_temps(nested) should return:
[6.5,
0.25,
1.0]
Graphics
Magic Wand
To simulate a magic wand on the cursor, we will draw a black rectangle that follows the user's cursor and emits yellow sparkles (circles) that float upwards. The bottom right corner of the magic wand is attached to the mouse, and this wand is a black rectangle with dimensions WAND_WIDTH by WAND_HEIGHT. Every timestep, a yellow circle with radius SPARKLE_RADIUS should appear at the top center of the wand, and move upwards with velocity SPARKLE_Y_VAL. Note that this velocity is just the magnitude, so to make the sparkles move upwards, you should move them in the negative velocity. You should write your code in an animation loop, so that the wand and sparkles continue moving around the screen at each timestep, with a delay of DELAY seconds. It's fine to have the sparkles move off of the screen; you don't need to do anything special to delete them after they move beyond the edge of the screen. You can start your wand off with its upper left at (0, 0).
Here are some screenshots from the program:

Strings
Password Maker
Write the function make_password(str) that takes in a string str and makes it into a password by replacing common letters with similar looking special characters.
- Any a's should become @'s,
- i's should become !'s,
- and o's should become 0's.
- This should be case-insensitive, meaning that the uppercase versions of these letters should also be converted to their special characters.
- However, make sure that any other characters that were originally uppercase stay uppercase in the returned value.
Here are a few sample calls of this function:
>>> make_password('HI!')
'H!!'
>>> make_password('this is a good password')
'th!s !s @ g00d p@ssw0rd'
Longest Consonants
Write a function longest_consonants(str) that takes in a string str and returns the longest number of consonants that appear in a row. We'll consider consonants to be letters that are not A, E, I, O, or U.
- If str does not contain any consonants, you should return 0.
- Your count should be case-insensitive, meaning your function does not distinguish between uppercase or lowercase letters when counting consonants.
-
There may also be non-alphabetic characters in str, which do not count as consonants.
- Hint: To check if a character is A, E, I, O, or U, you can check if that character is in the string 'AEIOU'.
Here are a few sample calls of the function:
>>> longest_consonants('rhythm')
6
>>> longest_consonants('what is the longest consonant here')
2
>>> longest_consonants('aaaaaa')
0
Dictionaries and File Reading
Grade Boost
Let's say that the CS106A instructors have randomly decided to give a 5-point bonus to students whose names begin with a certain letter. They've stored the test scores of every student in a dictionary, where the keys are student names, and the values are the scores that the student earned. For example:
students = {
'Ecy': 5,
'Chris': 20,
'Frankie': 40,
'Mehran': 20,
'Clinton': 40,
'Neel': 12
}
If the instructors choose to boost students whose names started with the letter 'C', this dictionary would become:
students = {
'Ecy': 5,
'Chris': 25,
'Frankie': 40,
'Mehran': 20,
'Clinton': 45,
'Neel': 12
}
Write a function grade_boost(students, letter), which takes in a dictionary of students like the one shown above and a letter indicating which students' names to boost, and updates the students dictionary to boost the corresponding grades by 5 points. You can assume the given letter will be uppercase, and all student names will start with an uppercase letter.
A sample call of the function is shown below:
>>> grade_boost({'Ecy': 5, 'Chris': 20, 'Frankie': 40, 'Mehran': 20, 'Clinton': 40, 'Neel': 12}, 'C')
{'Ecy': 5, 'Chris': 25, 'Frankie': 40, 'Mehran': 20, 'Clinton': 45, 'Neel': 12}
>>> grade_boost({'Student1': 10, 'Student2': 15}, 'F')
{'Student1': 10, 'Student2': 15}
Animal Counts
Let's say we had everyone in class vote on their favorite animals by entering an animal name into an online poll. The results were then put into a file so that each line of the file is an animal name and the number of votes it received. Here some some of the results:
Dog: 34
Bird: 20
cat: 14
Elephant: 7
dog: 5
CAT: 2
What we want to do is to read in the data from this file into a dictionary where the key is the animal name (string) and the value is the number of votes this animal got (integer).
Unfortunately, the polling mechanism didn't take into account that some people would capitalize the names of animals differently. Notice that above, “Dog” and “dog” each get their own score, but really we'd like to sum all the votes for each animal name in a case-insensitive way, so that we see that 39 people have “dog” as their favorite animal.
Your task is to write a helper function get_animal_counts(filename) that takes in a filename and returns a dictionary with the duplicate counts (for keys with the same characters but different capitalization) combined. The new keys should be all lowercase. Calling our helper function with the file above would return:
{
'dog': 39,
'bird': 20,
'cat': 16,
'elephant': 7
}
Finding Grandchildren
Implement a function find_grandchildren(parents_to_children), which is given the dictionary parents_to_children whose keys are strings representing parent names and whose values are lists of that parent's children's names. Create and return a dictionary from people's names to lists of those people's grandchildren's names.
For example, given this dictionary:
parents_to_children = {
'Khaled': ['Chibundu', 'Jesmyn'],
'Daniel': ['Khaled', 'Eve'],
'Jesmyn': ['Frank'],
'Eve': ['Grace']
}
Daniel's grandchildren are Chibundu, Jesmyn, and Grace, since those are the children of his children. Additionally, Khaled is Frank's grandparent, since Frank's parent is Khaled's child. Therefore, calling find_grandchildren(parents_to_children) returns this dictionary:
{
'Khaled': ['Frank'],
'Daniel': ['Chibundu', 'Jesmyn', 'Grace']
}
Note that the people who aren't grandparents don't show up as keys in the new dictionary. Depending on the way your process the dictionary, the order of your results may be different, but you should have the same keys and values.
Classes
Library Class
Implement a class Library with the following methods: init(self) - initializes a new Library instance and any member variables return_book(self, title) - returns a book to the library with the given title check_out(self, title) - removes a book from the library with the given title, or prints 'No book with that title' if that book isn't found get_catalog(self) - returns a list of all books currently in the library, sorted alphabetically
Here's how your class might be used from another program.
from library import Library
def main():
green_library = Library()
green_library.return_book('Karel the Robot Learns Python')
green_library.return_book('The Giving Tree')
green_library.return_book('Design as Art')
print(green_library.get_catalog()) # prints ['Design as Art', 'Karel the Robot Learns Python', 'The Giving Tree']
green_library.check_out('The Giving Tree')
green_library.check_out('Annihilation') # prints No book with that title
print(green_library.get_catalog()) # prints ['Design as Art', 'Karel the Robot Learns Python']
if __name__ == '__main__':
main()
Here's what the starter code looks like:
# File: library.py
class Library:
def __init__(self):
"""
Creates a new instance of the Library class
"""
pass
def return_book(self, title):
"""
Returns a book with the given title to the library
"""
pass
def check_out(self, title):
"""
Removes a book with the given title from the library, or prints
'No book with that title' if that book isn't found
"""
pass
def get_catalog(self):
"""
Returns a list of all books currently in the library, sorted
alphabetically
"""
pass
Tuples/Sorting
Predict what each of the following blocks of code will do:
Tracing
counting = [5, 6, 7, 8]
jenny = [8, 6, 7, 5, 3, 0]
lst = list(map(lambda lst: lst.append(9), [counting, jenny]))
counting = [5, 6, 7, 8]
jenny = [8, 6, 7, 5, 3, 0]
lst = list(map(lambda lst: lst + [9], [counting, jenny]))
Note: Answers are at the bottom of the handout
Sorting Houses
Given a list of tuples that represent houses for rent, the number of bedrooms, and their prices, like so:
houses = [('main st.', 4, 4000), ('elm st.', 1, 1200), ('pine st.', 2, 1600)] Sort the list in the following ways:
In ascending order by number of rooms In descending order of price In ascending order of price-per-room
We have provided a file for section/quiz review but you may notice that there are not written doctests or provided ways to test some of the functions. This is because we want to enourage you to study how you will write code on the final (without the immediate feedback of running your code). If you have questions about if your specific implementation will work, feel free to post on Ed or ask about in LaIR!
TUPLE ANSWER:
- The first snippet: Because the lambda doesn't return anything (but it needs to), the list will be [None, None]
- The second snippet: Because the lambda does return something, the mapping will return [[5, 6, 7, 8, 9], [8, 6, 7, 5, 3, 0, 9]]. Note that + [9] performs the extend and not append function.