One important mission of COOP falls under the broad term Computer Science and Engineering, or CSE. To get a feel for what we do, we ask for candidates to play with a sample of Python code that represents many of the topics that are important to us. Specifically, the task is to edit the code so that:
- It can be called from an other module
- It is “clean”, i.e. follows coding standards
- It gains some flexibility and functionality
If you’ve been asked to perform this task and ended up here, please read the instructions below, and send your results to the person you’ve been in contact with. Note that if you are comfortable with Python, the full test should take less than an hour. If not, tentative ETAs are given for each task.
We start from a python script solving the equations of a SIR epidemiological model, found in this blog article.
import numpy as np from scipy.integrate import odeint import matplotlib.pyplot as plt # Total population, N. N = 1000 # Initial number of infected and recovered individuals, I0 and R0. I0, R0 = 1, 0 # Everyone else, S0, is susceptible to infection initially. S0 = N - I0 - R0 # Contact rate, beta, and mean recovery rate, gamma, (in 1/days). beta, gamma = 0.2, 1./10 # A grid of time points (in days) t = np.linspace(0, 160, 160) # The SIR model differential equations. def deriv(y, t, N, beta, gamma): S, I, R = y dSdt = -beta * S * I / N dIdt = beta * S * I / N - gamma * I dRdt = gamma * I return dSdt, dIdt, dRdt # Initial conditions vector y0 = S0, I0, R0 # Integrate the SIR equations over the time grid, t. ret = odeint(deriv, y0, t, args=(N, beta, gamma)) S, I, R = ret.T # Plot the data on three separate curves for S(t), I(t) and R(t) fig = plt.figure(facecolor='w') ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True) ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible') ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected') ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity') ax.set_xlabel('Time /days') ax.set_ylabel('Number (1000s)') ax.set_ylim(0,1.2) ax.yaxis.set_tick_params(length=0) ax.xaxis.set_tick_params(length=0) ax.grid(b=True, which='major', c='w', lw=2, ls='-') legend = ax.legend() legend.get_frame().set_alpha(0.5) for spine in ('top', 'right', 'bottom', 'left'): ax.spines[spine].set_visible(False) plt.show()
This outputs the following graph:
ETA: 10 - 20 min
Paste the code in a file
sir_model.py and create a caller code
the same folder with the following lines:
from sir_model import sir, epidemic_plot result = sir(days=160, population=1000, infected=1, contact_rate=0.2, infection_rate=0.1) epidemic_plot(result)
sir_model.py to make
test.py work. Just use the fact that these
files are in the same folder, no
setup.py work needed here.
ETA: 30 min - 1h
Readability counts for good code mainteance! Please tidy this code up so that it becomes easy for maintainers to read in the future, but keep the exact same functionalities.
We like to stick to Python standards for code quality, not for each dev to decide what “clean” should look like. The bible of Python style is PEP8, buy you can get some help from Pylint, if you wish. If you don’t know about Pylint, you can check it out online, or start with our blog post on the
ETA: 1 - 2 hours
Upgrade the code to add an optional “lockdown mode”, with a choice of lockdown length in days. It should, for example, allow to set a lockdown period of 40 days each time the relative proportion of infected people reaches 5%. During the lockdown, the contact rate is decreased tenfold.
The API must keep the possibility to NOT include a quarantine mode in the simulation. The result should look like this:
Don’t forget to send your code to your COOP contact.