CS 211, 004/006
Lab Exercise-6
due Thursday, October 11th at noon


There are three major types an errors a program can have - compiler errors, runtime errors, and logical errors. The objective of this lab is to analyze a program which has all three types of errors, and to find a remedy for each.

Overview:

  1. Download the provided Lab6 java file.
  2. Use the compiler error messages to fix all compiler errors.
  3. Use the thrown error message to fix the runtime error.
  4. Use debug statements to track down and fix the logical error.
  5. Prepare and submit the working code and the output of the program.
This is a lab exercise on which collaboration (including discussing the solution on Piazza or searching online sources) is explicitly permitted. It is still in your interest to understand and prepare your final submission yourself.

Background:

There are three major types of errors you will see when creating a program: compile-time errors, runtime errors, and logical errors.

Compile-time errors (and warnings) are problems with the way you've written your code which the compiler will catch and report. If a program has any compile-time errors, it will not produce an executable. These kinds of errors are typically not difficult to fix, because the compiler will indicate where the error is an what it is. It's a good idea to begin with the first error and work downwards, because often secondary error messages are triggered by the original error. Your program may also have warnings, which will not prevent your program from running, but are a good idea to fix because they may suggest a deeper problem.

Runtime errors are errors are illegal conditions which are triggered while the program is running. Divide-by-zero, null pointer exception (using an object's members when it's been initialized to null), or going outside the bounds of an array are typical examples. These types of errors can be caught by the program, but if they are not, they will cause the program to stop and report the error. This shows up in the form of a stack trace, which tells you what kind of error and where in the program the error was triggered.

Logical errors happen when a program compiles and runs without producing any error conditions, but nevertheless does not produce the desired output. These types of errors involve some kinds of expression or flow control logic which is incorrect. Finding and fixing the error ranges in difficulty, but can often be very subtle and tricky. It becomes easier with practice, because you will become familiar with common, easy-to-make mistakes as you debug your own programs throughout the semester.

In this lab, you are provided with a program which has examples of all three types of errors, and you will find ways to fix each kind of error. Fixing the first two types of errors typically involves relying on error messages, while fixing the last two (runtime errors are a hybrid) typically relies on tracking the way the state of the program and its flow changes as it executes. You may also find it helpful to use debugging tools, which will allow you to step through a running program, watch its state, and break when certain locations are reached.

Task:

Download the following program:

The program itself demonstrates three things: classes that implement an interface; the fact that you can use polymorphism by referring to an object via one of the interfaces it implements; as well as the fact that you can define things like classes and interfaces inside of another class (helping us get around the restriction that you have to have no more than one class per file).

After downloading the program, try to compile and run it. You will not be able to run it because of what? A compiler error. The syntax on one of the lines is wrong. The compiler tells you where and what, so fix it. Of course, a program often has more than one error. Compile again, and see what else is a problem. The compiler will tell you what the next error is. Fix this error as well. Hint: if you are unsure about what the method needs to produce, look at the comments in the program to help you decide.

Once you've successfully compiled, try to run the program. You will see an error message produced (Java's runtime error messages tend to by flamboyant, because they show you the entire stack trace, i.e. the series of method calls which were needed to reach the error, whenever an error is thrown). The good news is that the error message tells you the type of error (you should be able to figure out what it means in this case) and the line which the error occurred on (look for the most recent method name which is defined in your program). Fix this error. Hint: the order in which the conditions are checked may not be in the right order. You do not want to dereference an array index unless you've checked the bounds first.

If a program compiles and runs without error, that still may not indicate that the program produces the output that you want. If you look at the comments in the Lab6 file, you'll see that the TotalArray class is supposed to get its value by adding up all of the non-negative elements inside of its internal list. So if you initialize it with the list {4, 1, -1}, it should produce the value 4 + 1 = 5.

This program produces three lines of output. The first comes from a ValNum object, and should be easy to verify that it is a correct value. The next is from a TotalArray with a small list, which should also be correct. Is the result of the final TotalArray correct? It's a short list, so it should be easy to verify by hand. Our program is not producing what we expect, so we need to track down the bug.

In this case, we have an output which is produced by a loop. A good place to start debugging is to watch how the output value changes as the loop executes. To do this, include the following line in the loop after the i++:

System.out.println(sum);

Now we will be able to see how the sum changes after every iteration of the loop. When we run the program now, we will see several extra lines of output, one for each iteration of the loop. The first three lines correspond to the first TotalArray. The final three lines correspond to the original program output. The remaining lines in between are from our problematic loop. Based on the output, can you figure out what the problem is with the code? We want to add all of the positive elements from the list, is the program doing that? Check how and when the conditions are checked, to see what needs to be changed to make the program work correctly.

Once everything is fixed, the program should print out eleven numbers: three for loop from the first array, five for the loop from the second array, and the three lines of the original output. The original output lines should now reflect the correct sums. Save the program output into an ordinary text file (not an .rtf or .doc file, because those contain extra markup information which will defeat an automatic checker). This file will be part of your submission.

Testing:

There is no tester script to download for this lab. The correct output should be a series of 11 numbers, one per line. To help you verify if it's correct, you can add the array values by hand to see if it produces what you would expect.

Submission:

Submission instructions are as follows.

  1. Let xxx be your lab section number (one of 213-220), and let yyyyyyyy be your GMU userid. Create the directory xxx_yyyyyyyy_E6/
  2. Save the output of the final version of the program into the text file xxx_yyyyyyyy_E6.txt.
  3. Place your updated .java file as well as the text output file into the directory that you've created.
  4. Create the file ID.txt in the format shown below, containing your name, userid, G#, lecture section and lab section, and add it to the directory.

    Full Name: Donald Knuth
    userID: dknuth
    G#: 00123456
    Lecture section: 004
    Lab section: 213

  5. compress the folder and its contents into a .zip file, and upload the file to Blackboard.