Authoring Otter Grader-Based Notebook#

This notebook contains a series of examples for different types of questions that are available in otter-grader. Please note that this is examples using Otter Grader 4.4.1. When we move to Otter Grader 5, we will make a new set of examples.

Otter Notebook Authoring#

Key Moments:

  • ASSIGNMENT CONFIG at the top of the notebook file

  • Cell Types:
    Cell Types

    • “Raw”: # BEGIN QUESTION, # END QUESION, # BEGIN SOLUTION, # END SOLUTION, # BEGIN TESTS, # END TESTS

    • “Code”: Anything code that needs to be executed

    • “Markdown”: Cells will be rendered by applying styles to markdown syntax(like this one!)

Assignment Config#

The parent(or raw) notebook – we have never come up with a good name must must contain # ASSIGNMENT CONFIG at the top. A full description of what might be included in the assignment config can be found here It might look like this

Standard Programming Questions Formats Prompting a Student to write code#

There are a few pieces that are critical to understanding the structure of a question.

  • Notice the “points” section below. Each dashed line corresponds to the test cases below the solution. Three dashes would mean you need to have three and in this case the first two tests are not worth any points and the final test is worth four. You will also notice that the final test is marked “# HIDDEN” This means that the student notebook will not contain this test as self-check in the notebook but instead it will be used when we grade the notebook ourselves using otter grade or otter run

  • The solution section has many customizations, here is a reference. The one below will render this in the student notebook:

    import math
    weird_numbers = ...
    weird_numbers
    

    The "..." is prompting the student to complete this line.

Question 1. Make an array called weird_numbers containing the following numbers (in the given order) (4 Points):

  1. -2

  2. the floor of 12.6

  3. 3

  4. 5 to the power of the ceil of 5.3

Hint: floor and ceil are functions in the math module. Importing modules is covered in Lab 2!

Note: Python lists are different/behave differently than NumPy arrays. In Data 8, we use NumPy arrays, so please make an array, not a Python list.

import math
weird_numbers = make_array(-2, math.floor(12.6), 3, 5**math.ceil(5.3)) # SOLUTION
weird_numbers
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[1], line 2
      1 import math
----> 2 weird_numbers = make_array(-2, math.floor(12.6), 3, 5**math.ceil(5.3)) # SOLUTION
      3 weird_numbers

NameError: name 'make_array' is not defined
import numpy as np # you can include the imports at the top of the notebook
# It looks like you didn't make an array.
type(weird_numbers) == np.ndarray
len(weird_numbers) == 4
# HIDDEN
np.allclose(weird_numbers, np.array([   -2,    12,     3, 15625]), rtol=1e-03, atol=1e-03)

Manual-Graded Questions#

Otter can render questions prompting the user for an open-neded response or to generate a series of visualizations – otter can’t analyze a plot easily. These, of course, are not automatically graded.

Key Moments:

  • No points section in the question configuration

  • manual: true is set in the question configuration

Asking for a visualization#

Question 5. In the code cell below, create a visualization that will help us determine if there is an association between birth rate and death rate during this time interval. It may be helpful to create an intermediate table here. (4 Points)

Things to consider:

  • What type of chart will help us illustrate an association between 2 variables?

  • How can you manipulate a certain table to help generate your chart?

  • Check out the Recommended Reading for this homework!

# In this cell, use birth_rates and death_rates to generate your visualization
birth_rates = pop.column('BIRTHS') / pop.column('2015')
death_rates = pop.column('DEATHS') / pop.column('2015')
pop.with_columns("Birth Rate", birth_rates, "Death Rate", death_rates).scatter(8, 9) # SOLUTION

Asking for Written Response#

Question 7. Why is your solution in Question 6 the case? Based on one of the following two readings, why are the distributions for Boston and Manila different? (4 Points)

Hint: Try thinking about external factors of the two cities that may be causing the difference! There may be multiple different factors that come into play.

SOLUTION: This could be because there’s more traffic in Manila, or because the weather is not pleasant in Boston in the winter, so people may choose to take a car for short trips rather than walk.

Multiple Choice#

Key Moments:

  • Notice the points section. Three tests with the second test worth a point – yes, they get a point for giving one of the possible answers! The third test is “# HIDDEN” and contains the correct answer. The implication here is that the student notebook checks to see if the answer is valid but the instructor uses the third test, the “# HIDDEN” test, to assign points when the notebook is graded by otter.

Question 3. Suppose we run t.hist('y'). Which histogram does this code produce? Assign histogram_column_y to either 1, 2, or 3. (5 Points)

  1. Histogram A

  2. Histogram B

  3. Histogram C

histogram_column_y = 2 # SOLUTION
# Make sure you assign histogram_column_y to either 1 or 2!
type(histogram_column_y) == int
# Make sure histogram_column_y is assigned to 1, 2 or 3.
histogram_column_y == 1 or histogram_column_y == 2 or histogram_column_y == 3
# HIDDEN
histogram_column_y == 2