Getting started¶
scicode-widgets can be installed with:
pip install scicode-widgets
Important
Jupyter widgets cannot be run within in documentation. To be able to interact with the widget you must run a mybinder instance. To run a mybinder instance of this notebook please use this link https://mybinder.org/v2/gh/osscar-org/scicode-widgets/HEAD?labpath=docs%2Fsrc%2Fgetting_started.ipynb.
Creating a code execrcise¶
This is how a simple coding exercise can look like.
[1]:
from scwidgets import CodeExercise
import matplotlib.pyplot as plt
import numpy as np
# This is what the students sees and can adapt
def sin(x, omega):
import numpy as np
# We provide already the solution for the demo
return np.sin(x*omega)
x = np.linspace(-2*np.pi, 2*np.pi, 100)
def update_func(code_ex):
y = code_ex.code(x, code_ex.parameters["omega"])
ax = code_ex.figure.gca()
ax.plot(x, y)
code_ex = CodeExercise(
code=sin,
outputs=plt.figure(),
parameters={"omega": (0.5, 3.14, 0.1)},
update=update_func,
update_mode="continuous",
title="Sinus function",
description="Implements $\\sin(x\\omega)$",
)
code_ex.run_update() # For the demonstration we run the widget one time
display(code_ex)
Please look at section exercises for more information about the execrises that can be created and their customization options.
Check students solution¶
You can create checks for student that work like unit tests helping the student to verify the students solution
[2]:
from scwidgets import (
CheckRegistry,
assert_numpy_allclose,
assert_shape,
assert_type,
)
check_registry = CheckRegistry()
def sinus(arr):
import numpy as np
return np.cos(arr) # oops! wrong solution
check_code_ex = CodeExercise(
code=sinus,
update=lambda code_ex: print(code_ex.code(np.pi)),
check_registry=check_registry,
)
def assert_2pi_periodic() -> str:
out = check_code_ex.code([0, 2*np.pi])
if not np.allclose(out[0], out[1]):
return "Function is not periodic."
return "" # empty strings means it passes
check_registry.add_check(
check_code_ex,
asserts=[
assert_2pi_periodic,
]
)
check_registry.add_check(
check_code_ex,
asserts=[
assert_type, # checks if same type as reference values
assert_shape, # checks if same shape as reference values
assert_numpy_allclose, # checks if allclose to reference values
],
inputs_parameters=[{"arr": np.asarray([0., 0.78539816, 1.57079633, 2.35619449, 3.14159265])}],
outputs_references=[(np.asarray([0., 7.07106781e-01, 1.00000000e+00, 7.07106781e-01, 0.]),)]
)
check_code_ex.run_check()
check_code_ex
[2]:
Please look at the section how to add checks for all options to create checks.
nbgrader integration¶
One can use nbgrader by using their macros.
def sin(arr: np.ndarray):
"""
:param arr: array of arbitrary shape
:return: returns the sinus
"""
import numpy as np
### BEGIN SOLUTION
sin_arr = np.sin(arr)
### END SOLTUION
return sin_arr
Then nbgrader will convert this to
[3]:
def sin(arr: np.ndarray):
"""
:param arr: array of arbitrary shape
:return: returns the sinus
"""
import numpy as np
# YOUR CODE HERE
raise NotImplementedError()
return sin_arr
code_ex = CodeExercise(
code=sin
)
display(code_ex)
It requires to add a hook in the config to copy over the students answers to the grading subfolder. A step-by-step tutorial how to make an nbgrader project compatible with scicode-widget can be seen in the repo TODO.