Debugging
Creating any application can be broken up into three phases: designing, developing, and debugging. In the design phase, you decide on which features you need to implement and how to organize the classes to do so. The majority of the coding happens in the development phase. Once you have testable code, you make sure it's working correctly in the debugging phase. This process is definitely not linear; very often you will have to change your design as you begin coding, and you should always be testing your code during the entire process of development. Most of the time spent writing any program is in the debugging phase. A well thought out and thorough design will make development easier, and careful coding will simplify debugging tremendously. Nevertheless, every application is going to have bugs and being able to debug them is an essential skill.
Goal: Gain familiarity with different types of bugs that are encountered while programming and learn elementary techniques for resolving them.
Incremental Coding
Gain familiarity with different types of bugs that are encountered while programming and learn elementary techniques for resolving them.
Bad Coding: Type all the code, try to compile it, get a hundred errors, run to a TA for help because you have no idea what's going on anymore.
Having bugs in your code does not indicate that you are a bad programmer. In fact, even the best programmers can't write bug-less code on the first try. The trick is to identify those bugs in the beginning stages of your program. After all, it's a lot easier to find a missing parenthesis in 10 lines of code than trying to fix 45 bugs in 1000 lines of code. This is where incremental coding comes in.
Good Coding: Fill in a method and try to compile it. If it works, Great! Call the method. Didn't get the expected results? Look through the method, fix the bug and try again! Worked? Awesome! Fill in the next method, didn't compile? Well the first method compiled, so it must be syntactically correct, that means the problem is in the last method you filled in: look in the code, fix the bug, compile again!
As you can probably guess by now, incremental coding is the practice of testing small portions of your code as you are writing them. It is MUCH easier to find bugs this way, since you will have less code to work with at any one time. You will also become much more familiar with your code, and the TAs will be much happier helping you tackle hard programming decisions rather than spending all their time scanning through pages of code trying to find the missing semi-colons and undefined variables.
Let's see how incremental coding could have worked for LiteBrite:
- Get the Palette and Grid to show up.
Test: Make sure it is working correctly before moving on. - Try to add colors to the Palette.
Test: Add one color, then test. Add a few more and test again. - Now get a Lite to show up when you click in the right spot.
Test: Spend some more time testing this; try different cases to make sure the Lite shows up every time. - Finally, get a Lite to show up in the right spot with the right color.
Test: Try different spots and different colors; make sure it's always working as expected.
Different Types of Bugs...
All bugs can be broken down into two categories: compile-time bugs and run-time bugs. Compile-time bugs happen when you violate the rules of the programming language and the compiler has no idea what you are trying to do. Examples of this would be: missing semicolon, a typo on a variable name, or calling a method that doesn't exist. Run-time bugs indicate an error in the logic of the code. These bugs can either cause your program to crash (ex: NullPointerException) or cause incorrect functionality (ex: I click on one spot on the screen but the Lite shows up in another). As you become more and more familiar with Java, compile-time errors will become easy to fix and much more of your time will be spent on run-time bugs, some of which can be extremely tricky.