Lab 3: Due Wednesday, September 27, 2000

 

Part I: Building Your Own Classes

From this point on in the course you will be spending extensive time constructing your own Java classes. Ultimately this will come easy to you, but in the early stages it can be difficult conceptually. The first part of this lab will consist of constructing a simple Student class that might be used as part of a database system, or in a course registration system. The file "cards" in the course material folder contains data on all of the students at Bowdoin enrolled in 1998. The information for each student consists of a student number, their class (year of graduation), the number of courses they would like to enroll in, the number of courses that they have listed, and the names of each of those courses. Your first lab task is to figure out how to read all of this information in from the file.

Reading Files

Reading from files is almost identical to reading from the keyboard in Java. There are, however, several important differences. First you need access to the part of the Java language that deals with files. You can get this by making the first command of your program the following:

import java.io.*;

You also need to tell Java where you’ll be reading from. In Java input and output are handled as "streams." We have already seen how to make a ReadStream for reading from the keyboard. Now you will make an input stream for reading from files. This can be done in your program with a command such as the following:

InputStream istream = new InputStream(filename);

For this lab "filename" will be "cards" (with the quotes). Once that’s done, you can make a variable of type ReadStream with the proper context as follows.

ReadStream cardReader = new ReadStream(istream);

The important bit here is that we have given the ReadStream constructor an extra parameter to work with corresponding to the file we’re going to read.

Finally, Java is rather finicky about letting people open up files. Many things can go wrong during this process — they can be misnamed, they might not exist, the user might not have permission to them, etc. — to combat this Java forces you to wrap all of the file creation and reading operations within a try and catch combination. Ultimately, your code will end up looking something like this:

try  {
       InputStream istream = new FileInputStream("cards");
       ReadStream r = new ReadStream(istream);
       .
       .
       .
catch (IOException e) 
    {
       System.err.println(e); 
    }

The "catch" part of the code looks for errors generated during the IO process and when it finds them prints them out as system errors.

The Student Class

Once you’ve figured out how to read in a single student, your next task will be to figure out how to store as many as 1500 of them. Since we’d like all of the information about one student in one place, a natural way of accomplishing this is by making a Student class. Your student class should be able to store all of the information that can be gleaned from the cards file (e.g. student number, class, classes asked for, etc.). In addition we will want the facility to retrieve these fields. To that end you will need to write simple methods to return any of the relevant information. Obviously you will need a constructor as well. The trickiest part of all of this will be handling the variable number of courses that each student asks for.

Once a single student can be read into an instance of a Student class it should be a simple matter to read 1500 of them into a data structure. A natural way to do this is by creating a Vector of Students. As each student is read in they are put into a Student and then added to the Vector.

Part II: Querying the Data Structure

Now that you have read all of this information into a data structure you will need to have the ability to make use of it. Ideally, a user could ask for relevant information on any student — e.g. the classes they are trying to register for, their class, etc. Your next task for this lab will be to define an interface to accomplish this. You should offer the user a number of choices and provide answers to their queries.

One of the chief difficulties in answering a user query will be to find the relevant information. E.g. if the user wants to know how many classes student 1500 asked for, first you need to locate student 1500’s record. Fortunately, this is fairly simple because the card datafile comes presorted (we will discuss sorting shortly). Searching a Vector of sorted items is very simple using a technique called "binary search."

Binary search is one of the simplest and most powerful algorithms in computer science. The idea is that we compare what we are looking for to the item in the middle of the sorted data structure. If our item is less than that item we know that it must be in the second half of the data structure. If it is greater than that item we know it is in the first half. Thus we have eliminated half of the data structure with one comparison. We can continue doing this until we finally compare our item to itself or we run out of items to compare it to (which would only happen if the item were not in the data structure). You can find a discussion of this algorithm and some basic code for it on pages 127-128 of your book.

 

The Assignment

When you are done you should have a program that reads in all of the data from the cards file and then allows the user to ask questions about individual students. Your project should contain at least four files — your main program, your Student class, the Vector class, and the ReadStream class. As usual, you should give me a hard copy of all of your code as well as putting a copy of your folder into the drop box.