// Grade Program with array of objects
// Programmer: Bob Comer
// Completed : 4/27/99
// Status    : Complete
//
// Description:
//   This program reads a list of names and grades for a class
//   and calculates how far the grade is from the average.
//   The program will handle up to CLASS_SIZE grades.
//
//*************************************************************

#include <iostream.h>
#include <iomanip.h>
#include <string>
using namespace std;

class Student
{
private:
   string name;        // student name
   int grade;          // student grade

public:
   void Set( string nme, int grde )
   {
   // need to add validation checks on parameters
      name = nme;
      grade = grde;
   }

   string GetName()
   {
      return name;
   }

   int GetGrade()
   {
      return grade;
   }
};

const int CLASS_SIZE = 20;   // Number of students in class

void GetGrades( Student students[], int &numStudents );
float Avg( Student students[], int numStudents );
void PrintDiff( Student students[],
		int numStudents, float average);

int main()
{
   Student students[CLASS_SIZE]; // List of student info for a class
   int numStudents;              // Number of students stored
   float average;                // Average grade

// Get the list of grades
   GetGrades( students, numStudents );

// Calculate average grade
   average = Avg( students, numStudents );

// Print difference between each grade and the average
   PrintDiff( students, numStudents, average );

// Signal normal exit
   return 0;
}

//************************************************************
// Function: GetGrades
//
// This function inputs a list of student names and grades.
//************************************************************

void GetGrades( Student students[], int &numStudents )
{
   int studNo;    // Student number
   string name;     // A student name
   int grade;       // Grade for a student

// Get list of student names and grades
   studNo = 0;
   cout << "Enter name for student " << studNo + 1
	<< " (or 'END' to quit): ";
   cin >> name;
   while (name != "END" && studNo < CLASS_SIZE)
   {
      cout << "Enter grade for student " << studNo + 1 << ": ";
      cin >> grade;
      students[studNo].Set(name, grade);
      studNo++;
      cout << "Enter name for student " << studNo + 1
	   << " (or 'END' to quit): ";
      cin >> name;
   }
   numStudents = studNo;
}

//************************************************************
// Function: Avg
//
// This function calculates the average of the grades.
//************************************************************

float Avg( Student students[], int numStudents )
{
   int studNo;    // Student number
   int sum;       // Sum of the grades

// Sum the student grades
   sum = 0;
   for (studNo = 0; studNo < numStudents; studNo++)
      sum = sum + students[studNo].GetGrade();

// Return average of grades
   return float(sum) / float(numStudents);
}

//************************************************************
// Function: PrintDiff
//
// This function prints each grade and it's difference
// from the average.
//************************************************************

void PrintDiff( Student students[], int numStudents,
		float average)
{
   int studNo;    // Student number

// Set up format for floating point output
   cout << setiosflags(ios::fixed) << setprecision(2);

// Print class average
   cout << "\nThe class average is : " << average
	     << endl << endl;

// Print heading
   cout << setw(12) << "Student No"
	<< setw(12) << "Name"
	     << setw(8)  << "Grade"
	     << setw(16) <<"Dist from avg"
	     << endl;

   for (studNo = 0; studNo < numStudents; studNo++)
      cout << setw(12) << (studNo + 1)
	   << setw(12) << students[studNo].GetName()
		<< setw(8)  << students[studNo].GetGrade()
		<< setw(16)
		<< students[studNo].GetGrade() - average
		<< endl;
}

