Debugging
The single most important aspect of programming is debugging. If
you cannot debug your own code, you will never be able to program
successfully. You will spend most of your time working in one of
the labs without the assistance of the instructor. If every time
you run into difficulty you simply ask for help, you will not learn
how to write and debug good code.
The most important aspect of debugging is to identify the
exact location of the error. The simplest way to do that
is to print messages to the screen. You should print notes saying
where you are in the code, and also print the value of all the
variables you have read from the user or from a file. You should
also print the values of all variables which you have performed
calcualtions on.
Below is a program that reads some integers from the user, calls a
function to calculate their average, and prints that average to
the screen. Not only does this section of code demonstrate how to
use debugging messages, it also demonstrates how to construct
loops which work properly. While the code below is not necessarily
the best way to write a Java program, the point is to demonstrate the
techniques used to debug it.
public class test1 {
// the maximum number of integers which can be read
private static final int MAX_SIZE = 100;
public static void main(String args[])
{
// array declaration
int array[] = new int[MAX_SIZE];
int i=0, num=0; /* ALWAYS initialize your variables */
double sum = 0.0;
// say where you are in the program
System.out.println("Started program");
// say what the program does
System.out.println("This program will read in integer values from the user and calculate their average");
// read the input from the user
System.out.println("Enter some integers, -1 to quit");
// you need an initial value to get into the loop
num = SavitchIn.readLineInt();
i = 0; /* redundant, but a good idea to ALWAYS intialize counters
before starting a loop, just to be safe */
/* make sure not to overrun the array */
while((num != -1) && (i < MAX_SIZE)){
array[i]=num;
/* printing something inside the loop lets you see if you're in an
infinite loop, as opposed to just having the program hang */
/* print loop index and value read in */
System.out.println("array[" + i + "]=" + array[i]);
/* bump index and get next value */
i++;
num = SavitchIn.readLineInt();
}
/* identify where you are in the program */
System.out.println("calling the average function");
sum = average(array,i);
/* if this prints, you know the function exited properly */
System.out.println("returned from the average function");
System.out.println("The average was " + sum); /* print the result */
System.out.println("Exiting main"); /* say you're leaving just before the LAST closing curly brace */
}
static double average(int array[], int num_count)
{
double sum = 0.0; /* INITIALIZE YOUR VARIABLES */
int i=0;
/* indicate which function you are in */
System.out.println("Entering the average function");
sum = 0.0; /* again, it's a good idea to ALWAYS initialize variables
before starting a loop... In a large program, you may
use the same variables more than once. It is a good
habit to have. */
/* yes, we already set i=0, but ALWAYS initialize the loop counter */
for(i=0;i < num_count;i++){
/* type promotion will happen here, but do it explicitly */
/* to show that you understand what you're doing */
sum = sum + (double)array[i];
/* print SOMETHING in the loop to make sure */
/* you aren't in an infinite loop */
System.out.println("i = " + i + ", array[" + i + "] = " + array[i] + ", sum = " + sum );
}
/* print all related info before and after arithmetic operations */
System.out.println("sum = " + sum);
System.out.println("num_count = " + num_count);
sum = sum/num_count;
System.out.println("sum/num_count = " + sum );
/* say when you are leaving the function */
System.out.println("Exiting the average function");
return sum;
}
}
There are a lot of error messages in the code, true. You may not
need to use that many. However, if your program is not working
properly you have to track down where it is failing. You might start
by adding error messages at the entry and exit of every function.
Otherwise, you can make a guess on how far the program is going and
put an error message at that point to be sure. Then you can narrow
the location of the error down by putting error messages after every
questionable line of code. Also, whenever you change a line of code
you may introduce even more errors, so you may want to add an error
message after the line of code you just changed, just to be sure the
program made it that far.
IMPORTANT NOTE: this is how the instructor would have to debug your
code, if it is more than a nontrivial function. Please note that we
will not spend our time writing all these error messages for you. If
you have a bug and ask about it, without trying to narrow down where
the error is, we will not be inclined to help you. It is our job to
tell you WHY the failure is occurring, and we will do our best to fix
it. But we are not going to spend our time finding the location of
the error. You must learn to do it yourself. It takes too much time
which would be better spent helping many students instead of just one.
However, once you learn to find where the mistake is, it will be a lot
easier for you to fix the error yourself. Also, the only way we
learned the difficult coding lessons was to debug the code ourselves.
We have spent many hours finding the causes of exceptions and logic
errors, but once we learned why they happened, we rarely made the same
mistake again.