This time we've got a list of email addresses saved in "email-addr.txt". We want to read this list from the file and perform the following two tasks:

Print out the email addresses from either an illinois.edu or gmail.com hostname.

Print out the emails addresses ending with a .edu extension.

We'll write a simple ODE time-stepper for the harmonic oscilator:

$$ \ddot{x}(t) + x(t) = 0 $$As a first step, we'll rewrite this as a system of ODEs in $x(t)$ and $v(t)$ as:

$$ \begin{align} \dot{x}(t) &= v(t) \\ \dot{v}(t) &= -x(t) \end{align} $$Our method will work as follows: First, pick an initial $x_0$, $v_0$ and a time-step $h$. Then, repeat the time-step:

$$ \begin{align} x_{n+1} &= x_n + h \cdot v_n \\ v_{n+1} &= v_n - h \cdot x_{n+1} \end{align} $$Implement this method and keep track of the time, position and velocity at each step.

*Warning! If you've seen basic time-stepping methods before, this isn't plain Euler's method! Notice that $v_{n+1}$ depends on $x_{n+1}$! This is one of the simplest examples of a so-called symplectic integrator...which you could very likely discover as a mis-implementation of plain Euler's method!*

Simulate the system up until at least $t=2 \pi$. Write the time, position and velocity to a file 'trajectory.txt'. You should use a format like:

t0 x0 v0 t1 x1 v1 t2 x2 v2 ... ...

Write a second program which reads the entries from 'trajectory.txt' back into a list of floats. We want to use Matplotlib to turn this data into two plots.

The first plot will be an $x$-$v$ scatter plot in the phase space. To do this, we can use Matplotlib's `scatter` function just like we did with the histogram function

plt.scatter(x, v)

Just give `scatter` a list of x-values and a list of v-values to produce the plot. You should expect to get a circle for this one. (*Though it may show up as an ellipse due to axes scaling!*)

The second plot will be a plot of $t$-$x$ and $t$-$v$ together in the same plot. To do this, we can use Matplotlib's aptly-named `plot` function.

plt.plot(t, x) plt.plot(t, v)

Where `t` is our list of `t`-values and `x` and `v` are our list of `x` and `v` values respectively. You should expect to get two oscilatory functions out of phase with each other.

In this problem, we're going to draw a Koch snowflake!

We'll do this by designing our very own mini programming language representing an L-system.

Our language will have a very simple syntax! It will just be strings consisting of the characters F, + and -. These are going to translate into commands "Move Forward By Distance 1", "Turn Right By $\pi$/3" and "Turn Left By $\pi$/3" respectively.

For example, the program "F++F++F" means:

go forward turn by pi/3 turn by pi/3 go forward turn by pi/3 turn by pi/3 go forward

In order to run this program, we'll keep track of a marker at some initial $(x, y)$ position along with an angle $\theta$ that it's facing.

Each symbol will update the $(x, y)$ position or the angle $\theta$ according to it's corresponding command description.

In order to draw the final snowflake, we'll keep track of of all the $(x, y)$ positions we've been to in a list. (It's probably easiest to append the new position after every move forward command.)

*Note that the plot function isn't restricted to graphs of functions! It can draw arbitrary polygons described by (x, y) coordinates.*

Once that is implemented, we'll draw a snowflake by using the following program:

prog = "F++F++F"

Unfortunately, this only draws a triangle... To do better, what we want to do is apply a rewrite rule to transform the program

F -> F−F++F−F

This can be done by using the `replace` command for strings. For example,

s = "Hello!" s.replace("l", "#*") -> "He#*#*o!"

*Once you have this working, you should feel good about designing your own small fractal programming language! :-)*

See if you can extend it to draw other fractals! I think if you read a bit more into L-systems, there should be more examples there. </em>