This set of IPython magic extensions is provided to the first year students enrolled in the algorithmics course at ISFATES (University of Lorraine).

Installation

In a Jupyter Notebook cell, simply paste this in a new cell and run it (shift-enter).


In [ ]:
!pip install algo_magic

Alternatively, under an open terminal:

pip install algo_magic

Loading

Manual

When you open or reopen a Jupyter notebook, you need to load the set of extensions before using any of them:


In [ ]:
%load_ext algo_magic

Automatic

If you are tired of typing the previous command, you can make algo_magic load automatically each time you open a new notebook. Execute the following command under an open terminal:

  ipython profile create

Locate and edit the created file (e.g.: ~/.ipython/profile_default/ipython_config.py) and replace the following lines:

  ## A list of dotted module names of IPython extensions to load.
  #c.InteractiveShellApp.extensions = []

by these ones:

  ## A list of dotted module names of IPython extensions to load.
  c.InteractiveShellApp.extensions = [
      "algo_magic",
  ]

Save the modified file and you are done.

Usage

pep8

This extension is a thin wrapper around YAPF, a general formatter for Python files. Use it to reformat a cell code along the rules of PEP 8, the official style guide for Python code. For example, evaluating this piece of shit:


In [ ]:
%%pep8
x = {  'a':37,'b':42,

'c':927}

y = 'hello ''world'
z = 'hello '+'world'
a = 'hello {}'.format('world')
class foo  (     object  ):
  def f    (self   ):
    return       37*-+2
  def g(self, x,y=42):
      return y
def f  (   a ) :
  return      37+-+a[42-x :  y**3]

... will replace the cell contents with:


In [4]:
x = {'a': 37, 'b': 42, 'c': 927}

y = 'hello ' 'world'
z = 'hello ' + 'world'
a = 'hello {}'.format('world')


class foo(object):
    def f(self):
        return 37 * -+2

    def g(self, x, y=42):
        return y


def f(a):
    return 37 + -+a[42 - x:y**3]

You also can load a reformatted version of any given file, without modifying it on disk:


In [ ]:
%pep8 shit.py

tutor

This extension visualizes the execution of a cell under Online Python Tutor, created by Philip Guo.


In [6]:
%%tutor 640x400
a = 1
b = 2

aux = a
a = b
b = aux

print(a, b)


Specifying the size of the embedded frame is optional.

With a single %, you also can visualize the execution of a given Python file:


In [ ]:
%tutor swap.py

truth

This extension generates the truth table of a given boolean formula.


In [8]:
%truth a and b


| a     | b     | a and b |
|-------|-------|---------|
| False | False | False   |
| False | True  | False   |
| True  | False | False   |
| True  | True  | True    |

You may hide the result:


In [9]:
%truth? a and b


| a     | b     | a and b |
|-------|-------|---------|
| False | False |         |
| False | True  |         |
| True  | False |         |
| True  | True  |         |

Replace False and True by conventional single characters:


In [10]:
%truth01 a and b


| a | b | a and b |
|---|---|---------|
| 0 | 0 | 0       |
| 0 | 1 | 0       |
| 1 | 0 | 0       |
| 1 | 1 | 1       |

In [11]:
%truthFV a and b


| a | b | a and b |
|---|---|---------|
| F | F | F       |
| F | V | F       |
| V | F | F       |
| V | V | V       |

In [12]:
%truthFT a and b


| a | b | a and b |
|---|---|---------|
| F | F | F       |
| F | T | F       |
| T | F | F       |
| T | T | T       |

You can easily compare several boolean expressions, given on one or several lines:


In [13]:
%truth a ^ b, (a and not b) or (not a and b)


| a     | b     | a ^ b | (a and not b) or (not a and b) |
|-------|-------|-------|--------------------------------|
| False | False | False | False                          |
| False | True  | True  | True                           |
| True  | False | True  | True                           |
| True  | True  | False | False                          |

In [14]:
%truth a and b, ? not(a and b), not a, not b, ? not a or not b


| a     | b     | a and b | not(a and b) | not a | not b | not a or not b |
|-------|-------|---------|--------------|-------|-------|----------------|
| False | False | False   |              | True  | True  |                |
| False | True  | False   |              | True  | False |                |
| True  | False | False   |              | False | True  |                |
| True  | True  | True    |              | False | False |                |

In [15]:
%%truth
a and b
? not(a and b)
not a
not b
? not a or not b


| a     | b     | a and b | not(a and b) | not a | not b | not a or not b |
|-------|-------|---------|--------------|-------|-------|----------------|
| False | False | False   |              | True  | True  |                |
| False | True  | False   |              | True  | False |                |
| True  | False | False   |              | False | True  |                |
| True  | True  | True    |              | False | False |                |

Note that the generated tables can be pasted in a Markdown cell in order to appear as:

a b a and b not(a and b) not a not b not a or not b
False False False True True
False True False True False
True False False False True
True True True False False

Limitation. The boolean variables must consist in one single character.

dis

A thin wrapper around the standard disassembler for CPython bytecode. Especially useful for comparing two variants of the same snippet, for instance:


In [1]:
%%dis
if max_so_far < current_value:
    max_so_far = current_value


  1           0 LOAD_NAME                0 (max_so_far)
              3 LOAD_NAME                1 (current_value)
              6 COMPARE_OP               0 (<)
              9 POP_JUMP_IF_FALSE       18

  2          12 LOAD_NAME                1 (current_value)
             15 STORE_NAME               0 (max_so_far)
        >>   18 LOAD_CONST               0 (None)
             21 RETURN_VALUE
None

In [2]:
%dis max_so_far = max(max_so_far, current_value)


  1           0 LOAD_NAME                0 (max)
              3 LOAD_NAME                1 (max_so_far)
              6 LOAD_NAME                2 (current_value)
              9 CALL_FUNCTION            2 (2 positional, 0 keyword pair)
             12 STORE_NAME               1 (max_so_far)
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE
None