12345 90.0 37.2 89.1 99.7 12937 100.0 95.0 100.0 97.0 93701 65.0 75.3 89.2 98.6 73920 78.3 82.1 75.0 77.0
This assignment is due on Thursday, February 7, 2008 at 5:00 PM.
[2008-02-05] Corrected error in description of GradeReader usage in the C level. It said that GradeReader has a method getQuiz(int); the correct name is getQuizScore(int).
Added clarifying note to the A level. It is only a clarification, and in no way affects what is required for the assignment.
The purpose of this assignment is to give you some initial experience writing Java code using basic control structures (loops, etc.) and reading data from a file.
|
Note
|
You must do this assignment in groups of 2. |
|
Note
|
Assignments are structured with three levels: C, B, and A. The grading for the assignments will be done so that doing everything correctly for a particular level will result in a grade equivalent to that letter grade. The levels are also cumulative — to receive a B, you must do everything in both the C and B levels (usually, the work in each level will depend on the earlier levels). |
|
Warning
|
When an assignment description tells you to give something a particular name, you must give it exactly that name. Failure to do so may result in a very low or zero score due to inability to properly run your code. |
|
Warning
|
Your program must output its results in exactly the format we describe, with no additional text being written. If you insert additional output statements to aid in debugging, make sure they are removed before you submit. |
Your task in this assignment is to write a program which analyzes and summarizes grade information for quizzes in a class.
The data is stored in a text file called students.dat with each student's record on a separate line. Each record consists of a student ID (an integer), followed by four quiz scores (floats/doubles). A sample file looks like this:
12345 90.0 37.2 89.1 99.7 12937 100.0 95.0 100.0 97.0 93701 65.0 75.3 89.2 98.6 73920 78.3 82.1 75.0 77.0
At the C level, your program will print each student's average quiz score, along with their ID, with one student per line.
At the B level, your program will print (in addition to the C-level report) the average score across all students for each quiz.
At the A level, your program will compute the student averages by dropping the lowest quiz score for each student. Additionally, it will compute the overall average (the average of the averages).
Following is a sample of the output at the A level:
12345: 92.933333 12937: 99.000000 93701: 87.700000 73920: 79.133333 STATS (min, max, avg): Quiz 1: 65.000000, 100.000000, 83.325000 Quiz 2: 37.200000, 95.000000, 72.400000 Quiz 3: 75.000000, 100.000000, 88.325000 Quiz 4: 77.000000, 99.700000, 93.075000 Avg: 79.133333, 99.000000, 89.691667
In Eclipse, create a new Java project. Download the following two files, and import them into your project (see the Lab 0 description for how to do this):
build.xml (import this into your project root folder)
students.dat (sample data file; it also goes in your project root folder)
GradeReader.java (import this into your src/ folder)
Once you have imported the files, create a new class in your src/ folder called GradeProcessor, and give it a public static void main method (click the corresponding checkbox in the New Class dialog).
To receive a C, you must write the code to read in the data file and print out each student's average score.
The GradeReader.java file contains a class we provide, GradeReader, which will help you read the data from the file. Later, you will learn how to do the file I/O directly, but for now it hides some Java details that we haven't covered yet so you can complete this assignment in a straightforward fashion.
You need to do the following in your main method in the GradeProcessor class:
Create a new variable to hold a GradeReader.
Initialize this variable to hold a new GradeReader object which can read from the students.dat file.
Write the code to read each record from the file, compute the average (statistical mean) of their score, and print it. It should print in the following format:
StudentID: Score
In order to do anything with most classes, you must instantiate them; that is, create a new object from them. In Java, you do this with the new keyword. For example, to create a new object of class Color, you could do the following:
Color c = new Color();
The Color() part is just like a method call; you can put arguments in the parentheses. It calls a “magic” method called a constructor.
The constructor for the GradeReader class requires an argument — a string — which is the file name it will read from.
The GradeReader class class allows you to read from a data file, one line (or record) at a time. It has a notion of a “current record”, and allows you to get data from the current record. When it is first created, it has no current record.
The advance() method of GradeReader advances the current record by 1 record. The first call to advance() makes the first record the current record. It also returns a boolean value — true if it found another record, or false if it reached the end of the file.
The getStudentID() method gets the student ID number, as an integer, from the current record. The getQuizScore(int) method takes an integer quiz number (from 1-4 inclusive) as its sole parameter and returns the student's score for that quiz. Neither of these methods can be called before advance() is called at least once, and neither of them can be called after advance() has returned false.
|
Note
|
If you violate the rules regarding calling advance() and getting record information, your program will terminate with a RuntimeException stating that the grade reader is not in a valid state. |
Thus, the basic structure of code to process the records in the file looks like this (in pseudocode):
while advance() returns true
process a record
Java provides an object, System.out, which lets you print data to the standard output stream (which goes to your console in Eclipse, or to the terminal from which you ran the program if you're using a command line). There are a couple methods of interest here:
This method prints a string or other data object.
This method takes a string (or other data, such as an integer) and prints it, followed by an end-of-line character.
This method takes a string followed by several other parameters and prints the string, after inserting the other parameters in place of certain character sequences in the initial string. It is used for nicely formatting output. See Using format for more information.
Look at the PrintStream class in the Java API reference for information on more options for outputting data.
Add code to your Level C solution to compute the average score, across all students, for each quiz. After going through and printing all the student's averages, it should output a blank line followed by a set of lines like the following:
STATS: Quiz 1: <Q1 Average> Quiz 2: <Q2 Average> Quiz 3: <Q3 Average> Quiz 4: <Q4 Average>
For this level, you need to add the following:
Modify the computation of each student's average grade to drop their lowest grade. That is, the average is the average of the three highest grades.
Compute the average of the averages, along with the average for each quiz.
Compute the minimum and maximum values of each of the quizzes and the student quiz averages.
To compute a minimum or maximum, create a variable to hold the min or max value. Initialize this variable to some very large (for minimum) or very small (for maximum) value. Since we're working with double values, the values Double.POSITIVE_INFINITY and Double.NEGATIVE_INFINITY are the greatest possible and least possible numbers, respectively. Then, in your loop, check each value against the current best minimum or maximum. If it's less than the minimum, it should be the new minimum, and the maximum case is equivalent.
Modify the output to be minimum, maximum, and average (in that order, separated by “, ”). Modify the output of the “STATS:” line to say “STATS (min, max, avg):”.
|
Note
|
The average of averages and min/max of averages are the average, min, and max of the students' quiz averages. The goal is to compute the minimum, maximum, and averages of the final overall quiz scores that the students received. |
Before you submit your assignment, you must create a text file called group.txt in your project directory. In this file, put the names and x.500 ID's of the members of your group.
Copy your code and other files (group.txt, students.dat, build.xml) to an ITLabs computer for final testing. On the ITLabs computer, run ant run in your code's directory and make sure the program works. Then run ant package to create the HW package, and submit the resulting hw1.tgz file via Submit.
For a small amount of extra credit, you can modify your program to also compute the median and mode of each of the quiz scores. If you do the extra credit, submit it as the assignment hw1-extra (and still submit your A-level solution as hw1).
|
Note
|
You may only attempt to get the extra credit if you also submit an A-level solution. |
The format method of the PrintStream class allows you to format output by having Java substitute various values for string sequences in a template (called a “format string”). The first parameter to `format' is always a string, the format string. The data that is to be substituted in to the format string is passed as the remaining parameters.
The format string contains special codes beginning with the “%” character to indicate substitutions. Some important ones are “%s”, which tells Java to insert a string, “%d” for decimal integers, and “%f” for floating-point (float or double) numbers. If you want to include a literal “%” sign in the output, use “%%”.
Each of the “%” sequences that inserts a value takes a parameter. The parameters are used from left to right. For example, the following call:
System.out.format("The square root of %d is %f\n", 5, 2.236068);
results in the following output:
The square root of 5 is 2.236068
format does not automatically generate a new line at the end of the string; the “\n” sequence indicates the newline character and causes the new line to be printed.