Here's the Section 6 starter code. You'll unzip/extract this file and open it in PyCharm just like you do with your assignment starter code. The sorting problems can be implemented directly in the Python interpreter.
Random Circles
from graphics import Canvas
import random
CANVAS_WIDTH = 300
CANVAS_HEIGHT = 300
CIRCLE_SIZE = 20
N_CIRCLES = 20
def draw_random_circles(canvas):
for i in range(N_CIRCLES):
# Generate random coordinates for the circle's bounding box
x = random.randint(0, CANVAS_WIDTH - CIRCLE_SIZE)
y = random.randint(0, CANVAS_HEIGHT - CIRCLE_SIZE)
# Generate a random color
color = random_color()
# Draw the circle on the canvas
canvas.create_oval(x, y, x + CIRCLE_SIZE, y + CIRCLE_SIZE, color)
def random_color():
colors = ['blue', 'purple', 'salmon', 'lightblue', 'cyan', 'forestgreen']
return random.choice(colors)
def main():
print('Random Circles')
canvas = Canvas(CANVAS_WIDTH, CANVAS_HEIGHT)
draw_random_circles(canvas)
canvas.mainloop()
if __name__ == '__main__':
main()
Tuples and Sorting
These problems can be completed in the Python interpreter, which you can access via the terminal by entering python3 (using py or python on Windows) and then entering lines of Python code. Here's an example of sorting a list of strings alphabetically by their second character in the interpreter.
$ python3
>>> def second_char(str):
... return str[1]
...
>>> lst = ['#hey', '$there', '@cs106a']
>>>
>>> sorted(lst, key=second_char)
['@cs106a', '#hey', '$there']
Pi Difference
Given a list of numbers, sort the numbers based on the absolute value of their difference with pi.
You can use 3.14 as an approximation of pi. As an example, if we use the same list as above,
[3, 2, -1, 7, -7, 5, 14]
your function would return:
[3, 2, 5, 7, -1, -7, 14]
You can find the absolute value of a number by calling the built‑in abs function as follows:
>>> x = -7
>>> abs(x)
7
def sort_by_abs_pi(num):
return abs(3.14 - num)
sorted(nums, key=sort_by_abs_pi)
Case Insensitive
Given a list of strings, sort the list case‑insensitively. As an example, if you have the following list of strings,
['Mehran', 'juliette', 'KaTiE', 'CS106A', 'pYtHoN']
your sorting should produce:
['CS106A', 'juliette', 'KaTiE', 'Mehran', 'pYtHoN']
def sort_without_case(s):
return s.lower()
sorted(strs, key=sort_without_case)
Zip Code Tuple Sort
Given a list of tuples representing addresses in the form (city, state, zipcode), sort the list of addresses based on the numeric value of the zipcode. For example, sorting the list
[('Stanford', 'CA', 94305), ('Milwaukee', 'WI', 53222), ('New York', 'NY', 10001)]
would result in the following list:
[('New York', 'NY', 10001), ('Milwaukee', 'WI', 53222), ('Stanford', 'CA', 94305)]
def sort_by_zipcode(tup):
return tup[2]
sorted(addresses, key=sort_by_zipcode)
Sorting with Lambdas
Given a list of tuples that represent houses for rent, the number of bedrooms, and their prices:
houses = [('main st.', 4, 4000), ('elm st.', 1, 1200), ('pine st.', 2, 1600)]
Use lambdas to sort the list in the following ways:
- Ascending order by number of rooms
- Descending order of price
- Ascending order of price-per-room
# 1.
>>> sorted(houses, key=lambda tup:tup[1])
[('elm st.', 1, 1200), ('pine st.', 2, 1600), ('main st.', 4, 4000)]
# 2.
>>> sorted(houses, key=lambda tup:tup[2], reverse=True)
[('main st.', 4, 4000), ('pine st.', 2, 1600), ('elm st.', 1, 1200)]
# 3.
>>> sorted(houses, key=lambda tup:tup[2]/tup[1])
[('pine st.', 2, 1600), ('main st.', 4, 4000), ('elm st.', 1, 1200)]
Tuple Sorting Mystery !
The list has been sorted using a hidden rule. Can you figure out what the code for the rule is?
Original list:
[(3, 'vanu', 5), (1, 'luke', -10), (-3, 'rachel', -3), (2, 'tyler', -1)]
Sorted list:
[(1, 'luke', -10), (2, 'tyler', -1), (-3, 'rachel', -3), (3, 'vanu', 5)]
def sort_by_difference(tup):
return tup[2] - tup[0]
sorted(lst, key=sort_by_difference)
Bonus: Mindset
Over the past two centuries, humanity has witnessed profound shifts in both health and wealth, reshaping the global landscape. In 1809, life expectancy languished below 40 years, and average income struggled to exceed $3000 annually. However, post-World War II, progress accelerated.
Inspired by Hans Rosling's analyses, we aim to visualize the evolution of life expectancy and income per person across 200 countries. Our journey begins in 1809, portraying the gradual improvement in health and economic status globally. Rosling's data point to a closing gap between Western and non-Western countries, fostering a "converging world" perspective. His main message is that there are no longer two types of country in the world. The old division between developed and developing countries has been replaced by countries on a continuum of social and economic development levels.
The red bubble tracks the country we are focusing on throughout the visualizations

