Week 2: Review of Python#
Laboratory 1
Last updated July 19, 2023
00. Content #
Mathematics
Functions
Programming Skills
Data types and basic operations
Lists and arrays
Functions
Loops and comprehension
Plotting
Embedded Systems
N/A
0. Required Hardware #
N/A
Write your name and email below:
Name:
Email:
1. Datatypes and Operators #
Datatypes#
Let’s initialize a variable in a cell.
a = 1
We can still access the variable in the next cell without needing to redefine it. However, if you restart the kernel and only execute the subsequent cell, an error will occur. This is because when the kernel is restarted, it loses knowledge of the value assigned to variable a
. Consequently, when attempting to print the variable, an error is thrown.
print(a)
Throughout this course, we will use the following data types in Python:
Boolean (
bool
): Boolean variables are eitherTrue
orFalse
and are equivalent to1
(true) or0
(false).String (
str
): Strings contain a sequence of characters.Numeric (
int
,float
):The
int
data type holds signed integer values of arbitrary length.float
variables hold floating-point numbers. They are only accurate to 15-16 digits.
You can check the datatype of a variable in Python with the type()
function.
type(a)
Operators#
Here is a list of the operators that may come in handy, along with their descriptions:
Operation |
Description |
---|---|
|
Returns |
|
Returns |
|
Equality; gives |
|
Tests if not equal |
|
Less than, less than or equal to, greater than, greater than or equal to |
|
Used to compare types, NOT values |
|
Negation |
|
Complement operator |
|
Addition |
|
Subtraction |
|
Multiplication |
|
Division |
|
Exponentiation; |
|
Integer division; division without the remainder |
|
Modulo operator; |
|
|
2. Functions and Loops #
Functions#
Defining your own functions will be a key skill in this course. Make sure to give your functions descriptive names as it helps you and others to read and interpret your code easily.
def add_two_nums(num1, num2):
return (num1 + num2)
print(add_two_nums(2,3))
print(add_two_nums(23,-5))
Loops#
Loops allow us to iterate through a list of values. While loops continue executing the loop as long as a condition is true, and for loops iterate through a list.
The range(start, stop, step)
function returns a sequence of values that starts at start
, ends before end
, and increments by step
. By default, start
is 0, and step
is 1.
i = 0
while i < 10: # start at 0, increment by 1 until 9 (10 not included)
print(i)
i += 1
for i in range(10): # start at 0, increment by 1 until 9 (10 not included)
print(i)
for i in range(2,13,2): # start at 2, increment by 2 until 12 (13 not included)
print(i)
for i in range(20,0,-5): # start at 20, decrement by 5 until 5 (0 not included)
print(i)
Exercise 1#
When \(n\) is a natural number, the factorial of \(n\) is
We define \(0!=1\).
Write a function that returns \(n!\) if the input \(n\) is a natural number; otherwise, it should print an error message.
Write Answer for Exercise 1 Below
Exercise 2#
Write a function with one parameter, \(n\), that prints the first \(n\) rows of the pyramid.
1 2 2 3 3 3 4 4 4 4 ...
Call your function when \(n=3\) and \(n=10\).
Write Answer for Exercise 2 Below
3. Lists and NumPy Arrays #
Lists#
A list is a collection or sequence of values that can be stored and accessed together. It’s like a container that holds multiple items, such as numbers, strings, or even other lists. You can think of a list as a way to keep related pieces of data organized. For example, if you have to make a list of the dorms you’re willing to stay at on campus, you could write it as a Python list like so:
dorms = ["Hawkins", "Wiley", "Frieda Parker", "Cary"] # creates a list of dorms
print(dorms) # prints the list of dorms
Once you have a list, you can perform various operations on it. You can access individual elements by their position in the list, starting from zero. The position of an element in the list is called its index. For example, to retrieve the first dorm from our dorms
list, you can use dorms[0]
. Similarly, dorms[1]
would give you the second dorm, and so on. Negative numbers can also be used as indices in a list. If you want to access the last dorm in our list, you can use dorms[-1]
. If you want the second-to-last dorm, you can use dorms[-2]
.
print(dorms[0]) # prints first dorm
print(dorms[1]) # prints second dorm
print(dorms[3]) # prints fourth dorm
print(dorms[-1]) # prints last dorm in list
You can also add new elements to the list or remove existing ones. For instance, to add “Windsor” to the dorms
list, you can use the append()
method like this: dorms.append("Windsor")
. This will add “Windsor” to the end of the list. To remove an element, you can use the remove()
method and provide the value you want to remove. Additionally, you can obtain the length of a list using the len()
function.
dorms = ["Hawkins", "Wiley", "Frieda Parker", "Cary"] # creates a list of dorms
print(dorms)
print("The length of the list is:", len(dorms)) # prints length of dorms list
dorms.append("Windsor") # adds 'Windsor' to the end of the list
print(dorms)
print("The length of the list is:", len(dorms)) # prints length with 'Windsor' added
dorms.remove("Wiley") # removes 'Wiley' from list
print(dorms)
print("The length of the list is:", len(dorms)) # prints length with 'Wiley' removed
You can iterate through a list using a loop, similar to how we did with the range function.
example_list = [1,1,2,3,5]
for num in example_list: # iterates through each element without using its index
print(num)
A string is nothing but a list of characters. You can manipulate and use strings in the same manner that you can with lists. For example, you can print every individual character of the string using a loop like so:
my_dorm = "Wiley"
for character in my_dorm:
print(character)
You can also manipulate and use a string within a list like so:
for dorm in dorms:
for character in dorm:
print(character) # prints every character in every string of the dorms list
print("\n\n") # prints two line breaks to seperate each dorm
print(dorms[0][0]) # prints the first character of the first dorm in the dorms list
print(dorms[-1][-1]) # prints the last character of the last dorm in the dorms list
print(dorms[3][-2]) # prints the second to last character of the fourth dorm in the dorms list
Exercise 3#
A palindrome is a sequence that reads the same forward and backward. Write a function that checks if a given list or string is a palindrome. For example, if the input to your function is "level"
or [2,1,4,5,5,4,1,2]
, then the function should return True
.
Write Answer for Exercise 3 Below
List Comprehension#
Python offers a convenient feature called list comprehension that enables us to define lists in a single line. It is recommended to use list comprehension when the operation is straightforward and clear. Avoid unnecessarily complicating the code solely for the sake of brevity.
[i for i in range(10) if i%2==1] # creates a list of odd numbers
[num**2+8 for num in example_list] # creates new list using elements of example_list as inputs
Exercise 4#
Write a list comprehension that finds the length of each dorm name in the dorms
list.
Write Answer for Exercise 4 Below
Numpy#
Up until now, we have been utilizing Python lists. However, NumPy arrays share similarities with lists. Once we import the NumPy library, we can initialize an array in the following manner:
import numpy as np
print("This is an example_list:", example_list)
example_array = np.array(example_list) # creates a numpy array from example_list
print("This is an example_array:", example_array)
print(len(example_array)) #prints the length of the example array
The indexing of arrays is identical to that of lists. Just like with the range()
function, we can create subarrays by slicing the original array as example_array[start:stop:step]
. The syntax to slice a list or a string is the same. If not explicitly specified, the default start index is 0, the default end index is the last index, and the default step size is 1. Additionally, a negative index can be used to count from the end of the array.
print(example_array[0]) # first element is at index 0
print(example_array[4]) # last element
print(example_array[-1]) # also the last element
print(example_array[0:3]) # subarray of elements at index 0,1,and 2 (3 not included)
print(example_array[:3]) # same subarray as before, 0 is default start
print(example_array[0:3:2]) # every other element of the subarray above
print(example_array[-2:]) # subarray from second to last element to the end
print(example_array[1::3]) # every third element starting with index 1 to the end of the array
The same indexing rules apply to each index in a multi-dimensional array. The array defined below consists of 5 rows and 4 columns. At each row and column index, there is an array of length 3.
A = np.arange(60).reshape((5,4,3)) # creates an array A with 5 rows, 4 columns, and 3 depth, containing sequential values from 0 to 59
print(len(A)) # the number of rows of A
print(A.shape) # the shape of A
print(A[0,0]) # the length 3 array at [0,0]
print(A[0,0,2]) # the last element of length 3 array at [0.0]
It is also easy to perform basic operations on an array without the need for loops. However, be careful when working with lists. For instance, adding two lists [1,2]+[3,4]
will result in [1,2,3,4]
. On the other hand, adding two arrays will perform element-wise addition. For example, np.array([1,2])+np.array([3,4])
yields np.array([4,6])
. Therefore, it is always important to verify that the outputs match your expectations.
# creating a new list from example_list
new_list = []
for num in example_list:
new_list.append(num**2+8)
print(new_list)
# the same operation on an array
print(example_array**2+8)
If you’re interested in more information about numpy, you can look at the documentation here.
Exercise 5#
Write a function with two parameters, \(m\) and \(n\), that returns a 2-dimensional array with \(m\) rows and \(n\) columns. Set the value in the i-th row and j-th column to be \((i+j)\mod (\min(m,n))\).
Create a new array from the output of your function by multiplying every odd-indexed row by 3 and every even-indexed column by 2.
Print the results when \(m=6\) and \(n=4\).
Write Answers for Exercise 5 Below
4. Plotting #
We will primarily use the matplotlib.pyplot module for our data visualizations. There are many customizations you can make. To see more examples, glance through the documentation.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8,4)) # optional to specify figsize
x = np.arange(10) # we could use np.linspace() to make our graph smoother
y = np.sin(x)
ax.plot(x, y, '-o', label='label 1') # '-o' makes the curve styled to be a line with points
ax.plot(x, y+1, 'r-o', label='label 2') # 'r-o' makes the curve styled to be a red line with points
ax.set_title("example plot")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend()
plt.show()
Exercise 6#
Run the cell of code below to get an array of random dorms from our dorms
list.
# the line below creates a new array that chooses a random dorm 100 times
random_dorms = np.random.choice(dorms, size = 100)
After executing the cell above, create a histogram graphing the frequency of each dorm in the random_dorms
list. Here’s an example of a bar chart.
Hint: Refer to np.unique. Look closely at the optional outputs.
Write Answers for Exercise 6 Below
Exercise 7#
Plot a smooth graph of \(y=\sin(x)+1\) on the interval \(0 \leq x \leq 4\). On the same graph, add a bar chart representing the rectangles in a left Riemann sum on 12 subintervals.
Write Answers for Exercise 7 Below
Reflection #
Are there any concepts or functions in this lab that you didn’t know previously that you believe may be very helpful in later labs?
Which part of the lab did you find the most challenging?
Which part of the lab was the easiest?