#!/usr/bin/env python # coding: utf-8 # > This is one of the 100 recipes of the [IPython Cookbook](http://ipython-books.github.io/), the definitive guide to high-performance scientific computing and data science in Python. # # # 3.1. Teaching programming in the notebook with IPython blocks # You need to install ipythonblocks for this recipe. You can just type in a terminal `pip install ipythonblocks`. Note that you can also execute this shell command from the IPython notebook by prefixing this command with `!`. # In[ ]: get_ipython().system('pip install ipythonblocks') # For the last part of this recipe, you also need to install Pillow: you will find more instructions in Chapter 11. (https://python-pillow.org/) # Finally, you need to download the *Portrait* image on the [book's website](http://ipython-books.github.io) and extract it in the current directory. You can also play with your own images! # 1. First, we import some modules. # In[ ]: import time from IPython.display import clear_output from ipythonblocks import BlockGrid, colors # 2. Now, we create a **block grid** with 5 columns and 5 rows, and we fill each block in purple. # In[ ]: grid = BlockGrid(width=5, height=5, fill=colors['Purple']) grid.show() # 3. We can access individual blocks with 2D indexing. This illustrates the indexing syntax in Python. We can also access an entire row or line with `:` (colon). Each block is represented by an RGB color. The library comes with a handy dictionary of colors, assigning RGB tuples to standard color names. # In[ ]: grid[0,0] = colors['Lime'] grid[-1,0] = colors['Lime'] grid[:,-1] = colors['Lime'] grid.show() # 4. Now, we are going to illustrate **matrix multiplication**, a fundamental notion in linear algebra. We will represent two $(n,n)$ matrices $A$ (in cyan) and $B$ (lime) aligned with $C=A \cdot B$ (yellow). To do this, we use a small trick consisting in creating a big white grid of size $(2n+1,2n+1)$. The matrices $A$, $B$ and $C$ are just *views* on parts of the grid. # In[ ]: n = 5 grid = BlockGrid(width=2*n+1, height=2*n+1, fill=colors['White']) A = grid[n+1:,:n] B = grid[:n,n+1:] C = grid[n+1:,n+1:] A[:,:] = colors['Cyan'] B[:,:] = colors['Lime'] C[:,:] = colors['Yellow'] grid.show() # 5. Let's turn to matrix multiplication itself. We perform a loop over all rows and columns, and we highlight the corresponding rows and columns in $A$ and $B$ that are multiplied together during the matrix product. We combine IPython's `clear_output()` method with `grid.show()` and `time.sleep()` (pause) to implement the animation. # In[ ]: for i in range(n): for j in range(n): # We reset the matrix colors. A[:,:] = colors['Cyan'] B[:,:] = colors['Lime'] C[:,:] = colors['Yellow'] # We highlight the adequate rows # and columns in red. A[i,:] = colors['Red'] B[:,j] = colors['Red'] C[i,j] = colors['Red'] # We animate the grid in the loop. clear_output() grid.show() time.sleep(.25) # 6. Finally, we will display an image with IPython blocks. We import the JPG image with `Image.open()` and we retrieve the data with `getdata()`. # In[ ]: from PIL import Image imdata = Image.open('data/photo.jpg').getdata() # Now, we can create a `BlockGrid` with the appropriate number of rows and columns, and set each block's color to the corresponding pixel's color in the image. We use a small block size, and we remove the lines between the blocks. # In[ ]: width, height = imdata.size grid = BlockGrid(width=width, height=height, block_size=4, lines_on=False) for block, rgb in zip(grid, imdata): block.rgb = rgb grid.show() # > You'll find all the explanations, figures, references, and much more in the book (to be released later this summer). # # > [IPython Cookbook](http://ipython-books.github.io/), by [Cyrille Rossant](http://cyrille.rossant.net), Packt Publishing, 2014 (500 pages).