3. Debug your code
What is programming about
Last week we introduced the programming language Python. We went swiftly over concepts like functions, classes and objects. We also introduced constructs for controlling the flow of a program.
Learning programming is like learning a how to write an essay. First you have to learn the language you are using. A language consists of syntax (significant whitespace, function definition), semantics (the meaning of a[i]
, for ...
, if ...
) and abstract concepts you can use (classes, objects, functions). Different languages use different syntax and sometimes different semantics, but abstract concepts are mostly transferable between languages.
After learning the underpinnings of a language you will have to learn the words/tools a language provides. Each language comes with a base library that provides you with a set of tools that you can use to write programs faster.
Lastly there is learning how to express your thoughts abstractly and how to model your research problem with a computer.
In the following lectures we will introduce you mostly to tools and hopefully guide you towards how to express your thoughts with code.
Significant whitespace
A concept we glossed over last time is significant whitespace.
In C-like languages a for loop looks like this
for(int i = 0; i < 10; ++i) {
...
}
In Fortan like languages a for loop looks like this
for i in 0:9
...
end
In Python on the other hand it looks like
for i in range(0, 10):
...
The important difference is that Python uses four spaces to delineate blocks (while
, if
, for
, def
, class
). This reduces the level of frustration because you wont forget opening and closes bracing and semicolons. The only drawback is that the following is totally legal
counter = 0
while (counter < 100):
doSomethingFancy(counter)
counter = counter + 1
Paths
In order for the command line to know where to find executables/binaries it has to search the file-system for a binary with the name you entered. To direct this search the $PATH
variable exits.
Do echo $PATH
to see you current path and open the file .profile to adjust the $PATH
variable to contain $HOME/.local/bin
.
Array vs Lists
In Python arrays are homogenou (containing elements of one type) blocks of memory that contain a fixed number of elements. See array or numpy
for an implementation.
Lists on the other hand can be homogenous or heterogenous (containing elements of different type) and are implemented as an array of pointers to Python Objects. See the actual CPython implentation
Debugging
In order to deal with bugs we can use a tool called debugger. Once you encounter behavior of your program the first instinct is to go into your source code and add a lot of print
statements to inspect the state of the program. Instead of doing that we will use a debugger to inspect the program at points of interests.
Static analysis
There are also tools to statically analyse your source without actually running the code. These tools will inform you about missing imports, syntax problems and places where you likely misspelled a variable.
A good one is pyflakes
and if you are writing a lot of python code I recommend looking into it and running it every time you safe your code. It is like having a private tutor ;)
Resources
- Introduction on
pdb
/ipdb
andpyflakes
by scipy-lectures - intro to python debugging
- Five exercises to master the Python debugger
- Learn Python The Hard Way Exercise 36: Designing and Debugging
- Think Python: debugging
- Debugging Python Like a Boss
- UDacity debugging course Not limited to python
Debugging in Python with ipdb
- Install the debugger with
pip3 install ipdb
. - Run a script under the debugger with
ipdb3 my_script.py
Commands
?
/h
(help)w
(where) prints a stacktraceb
(break) set a breakpointENTER
(repeat previous)q
(quit)p <variable>
(print value)c
(continue)l
(list where you are)s
(step into subroutine)r
(continue till the end of the subroutine)! <python command>
Breakpoints
A breakpoint
is a place in your program where the debugger will stop for execution and wait for your commands. Copy the following code into a file and run it with under a debugger.
i = 0
while i < 10 :
# breakpoint here
i %= 2
if (i == 0):
print("Found a even number")
i += 1
IDEs
An Integrated Development Environment is a program that makes tasks like debugging a program easier. They have a lot of bells and whistle and can be really complicated tools, that enable somebody who is proficient at using them to be very efficient.
Good IDEs for Python are Ninja and PyCharm. We still encourage you to familiarize yourself with running Python from the command line and with using Jupyter.
Homework
The homework is due on October 8 2015 at 12:00pm (eg. noon). Hand in your homework either as a IPython notebook or a pdf + the source code you wrote.
Note: Doing something manually means that you should not use the Python base library, but rather implement the algorithm from first principles.
- Describe in your own words what a Object is. What is the relation between objects and classes?
Implement a
sort
function that manually sorts a list.import random a = [random.random() for i in range(0,10)] b = sort(a) print(b)
Describe how you sort a list. Is this the most efficient way? How is the number of steps your algorithm takes dependent on the size of the list?
Take a sorted list and manually search for an element stored in it.
Describe how your algorithm works. Is there are more efficient way? How many steps does your algorithm take:
- If the element is not in the list
- If the element is at the very end of the list
- If the element is in the middle of the list
There are several example pieces of code. Identify what's wrong with each one, and describe the circumstances in which you could make such an error. There can be more than one error.
if (foo = 7): print("7")
if (bar == 7): do_something(1) elif (bar = 8): do_something(2) elif (bar = 9): do_something(1) else: do_something(1)
# you are writing a function to change the contents of a variable i = 1 def foo(i): i = 5 return(i) foo(i)
class Person: def __init__(name, age, occupation): self.name = name self.ocupation = occupation ta = Person("Valentin", 23, "Graduate Student") def say(person): print(person.name, " is ", person.age, " old and works as a ", person.occupation) ta.say()