Code rarely works perfectly the first time, even for experienced developers. But the more skilled a developer is, the better they are at debugging the code, meaning analyzing and fixing bugs.
Debugging skills do not just happen. You should start developing them as early as possible. While learning, you will do assignments and practice, which will help you gain experience. Over time, analyzing and correcting errors will become a habit if you spend enough time practicing.
How to find errors in your code
You can debug faulty code by trial and error, but it is long and unproductive. It is much easier to understand the problem first and start fixing it then. Understanding is the essential step. Without it, no further steps are possible.
Before debugging the code, you need to figure out what is wrong with it.
We can do it in two steps:
Step 1. Study traceback. It is a list of all function calls from the program start to the point of failure. Traceback helps understand how the program ran, including which functions were called successfully and which had problems. Each traceback entry points to the file, the line, and the function we called.
Suppose you have written code in users.eu
and decided to run the main()
function on line 4. The traceback entry will look like this:
File "users.eu", line 4, in <module>
main()
As you can see, not only are the file and line specified here, but also the module name. You can tell where the problem is. It could be in your code or some library you did not write but still used.
Step 2. When the traceback reaches the problem area, it will display an error message. For example, this:
NameError: name 'create' is not defined
You will quickly understand the message:
The name
create
is not defined
This error most often occurs due to a typo in the name. You need to check this point. Without knowledge of English, too, you can figure it out if you use a dictionary or an online translator.
Now we will see how the traceback and the error message look together:
Traceback (most recent call last):
File "users.eu", line 4, in <module>
main()
File "users.eu", line 2, in main
create()
NameError: name 'create' is not defined
You can see the whole chain of events in the example above: the program successfully handled the main()
function, moved on to the create()
function, and encountered an error in the name.
Besides NameError, Python has many other errors, which fall into three groups.
Types of errors
The most straightforward errors are syntactic ones. They are due solely to the fact that the code runs incorrectly. For example, we used the wrong quotes.
When these errors are output, you will see the SyntaxError:
phrase. When you debug the code, you should look at the spot with the error. Let us look at an example. Here the syntax error occurred because this quotation mark '
was used instead of "
:
Traceback (most recent call last):
File "users.eu", line 2
print("Hello" + "world')
^
SyntaxError: EOL while scanning string literal
The second large group of errors is programming errors. These can include:
- Calling a function that does not exist
- Using an undeclared variable
- Passing the wrong arguments (for example, arguments of the wrong type)
These errors are more difficult to correct than syntactic errors. Usually, they result from faulty logic in another earlier call.
The last type is logical errors. The situation can be hard to fix because the program generally works but gives the wrong result with some values. In most cases, the problem lies in faulty logic. For example, instead of adding, the program performs a subtraction:
# The function should count the sum of the numbers
# But it counts the difference instead:
def sum(a, b):
return a - b
# When called like this, the error isn't obvious
# Both addition and subtraction will have the same result
sum(4, 0) # 4
Debugging methods
There are many ways to debug programs, but they all have one thing in common: You need to analyze how variable values change as the code runs.
Let us look at a specific example. Below is a function that counts the sum of the numbers from the start
number to the finish
number. If start
equals three and finish
equals five, the program should calculate: 3 + 4 + 5
.
Here is the code:
def sum_of_series(start, finish):
result = 0
n = start
while n < finish:
result = result + n
n = n + 1
return result
There is an error in this code. In the sum_of_series()
function, we see two main variables: n
and result
. From this, we can conclude we need to see what values the variables get at each iteration. After that, it will not be hard to find the error.
There is one handy way to keep track of variable values during code execution - visual debuggers. They are built into popular code editors and allow you to execute a program step by step and see all the changes visually. If you want to learn more about debuggers, you can Google Python Debuggers.
There is no debugger in the Hexlet environment, so we use another approach here — debug printing. The essence is the same as in the visual debugger. The only difference is that you use the regular screen printout to output the values of the variables. The editor automatically switches to the OUTPUT
tab during the check. Here we see what the printed output is on the screen. Let us look at an example:
def sum_of_series(start, finish):
result = 0
n = start
while n < finish:
print('new iteration !!!!')
print(n)
result = result + n
n = n + 1
print(result)
return result
sum_of_series(3, 5)
# New iteration
# 3
# 3
# New iteration
# 4
# 7
Here you can see that there is one less iteration of the loop than necessary. For some reason, it does not add for the last number marked as finish
. Indeed, if you look at the definition, you will see that it uses n < finish
instead of n <= finish
. We could find the error thanks to debugging. Here, we used the <
sign instead of <=
.
There is nothing wrong with making mistakes. Experienced developers make them just as often as beginners. Writing perfect code is hard to learn, but you can develop debugging skills and an eye for bugs.
Newbies think experienced developers can look at code and immediately understand the error. Yes, experience helps make you better at finding bugs. But it is not that simple. It is hard to tell what went wrong from the code snippet. If you need advice from an experienced developer, it is better to show the error message rather than the faulty code.