'''
=======
widgets
=======
Tools relating to ipywidgets
'''
from collections import OrderedDict
import collections.abc, inspect
from IPython import display
import ipywidgets
from .renderers import html_table
[docs]def explore(obj):
'''
Interactive object explorer
Args:
obj: Object to introspect
This widget displays an object and some information about it (eg: its
signature, if it's callable) and provides a dropdown to select one of its
attributes. The selected attribute is displayed in the same way (including
a dropdown of the attribute's attributes.)
'''
def show_markdown(markdown):
display.display(display.Markdown(markdown.replace('>', '\\>')))
flag_predicates = {'callable': callable}
flag_predicates.update({k: v for k, v in vars(inspect).items() if k.startswith('is') and callable(v)})
show_markdown('### {typ}'.format(typ=type(obj).__name__))
display.display(obj)
flag_names = sorted(k[2:] for k, v in flag_predicates.items() if v(obj))
if flag_names:
show_markdown('_({})_'.format(', '.join(flag_names)))
if callable(obj):
try:
sig = inspect.signature(obj)
except:
show_markdown('_No signature available_')
sig = None
if sig is not None:
param_attrs = ['name', 'kind', 'default', 'annotation']
display.display(display.Markdown('##### Parameters'))
def str_or_null(x):
return '' if x is inspect._empty else str(x)
display.display(display.HTML(str(html_table([[str_or_null(getattr(p, a)) for a in param_attrs] for p in sig.parameters.values()],
header_row=param_attrs))))
attr_descriptions = OrderedDict([('', None)])
retval_key = '<return value>'
if callable(obj):
attr_descriptions[retval_key] = retval_key
attr_descriptions.update(('{val} ({typ})'.format(typ=type(getattr(obj, k)).__name__, val=k), k) for k in dir(obj))
@ipywidgets.interact(attribute=attr_descriptions)
def explore_attr(attribute):
if attribute is not None:
explore(obj() if attribute == retval_key else getattr(obj, attribute))
def _replace_literals(template, substitutions):
'''
Make multiple literal replacements in a template string.
This can be more convenient than :meth:`str.format` when the format
string contains {} characters.
Args:
template (str): Template string in which to make replacements
substitutions (:class:`collections.ABC.Mapping` or :class:`collections.ABC.Iterable`): pairs of: (<string to replace>, <replacement>)
Returns: str
Example:
>>> _replace_literals('soup to nuts', {'soup': 'farewell', 'nuts': 'arms'})
'farewell to arms'
>>> js_template = 'function my_fun() {x = 1/*replace this*/; return x;}'
>>> replacements = {'1/*replace this*/': 3}
>>> _replace_literals(js_template, replacements)
'function my_fun() {x = 3; return x;}'
'''
result = template
for k, v in (substitutions.items() if isinstance(substitutions, collections.abc.Mapping) else substitutions):
result = result.replace(str(k), str(v))
return result
[docs]def notebook_full_width():
'''
Make the cells in the notebook the full width of the browser window.
'''
display.display(display.HTML("<style>.container { width:100% !important; }</style>"))
if __name__ == '__main__':
import doctest
doctest.testmod()