Make me look good. Click on the cell below and press Ctrl+Enter.
from IPython.core.display import HTML
HTML(open('css/custom.css', 'r').read())
List comprehensions
Errors
Conditional tests and statements
Advanced Jupyter features
Warm up. Use a for
loop and the .append()
method to create a list of the first 10 cubic numbers, starting with $0^3, 1^3, 2^3, ...$ Print the list to check your work.
# Write your code here
# Initialize empty list
cubics = []
# Iterate over first 10 integers, starting at 0
for i in range(10):
cubics.append(i**3)
# Print the list
print(cubics)
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
A list comprehension is a compact way of constructing lists.
For example, to create the same list we built in the above warm up example:
# Create list with list comprehension
another_cubics = [i**3 for i in range(10)]
# Print the list
print(another_cubics)
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
List comprehensions are 😎 (and easier to read and write when you get used to them)...
But the .append()
technique is 👍 too.
Python is a language in much the same way that English is a language.
Below is an example of a poorly constructed, grammatically incorrect, English sentence.
The dawg the car chsed exited.
Note that our brains can sometimes make sense of even very poorly constructed sentences in English.
The Python interpreter is not as forgiving.
Let's look at an example of Python code that contains syntax errors:
# Print the numbers 1 through 10
For i in RANGE(1, 11)
print(i)
File "<ipython-input-4-715aeb7e83f0>", line 2 For i in RANGE(1, 11) ^ SyntaxError: invalid syntax
# Print the numbers 1 through 10
For i in RANGE(1, 11)
print(i)
Write your notes here. Double-click to edit.
# Define list of veggies
veggies = ['lettuce', 'celery', 'carrot', 'cucumber'
# Sort veggies in alphabetical order
veggies.sort()
# Print the list of veggies in alphabetical order
print(veggies)
File "<ipython-input-5-05c6a87bb9e0>", line 5 veggies.sort() ^ SyntaxError: invalid syntax
Important tip. Always check above the code that Python points you to in an error message, just in case.
Let's fix this code:
# Define list of veggies
veggies = ['lettuce', 'celery', 'carrot', 'cucumber'
# Sort veggies in alphabetical order
veggies.sort()
# Print the list of veggies in alphabetical order
print(veggies)
Write your notes here. Double-click to edit.
When we write English sentences, we might introduce logical errors that lead to unintended meanings. For example:
Let's eat, Grandma!
Let's eat Grandma!
We can also introduce logical errors when writing Python code. For example:
# Create a list containing all odd numbers from 1 - 20
odd_numbers = []
for number in range(0, 20, 2):
print(number)
# Let's check our work
print(odd_numbers)
0 2 4 6 8 10 12 14 16 18 []
Note that when we ran the code, we didn't get any error messages. However, we didn't get we what wanted.
Let's fix this code together:
# Create a list containing all odd numbers from 1 - 20
odd_numbers = []
for number in range(0, 20, 2):
print(number)
# Let's check our work
print(odd_numbers)
A conditional test is an expression that evaluates to True
or False
.
Perhaps the most basic conditional test is to check for equality using the ==
operator:
==
are equal, then it returns True
.False
.# Let's define today to be Tuesday
today = "Tuesday"
# Is today Tuesday?
print(today == 'Tuesday')
True
# Is today Friday?
print(today == 'Friday')
False
Comparison | Meaning |
---|---|
== |
equal |
!= |
not equal |
< |
less than |
> |
greater than |
<= |
less than or equal |
>= |
greater than or equal |
=
is used to assign the value of something.==
is used to check if something is equal to something else.and
and or
:# Let's define a variable with our age
age = 85
# Am I between 20 and 30 years old?
print((age >= 20) and (age <= 30))
# Am I under 20 or over 30 years old?
print((age < 20) or (age > 30))
False True
# Define list of veggies again
veggies = ['lettuce', 'celery', 'carrot', 'cucumber']
# Is 'cucumber' in our list of veggies?
print('cucumber' in veggies)
# ... but is 'Cucumber' in our list of veggies?
print('Cucumber' in veggies)
True False
Simple if
statements:
if conditional_test:
do something
For example, to check if a number is a mutliple of 3:
# Pick a number
number = 15
# Check if it is a multiple of 3
if number % 3 == 0:
print(f'The number {number} is a multiple of 3.')
The number 15 is a multiple of 3.
if
-else
statements:
if conditional_test:
do something
else:
conditional_test is False, so do something else
Building upon the previous example:
# Pick a number
number = 14
# Check if it is a multiple of 3
if number % 3 == 0:
print(f'The number {number} is a multiple of 3.')
else:
print(f'The number {number} is NOT a multiple of 3.')
The number 14 is NOT a multiple of 3.
if
-elif
-else
statements:
if conditional_test_1:
do something
elif conditional_test_2:
here, conditional_test_1 is False, but conditional_test_2 is True
do something else
else:
here, both conditional_test_1 and conditional_test_2 are False
do something craaaazy
The else
part is optional (i.e. you can have an if
-elif
statement).
What's the difference between using an if
-elif
statement vs. two if
statements? Let's take a look at the following two examples.
from IPython.display import IFrame
IFrame("http://pythontutor.com/iframe-embed.html#code=%23%20Pick%20a%20number%0Anumber%20%3D%2015%0A%0A%23%20Check%20if%20it%20is%20a%20multiple%20of%203%0Aif%20number%20%25%203%20%3D%3D%200%3A%0A%20%20%20%20print%28f'The%20number%20%7Bnumber%7D%20is%20a%20multiple%20of%203.'%29%0Aelif%20number%20%25%205%20%3D%3D%200%3A%0A%20%20%20%20print%28f'The%20number%20%7Bnumber%7D%20is%20a%20multiple%20of%205.'%29&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=nevernest&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=800, height=450)
from IPython.display import IFrame
IFrame("http://pythontutor.com/iframe-embed.html#code=%23%20Pick%20a%20number%0Anumber%20%3D%2015%0A%0A%23%20Check%20if%20it%20is%20a%20multiple%20of%203%0Aif%20number%20%25%203%20%3D%3D%200%3A%0A%20%20%20%20print%28f'The%20number%20%7Bnumber%7D%20is%20a%20multiple%20of%203.'%29%0Aif%20number%20%25%205%20%3D%3D%200%3A%0A%20%20%20%20print%28f'The%20number%20%7Bnumber%7D%20is%20a%20multiple%20of%205.'%29&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=nevernest&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=800, height=450)
There are keyboard shortcuts, but they can be a little tricky to use. Take a look at Help → Keyboard Shortcuts.
If you click in the text box of a code cell or double-click in a Markdown cell, then it is outlined by a green box. This is called Edit Mode.
If you click on the side of a code cell, then it is outlined by a blue box. This is called Command Mode.
To enter Command Mode from Edit mode, press Esc.
Here are three really useful keyboard shortcuts:
# Try turning on and turning off line numbers in this cell.
# Play around with indenting and de-indenting code.
student_names = ["Amy", "Bob", "Carol"]
for name in student_names:
print(f"The name of this student is {name}.")
print(f"The name of this student is all uppercase is {name.upper()}.")
print(f"The name of this student is all lowercase is {name.lower()}.")
The name of this student is Amy. The name of this student is all uppercase is AMY. The name of this student is all lowercase is amy. The name of this student is Bob. The name of this student is all uppercase is BOB. The name of this student is all lowercase is bob. The name of this student is Carol. The name of this student is all uppercase is CAROL. The name of this student is all lowercase is carol.
You can run all the cells in a notebook by selecting Cell → Run All.
You can run all the cells above/below the current cell by selecting Cell → Run All Above/Below.
You can clear the output of a code cell by selecting Cell → Current Output → Clear.
You can clear the output of all code cells by selecting Cell → All Output → Clear.
Problem 1. In this question we work with numbers mod 7. The number 8 is equal to (1 mod 7) because its remainder upon division by 7 is equal to 1. You can compute and print the value of (8 mod 7) in Python by writing:
print(8 % 7)
1
Using a for
loop and an if
statement, compute the sum of the positive integers less than 55 that are equal to (1 mod 7).
# Write your code here
# Initialize total value to 0
total = 0
# Iterate over all positive integers less than 55
for i in range(1, 56):
# Check if the integer is equal to 1 mod 7
# If so, include it in the total
if i % 7 == 1:
total += i
print(f"The sum of the numbers from 1 to 55 that equal 1 mod 7 is {total}.")
The sum of the numbers from 1 to 55 that equal 1 mod 7 is 204.
Problem 2. (PCC 5-10: Checking Usernames) Do the following to create a program that simulates how websites ensure that everyone has a unique username.
current_users
.new_users
. Make sure one or two of the new usernames are also in the current_users
list.new_users
list to see if each new username has already been used. If it has, print a message that the person will need to enter a new username. If a username has not been used, print a message saying that the username is available.# Write your code here
# List of current usernames
current_users = ['John', 'Emily', 'Carl', 'Jake', "Cindy"]
# List of new usernames
new_users = ['JOHN', 'Edith', "Kevin", "Jody", "cindy"]
# To make comparisons case insensitive, let's make a new list
# with the current usernames in lowercase
current_users_lower = []
for name in current_users:
current_users_lower.append(name.lower())
# Iterate over new user names
for name in new_users:
# Check if the name (in all lowercase) is in
# the list of current users (in all lowercase)
if name.lower() in current_users_lower:
print(f"I'm sorry, the username '{name}' is unavailable.")
else:
print(f"Congratulations! The user name '{name}' is available'!")
I'm sorry, the username 'JOHN' is unavailable. Congratulations! The user name 'Edith' is available'! Congratulations! The user name 'Kevin' is available'! Congratulations! The user name 'Jody' is available'! I'm sorry, the username 'cindy' is unavailable.
Problem 3. (PCC 5-11: Ordinal Numbers) Ordinal numbers indicate their position in a list, such as 1st or 2nd. Most ordinal numbers end in th, except 1, 2, and 3.
if
-elif
-else
chain inside the loop to print the proper ordinal ending for each number. Your output should look like this:1st
2nd
3rd
4th
5th
6th
7th
8th
9th
# Write your code here
# List of numbers 1 through 9
numbers = list(range(1,10))
# Iterate through the numbers
# Check for special cases of ordinal endings
for number in numbers:
if number == 1:
print("1st")
elif number == 2:
print("2nd")
elif number == 3:
print("3rd")
else:
print(f"{number}th")
1st 2nd 3rd 4th 5th 6th 7th 8th 9th
Problem 4. (PCC 5-13: Your Ideas) At this point, you are a more capable programmer than you were when you started this book. Now that you have a better sense of how real-world situations are modeled in programs, you might be thinking of some problems you could solve with your own programs. Record any new ideas you have about problems you might want to solve as your programming skills continue to improve. Consider games you might want to write, data sets you might want to explore, and web applications you would like to create.
Write your ideas here. Double-click to edit.
Problem 5. In the code cell below, we have the data for several recipes from Cooking Light Magazine, September 2016:
Use the variables defined below for your code. We store the six names in the above order in the list recipe_names
. Corresponding data is stored in the lists recipe_active_times
, recipe_total_times
, recipe_calories
, recipe_fats
, recipe_proteins
, recipe_carbs
, recipe_fibers
, recipe_sugars
, recipe_cholesterols
, recipe_irons
, recipe_sodiums
, recipe_calciums
.
# Recipe data - do not modify
recipe_names = ['pizza', 'gnochi', 'quinoa', 'chicken salad',
'pasta with shrimp', 'enchiladas']
recipe_active_times = [30, 18, 25, 35, 20, 25]
recipe_total_times = [30, 30, 40, 35, 20, 40]
recipe_calories = [314, 301, 519, 318, 472, 348]
recipe_fats = [11.9, 8.7, 25.1, 20.6, 21.7, 14.5]
recipe_proteins = [13, 10, 22, 20, 24, 29]
recipe_carbs = [41, 44, 53, 14, 46, 28]
recipe_fibers = [9, 10, 7, 4, 8, 5]
recipe_sugars = [5, 3, 6, 6, 1, 3]
recipe_cholesterols = [10, 13, 186, 81, 114, 101]
recipe_irons = [3, 5, 5, 2, 3, 1]
recipe_sodiums = [492, 640, 722, 447, 575, 613]
recipe_calciums = [139, 68, 169, 159, 241, 329]
for
loop to do so without hard coding the number of recipes.# Write your code here
for i in range(len(recipe_names)):
if recipe_total_times[i] <= 30:
print(f"{recipe_names[i].title()} takes no more than half an hour to cook.")
Pizza takes no more than half an hour to cook. Gnochi takes no more than half an hour to cook. Pasta With Shrimp takes no more than half an hour to cook.
for
loop to do so without hard coding the number of recipes.# Write your code here
for i in range(len(recipe_names)):
if recipe_calories[i] < 400 and recipe_fibers[i] > 5:
print(f"{recipe_names[i].title()} has less than 400 calories and more than 5g of fiber.")
Pizza has less than 400 calories and more than 5g of fiber. Gnochi has less than 400 calories and more than 5g of fiber.
# Write your code here
for i in range(len(recipe_names)):
if recipe_proteins[i] > 20 or recipe_sugars[i] < 3:
print(f"{recipe_names[i].title()} has more than 20g of protein or less than 3g of sugar.")
Quinoa has more than 20g of protein or less than 3g of sugar. Pasta With Shrimp has more than 20g of protein or less than 3g of sugar. Enchiladas has more than 20g of protein or less than 3g of sugar.
Problem 6. (Seven Up) Seven Up is a fun game to play with elementary school students. Going around the room, each student says a number in the sequence 1, 2, 3,... However, if a number ends in seven (like 17) or if a number is divisible by 7 (like 14) then the student instead says "up". In the game, when a student makes a mistake, they are eliminated and the remainder of the class starts again at 1, but we'll assume that our students always say the correct thing.
# Write your code here
# Initialize empty list of the things that the students say
students_say = []
# Iterate through numbers 1 to 50
for i in range(1, 51):
# If the number is divisible by 7
# or if the number ends in 7,
# add "up" to the list
if (i % 7 == 0) or ((i - 7) % 10 == 0):
students_say.append("up")
# Otherwise, add the number to the list
else:
students_say.append(i)
# Print the list
print(students_say)
[1, 2, 3, 4, 5, 6, 'up', 8, 9, 10, 11, 12, 13, 'up', 15, 16, 'up', 18, 19, 20, 'up', 22, 23, 24, 25, 26, 'up', 'up', 29, 30, 31, 32, 33, 34, 'up', 36, 'up', 38, 39, 40, 41, 'up', 43, 44, 45, 46, 'up', 48, 'up', 50]
# Write your code here
# Initialize empty list of the things that the 3rd student says
third_student_says = []
# Iterate through the integers 1 to 1000
for i in range(1, 1000):
# Check if the 3rd student is supposed to say something
if i % 18 == 3:
# If the number is divisible by 7
# or if the number ends in 7,
# add "up" to the list
if (i % 7 == 0) or ((i - 7) % 10 == 0):
third_student_says.append("up")
# Otherwise, add the number to the list
else:
third_student_says.append(i)
print(third_student_says)
[3, 'up', 39, 'up', 75, 93, 111, 129, 'up', 165, 183, 201, 219, 'up', 255, 'up', 291, 309, 'up', 345, 363, 381, 'up', 'up', 435, 453, 471, 489, 'up', 'up', 543, 561, 579, 'up', 615, 633, 'up', 669, 'up', 705, 723, 741, 759, 'up', 795, 813, 831, 849, 'up', 885, 'up', 921, 939, 'up', 975, 993]
Problem 7. (The Locker Problem) A hallway has 1000 open lockers numbered 1 to 1000. There are 1000 students and every number from 1 to 1000 is assigned to a student. Student 1 goes and shuts every locker. Student 2 goes and changes the state of every locker with an even number (i.e. this student opens closed lockers and closes any open lockers). This process continues with student $k$ changing the state of every locker whose number is evenly divisible by $k$. Which of the lockers are closed at the end of the process? Write code to implement the closing and opening of lockers and see.
# Write your code here
# Initialize a list of 1000 entries representing the
# state of each locker. In the beginning, all locker are open.
state = ['open' for i in range(1, 1001)]
# Go through all the students
for student in range(1, 1001):
# Each student does something to the lockers
for locker in range(1, 1001):
if locker % student == 0:
if state[locker - 1] == 'open':
state[locker - 1] = 'closed'
elif state[locker - 1] == 'closed':
state[locker - 1] = 'open'
# Print the numbers of the lockers that are closed
# after all 1000 students do their thing
for locker in range(1, 1001):
if state[locker - 1] == 'closed':
print(f"Locker {locker} is closed.")
Locker 1 is closed. Locker 4 is closed. Locker 9 is closed. Locker 16 is closed. Locker 25 is closed. Locker 36 is closed. Locker 49 is closed. Locker 64 is closed. Locker 81 is closed. Locker 100 is closed. Locker 121 is closed. Locker 144 is closed. Locker 169 is closed. Locker 196 is closed. Locker 225 is closed. Locker 256 is closed. Locker 289 is closed. Locker 324 is closed. Locker 361 is closed. Locker 400 is closed. Locker 441 is closed. Locker 484 is closed. Locker 529 is closed. Locker 576 is closed. Locker 625 is closed. Locker 676 is closed. Locker 729 is closed. Locker 784 is closed. Locker 841 is closed. Locker 900 is closed. Locker 961 is closed.
Do you see a pattern in which lockers are open? Write your notes here. Double-click to edit.
The closed lockers are those with square numbers.
Problem 8. Write code that sets the variable time
to 1155
and another variable half
to either 'am'
or 'pm'
. Now write code that converts this time to 24 hour zulu time, stores the result in a variable zulu
and writes a sentence to the screen, such as "1155 pm is equivalent to 2355 zulu time."
Your code should produce the correct answer in both cases (am or pm). What should the output be when time = 1245
and half = pm
? Recall that pm stands for the Latin expression post meridiem (after midday).
# Write your code here for 1155
time = 1155
half = 'pm'
if half == 'pm' and time < 1200:
zulu = time + 1200
elif half == 'pm' and time > 1200:
zulu = time
elif half == 'am' and time >=1200:
zulu = time -1200
else:
zulu = time
print(f"{time} {half} is equivalent to {zulu} in zulu time.")
1155 pm is equivalent to 2355 in zulu time.
# Write your code here for 1245
time = 1245
half = 'pm'
if half == 'pm' and time < 1200:
zulu = time + 1200
elif half == 'pm' and time > 1200:
zulu = time
elif half == 'am' and time >=1200:
zulu = time -1200
else:
zulu = time
print(f"{time} {half} is equivalent to {zulu} in zulu time.")
1245 pm is equivalent to 1245 in zulu time.
Problem 9. Here's a fun way to try to estimate $\pi$. Consider a circle of radius 1 sitting inside a square of side length 2 centered at the origin, as in the image below.
First import the random
package. Once you've done that, random.uniform(-1, 1)
will generate a random value between -1 and 1.
Using for
loops, generate 10,000 random points in the xy-plane inside the square between (-1, -1) and (1, 1). Hint. You can represent these points with 2 lists, one with the x-coordinates, and one with the y-coordinates.
Now count the number of random points you generated are in the circle. Hint. What equation does $(x,y)$ need to satisfy in order to be inside the circle?
We expect the proportion to be approximately equal to the ratio of the area of the circle to the area of the square, $\pi/4$. Multiply your observed proportion by 4 to get an estimate of $\pi$.
How accurate is your estimate? What can you do to make it more accurate?
# Write your code here
import random as random
# Here are two list comprehensions that generate the x and y points.
# You can use the .append() technique too.
x_points = [random.uniform(-1,1) for i in range(10000)]
y_points = [random.uniform(-1,1) for i in range(10000)]
# Initialize the number of points in the circle to be 0
in_circle = 0
# Check if each point is in the circle
for i in range(0, 10000):
if x_points[i]**2 + y_points[i]**2 <= 1:
in_circle += 1
# Compute approximation of pi
pi_approx = 4 * in_circle / 10000
print(f"Our approximation to pi using 10000 points is {pi_approx}.")
Our approximation to pi using 10000 points is 3.1488.