Appendix J — Assignments
K Assignment 5
K.1 Question 1: Using slice notation
Given a collection, return a subset starting and stopping at the specified location, using the specified step size. If not start, stop or step are given, then use the default values.
Examples:
1, 2, 3, 4, 5], 1, -2) # Returns [2, 3]
A5Q1([='abcdefghi', start=-4, stop=2, step=-1) # Returns 'fed' A5Q1(c
K.2 Question 2: Using sets
Given 2 lists find the elements in common and the elements unique to each, and return both in that order.
Examples:
1, 2, 3], [2, 3, 4]) # Returns ({2, 3}, {1, 4}) A5Q2([
K.3 Question 3: Fixing formatting
Fix all the whitespace mistakes in the following function according to pep8:
def A5Q3(a, b=1, c = 5):
=( -b + (b**2-4*a*c) ** 0.5 ) /(2*a) # One root
ans1= (-b-(b**2-4*a*c)**0.5)/(2*a) # The other root
ans2 return(ans1, ans2)
K.4 Question 4: Catching Errors
Write a function which accepts two arbitrary values and attempts to multiply them together. If multiplication is not possible, return None
.
Examples:
2, 5) # Returns 10
A5Q4('abcd', [1, 2, 3]) # Returns None A5Q4(
K.5 Question 5: Default Arguments
Write a function which accepts between 1 and 4 integers and multiplies them all together.
Examples:
1, 2, 3) # Returns 6
A5Q5(3, 3) # Returns 9 A5Q5(
K.6 Question 6: Docstrings
Update the following function to include a docstring with both Parameters and Returns sections.
def A5Q6(a, b, c=0):
= (a**2 + b**2 + c**2)**0.5
hypt return hypt
L Assignment 6
L.1 Question 1: Convert between types
Given an ndarray
containing floats
, convert the array type to int
and return it.
= np.array([2.2, 4.8, 0.9, 3.0])
arr # Returns array([2, 4, 0, 3]) A6Q1(arr)
L.2 Question 2: Perform mathematical operations
Given the radius values for N spheres, compute the volumes and surface areas, and return the results in an N-by-2 ndarray
.
4.4, 3.2, 8.3]) # Returns array([[ 356.8179048 , 243.28493509],
A6Q2([# [ 137.25827743, 128.67963509],
# [2395.09578482, 865.69727162]])
L.3 Question 3: Create your own split function
Create a new function which splits a 2D array both horizontally and vertically at the given locations. The returned result should be a list
which can be used to access the respective quadrants of the input array. Use slice notation.
= [[0, 1, 2, 6, 7],
arr 3, 4, 5, 8, 9]]
[1, 3]) # Returns [[array([0, 1, 2]), array([6, 7])], [array([3, 4, 5]), array([8, 9])]] A6Q3(arr, [
L.4 Question 4: Counting values
Write a function which accepts an ndarray
of values and a threshold value, and returns a tuple
containing the number of items which are less than, equal to, and greater than the threshold, in that order. Do not use a for-loop.
= [[4, 6, 2], [5, 4, 7]]
arr 5) # Returns (3, 1, 2) A6Q4(arr,
L.5 Question 5: Normalize an array
Write a function which takes an ndarray
and returns a “normalized” ndarray
such that all values are between 0 and 1. Assume the input array can have any real numbers (not +/- infinity). (As usual, differences in the decimal places do not matter).
= [[1, 4, -2], [-2, 0, 1]]
arr # Returns array([[0.500, 1.000, 0.000],
A6Q5(arr) # [0.000, 0.333, 0.500]])
L.6 Question 6: Find maximum and minimum
Given a 2D ndarray
, find the maximum and minimum of each column, and return the results as an ndarray
with a shape of 2-by-Ncols.
= [[3, 5, 2, 4],
arr 2, 6, 1, 5],
[2, 4, 4, 8],
[1, 1, 5, 3]]
[# Returns array([[3, 6, 5, 8],
A6Q6(arr) # [1, 1, 1, 3]])
L.7 Question 7: Join multiple arrays
Given 2 ndarrays
, stack them either horizontally or vertically, whichever is feasible based on the shapes of the two arrays. If the shape of the inputs is such that it is unclear which direction to stack or not possible, then return None
.
= [1, 2, 3]
arr1 = [[4, 5, 6],
arr2 7, 8, 9]]
[# Returns array([[1, 2, 3],
A6Q7(arr1, arr2) # [4, 5, 6],
# [7, 8, 9]])
= [1, 2, 3]
arr1 = [4, 5]
arr2 # Returns array([1, 2, 3, 4, 5])
A6Q7(arr1, arr2)
= [1, 2]
arr1 = [4, 5]
arr2 # Returns None A6Q7(arr1, arr2)
L.8 Question 8
Given an ndarray
of ints
, find the sum of all the even numbers. Do not use a for-loop!
= [[4, 3, 7],
arr 2, 6, 9],
[0, -2, 1]]
[# Returns 10 A6Q8(arr)
M Assignment 7
M.1 Question 1: Broadcasting
Given two arrays, check to see if they can be successfully broadcast together and return True
or False
accordingly
= np.ones((3, 3))
arr1 = np.ones((1, 3))
arr2 # Returns True
A7Q1(arr1, arr2)
= np.ones((3, 3))
arr1 = np.ones((1, 4))
arr2 # Returns False
A7Q1(arr1, arr2)
= 1.0
arr1 = np.ones((1, 4))
arr2 # Returns True
A7Q1(arr1, arr2)
= np.ones((3, 3))
arr1 = np.ones((4, ))
arr2 # Returns False A7Q1(arr1, arr2)
M.2 Question 2: Write a wrapper function
Write a function that accepts two arrays and an operator symbol in the form of a string (i.e. '+'
, '-'
), and perform the operation using the equivalent Numpy ufunc (i.e. add()
, subtract
). The function must support +
, -
, *
, /
, //
, %
and **
.
= np.arange(4)
arr1 = np.arange(4, 8)
arr2 "+") # Returns np.array([4, 6, 8, 10])
A7Q2(arr1, arr2, "*") # Returns np.array([0, 5, 12, 21]) A7Q2(arr1, arr2,
M.3 Question 3: Find bounding box
Write a function which computes the corners of a box that bounds a set of 2D points. The corners should be returned as a tuple like ((x_lower, y_lower), (x_upper, y_upper))
. The box is oriented along the x-y axes.
= np.array([[0.3, 0.2],
pts 0.8, 0.3],
[0.4, 0.7],
[0.2, 0.5]])
[# Returns ((0.2, 0.2), (0.8, 0.7)) A7Q3(pts)
M.4 Question 4: Normalize a vector
Write a function which accepts an N-dimensional vector and returns the normalized vector (i.e. unit length). As usual, do not fret over values in trailing decimal places.
= [4.1, 3.3, 5.0, -2.0]
vec # Returns array([ 0.54449303, 0.43825049, 0.66401589, -0.26560636]) A7Q4(vec)
M.5 Question 5: Matrix multiplication
Write a function which accepts a 2D coefficient matrix \(A\), and a 1D vector of \(x\) values, and returns the product of \(Ax\).
= np.arange(16).reshape((4, 4))
A = np.arange(100, 104)
x # Returns array([ 614, 2238, 3862, 5486])
A7Q5(A, x)
= np.arange(16).reshape((4, 4))
A = np.arange(100, 104).reshape((4, 1))
x # Returns array([ 614, 2238, 3862, 5486]) A7Q5(A, x)
M.6 Question 6: Boolean indexing meets linear algebra
Write a function which computes the trace of a square matrix without using any of Numpy’s built-in trace
functions, or for-loops (Hint: use boolean indexing)
= np.arange(16).reshape((4, 4))
A # Returns 30 A7Q6(A)
M.7 Question 7: Boolean indexing meets linear algebra, part 2
Write a function that determines if a given matrix is upper or lower triangular. Because this requires comparing floats
you may need to round values.
= np.array([[1, 2, 3, 4],
A1 0, 2, 3, 4],
[0, 0, 3, 4],
[0, 0, 0, 4]])
[# Returns True
A7Q7(A1)
= np.array([[1, 2, 3, 4],
A2 3, 2, 3, 4],
[3, 0, 3, 4],
[1, 0, 1, 4]])
[# Returns False A7Q7(A2)
N Assignment 8
N.1 Question 1: Generate a scatter plot
Write a function which accepts x and y data in the form of Numpy arrays and plots them using a scatter plot. The function should return a tuple containing the figure and axis handles, in that order.
import numpy as np
= np.random.rand(2, 200)
x, y # Should return (fig, ax) A8Q1(x, y)
N.2 Question 2: Generate a plot with several subplots
Write a function which accepts N Numpy arrays (2 <= N <= 5) and plots a histogram for each array. The histograms should all be contained in a single figure with N separate axis in a row. The function should return a tuple containing the figure handle and one axis handle which can be used access each subplot.
= np.random.rand(3, 200)
x, y, z # Should return (fig, ax) A8Q2(x, y, z)
Note that len(ax) == N
should be True
.
N.3 Question 3: Plot an image
Write a function which accepts a 2D Numpy array and plots is as an image. The function should return a tuple containing a figure and axis handle, in that order.
= np.random.rand(100, 100)
im # Should return (fig, ax) A8Q3(im)
N.4 Question 4: Set axis properties
Write a function which accepts a figure handle and Matplotlib named color as a string, changes the background of the figure to the given color, and returns the figure handle.
=fig, color='grey') # Should return fig A8Q4(fig
N.5 Question 5: Validate data
Given two Numpy arrays x
and y
. Generate an x-y scatter plot of the data, but only include data points that lie between 0 and 1. Any data that is less than 0 or greater than 1 should be ignored. The function should return a tuple containing a figure and axis handle, in that order.
# Should return (fig, ax) A8Q5(x, y)
O Assignment 9
O.1 Question 1: Overload the __setitem__
method
Create a subclass of a dict
that overloads the __setitem__
method to ensure that all the dictionary keys are strings. If a user attempts to use a key that is not a string, nothing should be written to the object. Optionally, you can raise an Exception
.
= A9Q1()
c 'val1'] = 1.0 # This should work
c[0] = 2.0 # This should raise an Exception c[
O.2 Question 2: Overwrite the __init__
method
Create a subclass of a dict
that accepts another dict
as a positional argument and incorporates it into it self, and accepts keyword arguments but ignores them. To do this question you’ll need to read Section 11.5.
= A9Q2({'key1': 0.3, 'key2': 22}, key3=10.0) c
O.3 Question 3: Add a size
method
Create a subclass of a list
which has a size
method that returns the number of elements in the list
. Treat any nested lists
as single elements.
= A9Q3([1, 2, 5, 2])
c # Should return 4
c.size() = A9Q3([1, 2, [3, 2, 1]])
c # Should return 3 c.size()
O.4 Question 4: Create your own DataFrame
class
Create a subclass of a dict
which behaves like a simple version of the pandas.DataFrame
. The initialization of the array should only accept 1 argument: the allowed length of the arrays. This class should do the following:
- Convert all values to Numpy
ndarrays
- Ensure all arrays are 1D, and prevent writing if not
- If a scalar is received, it should be “broadcast” to a 1D array of the correct length, with all elements set to the scalar value.
- Ensure all arrays are the same length, and prevent writing if not
= A9Q4(4)
c 'arr1'] = np.arange(4) # Should work
c['arr2'] = np.ones(5) # Should fail
c['arr3'] = [1, 3, 6, 10.0] # Should work
c['arr4'] = np.random.rand(4, 2) # Should fail
c['arr5'] = 1.0 # Should work c[