/* testScores.cpp
 * ...
 */

/* testScores.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 <cassert>
#include <iostream>                        // cout, cin, <<, >>
#include <fstream>                         // ifstream
#include <string>                          // string
#include <vector>                          // vector<T>
#include <algorithm>                       // max, min_element()
#include "myVector.h"                      // read(), mean()
using namespace std;

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 inputFileName;
   cin >> inputFileName;
   
   ifstream fin( inputFileName.data() );    // open stream to roster file


   vector<string> roster;                   // class roster vector
   read(fin, roster);                       // -- fill it from stream

   vector<double> scores;                   // score sequence vector
   promptAndRead(roster, scores);           // -- fill it from kbd

   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;
}

/* 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 aScore;                          // input variable
   for (int i = 0; i < names.size(); i++)  // for each index in sequence
   {
      cout << "Enter the score for "
           << names[i] << ": ";            //   prompt,
      cin >> aScore;                       //   read, and
      scores.push_back(aScore);            //   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>                       // setprecision()
using namespace std;

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

   for (int i = 0; i < names.size(); i++)  // for each index in names:
      out << setw(20) << left << names[i]  //   display name,
           << noshowpos << setw(5) << right
           << scores[i] << "\t("           //      score, and
           << showpos << setw(5)
           << scores[i] - meanScore        //      difference from mean
           << ')' << endl;
}