Our goal is to recreate this visualization, and we will break this big task into two parts: adding data points into the visualization and then creating the graphics for the visualization.
Mindset: Part 1
We are assigned the task of implementing the add_data function in mindset.py, which will help us add new data points into the visualizations. The function takes in CSV files containing data such as GDP, population, and life expectancy, with the objective of generating a JSON file, mindset.json, to store the data in a dictionary format. Each year is represented as a key in the JSON dictionary, with associated values containing data for each country in that year. For instance:
{
"1800": {
"Afghanistan": {"life": 28.21, "pop": 3280000, "gdp": 603.0},
"Albania": {"life": 28.2, "pop": 3284351, "gdp": 604.0},
...
"Zimbabwe": {"life": 20.8, "pop": 12226542, "gdp": 98.0}
},
...
}
The add_data function processes CSV files named
fghanistan,28.21,28.2,28.1 ...
After you are done writing add_data, check out mindset.json to make sure it looks right!
def add_data(data, file_name):
"""
The file_name is of the format <key>.csv where
key is one of "life", "pop", "gdp"
Each file is a list of rows formatted like:
Afghanistan,28.21,28.2,28.1 ...
Our data dictionary is formatted like this
{
1800: {
"Afghanistan": {
"life":28.21,
"pop":3280000,
"gdp":603.0
},
"Albania": {
"life": 20.8,
"pop": 12226542,
"gdp": 98.0
}
...
},
1801: { ... }
...
}
"""
key = file_name.split('.')[0]
for line in open(file_name):
line = line.strip()
parts = line.split(',')
country_name = parts[0]
for i in range(N_YEARS):
next_value = float(parts[i + 1])
year = START_YEAR + i
print(key, country_name, next_value, year)
if not year in data:
data[year] = {}
year_data = data[year]
if country_name not in year_data:
year_data[country_name] = {}
data[year][country_name][key] = next_value
Mindset: Part 2
For the next part in mindset_visualize.py, we are going to use our graphics skills to visualize the data we just processed. First, load the JSON file we just created, so we can work with it.
The given starter code prompts the user to input a country to track, and saves this input into a variable track_country. We also draw the Canvas and the axes of the plot for you as well as the animation.
...
canvas = make_canvas(CANVAS_WIDTH, CANVAS_HEIGHT, 'Mindset')
# for each year to be visualized
for year in range(START_YEAR, END_YEAR + 1):
# draw the current year
clear_canvas(canvas)
draw_graph_background(canvas)
draw_year_text(canvas, year)
# TODO: extract year data from data
year_data = 0
plot_year_bubbles(canvas, year_data, track_country)
# animate
canvas.update()
if year % 10 == 0:
input('Enter to continue')
canvas.mainloop()
...
Your task is to extract year data from data and implement the plot_year_bubbles function, which will draw bubbles representing each country's data for a specific year on a canvas:
def plot_year_bubbles(canvas, year_data, track_country):
def main():
data = json.load(open('mindset.json'))
track_country = input('Country to track: ')
canvas = make_canvas(CANVAS_WIDTH, CANVAS_HEIGHT, 'Mindset')
# for each year to be visualized
for year in range(START_YEAR, END_YEAR + 1):
# draw the current year
clear_canvas(canvas)
draw_graph_background(canvas)
draw_year_text(canvas, year)
year_data = data[str(year)]
plot_year_bubbles(canvas, year_data, track_country)
# animate
canvas.update()
if year % 10 == 0:
input('Enter to continue')
canvas.mainloop()
def plot_year_bubbles(canvas, year_data, track_country):
for country_name in year_data:
country_data = year_data[country_name]
life = country_data['life']
pop = country_data['pop']
gdp = country_data['gdp']
filled = country_name == track_country
draw_bubble(canvas, life, gdp, pop, filled)