Managing state#

The notebook is an interactive computing environment. It lets you execute code in a step-by step fashion. This is powerful for thinking through a problem and taking your next steps based on what you see or do in the cell above. But it can lead to some challenging, non-intuitive behaviours if you run cells out of order or multiple times. In this notebook, we capture some “gotchas” and tips for avoiding tying your notebook in a knot. If you have ideas or experiences to contribute here, contributions to this repository are welcome!

import numpy as np
import matplotlib.pyplot as plt

Variable assignment#

Sometimes as you are working, you might do simple computations, updates to a variable. One way to do this is to just over-write the variable name. The danger here is that if you re-run the second or third cell below, the value will update again, which may not be intended.

If you have a large notebook and update a parameter above, re-run the cells below, this can be easy to miss and generate non-intuitive results.

a = 2
a *= 2
print(a)
4
a = a*2
print(a)
8

A safer way to do this operation is to create a new variable with a different name. No matter how many times we execute the second cell below, the value will always be 4

a = 2
a_times_2 = a*2
print(a_times_2)
4

Scope of functions#

The scope of variables assigned at the top level in the notebook (e.g. not inside a function or class) is global. This means you can still use them inside of a function. In the second cell below, we create a sine wave with a given frequency.

frequency = 1
def sketchy_sine_wave(x):
    return np.sin(2*np.pi*frequency*x)
x = np.linspace(0, 1, 100)
plt.plot(x, sketchy_sine_wave(x));
../../_images/managing-state_12_0.png

If we change the value of frequency, then the the behaviour of sine_wave changes. So even though the second cell has code that is identical to the cell above, the output is different. This can be confusing!

frequency = 2
plt.plot(x, sketchy_sine_wave(x));
../../_images/managing-state_15_0.png

A safer approach is to keep the scope of variables inside a function local to that function and assign default-values to parameters as appropriate. This will also allow you to much more easily pull functions / classes that you write in the notebook into a python file to create a module if you want to later re-use that code.

def safer_sine_wave(x, frequency=1):
    return np.sin(2*np.pi*frequency*x)