Exercise solutions

This section contains possible solutions to the exercises posed in the Python basics module. There is more than one correct solution for most of the exercises so these answers are for reference only.

Download the exercise solutions notebook

To view the solutions as an interactive notebook, download the file to your machine and upload it to the Sandbox as in the Python basics lessons.

Python basics 1

1.1 Fill the asterisk line with your name and run the cell.

[1]:
# Fill the ****** space with your name and run the cell.

message = "My name is Python"

message
[1]:
'My name is Python'

1.2 You can add new cells to insert new code at any point in a notebook. Click on the + icon in the top menu to add a new cell below the current one. Add a new cell below the next cell, and use it to print the value of variable a.

[2]:
a = 365*24

# Add a new cell just below this one. Use it to print the value of variable `a`
[3]:
a
[3]:
8760

Question: Now what happens if you scroll back up the notebook and execute a different cell containing print(a)?

Answer: It should now print 8760 as ‘global state’ means the value of a has been changed.

Python basics 2

[4]:
import numpy as np

2.1 Use the numpy add function to add the values 34 and 29 in the cell below.

[5]:
# Use numpy add to add 34 and 29

np.add(34,29)
[5]:
63

2.2 Declare a new array with contents [5,4,3,2,1] and slice it to select the last 3 items.

[6]:
# Substitute the ? symbols by the correct expressions and values

# Declare the array

arr = np.array([5, 4, 3, 2, 1])

# Slice array for the last 3 items only

arr[-3:]
[6]:
array([3, 2, 1])

2.3: Select all the elements in the array below excluding the last one, [15].

[7]:
arr = np.array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])

# Substitute the ? symbols by the correct expressions and values

arr[:-1]
[7]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

2.4 Use arr as defined in 2.3. Exclude the last element from the list, but now only select every 3rd element. Remember the third index indicates stride, if used.

Hint: The result should be [0,3,6,9,12].

[8]:
# Substitute the ? symbols by the correct expressions and values

arr[:-1:3]
[8]:
array([ 0,  3,  6,  9, 12])

2.5 You’ll need to combine array comparisons and logical operators to solve this one. Find out the values in the following array that are greater than 3 AND less than 7. The output should be a boolean array.

Hint: If you are stuck, reread the section on boolean arrays.

[9]:
arr = np.array([1, 3, 5, 1, 6, 3, 1, 5, 7, 1])

# Use array comparisons (<, >, etc.) and logical operators (*, +) to find where
# the values are greater than 3 and less than 7.

boolean_array = (arr > 3)*(arr < 7)
[10]:
boolean_array
[10]:
array([False, False,  True, False,  True, False, False,  True, False,
       False])

2.6 Use your boolean array from 2.5 to mask the False values from arr.

Hint: The result should be [5, 6, 5].

[11]:
# Use your resulting boolean_array array from 2.5
# to mask arr as defined in 2.5

arr[boolean_array]
[11]:
array([5, 6, 5])

Python basics 3

[12]:
%matplotlib inline

import numpy as np
from matplotlib import pyplot as plt

im = np.copy(plt.imread('Guinea_Bissau.JPG'))

3.1 Let’s use the indexing functionality of numpy to select a portion of this image. Select the top-right corner of this image with shape (200,200).

Hint: Remember there are three dimensions in this image. Colons separate spans, and commas separate dimensions.

[13]:
# Both options below are correct

topright = im[:200, -200:, ]

topright = im[:200, 400:600, ]

# Plot your result using imshow

plt.imshow(topright)
[13]:
<matplotlib.image.AxesImage at 0x7f08e28f7940>
../_images/python_basics_06_python_solutions_27_1.png

3.2 Let’s have a look at one of the pixels in this image. We choose the top-left corner with position (0,0) and show the values of its RGB channels.

[14]:
# Run this cell to see the colour channel values

im[0,0]
[14]:
array([249, 196, 104], dtype=uint8)

The first value corresponds to the red component, the second to the green and the third to the blue. uint8 can contain values in the range [0-255] so the pixel has a lot of red, some green, and not much blue. This pixel is a orange-yellow sandy colour.

Now let’s modify the image.

What happens if we set all the values representing the blue channel to the maximum value?

[15]:
# Run this cell to set all blue channel values to 255
# We first make a copy to avoid modifying the original image

im2 = np.copy(im)

im2[:,:,2] = 255

plt.imshow(im2)
[15]:
<matplotlib.image.AxesImage at 0x7f08e23d0ac8>
../_images/python_basics_06_python_solutions_32_1.png

