{ "metadata": { "name": "ipythonblocks_demo" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "ipythonblocks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is a demo of the `ipythonblocks` module available at [https://github.com/jiffyclub/ipythonblocks](https://github.com/jiffyclub/ipythonblocks). `ipythonblocks` provides a `BlockGrid` object whose representation is an HTML table. Individual table cells are represented by `Block` objects that have `.red`, .`green`, and `.blue` attributes by which the color of that cell can be specified.\n", "\n", "`ipythonblocks` is a teaching tool that allows students to experiment with Python flow control concepts and immediately see the effects of their code represented in a colorful, attractive way. `BlockGrid` objects can be indexed and sliced like 2D NumPy arrays making them good practice for learning how to access arrays." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from ipythonblocks import BlockGrid" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "code", "collapsed": false, "input": [ "grid = BlockGrid(10, 10, fill=(123, 234, 123))" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "code", "collapsed": false, "input": [ "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 3, "text": [ "" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "grid[0, 0]" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 4, "text": [ "" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "`BlockGrid` objects support iteration for quick access to individual blocks. `Block`s have `.row` and `.col` attributes (zero-based) to help track where in the grid you are. The individual color channels on each `Block` can be modified directly." ] }, { "cell_type": "code", "collapsed": false, "input": [ "for block in grid:\n", " if block.row % 2 == 0 and block.col % 3 == 0:\n", " block.red = 0\n", " block.green = 0\n", " block.blue = 0\n", "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 5, "text": [ "" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "`BlockGrid` objects have `.height` and `.width` attributes to facilitate loops over the grid. Individual `Block`s can be accessed via Python- or NumPy-like indexing." ] }, { "cell_type": "code", "collapsed": false, "input": [ "for r in range(grid.height):\n", " for c in range(grid.width):\n", " sq = grid[r, c]\n", " sq.red = 100\n", " \n", " if r % 2 == 0:\n", " sq.green = 15\n", " else:\n", " sq.green = 255\n", " \n", " if c % 2 == 0:\n", " sq.blue = 15\n", " else:\n", " sq.blue = 255" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `BlockGrid.show()` method can also be used to display the grid or individual blocks." ] }, { "cell_type": "code", "collapsed": false, "input": [ "grid.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "grid[5, 5].show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Slicing a `BlockGrid` returns a new `BlockGrid` object that is a view of the original, much like NumPy arrays." ] }, { "cell_type": "code", "collapsed": false, "input": [ "sub_grid = grid[:, 5]\n", "sub_grid.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "for block in sub_grid:\n", " block.red = 255" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "sub_grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 11, "text": [ "" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 12, "text": [ "" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Slicing can be used with iteration to work on a sub-grid. The `Block.set_colors` method can be used to update all the colors at once." ] }, { "cell_type": "code", "collapsed": false, "input": [ "for block in grid[2:6, 2:4]:\n", " block.set_colors(245, 178, 34)\n", "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 13, "text": [ "" ] } ], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like NumPy arrays, the `BlockGrid.copy()` method can be used to get a completely independent copy of the grid or slice." ] }, { "cell_type": "code", "collapsed": false, "input": [ "sub_copy = grid[3:-3, 3:-3].copy()\n", "sub_copy.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "sub_copy[:] = (0, 0, 0)\n", "sub_copy.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 16, "text": [ "" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Blocks can also be modified by assigning RGB tuples. This type of assignment can be used on individual blocks, or on slices to change many blocks at once." ] }, { "cell_type": "code", "collapsed": false, "input": [ "grid[5] = (0, 0, 0)\n", "grid.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 17 }, { "cell_type": "code", "collapsed": false, "input": [ "grid[:, 5] = (255, 0, 0)\n", "grid.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 18 }, { "cell_type": "code", "collapsed": false, "input": [ "grid[-3:, -3:] = (0, 124, 124)\n", "grid.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 19 }, { "cell_type": "code", "collapsed": false, "input": [ "grid[1, 1] = (255, 255, 255)\n", "grid.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 20 }, { "cell_type": "code", "collapsed": false, "input": [ "grid[:, :] = (123, 234, 123)\n", "grid.show()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "display_data", "text": [ "" ] } ], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The displayed size of blocks (in pixels) can be controlled with the `block_size` keyword, allowing some flexibility in how many blocks can comfortably fit on the screen." ] }, { "cell_type": "code", "collapsed": false, "input": [ "grid = BlockGrid(50, 50, block_size=5)\n", "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 22, "text": [ "" ] } ], "prompt_number": 22 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The block display size can be modified at any time by changing the `BlockGrid.block_size` attribute." ] }, { "cell_type": "code", "collapsed": false, "input": [ "grid.block_size = 2\n", "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 23, "text": [ "" ] } ], "prompt_number": 23 }, { "cell_type": "markdown", "metadata": {}, "source": [ "And the grid lines between individual cells can be toggled by setting the `BlockGrid.lines_on` attribute." ] }, { "cell_type": "code", "collapsed": false, "input": [ "grid.lines_on = False\n", "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 24, "text": [ "" ] } ], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "grid.lines_on = True\n", "grid" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
" ], "output_type": "pyout", "prompt_number": 25, "text": [ "" ] } ], "prompt_number": 25 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }