This notebook contains material from CBE40455-2020; content is available on Github.
As a simple demonstration, let's consider the task of modeling the progess of a disease in a single person. The person will go through several stages of the disease
$$\text{Uninfected} \quad \longrightarrow \quad \text{Exposed} \quad \longrightarrow \quad \text{Infectious} \quad \longrightarrow \quad \text{Recovered}$$Python generators are the basic building block for discrete event simulation in Python. Python generators are similar to functions with three profound differences:
yield
statement rather than a return
statement. They don't disappear from memory until all statements have been executed.next
statement.def a_function():
return 3
a_function()
def a_generator():
yield 3
a_generator()
Using a generator is different from a function because they don't disappear from memory
a = a_generator()
next(a)
Let's create a generator that can return multiple values.
def my_first_generator():
yield 1
yield 2
yield 3
yield 4
a = my_first_generator()
print(next(a))
Let's get the next value.
print(next(a))
Let's create a second instance of the same generator.
b = my_first_generator()
print(next(b))
Note how the instances each retain a unique state.
print(next(a))
print(next(b))
Create a generator that produces a sequence of successive squares.
def succ_sq():
k = 0
while True:
yield k**2
k = k + 1
a = succ_sq()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
Create generator that creates the Fibonacci sequence
$$\begin{align*} F_0 & = 0 \\ F_1 & = 1 \\ F_{n} &= F_{n-1} + F_{n-2} \end{align*}$$def fib():
a = 0
b = 1
yield a
yield b
while True:
a, b = b, a+b
yield b
f = fib()
for k in range(0, 20):
print(next(f))
Write a Python generator that simulates the response of a differential equation describing concentration in a stirred tank reactor.
$$\frac{dC}{dt} = -k C + q(t)$$where k = 1.0, C(0) = 1.0 and q(t) = 0.5. Use Euler's approximation.
q = 0.5
def reactor(dt, k):
C = 1.0
t = 0.0
while t <= 5.0:
yield t, C
t = t + dt
C = C - k*C*dt + q*dt
a = reactor(0.2, 1.0)
for t, C in a:
print(round(t, 2), round(C, 3))