import java.io.*;
import java.text.*;
//--------------------------------------------------------------
// Grades.java
// CS100 P3Q2
//
// Wei Tsang Ooi 16 July 1999
//
// This program prompts the user for a list of students and their
// grades, then summarises their final score and pass/fail status.
// The classes used by this program is as follows :
//
// - Class - encapsulate a class with a fixed number of students.
// - we can add students into the class, and print out
// information about the students.
//
// - Student - encapsulate a student, with a series of grades.
// - we can get various information about the student.
//
// - LetterStudent - students taking the class for a letter grade.
//
// - PassFailStudent - students taking the class for a pass/fail grade.
//
//--------------------------------------------------------------
class Grades
{
static BufferedReader stdin;
//--------------------------------------------------------------
// getName
//
// prompt the user for a name and returns a string entered by user.
//--------------------------------------------------------------
static String getName() throws IOException
{
System.out.println("Name : ");
return stdin.readLine();
}
//--------------------------------------------------------------
// getInt
//
// input : a message to print
// output : an integer input by the user
// read an positive int from user and returns it.
//--------------------------------------------------------------
static int getInt(String message) throws IOException
{
String errMessage = "ERROR : input must be positive. " +
"Try again :";
// prompt and read in the grade.
System.out.println(message);
int input = Integer.parseInt(stdin.readLine());
// make sure that grade is valid.
while (input < 0)
{
System.out.println(errMessage);
System.out.println(message);
input = Integer.parseInt(stdin.readLine());
}
// invariant : input is positive. Return the input.
return input;
}
//--------------------------------------------------------------
// getGrade
//
// input : a message to print
// output : an double input by the user
// read a double between 0 and 100 from a user and returns it.
//--------------------------------------------------------------
static double getGrade(String message) throws IOException
{
String errMessage = "ERROR : grade must be between 0 and 100. " +
"Try again :";
// prompt and read in the grade.
System.out.println(message);
double grade = Double.valueOf(stdin.readLine()).doubleValue();
// make sure that grade is valid.
while (grade < 0 || grade > 100)
{
System.out.println(errMessage);
System.out.println(message);
grade = Double.valueOf(stdin.readLine()).doubleValue();
}
// invariant : grade is >= 0 and <= 100. We can be sure at this
// line that grade is valid. Return the grade.
return grade;
}
//--------------------------------------------------------------
// getPassFail
//
// input : none
// prompt the user to see if this student enroll as a Pass/Fail
// student.
//--------------------------------------------------------------
static boolean getPassFail() throws IOException
{
// prompt and read the name of the student.
System.out.print("Enroll as Pass/Fail ? ([y]/n) ");
String reply = stdin.readLine();
if (reply.equals("") || reply.equals("y") || reply.equals("Y")) {
// default answer is yes.
return true;
} else {
// all other replies are considered as "no"
return false;
}
}
//--------------------------------------------------------------
// createClass
//
// input : none
// prompt the user informations about students, add them into
// a Class object and returns the Class object.
//--------------------------------------------------------------
static Class createClass() throws IOException
{
double grade[]= new double[Student.NUM_OF_GRADES];
int numOfStudent = getInt("Enter the number of students : ");
// Create a new class with appropiate number of students.
Class cls = new Class(numOfStudent);
// Prompt and get students name and grades
for (int i = 0; i < numOfStudent; i++)
{
// prompt and read the name of the student.
String name = getName();
// prompt and see if the student enroll as Pass/Fail student
boolean passFail = getPassFail();
// read the grades of the students.
for (int j = 0; j < Student.NUM_OF_GRADES; j++)
{
grade[j] = getGrade("Grade for " + Student.GRADE_DESCRIPTION[j]);
}
if (passFail)
{
cls.addStudent(new PassFailStudent(name, grade));
}
else
{
cls.addStudent(new LetterStudent(name, grade));
}
}
return cls;
}
public static void main (String args[]) throws IOException
{
// This program just create a class and print it out.
stdin = new BufferedReader(new InputStreamReader(System.in));
Class cs100 = createClass();
cs100.printAllStudents();
}
}
//--------------------------------------------------------------
// class Class
//
// This encapsulates a class with some number of students. We
// can add a student in a class, print the information about
// all the student, or query the average score of the class.
//
// Wei Tsang Ooi 16 July 1999
//--------------------------------------------------------------
class Class {
Student [] students;
int numOfStudents;
double totalScore;
double min;
double max;
int studentCounter;
private static DecimalFormat formatter =
new DecimalFormat("##0.##");
//--------------------------------------------------------------
// contructor
//
// Receive a number of student as input, and creates the
// array of students.
//--------------------------------------------------------------
public Class (int numOfStudents)
{
this.numOfStudents = numOfStudents;
students = new Student[numOfStudents];
totalScore = 0;
min = Double.MAX_VALUE;
max = Double.MIN_VALUE;
}
//--------------------------------------------------------------
// printAllStudent
//
// Output the name of the students as well as the list of grades,
// weighted average, and pass/fail status (in neccessary).
//--------------------------------------------------------------
void printAllStudents()
{
printHeader();
for (int i = 0; i < numOfStudents; i++)
{
System.out.println(
students[i].getName() +
students[i].getAllGrades() +
students[i].getFormattedWeightedAverage() +
students[i].getFinalGrade()
);
}
System.out.println();
System.out.println("TOTAL NUMBER OF STUDENTS : " +
studentCounter);
System.out.println("AVERAGE SCORE : " +
formatter.format(getClassAverage()));
}
//--------------------------------------------------------------
// addStudent
//
// add a new student into the class. We make sure that the total
// number of student does not exceed the number specified when
// the class is created. We return true if the student is added
// successfully, and return false otherwise.
//--------------------------------------------------------------
boolean addStudent(Student student)
{
// check if we have exceed the limit of the class
if (studentCounter >= numOfStudents)
{
return false;
}
// add a new student
students[studentCounter] = student;
studentCounter++;
double weightedAverage = student.getWeightedAverage();
totalScore += weightedAverage;
if (min > weightedAverage)
{
min = weightedAverage;
}
if (max < weightedAverage)
{
max = weightedAverage;
}
return true;
}
//--------------------------------------------------------------
// getClassAverage
//
// return the average score of the class, using the data entered
// so far. (i.e. if there are less student than specified, we
// do not take in to consideration the "phantom students" when
// we calculate the average.
//--------------------------------------------------------------
double getClassAverage()
{
return totalScore/studentCounter;
}
//--------------------------------------------------------------
// printStats
//
// print the maximum, minimum and average value.
//--------------------------------------------------------------
void printStats()
{
System.out.println("MAX : " + max);
System.out.println("MIN : " + min);
System.out.println("MEAN : " + formatter.format(getClassAverage()));
}
//--------------------------------------------------------------
// findStudent
//
// input : name of a student
// return the student with this name, if exists. return null
// otherwise.
//--------------------------------------------------------------
Student findStudent(String name)
{
// Since the student list is not sorted, we perform a linear
// search.
for (int i = 0; i < numOfStudents; i++)
{
if (students[i].nameIs(name))
{
return students[i];
}
}
// invariant : no students with that name is available
return null;
}
//--------------------------------------------------------------
// printStudent
//
// input : name of a student
// print information about this student
//--------------------------------------------------------------
void printStudent(String name)
{
Student student = findStudent(name);
if (student == null)
System.out.println("ERROR : No such student : " + name);
else {
printHeader();
System.out.println(
student.getName() +
student.getAllGrades() +
student.getFormattedWeightedAverage() +
student.getFinalGrade());
}
}
//--------------------------------------------------------------
// printHeader
//
// print a header for the list of grades.
//--------------------------------------------------------------
static void printHeader()
{
System.out.println("NAME\tASS 1\tASS 2\tMIDTERM\tASS 3\tASS 4\tFINAL\tAVERAGE\tFINAL");
}
//--------------------------------------------------------------
// printLetterGradeStudents
//
// print name and average grades of the students who were taking
// this class for a letter grade.
//--------------------------------------------------------------
void printLetterGradeStudents()
{
System.out.println("NAME\tAVERAGE");
for (int i = 0; i < numOfStudents; i++)
{
if (students[i].takeLetterGrade())
{
System.out.println(students[i].getName() +
students[i].getFormattedWeightedAverage());
}
}
}
}
//--------------------------------------------------------------
// Student
//
// Encapsulates the data about a student, including its name,
// and the grades for six assignment.
//
// Wei Tsang Ooi 16 July 1999
//--------------------------------------------------------------
class Student {
// The name of this student, and an array of six for storing
// his/her grades.
private String name;
private double grades[];
protected double weightedAverage;
// Number of grades for each student
public final static int NUM_OF_GRADES = 6;
// These constant represents the weight of each assignment.
private final static double WEIGHT[] = {0.1, 0.1, 0.25, 0.2, 0.05, 0.3};
// Grade description : This describes what each grade is for.
public final static String GRADE_DESCRIPTION[] = {
"Assignment 1", "Assignment 2", "MidTerm", "Assignment 3",
"Assignment 4", "Final"};
// This beautify the output of doubles
protected static DecimalFormat formatter = new DecimalFormat("##0.##");
//--------------------------------------------------------------
// constructor
//
// Initializes the members in the class with the name, and
// grades. The grades should be an array of size
// Student.NUM_OF_GRADE. If there are more grades than that,
// extra grades will be thrown away. If there are less,
// default grade (0) will be assign.
//--------------------------------------------------------------
Student(String name, double grades[])
{
this.name = name;
this.grades = new double[NUM_OF_GRADES];
// how many grades are we going to copy ?
int howMany = (grades.length > NUM_OF_GRADES) ?
NUM_OF_GRADES :
grades.length;
// copy the grades.
// invariant : both grades and this.grades have at least
// howMany elements. So the following loop won't exceed
// the array bounds.
for (int i = 0; i < howMany; i++)
{
this.grades[i] = grades[i];
}
// calculate the weighted average of the students.
weightedAverage = calcWeightedAverage();
}
//--------------------------------------------------------------
// calcWeightedAverage
//
// Returns the weighted average grade for this student.
//--------------------------------------------------------------
private double calcWeightedAverage()
{
double average = 0;
for (int i = 0; i < grades.length; i++)
{
average += grades[i]*WEIGHT[i];
}
return average;
}
//--------------------------------------------------------------
// nameIs()
//
// input : a name
// Returns true if this student's name is name
//--------------------------------------------------------------
public boolean nameIs(String name)
{
return this.name.equals(name);
}
//--------------------------------------------------------------
// getName
//
// Returns the name of the student.
//--------------------------------------------------------------
public String getName()
{
return name + "\t";
}
//--------------------------------------------------------------
// getAllGrades
//
// Format the grades of this student as a string and returns.
//--------------------------------------------------------------
public String getAllGrades()
{
String description = "";
for (int i = 0; i < NUM_OF_GRADES; i++)
{
description += formatter.format(grades[i]) + "\t";
}
return description;
}
//--------------------------------------------------------------
// getWeightedAverage
//
// Format the grades of this student as a string and returns.
//--------------------------------------------------------------
public String getFormattedWeightedAverage()
{
return formatter.format(weightedAverage) + "\t";
}
//--------------------------------------------------------------
// getWeightedAverage
//
// Returns the weightedAverage of this student
//--------------------------------------------------------------
public double getWeightedAverage()
{
return weightedAverage;
}
//--------------------------------------------------------------
// getFinalGrade
//
// This returns the final grade of a student. It should be
// overwritten by the subclass to return the appropiate thing.
//
// A better way to do this is to define this as abstract.
//--------------------------------------------------------------
public String getFinalGrade()
{
return "";
}
//--------------------------------------------------------------
// takeLetterGrade
//
// Return true if this student takes this class for a letter grade.
// By default the student does not take the class for letter grade.
//
// A better way to do this is to define this as abstract.
//--------------------------------------------------------------
public boolean takeLetterGrade()
{
return false;
}
}
//--------------------------------------------------------------
// PassFailStudent
//
// Encapsulates the data about a student that takes the class
// as pass/fail.
//
// Wei Tsang Ooi 16 July 1999
//--------------------------------------------------------------
class PassFailStudent extends Student {
final static double PASS_WATERMARK = 70;
public PassFailStudent(String name, double grades[])
{
super(name, grades);
}
//--------------------------------------------------------------
// takeLetterGrade
//
// Return true if this student takes this class for a letter grade.
//--------------------------------------------------------------
public boolean takeLetterGrade()
{
return false;
}
//--------------------------------------------------------------
// pass
//
// Returns true if this student have pass the class.
//--------------------------------------------------------------
private boolean pass()
{
return weightedAverage >= PASS_WATERMARK;
}
//--------------------------------------------------------------
// getFinalGrade
//
// Format the data of this student for printing. This just call
// the super class toString and append a PASS/FAIL to the string.
//--------------------------------------------------------------
public String getFinalGrade()
{
return pass() ? "PASS" : "FAIL";
}
}
//--------------------------------------------------------------
// LetterStudent
//
// Encapsulates the data about a student that takes the class
// for a letter grade.
//
// Wei Tsang Ooi 16 July 1999
//--------------------------------------------------------------
class LetterStudent extends Student {
public LetterStudent(String name, double grades[])
{
super(name, grades);
}
//--------------------------------------------------------------
// takeLetterGrade
//
// Return true if this student takes this class for a letter grade.
//--------------------------------------------------------------
public boolean takeLetterGrade()
{
return true;
}
//--------------------------------------------------------------
// getFinalGrade
//
// This should returns a letter grade (A, B, C, D, E) absed on
// the weighted average. But now we just return nothing since
// the question did not specify how to calculate the letter grade.
//--------------------------------------------------------------
public String getFinalGrade()
{
return "";
}
}