/* testscores11.cpp processes a sequence of test scores, using a class
 * roster stored in a file.
 * Input(keyboard): the name of the roster file and
 *                  a sequence of test scores
 *  Input(file):    a sequence of names
 *  Precondition:   the sequence of names is not empty
 *  Output:         the mean of the sequence of test scores,
 *                    each student's name, the score for that student, 
 *                    and the difference between the score and the mean
 ***********************************************************************/

#include <fstream.h>
#include <iostream.h>                        // cout, cin, <<, >>
#include <string>                            // string
#include <vector>                            // vector<T>
#include <algorithm>                         // max, min_element()
#include "MyVector.h"                        // Read()

double Mean(const vector<double> & vec);

void PromptAndRead(const vector<string> & names, vector<double> & scores);

void PrintResults(ostream & out, double meanScore, 
                  const vector<string> & names, 
                  const vector<double> & scores);

int main()
{
   cout << "This program requires a roster of student names.\n"
	<< "Enter the name of the roster file: ";
   string rosterFile;
   cin >> rosterFile;

   vector<string> roster;                   // the class roster
   Read(rosterFile, roster);                // -- read it
   
   vector<double> scores;                   // the score sequence
   PromptAndRead(roster, scores);           // -- read it
   vector<double> originalScores = scores;  // save a copy
                                            // remove extreme values
   scores.erase(min_element(scores.begin(), scores.end()));
   scores.erase(max_element(scores.begin(), scores.end()));
  
   double meanScore = Mean(scores);         // find mean w/o extremes
                                            // output w/ extremes
   PrintResults(cout, meanScore, roster, originalScores);

   return 0;
}

// --- Open an ifstream interactively ---------------------

void InteractiveOpen(ifstream & theIFStream)
{
   cout << "Enter the name of the input file: ";
   string inputFileName;
   getline(cin, inputFileName);

   theIFStream.open(inputFileName.data());

   if (!theIFStream.is_open())
   {
      cerr << "\n***InteractiveOpen(): unable to open "
           << inputFileName << endl;
      exit(1);
   }
}


/* Mean() finds the mean value in a vector<double>.
 *
 * Receive:      vec, a vector<double>
 * Precondition: vec is not empty
 * Return:       the mean of the values in vec
 *****************************************************************/

double Mean(const vector<double> & vec)
{
   if (vec.size() > 0)
      return accumulate(vec.begin(), vec.end(), 0.0) / vec.size();
   else
   {
      cerr << "\n***Mean: empty vector received!\n" << endl;
      return 0.0;
   }
}


/* PromptAndRead() reads a sequence of test scores from the keyboard.
 *
 * Receive:      names, a vector of strings,
 *               scores, a vector of doubles
 * Precondition: names is not empty AND scores is empty
 * Output:       prompts for test scores, using names
 * Input:        a sequence of test scores
 * Pass back:    scores containing the input values
 **********************************************************************/

void PromptAndRead(const vector<string> & names, vector<double> & scores)
{
   double score;                           // input variable
   for (int i = 0; i < names.size(); i++)  // for each index in sequence
   {
      cout << "Enter the score for "
           << names[i] << ": ";            //   prompt,
      cin >> score;                        //   read, and
      scores.push_back(score);             //   append
   }
}

/* PrintResults() displays names, test scores, and differences between
 * the scores and the mean score.
 *
 *  Receive: meanScore, a double,
 *           names, a vector of strings,
 *           scores, a vector of doubles
 *  Output:  each name in names, each score in scores
 *           and the difference of each score and meanScore
 **********************************************************************/

#include <iomanip.h>                       // setprecision()

void PrintResults(ostream & out, double meanScore,
                  const vector<string> & names,  const vector<double> & scores)
{
   cout << "\nThe mean score is "          // format for test scores
        << setiosflags(ios:: fixed | ios:: showpoint)
        << setprecision(1) << meanScore    // show mean score
        << " (ignoring max and min).\n"
        << endl;

   for (int i = 0; i < names.size(); i++)  // for each index in sequence:
      cout << setw(20) << names[i]  << '\t'//   display name,
           << resetiosflags(ios::showpoint) << setw(5)
           << scores[i] << "\t("           //      score, and
           << setiosflags(ios::showpoint) << setw(5)
           << scores[i] - meanScore        //      difference from mean
           << ')' << endl;
}

