You can have students complete coding exercises, play with interactive demos, or have group discussions.
Provide students a brief explanation of the exercise. The first exercise should not be too difficult, to serve as a warm-up for students.
Outputs of the code cell will ideally be a plot (so students can easily check against the correct one).
- In limited cases, the output may be printing numbers, text, etc. In that case you need to write the solution output manually after the exercise (E.g.: "You should see [4, 5, 6] when running the cell above"). Warn them when they will use a helper function. For example: In this exercise, you will also invoke
multiply_array
which multiplies an array by a scalar (a silly example).
: In case of randomness and to ensure reproducibility, do not forget to use a random seed before the exercise or within the function.
In [ ]:
# @markdown *Execute this cell to enable the array multiplication function: `multiply_array`*
def multiply_array(x, c, seed):
"""Multiply every element in an array by a provided value
Args:
x (ndarray): An array of shape (N,)
c (scalar): multiplicative factor
seed (integer): random seed
Returns:
ndarray: output of the multiplication
"""
np.random.seed(seed)
y = x * c + 4*np.random.randn()
return y
the above structure allows us to make the notebooks cleaner by hiding functions but still keep relevant functions close to where students will encounter them. Make sure to have the function in the markdown text so it's searchable.
In [ ]:
def generic_function(x, seed):
"""Google style doc string. Brief summary of what function does here
Args:
x (ndarray): An array of shape (N,) that contains blah blah
seed (integer): random seed for reproducibility
Returns:
ndarray: The output is blah blah
"""
#################################################
## TODO for students: details of what they should do ##
# Fill out function and remove
raise NotImplementedError("Student exercise: say what they should have done")
#################################################
# Have a comment for every line of code they need to write, and when possible have
# variables written with ellipses where they should fill in or ellipses where they should
# fill in inputs to functions
y = multiply_array(..., 5, seed)
# Another comment because they need to add another line of code
z = ...
return z
x = np.array([4, 5, 6])
# We usually define the plotting function in the hidden Helper Functions
# so students don't have to see a bunch of boilerplate matplotlib code
## Uncomment the code below to test your function
z = generic_function(x, seed)
plotting_z(z)
- the presence of
# to_remove solution
in the first line of solution block - The absence of the fenced (
#####
) block that raises a NotImplementedError
- Valid code replacing all ellipses (
...
) - Code that uses or depends on the completed function/lines is uncommented
- Plotting code is indented under a
with plt.xkcd():
context manager.
In [ ]:
# to_remove solution
def generic_function(x, seed):
"""Google style doc string. Brief summary of what function does here
Args:
x (ndarray): An array of shape (N,) that contains blah blah
seed (integer): random seed for reproducibility
Returns:
ndarray: The output is blah blah
"""
# Have a comment for every line of code they need to write, and when possible have
# variables written with ellipses where they should fill in or ellipses where they should
# fill in inputs to functions
y = multiply_array(x, 5, seed)
# Another comment because they need to add another line of code
z = y + 6
return z
x = np.array([4, 5, 6])
# We usually define the plotting function in the hidden Helper Functions
# so students don't have to see a bunch of boilerplate matplotlib code
## Uncomment the code below to test your function
z = generic_function(x, seed=2021)
with plt.xkcd():
plotting_z(z)
Here, we will demonstrate how to create a widget if you would like to use a widget to demonstrate something. Make sure the use a @title cell and hide the contents by default, because the code to make the widget is often pretty ugly and not important for the students to see. If the widget makes use of a function that must be completed as part of an exercise, you may want to re-implement the correct version of the function inside the widget cell, so that it is useful for a student who got completely stuck. There should be specific questions asked about the demo (e.g. what happens when you do this?)
In [ ]:
# @markdown Make sure you execute this cell to enable the widget!
x = np.arange(-10, 11, 0.1)
def gaussian(x, mu, sigma):
px = np.exp(-1 / 2 / sigma**2 * (mu - x) ** 2)
px = px / px.sum()
return px
@widgets.interact
def plot_gaussian(mean=(-10, 10, .5), std=(.5, 10, .5)):
plt.plot(x, gaussian(x, mean, std))
interactive(children=(FloatSlider(value=0.0, description='mean', max=10.0, min=-10.0, step=0.5), FloatSlider(v…
In [ ]:
# to_remove explanation
"""
Discussion: Write a dicussion about/answers to any open-ended questions you pose (either about a demo or elsewhere)
You can write a paragraph or two of nice didactic text
within a single comment.
""";
note that the form header for the cell above is , not .
maybe some more text about what exercises showed (if helpful). The Gaussian is:
- bumpy in the middle
- symmetric
- almighty
In addition to code exercises and interactive demos, you can have "discussion exercises" where students discuss open-ended questions. Each should roughly replace a code exercise so take about 10 minutes.
- E.g.: What do you think contributes to a good learning experience? Take 2 minutes to think in silence, then discuss as a group (~10 minutes).
In [ ]:
# to_remove explanation
"""
Discussion: Write a dicussion about/answers to any open-ended questions you pose (either about a demo or elsewhere)
You can write a paragraph or two of nice didactic text
within a single comment.
""";