Python Tutor tests

There are various ways to embed Python tutor, first we put the recommended one.

RECOMMENDED: You can put a call to jupman.pytut() at the end of a cell, and the cell code will magically appear in python tutor in the output (except the call to pytut() of course). Does not need internet connection.

[1]:
import sys
sys.path.append('../')
import jupman
[2]:
lst = [5,8,4,10,30,20,40,50,60,70,20,30]

for x in lst:
    y = x * 2

jupman.pytut()
[2]:
Python Tutor visualization

Scope

BEWARE of variables which were initialized in previous cells, they WILL NOT be available in Python Tutor:

[3]:
w = 8
[4]:
x =  w + 5
jupman.pytut()
Traceback (most recent call last):
  File "../jupman.py", line 2453, in _runscript
    self.run(script_str, user_globals, user_globals)
  File "/usr/lib/python3.7/bdb.py", line 578, in run
    exec(cmd, globals, locals)
  File "<string>", line 2, in <module>
NameError: name 'w' is not defined
[4]:
Python Tutor visualization

Data types

Data display review:

[5]:
word = "wonder"
lst = [9,7,8]
t = (6,2,4,3)
mixed_set = {3,'b','e',9, 'm', 'n'}
numbers_set = {3,4,9}
char_set = {'r','a','h'}
d = {'a' : 8,
     'b' : 4,
     'c' : 5}

empty_str = ""
empty_tuple = ()
empty_set = set()
empty_dict = {}

#import numpy  # not supported!

def f(par):
    print(par)

class C:
    def hello():
        print('ciao')

    def __init__(self, name, age):
        self.name = name
        self.age = age

m = C.hello
g = f

c = C('blah',30)

jupman.pytut()
[5]:
Python Tutor visualization

Window overflow

When too much right space is taken, it might be difficult to scroll:

[6]:
x = [3,2,5,2,42,34,2,4,34,2,3,4,23,4,23,4,2,34,23,4,23,4,23,4,234,34,23,4,23,4,23,4,2]

jupman.pytut()
[6]:
Python Tutor visualization
[7]:
x =  w + 5
jupman.pytut()
Traceback (most recent call last):
  File "../jupman.py", line 2453, in _runscript
    self.run(script_str, user_globals, user_globals)
  File "/usr/lib/python3.7/bdb.py", line 578, in run
    exec(cmd, globals, locals)
  File "<string>", line 2, in <module>
NameError: name 'w' is not defined
[7]:
Python Tutor visualization

pytut execution

Some cells might execute in Jupyter but not so well in Python Tutor, due to its inherent limitations:

[8]:
x = 0
for i in range(10000):
    x += 1
print(x)
jupman.pytut()
10000
[8]:
Python Tutor visualization

Infinite loops

Since execution occurs first in Jupyter and then in Python tutor, if you have an infinite loop no Python Tutor instance will be spawned:

while True:
    pass

jupman.pytut()

Resizability

Long vertical and horizontal expansion should work:

[9]:
x = {0:'a'}
for i in range(1,30):
    x[i] = x[i-1]+str(i*10000)
jupman.pytut()
[9]:
Python Tutor visualization

Cross arrows

With multiple visualizations, arrows shouldn’t cross from one to the other even if underlying script is loaded multiple times (relates to visualizerIdOverride)

[10]:
x = [1,2,3]


jupman.pytut()
[10]:
Python Tutor visualization

Alignment test 1

Test for https://github.com/DavidLeoni/jupman/issues/105

Before fixing red arrow was badly misaligned and went way past the function call.

[12]:
def f(mat, i):
    """  Do something"""

    row = []
    row.append(mat[i ])
    return row

f([[2,3,4]], 0)
jupman.pytut()
[12]:
Python Tutor visualization

Alignment test 2

Check the arrow stays on right line even in long code.

[13]:
def f(mat, i):
    """  Do something else"""

    row = []
    row.append(mat[i])
    return row

m = [
      ['a','b'],
      ['c','d'],
      ['a','e'],
]

#row = f(m,0)

x = 3
if x == x:
    m = [
        [1,2,3],
        [4,3]
    ]
print("zim")

y = 1
if y == y:
    m = [
        [1,2,3],
        [4,3]
    ]
print("zam")


jupman.pytut()
zim
zam
[13]:
Python Tutor visualization

Cloned cell test

Tests PythonTutor output is correctly displayed when cells are cloned (solved issue)

[14]:
maremma = 123
jupman.pytut()
[14]:
Python Tutor visualization

Cloned cell:

[15]:
maremma = 123
jupman.pytut()
[15]:
Python Tutor visualization

Don’t nest data structures

By default data structures shouldn’t be displayed as nested (which is the actual default on Python Tutor site). Test for this issue

[16]:
listA = [ ['Keep', 'an'],
          ['eye', 'on'],
          ['the', 'arrow', 'tips']
]

listB = listA.copy()
jupman.pytut()
[16]:
Python Tutor visualization

Force nested data structures

[17]:
listA = [ ['Keep', 'an'],
          ['eye', 'on'],
          ['the', 'arrow', 'tips']
]

listB = listA.copy()
jupman.pytut(disableHeapNesting=False)
[17]:
Python Tutor visualization

Function pointers

Containers should always contain links to functions, not inlined names

[18]:

def f(): print('hello') def g(): print('world') fs = [f,g] jupman.pytut()
[18]:
Python Tutor visualization

Errors - Code after pytut

[19]:
x = 3

jupman.pytut()

print("ciao")
ERROR: the call to jupman.pytut() must be the last in the cell, instead, found this code afterwards:


print("ciao")
ciao

Errors - pytut double call

[20]:
x = 3

jupman.pytut()

jupman.pytut()
ERROR: There should only be one call to jupman.pytut(), found 2 instead
ERROR: There should only be one call to jupman.pytut(), found 2 instead

Errors - Nothing to show

[21]:
jupman.pytut()

        Nothing to show ! You have to put ALL the code IN THE SAME cell as pytut()
                          right before its call.

        Example:

            x = 5
            y = x + 3
            jupman.pytut()

Spaces in attributes

Check spaces don’t affect jupman.pytut() call strip

[22]:
la = [['a','b'], ['c','d']]

jupman.pytut(  disableHeapNesting   = False  )
[22]:
Python Tutor visualization

Alternative: HTML magics

Another option is to directly paste Python Tutor iframe in the cells, and use Jupyter %%HTML magics command.

HTML should be available both in notebook and website - of course, requires an internet connection.

Beware: you need the HTTPS !

[23]:
%%HTML

<iframe width="800" height="300" frameborder="0"
        src="https://pythontutor.com/iframe-embed.html#code=x+%3D+5%0Ay+%3D+10%0Az+%3D+x+%2B+y&cumulative=false&py=3&curInstr=3">
</iframe>

Alternative: NBTutor

To show Python Tutor in notebooks, there is already a jupyter extension called NBTutor , afterwards you can use magic %%nbtutor to show the interpreter.

Unfortunately, it doesn’t show in the generated HTML :-/

[24]:
%reload_ext nbtutor
[25]:
%%nbtutor

for x in range(1,4):
    print("ciao")
x=5
y=7
x +y

ciao
ciao
ciao
[25]:
12
[ ]: