In [33]:

```
def sawtooth_wave(teeth, base=2, height=3):
xy = [(0, 0)] # start
for n in range(teeth):
xy += [(base * (n + 1), height), (base * (n + 1), 0)]
xy.append((0, 0)) # return to start
return zip(*xy) # x then y
```

In [34]:

```
from pprint import pprint as pp
from bokeh.plotting import figure, output_notebook, show
from bokeh.models import ColumnDataSource
from bokeh.charts import Scatter
output_notebook()
```

In [35]:

```
teeth = 3
sawx, sawy = sawtooth_wave(teeth)
sawx, sawy = zip(*saw)
pl = figure(plot_width=400, plot_height=400, title=f'Sawtooth polygon with {teeth} right-angled triangle teeth')
#help(pl.line)
pl.line(sawx, sawy, line_width = 1, line_color="navy")
show(pl)
```

In [36]:

```
def area_by_shoelace(x, y):
"Assumes x,y points go around the polygon in one direction"
return abs( sum(i * j for i, j in zip(x, y[1:])) + x[-1] * y[0]
-sum(i * j for i, j in zip(x[1:], y)) - x[0] * y[-1]) / 2
```

In [37]:

```
print(" Area is:", area_by_shoelace(sawx, sawy))
```