At the moment I am on Day 13 of The Complete Python Pro Bootcamp for 2022 run by Dr Angela Yu, who has taught millions of people through her online courses how to become a programmer. I am definitely starting to get into the groove of things with Python by this point. Today’s focus has been debugging and I’m feeling quite confident in my ability to use what I have learnt up to this point to figure out what’s going wrong and how to fix it.
The first piece of code to debug is a program that tells the user whether a number is odd or even, a basic program that I wrote on Day 3. Running the program resulted in a ‘SyntaxError‘ with a very clear indicator pointing to the exact point where the code stopped working. The problem here was the “equals” = operator, this operator assigns a value to a variable. There is also an “is equal to” == operator which checks, using Boolean, whether something is True or False. For example:
# Assign a value to a variable
a_variable = 100
# Check if the variable is 100 or not, in this case it would be True and the if statement would print.
if a_variable == 100:
print("The variable is 100")
All I had to do to fix the code was assign the correct operator which in this case was replacing the ‘equals’ operator with the ‘is equal to’ operator and the code would run. Here’s the code so you can see what I am talking about:
number = int(input("Which number do you want to check?"))
# This if statement uses the 'is equal to' operator to check whether the number has a remainder equal to 0 and if it does, it will print that it's an even number, otherwise ('else') it will print that the number is odd.
if number % 2 == 0:
print("This is an even number.")
else:
print("This is an odd number.")
Problem solved, now onto the next!
Back on Day 3 I learnt about ‘if’ statements and I wrote a simple program that’s job is to tell the user whether the year they input is a leap year or not. We’ve now come back to the code however it seems to have a bug. The problem that was presented was a ‘TypeError‘ bug. The specific error was “not all arguments converted during string formatting”. From this I was able to understand that Python was not able to execute the if statement, because it was being given a string as an input and trying to perform a calculation with it. So, I made sure to convert the input into an integer using the int() type conversion and this allowed the if statement to run and the program returned the expected result.
# Without adding the int() type conversion, the input will be stored in the year variable as a string literal "2020" rather than as an integer.
year = int(input("Which year do you want to check?"))
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
print("Leap year.")
else:
print("Not leap year.")
else:
print("Leap year.")
else:
print("Not leap year.")
That’s the second program debugged, now onto the final problem.
Here I’ve been given a program called ‘FizzBuzz’ which is a numbers game. The aim of the game is to take turns in a group to count upwards starting from 1 but there are some rules. When it gets to your turn, if the number is divisible by 3, then you have to say “Fizz” instead. Then if the number is divisible by 5, you have to say “Buzz” instead and the last rule is that if you can divide that number by both 3 and 5, then you have to say “FizzBuzz”. This program is designed to count from 1 to 100 using these rules and work out when to print “Fizz”, “Buzz”, “FizzBuzz” or just print the number, however it has multiple issues that I need to debug.
1 for number in range(1, 101):
2 if number % 3 == 0 or number % 5 == 0:
3 print("FizzBuzz")
4 if number % 3 == 0:
5 print("Fizz")
6 if number % 5 == 0:
7 print("Buzz")
8 else:
9 print([number])
The first thing that I notice when I run the program is that the output is not what I am expecting to see. The problem is that it shouldn’t be printing every number, nor should it be printing multiple print statements for each number. The first thing I did was to break down the problem by imagining that the number is 3 and running through the logic:
First of all, my expectation is that if the number is 3, the program should just print “Fizz”. By walking through the code, I can work out that if the number is 3, then line 2 will be True and print “FizzBuzz”, then it will run the if statement on line 3 which is also True and print “Fizz” and then the statement on line 6 will return False because 3 % 5 = 2, so it will go to the else statement on line 8 and print the number 3. I can fix this issue by changing the if statements on lines 4 and 6 to elif statements, meaning that they will only run when the first if statement returns as False. This also means that the else statement will only run when all of the if and elif statements have been skipped because they returned as False.
Now I’m presented with a new bug. When I run the program I can see that every time a number is divisible by either 3 or 5, it prints “FizzBuzz” and I know that it should be only printing this line of code if the number is divisible by both 3 and 5. Having a look through the code I can see the problem is the first if statement on line 2 and that problem is the “or” operator. By changing this to “and” it will now check whether the number is divisible by both and if it isn’t, then it returns False. If both of these conditions are not met it will return False, even if one of them is True. This first if statement will now print “FizzBuzz” only when the number is divisible by both 3 and 5.
Finally, I’m going to remove the square brackets from the else print statement as it is not necessary to print the number as a list, I just want it to print the number. This is what the debugged code now looks like:
for number in range(1, 101):
if number % 3 == 0 and number % 5 == 0:
print("FizzBuzz")
elif number % 3 == 0:
print("Fizz")
elif number % 5 == 0:
print("Buzz")
else:
print(number)
I am really happy to say that this went well today, I was able to debug the problems that were presented to me by breaking down the code. By running through each line of code and as Angela likes to put it “playing computer”, I was able to really understand what it was actually doing versus what I was expecting it to do. When I was presented with an error in the console, I was able to use my existing knowledge of error codes to figure out what it was trying to tell me and edit or update the code to resolve the issue.
It also made it really clear to me that some of the time bugs in code won’t result in an error because it is a human error. When a program isn’t running the way I expect it to and it’s not throwing an error, it’s probably time to sit down and debug that program. I need to look at the code and figure out why it’s not behaving the way I think I’ve told it to behave. I can also use tools such as Thonny or an online debugger to help me visualise the problem. I have mainly been using these as a way to break down the code I am writing so that I can really understand what is happening line by line. I have a feeling I will be relying on these a lot in the future to break down large chunks of code and help me get to the problem a lot quicker than if I was going through the logic in my head like I was today.