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]:
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]:
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]:
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]:
[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]:
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]:
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]:
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]:
Print output
With only one line of print, Print output panel shouldn’t be too short:
[11]:
print("hello")
jupman.pytut()
hello
[11]:
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]:
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]:
Cloned cell test
Tests PythonTutor output is correctly displayed when cells are cloned (solved issue)
[14]:
maremma = 123
jupman.pytut()
[14]:
Cloned cell:
[15]:
maremma = 123
jupman.pytut()
[15]:
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]:
Force nested data structures
[17]:
listA = [ ['Keep', 'an'],
['eye', 'on'],
['the', 'arrow', 'tips']
]
listB = listA.copy()
jupman.pytut(disableHeapNesting=False)
[17]:
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]:
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]:
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
[ ]: