CSC 012

Introduction to Computer Science

 

Summary of 4/29 Lecture

Remember the lab exercise from last time.  Let's take a look at the solution.


Lab Exercise.  The results of a true-false exam have been coded for input.  The information for each student consists of two pieces of information, a student id number and an answer string.  For example, the data for the first student might look as follows:

0080    FTTFTFTTFT

If the correct answer key is:    FTFFTFFTFT,

then the student got 8 correct answers out of 10.

Write a program that

  1. reads in the correct answer string.  If we all use FTFFTFFTFT, then comparing notes would be easier.

  2. reads in each student's data, one at a time.

  3. after reading in a student's data, computes the number of correct answers for that student.

  4. stores the student's id in one array and the number of correct answers for that student in another array.

  5. after finishing processing the students' data, displays a table on the screen that looks as follows:

Student Identification             Number of Correct Answers
0080                                     8
0340                                     5
etc.

For the purposes of making checking the results easier, why don't we all agree to test the data in the file, test.txt.   You will find my solution in Testing.java.


Solution 1. (Interactive)

//File:    Testing.java
import CSLib.*;
public class Testing
{
    public static void main (String [] args)
    {
        InputBox in = new InputBox();
        in.setPrompt("Answer key please:");               wpe7.jpg (4555 bytes)
        String key = in.readString();
       
        in.setPrompt("How many students?");             wpe8.jpg (4362 bytes)
        int n = in.readInt();
       
        String [] id = new String [n];
        int [] correct = new int [n];
        String answer;
       
        for (int k=0; k<n; k++)
        {
            in.setPrompt("ID please:");        wpe9.jpg (4230 bytes)    wpeA.jpg (4541 bytes)
            id[k] = in.readString();
           
            in.setPrompt("Answers please:");
            answer = in.readString();
                                                            wpeB.jpg (4233 bytes)    wpeC.jpg (4523 bytes)
            for (int i=0; i<10; i++)
            {
                if (answer.charAt(i) == key.charAt(i))
                    correct[k]++;
            }
        }
       
        OutputBox out = new OutputBox();
out.setSize(360, 100);
        out.println ("Student Identification\tNumber of Correct Answers")

                        wpeE.jpg (6917 bytes)
       
        for (int k=0; k<n; k++)
        {
            out.println ("" + id[k] + "\t\t\t" + correct[k]);
        }
    }
}

You'll notice that I stopped at two students rather than proceeding to input the remaining 12 in the data file.  The time comsumed in completing the input interactively as well as the potential for error makes the process tedious at best.

Input from Files

It would be convenient if we could have the computer retrieve the data directly from the file, rather than asking us to retype the information each time we run the program.  This will require some knowledge of how Java handles this chore.

Input is accomplished in Java through the use of input streams.  In particular, files are viewed as byte streams ending with an end-of-file marker.   So the first task is to convert the byte streams to characters.  The character stream is then buffered (i.e., retrieved into RAM).  From this buffer, each line of input can be extracted as a String.  Finally, the String object can be tokenized and parsed to yield the data type required.   Let's indicate this process as follows:

  1. file (stream of bytes)

  2. FileReader object (stream of chars)

  3. BufferedReader object (buffers input allowing access from RAM instead of file)

  4. readLine() message to Buffered Reader object returns String reference to first line of input

  5. StringTokenizer object divides line of data from step 4 into distinct data items

  6. parse each data item to extract data of appropriate data type.

Let's apply this strategy to the data file for the lab exercise, test.txt.

Solution 2.  File input.

//File:    TestingFile.java
import CSLib.*;
import java.io.*;
import java.util.StringTokenizer;
public class TestingFile
{
    public static void main (String [] args)
    {
        String [] id = new String [100];
        int [] correct = new int [100];
       
        int k=0;
        try
        {   
            //Step 1. file (stream of bytes)
            String filename = "test.txt";
           
            //Step 2. FileReader object (stream of chars)
            FileReader fr = new FileReader(filename); //throws FileNotFoundException
           
            //Step 3. BufferedReader object (buffers input allowing access from RAM instead of file)
            BufferedReader br = new BufferedReader (fr);
       
            //Step 4. readLine() message to Buffered Reader object returns String reference to first line of input
            String key = br.readLine(); //throws IOException
               
            String line = br.readLine(); //throws IOException
            while (line != null)
            {
                //Step 5. StringTokenizer object divides line of data from step 4 into distinct data items
                StringTokenizer tokenizer = new StringTokenizer(line);
                id [k] = tokenizer.nextToken();       
                String answer = tokenizer.nextToken();
           
                for (int i=0; i<10; i++)
                {
                    if (answer.charAt(i) == key.charAt(i))
                        correct[k]++;
                }
           
                k++;
                line = br.readLine(); //throws IOException
            }
             br.close();   //close the stream
        }
        catch (FileNotFoundException e)
        {
            System.out.println(e.getMessage());
        }
        catch (IOException e)
        {
        }
       
        OutputBox out = new OutputBox();
        out.setSize(360, 300);
        out.println ("Student Identification\tNumber of Correct Answers");
       
        for (int j=0; j<k; j++)
        {
            out.println ("" + id[j] + "\t\t\t" + correct[j]);
        }
    }
}

Execution of this version of our solution requires no interactive input.   The following output is produced:

wpeF.jpg (12195 bytes)


Lab Exercise.  Add a class method to the NumberList class

public static int readIntList (String fileName, int [] list)

whose purpose is to input an array of int's, called "list", from a data filed named "fileName".  The method should return the number of items input from the file.


Lab Exercise.  Write a program to read a file of student records and then output the results to the screen, including the original class list along with the class average.   As a last resort, you can check my results.


Back to CSC 012 Home Page