# Project 3

## Problem 1

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:

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

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

## Problem 2

### Part 1

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!

### Part 2

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
...
...


### Part 3

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.

## Problem 3

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>