Writing code can be tricky. Some say that there is no non-trivial code that is completely error-free. Errors happen, and they happen frequently. Preventing, finding, and fixing errors (also known as bugs) in code are valuable skills for programmers to master. This chapter will cover three types of errors (syntax, semantic, and design) and discuss actions that programmers can take to prevent and fix these kinds of errors.
Syntax errors occur when the computer can't understand the code. It looks at the code, tries to make sense of it (i.e. tries to translate it into binary), but can't. This happens when the programmer doesn't stricly follow the rules of the programming language. Perhpas there was a typo or some misunderstanding of the language's syntax rules. Here are a few things you can do to prevent, find, and fix these errors:
Each of the six test functions in the exercise below has a syntax error. Run the code, read the error message from the output, and find and fix the errors.
deff test1(): print("test 1 passed") def test2(message]: print("test 2 passed: " + message) def test3(message): prnit("test 3 passed: " + message) def test4() print("test 4 passed") def test5(): print("test 5 passed") def test6(message): print("test 6 passed: " + message(0:4)) # tests, don't change these test1() test2("success") test3("way to go!") test4() test5() test6("yay!!!!!")
def test1(): print("test 1 passed") def test2(message): print("test 2 passed: " + message) def test3(message): print("test 3 passed: " + message) def test4(): print("test 4 passed") def test5(): print("test 5 passed") def test6(message): print("test 6 passed: " + message[0:4]) # tests, don't change these test1() test2("success") test3("way to go!") test4() test5() test6("yay!!!!!")
test_output_contains("test 1 passed\ntest 2 passed: success\ntest 3 passed: way to go!\ntest 4 passed\ntest 5 passed\ntest 6 passed: yay!") success_msg("Great job!")
Semantic errors are often more difficult to find than syntax errors. Semantic errors occur when the computer understands the command, but it's not the command that the programmer intended. The computer understands and runs the code, and the programmer is left wondering why the program doesn't work as expected. These errors are difficult to find because the computer doesn't report them: you have to look through your code and find them on your own.
One example of a semantic error was discussed in the strings chapter: the error of concatenating numerical strings instead of adding numbers together. If you try
c = a + b where
a is 235 and
b is 395, you might be surprised when
c comes out to be 235395 instead of 630 because you didn't realize that
b were numerical strings instead of ints.
Another common semantic error is related to misunderstanding the language's order of operations, also know as operator precedence. If you try
a = 2 + 4 * 6, you may be surprised when
a turns out to be 26 instead of 36 because the multiplcation is computed before the addition. The precedence of the
* operator is higher than the precedence of the
+ operator, so it is executed first even though the
+ command comes first when reading left to right.
Other semantic errors may be caused by typos. You might want to do
a * b but you accidentally type
a + b. You might accidentally type the variable name
first_name where you meant to use the variable
last_name. When a typo results in code that the computer can understand and run, it is a semantic error rather than a syntax error.
Semantic errors can be tricky to find, but are usually easy to fix once found. Here are some tips for finding semantic errors:
print(type(var))statements in your code so that you have a better idea of what the computer is doing with your variables. Once you find a variable that has a different value than you expected, trace your code back to where that variable was modified to figure out why it has that unexpected value.
Syntax errors occur when the computer doesn't understand the code. Semantic errors occur when the code runs but doesn't reflect the programmer's intentions. Design errors occur when the code runs according to the programmer's intentions, but the programmer's intentions are somehow wrong. A programmer might start coding with wrong assumptions or might misunderstand what the customer wants, thus the programmer fails to design a program that solves the problem at hand. The best way to prevent and find design errors is through frequent communication. If you are writing code for a class assignment, talk to an instructor, a classmate, or a TA to make sure you really understand the assignment. Read over the assignment description multiple times throughout the process to make sure no detail is left out. If you are writing code for a customer, keep the customer involved throughout the whole process. Create mockups and documentation that communicate all decisions that are made throughout the project. It takes work to stay on the same page, but it pays off when at the end you know that your intentions are in line with the customer's or the instructor's.