The index notation [:,:,2] is selecting pixels at all heights and all widths, but only the 3rd colour channel.

Can you modify the above code cell to set all red values to the maximum value of 255?

[16]:
im2 = np.copy(im)

im2[:,:,0] = 255

plt.imshow(im2)
[16]:
<matplotlib.image.AxesImage at 0x7f08e0b34ef0>
../_images/python_basics_06_python_solutions_35_1.png

Python basics 4

[17]:
%matplotlib inline

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import colors

# grass = 1
area = np.ones((100,100))
# crops = 2
area[10:60,20:50] = 2
# city = 3
area[70:90,60:80] = 3
index = {1: 'green', 2: 'yellow', 3: 'grey'}
cmap = colors.ListedColormap(index.values())

4.1 The harvesting season has arrived and our cropping lands have changed colour to brown. Can you:

4.1.1 Modify the yellow area to contain the new value 4?

4.1.2 Add a new entry to the index dictionary mapping number 4 to the value brown.

4.1.3 Plot the area.

[18]:
# 4.1.1 Modify the yellow area to hold the value 4
area[10:60,20:50] = 4
[19]:
# 4.1.2 Add a new key-value pair to index that maps 4 to 'brown'
index[4] = 'brown'
[20]:
# 4.1.3 Copy the cmap definition and re-run it to add the new colour
cmap = colors.ListedColormap(index.values())
# Plot the area
plt.imshow(area, cmap=cmap)
[20]:
<matplotlib.image.AxesImage at 0x7f08e0b26198>
../_images/python_basics_06_python_solutions_41_1.png

Hint: If you want to plot the new area, you have to redefine cmap so the new value is assigned a colour in the colour map. Copy and paste the cmap = ... line from the original plot.

4.2 Set area[20:40, 80:95] = np.nan. Plot the area now.

[21]:
# Set the nan area
area[20:40, 80:95] = np.nan
[22]:
# Plot the entire area
plt.imshow(area, cmap=cmap)
[22]:
<matplotlib.image.AxesImage at 0x7f08e0a78e48>
../_images/python_basics_06_python_solutions_45_1.png

4.3 Find the median of the area array from 4.2 using np.nanmedian. Does this match your visual interpretation? How does this compare to using np.median?

[23]:
# Use np.nanmedian to find the median of the area
np.nanmedian(area)
[23]:
1.0
[24]:
np.median(area)
[24]:
nan

np.median returns a value of nan because it cannot interpret no-data pixels. np.nanmedian excludes NaN values, so it returns a value of 1 which indicates grass. This matches the plot of area.

Python basics 5

[25]:
%matplotlib inline

import numpy as np
from matplotlib import pyplot as plt
import xarray as xr
guinea_bissau = xr.open_dataset('guinea_bissau.nc')

5.1 Can you access to the crs value in the attributes of the guinea_bissau xarray.Dataset?

Hint: You can call upon attributes in the same way you would select a variable or coordinate.

[26]:
# Replace the ? with the attribute name

guinea_bissau.crs
[26]:
'EPSG:32628'

5.2 Select the region of the blue variable delimited by these coordinates:

  • latitude of range [1335000, 1329030]

  • longitude of range [389520, 395490]

Hint: Do we want to use sel() or isel()? Which coordinate is x and which is y?

5.3 Plot the selected region using imshow, then plot the region using .plot().

[27]:
# Plot using plt.imshow
plt.imshow(guinea_bissau.blue.sel(x=slice(389520, 395490), y=slice(1335000, 1329030)))
[27]:
<matplotlib.image.AxesImage at 0x7f08cb8f0da0>
../_images/python_basics_06_python_solutions_58_1.png
[28]:
# Plot using .plot()
guinea_bissau.blue.sel(x=slice(389520, 395490), y=slice(1335000, 1329030)).plot()
[28]:
<matplotlib.collections.QuadMesh at 0x7f08cb824898>
../_images/python_basics_06_python_solutions_59_1.png

Can you change the colour map to 'Blues'?

[29]:
plt.imshow(guinea_bissau.blue.sel(x=slice(389520, 395490), y=slice(1335000, 1329030)), cmap='Blues')
[29]:
<matplotlib.image.AxesImage at 0x7f08cb763eb8>
../_images/python_basics_06_python_solutions_61_1.png
[30]:
guinea_bissau.blue.sel(x=slice(389520, 395490), y=slice(1335000, 1329030)).plot(cmap='Blues')
[30]:
<matplotlib.collections.QuadMesh at 0x7f08cb6d1710>
../_images/python_basics_06_python_solutions_62_1.png