Introduction to Computer Science

Program 5 Statistics (rubric)

Part 1: Design a class that will gather statistics about numeric data. A Stats object should be able to analyze a series of numbers added to the object over time. Such an object must be capable of providing (at any time during its lifetime) the number of values analyzed, the average value, and the maximum and minimum values. Each Stats object will ignore values above or below stated values. s.ignoreL(0.001) for example, will cause s to ignore values less than 0.001. A similar method exists for greater than. If no ignore limits are set, all numbers are counted. Data added to the object is subject to the ignore limits at the time it is added.

Provide a method named addData that is passed a number to be included in the statistics. This method will update the statistics about the data to reflect the new number (unless it is in the range to be ignored). A reset method will reset all of the stat data, but will not affect the ignore data limits. Other methods will need to be included to meet the testing requirements at the end of this assignment. You should assume that these tests are part of the specification of the class. Your Stats class must pass this test before going on to the next part of the program assignment.

Part 2: Create an application named Exams that reads data from an input file. Each line of data will contain a student ID code followed by three numeric values (separated by one or more spaces) representing exam scores (out of 100 points). You will need to determine the average score for each student. Count all of the scores in your average. You will also need to determine the max, min, and average for each of the exams, but in this case, ignore any scores below 25 (the instructor does not want these to affect the averages). You should use a Scanner instantiated from a FileReader (you should look up this class) to access the data file (named scores.txt).

Your program should display a list of student ID codes along with that student's average on the three exams. After all students are analyzed, display the number of students and the max, min, and average score for each exam. Use the printf method to display student averages with one decimal place, and exam averages with two decimal places of accuracy.

Sample output might look like this (the numbers are purely fictitious):

S3476 78.9
S2098 93.8
S3349 86.1
S1109 79.7
4 students processed
        Average  Minimum  Maximum  Count
Exam 1:  84.25     33.00   98.00    4
Exam 2:  79.33     55.50   92.50    3
Exam 3:  87.75     77.00   91.00    4

Here is a data file to be used for testing your application. Place it in the same folder as your class files so it can be easily opened for input by the FileReader.

Submission details: Be sure to follow the Documentation Standards (for this and every program). When you are ready to submit, obtain a printed copy of your program. Remember to sign and attach the required Academic Integrity Pledge cover sheet. The printed program must be turned in to your instructor by the start of class on the date the program is due. You must also email a zipped copy of the program to your instructor. Identify the email with the subject: ICS Program 5 and be sure that your name appears inside the message. The attached zip file must be named as your first initial and last name and the program number (example: JSmith_5.zip). The zip file must contain a folder having the same name (JSmith_5). Be sure to email your working solution before the due date! Do not submit non-working programs.

Email addresses: 

Testing application and data file - download it here or look at it below:

Testing application data:

3.6 43.9
-5.12
198.57 -34.678 109.3
12.7
-135 -7 -4
1
33
separation between data sets
-5 33 98 32 -1 44 -1 -1 13 22 11 99 88 -23 -55 -67 11
separation between data sets
100 200
an empty line follows this one

this is the last line of the file

Sample application output:

No data in this object yet
average: 0.0 max = 0.0 min = 0.0
0 data values were processed
Floating Point Data: 3.6 43.9 -5.12 198.57 -34.678 109.3 12.7 -135.0 -7.0 -4.0 1.0 33.0
average: 18.022666666666666 max = 198.57 min = -135.0
12 data values were processed
Integer Data: -5 33 98 32 -1 44 -1 -1 13 22 11 99 88 -23 -55 -67 11
Positive integer data
average: 45.1 max = 99.0 min = 11.0
10 data values were processed
Negative integer data
average: -21.857142857142858 max = -1.0 min = -67.0
7 data values were processed
String Data:
line 1 separation between data sets
Intermediate stats report
average: 28.0 max = 28.0 min = 28.0
1 data values were processed
line 2 100 200
Intermediate stats report
average: 17.5 max = 28.0 min = 7.0
2 data values were processed
line 3 an empty line follows this one
Intermediate stats report
average: 22.666666666666668 max = 33.0 min = 7.0
3 data values were processed
line 4
Intermediate stats report
average: 22.666666666666668 max = 33.0 min = 7.0
3 data values were processed
line 5 this is the last line of the file
Intermediate stats report
average: 25.25 max = 33.0 min = 7.0
4 data values were processed

Program:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

/**
 * Test the Stats class
 * 
 * @author tsm
 *
 */
public class TestStats {
	final private static String filename = "testdata.txt";
	/**
	 * Read some data from a file and report the statistics. In case
	 * the file is not found, a catch block will display an error message
	 * and terminate the application.
	 * 
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args){
		//Instantiate a scanner to read from a file
		Scanner in = null;
		try {
			in = new Scanner(new FileReader(filename));
		} catch (FileNotFoundException e) {
			// Display error and terminate
			System.out.println("The file ("+filename+") could not be found!");
			System.exit(-1);
		}
		Stats s1 = new Stats();
		//The Scanner is ready! Test calls before adding any data:
		report(s1,"No data in this object yet");
		
		//Analyze the first section of data in the file...
		System.out.print("Floating Point Data: ");
		while (in.hasNextDouble()){
			double dat;
			s1.addData(dat = in.nextDouble());
			System.out.print(dat + " ");
		}
		report(s1,"");
		
		//Now, process negative data separately from positive, and ignore 0's
		s1.ignoreL(.5); //ignore data below .5
		s1.reset();
		Stats s2 = new Stats();
		s2.ignoreH(-.5); //ignore data above -.5
		//throw away rest of current line and data seperator line
		while (!in.hasNextInt())
			in.nextLine(); 
		System.out.print("Integer Data: ");
		while (in.hasNextInt()){
			int dat = in.nextInt();
			s1.addData(dat);
			s2.addData(dat);
			System.out.print(dat + " ");
		}
		System.out.println();
		report(s1,"Positive integer data");
		report(s2,"Negative integer data");

		//Next, analyze the strings found on lines of the file
		System.out.println("String Data:");
		s1.reset();
		in.nextLine(); //discard the end of the current line
		int linenum = 1;
		while (in.hasNextLine()){
			String dat = in.nextLine();
			s1.addData(dat.length());
			System.out.println("line " + linenum++ + ":\t"+dat);
			report(s1,"Intermediate stats report");		
		}
	}
	
	/**
	 * Provide a printed report of the statistics information
	 * @param s The Stats object with information
	 * @param label A label to identify the source of the data
	 */
	private static void report(Stats s, String label){
		System.out.println(label);
		System.out.println("    average: "+s.getAverage()+
				"  max = "+s.getMax()+"  min = "+s.getMin());
		System.out.println("    "+s.getCount()+" data values were processed");
	}

}