When notebooks become modules, you can do some playful things with custom IPython reprs.
On an object
, IPython will recognize attributes beginning with _repr_*_
if *
is in values like html
, markdown
, svg
, png
__import__(__name__)
<module '__main__'>
__import__('__main__')
wraps in the current IPython session as a module. But, the repr does not inform the author much.
Ø = '__main__' == __name__
if Ø:
import deathbeds.__IPython_repr__ as reprs
print(reprs)
<module 'deathbeds.2018-07-09-IPython-reprs' from 'c:\\users\\deathbeds\\deathbeds.github.io\\deathbeds\\2018-07-09-IPython-reprs.ipynb'>
The module's imported representation informs the author about its name and location. This is most useful for the computer, and rarely the author.
If we name function as the names for custom IPython reprs
.
from matplotlib.pyplot import gcf
from base64 import b64decode, b64encode
import pandas as pd
df = pd.util.testing.makeDataFrame()
with __import__('io').BytesIO() as bit:
df.plot(); gcf().savefig(bit, format='png')
img = bit.getvalue()
_repr_png_ = lambda: b64encode(img).decode('utf-8')
module = __import__(__name__)
assert isinstance(module, __import__('types').ModuleType)
module # There is a png in the repr.
with __import__('io').BytesIO() as jpg:
df.plot(); gcf().savefig(jpg, format='jpg')
jpg = jpg.getvalue()
_repr_jpeg_ = lambda: b64encode(jpg).decode('utf-8')
with __import__('io').BytesIO() as svg:
df.plot(); gcf().savefig(svg, format='svg')
svg = svg.getvalue()
_repr_svg_ = lambda: svg.decode('utf-8')
__import__(__name__)
An author could prettify their reports with markdown. We had to start with images because markdown will take precedence.
_repr_markdown_ = lambda: f"""# I am a markdown repr
The `_repr_markdown_` function does recieve a self argument or take and arguments. And,
conveniently we have access to the scope of `{reprs}`
"""
__import__(__name__) # There is a md & images in the repr.
The _repr_markdown_
function does recieve a self argument or take and arguments. And,
conveniently we have access to the scope of <module 'deathbeds.2018-07-09-IPython-reprs' from 'c:\\users\\deathbeds\\deathbeds.github.io\\deathbeds\\2018-07-09-IPython-reprs.ipynb'>
png
and markdown
reprs are stored in the notebook format.After running this post, we can load in the saved state of the notebook.
if Ø:
from nbformat.v4 import reads
from pathlib import Path
df = pd.read_json(reprs.__file__, typ='Series').pipe(
lambda s: pd.DataFrame(s.loc['cells']))
outputs = df['outputs'].apply(pd.Series).set_index(df['source'].str.join('\n')).stack()
We can observe the incremental addition of new reprs to the output of our notebook.
Ø and outputs.apply(lambda x: x.get('data', None)).dropna().apply(dict.keys).apply(list).apply(pd.Series).fillna('')
0 | 1 | 2 | 3 | 4 | ||
---|---|---|---|---|---|---|
source | ||||||
__import__(__name__) | 0 | text/plain | ||||
from matplotlib.pyplot import gcf\n\n from base64 import b64decode, b64encode\n\n import pandas as pd\n\n\n\n df = pd.util.testing.makeDataFrame()\n\n with __import__('io').BytesIO() as bit:\n\n df.plot(); gcf().savefig(bit, format='png')\n\n img = bit.getvalue()\n\n\n\n _repr_png_ = lambda: b64encode(img).decode('utf-8') | 0 | image/png | text/plain | |||
module = __import__(__name__)\n\n assert isinstance(module, __import__('types').ModuleType)\n\n module # There is a png in the repr. | 0 | image/png | text/plain | |||
with __import__('io').BytesIO() as jpg:\n\n df.plot(); gcf().savefig(jpg, format='jpg')\n\n jpg = jpg.getvalue()\n\n _repr_jpeg_ = lambda: b64encode(jpg).decode('utf-8') | 0 | image/png | text/plain | |||
with __import__('io').BytesIO() as svg:\n\n df.plot(); gcf().savefig(svg, format='svg')\n\n svg = svg.getvalue()\n\n _repr_svg_ = lambda: svg.decode('utf-8') | 0 | image/png | text/plain | |||
__import__(__name__) | 0 | image/jpeg | image/png | image/svg+xml | text/plain | |
__import__(__name__) # There is a md & images in the repr. | 0 | image/jpeg | image/png | image/svg+xml | text/markdown | text/plain |
Ø and outputs.apply(lambda x: x.get('data', None)).dropna().apply(dict.keys).apply(list).apply(pd.Series).fillna('') | 0 | text/html | text/plain | |||
if Ø: import disqus | 0 | text/html | text/plain |
if Ø: import disqus