/********************************************************************************************
P5-A.cpp
    Program that finds the largest, smallest, average and median value from a set of data in
    a file supplied by the user, then echos those values to the user.
********************************************************************************************/
//included libraries
#include <iostream>
#include <fstream>
#include <string>
#include <assert.h>
using namespace std;

//function prototypes
void SetupArray(string filename, float array[], const int maxelements, int& size);
float largestOf(const float[], unsigned int count);
float smallestOf(const float[], unsigned int count);
float averageOf(const float[], unsigned int count);
float medianOf(const float[], unsigned int count);

//function definitions
int main()
    {
    int count = 0;
    const int maxelements = 1000;
    float list[maxelements];

    //prompt and extract the rest of the set
    cout << "Enter the filename to read: ";
    string filename;
    cin >> filename;

    SetupArray(filename, list, maxelements, count);

    //output the results
    cout << endl;
    if (count > 0)
      cout << "\nResults:" << endl
           << "   Smallest: " << smallestOf(list, count) << endl
           << "   Largest:  " << largestOf(list, count) << endl
           << "   Average:  " << averageOf(list, count) << endl
           << "    Median:  " << medianOf(list, count) << endl;
    else
      cout << "No valid input was received; therefore, there are no results." << endl;

    return 0;
    }

void SetupArray(string filename, float array[], const int maxelements, int& size)
    {

    ifstream fin(filename.c_str());
    if (!fin)
        {
        cerr << "Unable to open " << filename << " for reading.";
        size = -1;
        }
    else
        size = 0;

    for (int i = 0; i < maxelements; i++)
        {
        float input;
        if (fin >> input)
            {
            array[i] = input;
            size++;
            }
        else
            break;
        }

    return;
    }


//////////////////////////////////////////////////////////////////////////////////////////////
// Parses the array and returns the largest value of all elements in the array.
// count is the total number of valid elements in the array
float largestOf(const float A[], unsigned int count)
    {
    //check for a valid array
    assert(count > 0);

    //force-fit the first value as largest
    float largest = A[0];

    //check the rest of the set
    for (int i = 1; i < count; i++)
        if (A[i] > largest)
            largest = A[i];

    return largest;
    }

//////////////////////////////////////////////////////////////////////////////////////////////
// Parses the array and returns the smallest value of all elements in the array.
// count is the total number of valid elements in the array
float smallestOf(const float A[], unsigned int count)
    {
    //check for a valid array
    assert(count > 0);

    //force-fit the first value as smallest
    float smallest = A[0];

    //check the rest of the set
    for (int i = 1; i < count; i++)
        if (A[i] < smallest)
            smallest = A[i];
    return smallest;
    }

//////////////////////////////////////////////////////////////////////////////////////////////
// Parses the array and returns the arithmetic average all elements in the array.
// count is the number of elements to sum, and assumes that it is valid for the array in Arg1
float averageOf(const float A[], unsigned int count)
    {
    //check for a valid array
    assert(count > 0);

    float average, sigma = 0.;

    //Sum the elements
    for (int i = 1; i < count; i++)
        sigma += A[i];

    average = sigma/count;
    return average;
    }

//////////////////////////////////////////////////////////////////////////////////////////////
// Rreturns the mean of a (presumably) sorted array.
// count is the number of elements in the array
float medianOf(const float A[], unsigned int count)
    {
    //check for a valid array
    assert(count > 0);

    float median = A[(count-1)/2];

    return median;
    }