def test(n):
for i in range(n):
print(i)
Live coding 4
Live coding 4
In this blog, I will cover tips on Jupyter notebook and python debugger.
In the Youtube video, Jeremy goes over how to setup paperspace again. However, I covered it in the last article. So, I decided to talk about something I haven’t covered yet.
Jupyter notebook
Jupyter notebook is a great tool to work with because we can have code and notes at the same place. This way, we can explore ideas, take notes, and program at the same time. We can also add videos or diagrams in here as well. However, it’s not just for playing around. It can also be used for writing a book or a library with nbdev.
So, let’s get started. Cells can be executed with either Ctrl-Enter
or Shift-Enter
. Shift-Enter
moves onto the next cell whereas Ctrl-Enter
stays on the executed cell. Auto-complete works with tab
key in code. If we want to find out what a function does, first, we can write a function name. Then, move the cursor between the parenthesis and press Shift-tab
. Information about the function pops up something like this:
This way, we can easily read the docstring and find out what type of parameters the function takes. You can also do Shift-tab
twice. Find out what you get.
Another way to check the documentation string is using ?
before or after the function name. We get a nice modal from the bottom.
What if we want to look at the source code? We do not have to go anywhere else. We can check it out right here with ??
.
Another way to get help with the function is looking at the documentation. Again, we can look at the documentation right here with doc
. It requires nbdev, which can be installed using mamba install -c fastai nbdev
. This is not the full documentation. We can click on the Show in docs
link to go to the documentation page.
doc
only works on fastai things. For python built-in functions, it won’t provide useful output. However, it is still possible to ?
or ??
.
This is the documentation page. There are examples and tests here as well. It provides the most in depth information. It also provides a link to a source code.
When source
link is clicked, source code on GitHub is provided.
As we have seen, it is very easy to get help on Jupyter notebook. Also, there are many keyboard shortcuts available under Help
tab. To find out more, press h
in command mode or click on Help
tab and click keyboard shortcuts
. These can also be editted.
Python debugger
Python debugger is a powerful tool to use with many methods and features built in. However, this can be too daunting for some newcomers. So, let’s go over simple ones here to get it started.
First, we define a simple function, test
, which prints numbers from 0 to n - 1.
10) test(
0
1
2
3
4
5
6
7
8
9
With %%debug
in the beginning of the cell, we can start a debugging session. We will get a prompt at the end of the cell. We can quit with q
(quit). It is also possible to write quit
. On the pdb documentation, the command is written as q(uit). This means either q
or quit
works fine.
3) test(
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> <string>(2)<module>()
ipdb> q
Another thing we can do is get help with h
(help). When executed by itself, h
returns all the commands, and when another command is given as an agrument, it returns documentation for that command.
3) test(
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> <string>(2)<module>()
ipdb> h
Documented commands (type help <topic>):
========================================
EOF commands enable ll pp s until
a condition exit longlist psource skip_hidden up
alias cont h n q skip_predicates w
args context help next quit source whatis
b continue ignore p r step where
break d interact pdef restart tbreak
bt debug j pdoc return u
c disable jump pfile retval unalias
cl display l pinfo run undisplay
clear down list pinfo2 rv unt
Miscellaneous help topics:
==========================
exec pdb
ipdb> h s
s(tep)
Execute the current line, stop at the first possible occasion
(either in a function that is called or in the current
function).
ipdb> q
s
steps into the function and n
goes into the next line. After stepping into the function, we can look at the variables with p
. Here, we can use p i
to find out the value of i
. It can be cumbersome to keep entering the same command over and over, such as n
, so we can just press Enter
without any command to execute the previous command.
3) test(
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> <string>(2)<module>()
ipdb> s
--Call--
> /tmp/ipykernel_23823/3072799742.py(1)test()
----> 1 def test(n):
2 for i in range(n):
3 print(i)
ipdb> s
> /tmp/ipykernel_23823/3072799742.py(2)test()
1 def test(n):
----> 2 for i in range(n):
3 print(i)
ipdb> s
> /tmp/ipykernel_23823/3072799742.py(3)test()
1 def test(n):
2 for i in range(n):
----> 3 print(i)
ipdb> p i
0
ipdb> n
0
> /tmp/ipykernel_23823/3072799742.py(2)test()
1 def test(n):
----> 2 for i in range(n):
3 print(i)
ipdb> p i
0
ipdb> n
> /tmp/ipykernel_23823/3072799742.py(3)test()
1 def test(n):
2 for i in range(n):
----> 3 print(i)
ipdb> p i
1
ipdb> n
1
> /tmp/ipykernel_23823/3072799742.py(2)test()
1 def test(n):
----> 2 for i in range(n):
3 print(i)
ipdb>
> /tmp/ipykernel_23823/3072799742.py(3)test()
1 def test(n):
2 for i in range(n):
----> 3 print(i)
ipdb>
2
> /tmp/ipykernel_23823/3072799742.py(2)test()
1 def test(n):
----> 2 for i in range(n):
3 print(i)
ipdb>
--Return--
None
> /tmp/ipykernel_23823/3072799742.py(2)test()
1 def test(n):
----> 2 for i in range(n):
3 print(i)
ipdb>
--Return--
None
> <string>(2)<module>()
ipdb> p i
*** NameError: name 'i' is not defined
ipdb> q
When we are out of the function, i
is not defined.
If we want to find out where the error occured, we can use w
. In this case, we used %%debug
to get in the debugger.
l
lists the source code in the file. This can be helpful to give us where we are.
3) test(
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
None
> <string>(2)<module>()
ipdb> s
--Call--
> /tmp/ipykernel_23823/3072799742.py(1)test()
----> 1 def test(n):
2 for i in range(n):
3 print(i)
ipdb> l
----> 1 def test(n):
2 for i in range(n):
3 print(i)
ipdb> w
/home/kappa/mambaforge/lib/python3.10/bdb.py(597)run()
595 sys.settrace(self.trace_dispatch)
596 try:
--> 597 exec(cmd, globals, locals)
598 except BdbQuit:
599 pass
None
<string>(2)<module>()
> /tmp/ipykernel_23823/3072799742.py(1)test()
----> 1 def test(n):
2 for i in range(n):
3 print(i)
ipdb> q
Another way to get into the debugger is by having an error within the program. Here, I divide a number by 0, and it throws an ZeroDivisionError
.
def test2():
return 1 / 0
test2()
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) Cell In [21], line 1 ----> 1 test2() Cell In [20], line 2, in test2() 1 def test2(): ----> 2 return 1 / 0 ZeroDivisionError: division by zero
I can type %debug
(Single %) in the cell, and get into the debugger now to find out what just caused an error.
> /tmp/ipykernel_23823/2873590661.py(2)test2()
1 def test2():
----> 2 return 1 / 0
ipdb> w
None
/tmp/ipykernel_23823/2251835413.py(1)<module>()
----> 1 test2()
> /tmp/ipykernel_23823/2873590661.py(2)test2()
1 def test2():
----> 2 return 1 / 0
ipdb> l
1 def test2():
----> 2 return 1 / 0
ipdb> q
I can find out where the error occured with w
and print the source code with l
.
That’s it for python debugger. However, there are more commands listed in the documentation.
Here is a list of commands we covered:
n
: next.s
: step into.p
: print variable.Enter
: execute last command.l
: list the source code in a file.w
: where did the error occur?q
: quit
Conclusion
We covered tips on Jupyter notebook and python debugger. These tools have a learning curve, so it is a great idea to take time and learn them thoroughly. After a while, programming without them will get difficult. Also, check out these products made with Jupyter notebook: fastbook, fastai, and nbdev.