How to Debug â A Beginner's Guide to Finding and Fixing Errors
Learn how to debug code as a beginner: read error messages, use print statements, understand common error types, and develop a systematic approach to fixing bugs.
What You'll Learn
By the end of this tutorial, you will have a repeatable process for debugging code. You will understand the most common error types, know how to read a traceback, and use debugging techniques like print statements and rubber ducking.
Why It Matters
Bugs are a normal part of programming. Even the most experienced developers write code that breaks. The difference between a productive developer and a frustrated one is not writing perfect code â it is knowing how to fix imperfect code quickly.
Real-World Use
Durga Antivirus Pro runs millions of lines of code. Every release has bugs that are found and fixed. The debugging process is the same whether you are fixing a typo in your first Python script or a security vulnerability in production software.
Your Learning Path
flowchart LR
A[Choose a Language] --> B[How to Debug]
B --> C[Build Projects]
C --> D[Next Steps]
D --> E[Specialize]
B --> F{You Are Here}
style F fill:#f90,color:#fff
Prerequisites: You should have written at least a few small programs. Python is used for examples, but the concepts apply to any language.
What Is a Bug?
A bug is an error in your code that causes unexpected behavior. Bugs can be:
| Type | Description | Example |
|---|---|---|
| Syntax error | You broke the language rules | Missing a closing parenthesis |
| Runtime error | The code crashes while running | Dividing by zero |
| Logic error | The code runs but gives wrong results | Using + instead of * |
The Debugging Process
Follow these steps every time you encounter a bug:
- Read the error message â it tells you what went wrong and where
- Understand the expected behavior â what should the code do?
- Isolate the problem â narrow down which line or section causes the issue
- Fix and test â make one change, then test
- Verify â confirm the fix works for all cases, not just one
Reading Error Messages
When Python encounters an error, it prints a traceback. Here is an example:
# debug_example.py
def divide_numbers(a, b):
result = a / b
return result
x = 10
y = 0
print(divide_numbers(x, y))
Expected output:
Traceback (most recent call last):
File "debug_example.py", line 8, in <module>
print(divide_numbers(x, y))
File "debug_example.py", line 3, in divide_numbers
result = a / b
ZeroDivisionError: division by zero
Read the traceback from bottom to top:
- Error type:
ZeroDivisionErrorâ you tried to divide by zero - File and line:
debug_example.py, line 3 â the exact location - Function:
divide_numbersâ which function contains the error - Values:
x = 10,y = 0â you passed zero as the divisor
Using Print Statements
The simplest and most effective debugging technique is adding print statements to show what your code is doing:
def calculate_average(numbers):
print("DEBUG: numbers received:", numbers)
if len(numbers) == 0:
print("DEBUG: empty list, returning 0")
return 0
total = sum(numbers)
print("DEBUG: total is", total)
count = len(numbers)
print("DEBUG: count is", count)
average = total / count
print("DEBUG: average is", average)
return average
# Test the function
result = calculate_average([10, 20, 30, 40, 50])
print("Result:", result)
Expected output:
DEBUG: numbers received: [10, 20, 30, 40, 50]
DEBUG: total is 150
DEBUG: count is 5
DEBUG: average is 30.0
Result: 30.0
The print statements let you trace exactly what the function does step by step. When a bug occurs, the last DEBUG line that prints before the error tells you what was working correctly.
Common Error Types in Python
SyntaxError
# Wrong: missing closing parenthesis
print("Hello"
SyntaxError: '(' was never closed
NameError
# Wrong: variable not defined
print(username)
NameError: name 'username' is not defined
TypeError
# Wrong: adding a string and a number
result = "The answer is " + 42
TypeError: can only concatenate str (not "int") to str
Fix: Convert the number to a string first.
result = "The answer is " + str(42)
IndexError
# Wrong: accessing an index that does not exist
items = ["apple", "banana"]
print(items[5])
IndexError: list index out of range
KeyError
# Wrong: accessing a dictionary key that does not exist
user = {"name": "Alice"}
print(user["age"])
KeyError: 'age'
The Rubber Duck Method
When you are stuck, explain your code to an inanimate object â a rubber duck, a teddy bear, or even just talk out loud. The process of explaining forces you to think through your logic step by step. Half the time, you find the bug before you finish explaining.
This works because the bug is often not in the code itself but in your understanding of what the code does. When you explain it aloud, your brain processes the logic differently.
How to Approach Logical Bugs
Logical bugs are the hardest because the code runs without errors but produces wrong results:
def is_even(number):
# Bug: using = instead of ==
if number % 2 = 0:
return True
return False
This code does not run at all because = is assignment, not comparison. But consider this subtler bug:
def calculate_discount(price, is_member):
if is_member:
discount = 0.1 # 10% discount
else:
discount = 0.05 # 5% discount
# Bug: always applies 20% extra off
return price * (1 - discount) * 0.8
The bug is the hardcoded 0.8. The code runs and produces a result, but the result is wrong. Finding these bugs requires checking each value carefully.
Common Mistakes Beginners Make
1. Not Reading the Error Message
The error message tells you exactly what is wrong and where. Do not ignore it. Read it carefully before making any changes.
2. Making Multiple Changes at Once
Change one thing, test, then change the next thing. Making five changes at once means you do not know which one fixed the problem.
3. Fixing the Symptom, Not the Cause
If a function returns None and your code crashes when it tries to use that value, the root cause might be earlier in the function, not where the crash happens.
4. Not Using Print Statements or Logging
Guesswork is ineffective. Print the values of your variables at key points so you know exactly what your code is doing.
5. Giving Up Too Quickly
If you have been stuck for 30 minutes, take a 5-minute break. Walk away from the computer. Your brain continues working on the problem subconsciously.
6. Not Searching for the Error
Someone has almost certainly encountered the same error before. Copy the error message into a search engine and read the results.
7. Assuming the Bug Is Complex
Most bugs are simple: a typo, a wrong variable name, a missing conversion. Start with the simplest possible explanation. Check the obvious things first.
Practice Questions
1. What should you read first when you encounter an error? The error message, especially the error type and the line number where it occurred.
2. What is the rubber duck debugging method? Explaining your code out loud to an object or imaginary listener to force yourself to think through the logic step by step.
3. What is the difference between a syntax error and a logic error? A syntax error means the code does not follow the language rules and cannot run. A logic error means the code runs but produces incorrect results.
4. Why should you only make one change at a time when debugging? If you make multiple changes and the bug disappears, you do not know which change fixed it. Changing one thing at a time gives you clear cause and effect.
5. Challenge: Write a function that intentionally contains a bug. Swap code with a friend or set it aside for a day, then debug your own code. You will be surprised how many bugs you can find with fresh eyes.
Try It Yourself
Create a Python file called debug-practice.py and type the following buggy code:
def get_user_info(users, user_id):
for user in users:
if user["id"] == user_id:
return user
# Bug: missing return for not found case
users_list = [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"},
{"id": 3, "name": "Charlie"},
]
result = get_user_info(users_list, 5)
print("User name:", result["name"])
Expected behavior: This code crashes because when user_id is not found, the function returns None implicitly, and Python cannot access ["name"] on None.
Your task: fix the function to handle the case where a user is not found. The fix can return None with a check before accessing the name, or return a default message.
This is the exact same kind of edge case handling that the Durga Antivirus Pro team uses when a scan function receives unexpected input.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro