```python
from execnb.nbio import new_nb, mk_cell, read_nb, write_nb
from execnb.shell import exec_nb
from pathlib import Path
```
## Exploring This Snippet
I'm starting with a snippet of code from the bottom of execnb's 01_nbio.ipynb, breaking it down into pieces and seeing each part:
```python
nb = new_nb([mk_cell('print(1)')])
path = Path('test.ipynb')
write_nb(nb, path)
nb2 = read_nb(path)
print(nb2.cells)
path.unlink()
```
Funny, that original notebook built it up one cell at a time to get to that cell. Now I'm breaking down the finished result for myself to understand it better.
It looks clear and understandable enough. But just reading code doesn't build mental muscle memory. To truly learn I find I have to interact, evaluate cells, print things, and see what everything even the obvious does.
## About Post-Cell Explanations
I realize I've been writing before each cell instead of after. I'll try explaining after cells to better emulate Jeremy Howard's style. It's nice in a way because you get to look at the code and try to understand it for yourself first.
## Creating a Jupyter Notebook Programmatically
```python
nb = new_nb([mk_cell('print(1)')])
nb
```
Here I create a new notebook via `new_nb`. The outputs list is empty because this notebook cell hasn't been executed yet - I've only created the notebook structure in memory.
## Creating a Path to Write It To
```python
path = Path('test.ipynb')
path
```
Using standard pathlib here to create a path.
```python
print(path)
```
Printing it shows the relative path.
```python
path.absolute()
```
Here we can now see we're somewhere fun! So, relax and enjoy the rest of this experience.
## Writing and Rereading `test.ipynb`
```python
write_nb(nb, path)
```
```python
nb2 = read_nb(path)
nb2
```
Yay, we have written the notebook to test.ipynb and read it back in as nb2 successfully!
## Exploring the Cells
```python
nb2.cells
```
Here we see there's 1 cell, the one we originally created, as expected. This would be `nb2['cells']` if this were a normal dict, but we've got a nice fastcore `AttrDict` here with dot access.
```python
print(nb2.cells)
```
Printing the cells shows them on a single line.
## Cleaning Up Our Chef's Station
```python
path.unlink()
```
In pathlib, `unlink` deletes a file or symlink. We just deleted test.ipynb.
Careful with programmatic deletion of files. Keep the code as simple as possible. Here it's super-simple so we're fine.