10/15/19 7:38

The goal is to learn and explore L-Systems, as well as experiment with Jupyter Notebooks.

The purpose is to be able to model a basic L-System, then move on to more complex systems, with a focus on correctness of the model then visualization.

We will work on a concrete example first, then create a framework that can adapt to any (a large amount) L-System.

We will be using the examples from the L-Systems Wikipedia Article.

https://en.wikipedia.org/wiki/L-system#Examples_of_L-systems

```
util
# from https://stackoverflow.com/a/40857703/
def flatten(items):
"""Yield items from any nested iterable; see Reference."""
for x in items:
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
for sub_x in flatten(x):
yield sub_x
else:
yield x
```

We will use an enum to hold the variables of the current L-System

This system has no constants, so we will not create an enum for it this time.

This is the starting point/initial setup

We can think of rules as text replacements, or state function transitions. Something like that.

The algae example has two rules, \[ \begin{equation} (A \rightarrow AB), (B \rightarrow A) \end{equation} \]

We will be implementing these rules as one function.

`def rule(v: Variable) -> List[Variable]`

```
def rule(var: Variable) -> list:
if var == A:
return [A, B]
elif var == B:
return [A]
else:
print("FATAL: Unknown Variable: " + str(var))
```

Let’s inspect the results

`[<Variable.A: 'A'>, <Variable.B: 'B'>]`

`[<Variable.A: 'A'>]`

We will model the system state with the following Class

```
from typing import NamedTuple
class LSystem(NamedTuple):
n: int # the iteration number
state: list # the variables
```

We can describe our initial state as:

```
* n = 0
* state = axiom = [A]
```

`LSystem(n=0, state=[<Variable.A: 'A'>])`

Let’s define a transition function that can be used to model what happens in one iteration.

```
def transition(sys: LSystem, rule_func) -> LSystem:
new_state = []
# for each letter, apply the rule function
# and save the result to the new state
for letter in sys.state:
new_state += rule_func(letter)
return LSystem(sys.n + 1, list(flatten(new_state)))
```

This function will evalute an LSystem \(n\) number of times and output the final system

```
def evaluate(sys: LSystem, rule_func, n: int) -> LSystem:
for _ in range(n):
sys = transition(sys, rule_func)
return sys
```

This function converts the state list of an LSystem to a string for easier comprehension and comparison/validation with the examples in the wikipedia article.

`ABAABABAABAABABAABABAABAABABAABAAB`

The example for \(n = 7\) in wikipedia gives the following result: \(ABAABABAABAABABAABABAABAABABAABAAB\). Let’s see if our result matches this.

`True`

The purpose of the notebook was to explore L Systems, and correctly implement an example from Wikipedia. In this notebook, we have successfully implemented Example 1: *Algae*.