<jupyter_start><jupyter_text>Custom Display Logic Exercises<jupyter_code>from IPython.display import display
from IPython.display import (
    display_png, display_html, display_latex,
    display_javascript, display_svg
)<jupyter_output><empty_output><jupyter_text>Circle class with custom display methods Write a simple `MyCircle` Python class. Here is a skeleton to get you started:```pythonclass MyCircle(object):    def __init__(self, center=(0.0,0.0), radius=1.0, color='blue'):        self.center = center        self.radius = radius        self.color = color```Now add special display methods to this class for the following representations (remember to wrap them in Python strings):For HTML:    &x25CB;For SVG:                For LaTeX (wrap with `$` and use a raw Python string):    \bigcircFor JavaScript:    alert('I am a circle!');After you write the class, create an instance and then use `display_html`, `display_svg`, `display_latex` and `display_javascript` to display those representations.  Solution Here is the solution to the simple `MyCircle` class:<jupyter_code># %load -s MyCircle soln/mycircle.py
class MyCircle(object):

    def __init__(self, center=(0.0,0.0), radius=1.0, color='blue'):
        self.center = center
        self.radius = radius
        self.color = color

    def _repr_html_(self):
        return "&#x25CB; (<b>html</b>)"

    def _repr_svg_(self):
        return """<svg width="100px" height="100px">
           <circle cx="50" cy="50" r="20" stroke="black" stroke-width="1" fill="blue"/>
        </svg>"""
    
    def _repr_latex_(self):
        return r"$\bigcirc \LaTeX$"

    def _repr_javascript_(self):
        return "alert('I am a circle!');"<jupyter_output><empty_output><jupyter_text>Now create an instance and use the display methods:<jupyter_code>c = MyCircle()
#display(c)
display_html(c)
display_svg(c)
display_latex(c)
#display_javascript(c)<jupyter_output><empty_output><jupyter_text>PNG formatter for `MyCircle`<jupyter_code>%matplotlib inline
from matplotlib import pyplot as plt<jupyter_output><empty_output><jupyter_text>Now let's assume that the `MyCircle` class has already been defined and add a PNG representation using a formatter display function. Here is a function that converts a `MyCircle` instance to raw PNG data.<jupyter_code>from IPython.core.pylabtools import print_figure

def circle_to_png(circle):
    """Render AnotherCircle to png data using matplotlib"""
    fig, ax = plt.subplots()
    patch = plt.Circle(circle.center,
                       radius=circle.radius,
                       fc=circle.color,
                       )
    ax.add_patch(patch)
    plt.axis('scaled')
    data = print_figure(fig, 'png')
    # We MUST close the figure, otherwise IPython's display machinery
    # will pick it up and send it as output, resulting in a double display
    plt.close(fig)
    return data<jupyter_output><empty_output><jupyter_text>Now use the IPython API to get the PNG formatter (`image/png`) and call the `for_type` method to register `circle_to_png` as the display function for `MyCircle`.<jupyter_code># %load soln/mycircle_png.py
ip = get_ipython()
png_f = ip.display_formatter.formatters['image/png']
png_f.for_type(MyCircle, circle_to_png)
display_png(c)<jupyter_output><empty_output><jupyter_text>PNG formatter for NumPy arrays In this exercise, you will register a display formatter function that generates a PNG representation of a 2d NumPy array. Here is the function that uses the [Python Imaging Library (PIL)](http://www.pythonware.com/products/pil/) to generate the raw PNG data:<jupyter_code>from PIL import Image
from io import BytesIO
import numpy as np

def ndarray_to_png(x):
    if len(x.shape) != 2: return
    x = np.asarray(Image.fromarray(x).resize((500, 500)))
    x = (x - x.min()) / (x.max() - x.min())
    img = Image.fromarray((x*256).astype('uint8'))
    img_buffer = BytesIO()
    img.save(img_buffer, format='png')
    return img_buffer.getvalue()<jupyter_output><empty_output><jupyter_text>Use the `for_type` method of the PNG formatter to register `ndarray_to_png` as the display function for `np.ndarray`.<jupyter_code># %load soln/ndarray_png.py
ip = get_ipython()
png_f = ip.display_formatter.formatters['image/png']
png_f.for_type(np.ndarray, ndarray_to_png)<jupyter_output><empty_output><jupyter_text>Now create a few NumPy arrays and display them. Notice that their default representation in the Notebook is PNG rather than text.<jupyter_code>a = np.random.rand(100,100)
a<jupyter_output><empty_output><jupyter_text>You can still display the plain text representation using the `display_pretty` function.<jupyter_code>from IPython.display import display_pretty
display_pretty(a)
b = np.linspace(0,100.0, 100**2).reshape((100,100))
b<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10773077724525942, 'fraction_numerical': 0.012919358199624921, 'mean_word_length': 4.607476635514018, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '113075', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1610, 'n_tokens_neox': 1541, 'n_words': 441, 'path': '001-Jupyter/001-Tutorials/003-IPython-in-Depth/exercises/IPython Kernel/Custom Display Logic Exercises.ipynb', 'repo_name': 'willirath/jupyter-jsc-notebooks', 'size': '4799'}