Tuesday, March 14, 2017

Programming Challenge 9.3 - Drop Lowest Score

/* Drop Lowest Score - This program dynamically allocates an array large
   enough to hold a user-defined number of test scores. Once all scores
   are entered, the array is passed to a function that sorts them in
   ascending order.

   Another function is called that calculates the average score. The
   p rogram displays the sorted list of scores and averages with
   appropriate headings. Pointer notation is used rather than array
   notation whenever possible.

   Input Validation: No negative numbers for test scores is accepted.
  
   This is a modification of Programming Challenge 2. The lowest score
   entered by the user is detected and removed, before the scores are
   sorted, and the average is calculated. */

#include "Utility.h"

/* Function prototypes */
void mainMenu();
void displayIntro();
void displayMenuItems();
void getTestScores(double *, const int);
int dropLowestScore(double *, int);
void sortScores(double *, const int);
double calcAverage(double *, const int);
void displayResults(const double *, const double, const int);

int main()
{
   mainMenu();

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: mainMenu

   Allows the user to select from the following items:

      * View Introduction
      * Enter Test-Scores
      * View Score-Data
      * Quit

   It takes care of calling the necessary functions, passing
   and receiving results, and freeing up the memory when the
   user decides to quit the program.
   ********************************************************** */

void mainMenu()
{
   /* Dynamically allocated array */
   double *testScores = nullptr;

   const int DISPLAY_INTRODUCTION = 1,
             GET_TEST_SCORES = 2,
             VIEW_RESULTS = 3,
             QUIT = 4;

   int menuItem = 0,
       numScores = 0;

   double averageScore = 0.0;

   do
   {
      displayMenuItems();
      cin >> menuItem;

      /* Validate input */
      while (menuItem < DISPLAY_INTRODUCTION || menuItem > QUIT)
      {
         cout << "\n\tInvalid menu item selected!\n"
              << "\tYour choice: ";
         cin >> menuItem;
      }

      switch (menuItem)
      {
         case DISPLAY_INTRODUCTION:
         {
            displayIntro();
         }
         break;

         case GET_TEST_SCORES:
         {
            /* Get the number of scores (at least three) */
            cout << "\n\tHow many test-scores do you wish to enter?\n"
                 << "\t(3 and above): ";
            cin >> numScores;

            cout << "\n";

            /* Input validation */
            while (numScores < 3)
            {
               cout << "\tInvalid input!\n"
                    << "\tHow many test-scores do you wish to enter? ";
               cin >> numScores;
               cout << "\n";
            }

            /* Dynamically allocates the array to hold the number of
               test scores the user wishes to enter */
            testScores = new double[numScores];

            /* Gets the number of scores entered by the user */
            getTestScores(testScores, numScores);

            /* Sorts the scores with an ascending-order selection sort
               algorithm */
            sortScores(testScores, numScores);

            /* Gets the new number of elements contained in the array,
               finds and drops the lowest score */
            numScores = dropLowestScore(testScores, numScores);

            /* Sorts testScores once more after the lowest score has
               been dropped */
            sortScores(testScores, numScores);

            /* Calculates the average score and returns the result */
            averageScore = calcAverage(testScores, numScores);
         }
         break;

         case VIEW_RESULTS:
         {
            /* Displays the data after sorting the scores and
               calculating the average */
            displayResults(testScores, averageScore, numScores);
         }
         break;

         case QUIT:
         {
            cout << "\n\tDoing a little housekeeping ... ";

            /* Free up memory */
            delete[] testScores;
            testScores = nullptr;

            cout << "\n\ttestScores cleared: " << testScores
                 << "\n\tPress enter to close this window!\n";
         }
         break;
      }
   } while (menuItem != QUIT); 
}

/* **********************************************************
   Definition: displayMenuItems

   This function displays the menu items the user can select
   between.
   ********************************************************** */

void displayMenuItems()
{
   cout << "\n\n\t\tAVERAGE TEST SCORE CALCULATOR\n\n"
        << "\t1. View Introduction\n"
        << "\t2. Enter Test-Scores\n"
        << "\t3. View Score-Data\n"
        << "\t4. Quit\n\n"
        << "\tYour choice: ";
}

/* **********************************************************
   Definition: displayIntroduction

   This function introduces the program and how it works to
   the user.
   ********************************************************** */

void displayIntro()
{
   cout << "\n\n\t\tAVERAGE TEST SCORE CALCULATOR\n\n"
        << "\tThis program allows you to enter a number of scores to\n"
        << "\tbe averaged. The number of scores to be entered has to\n"
        << "\tbe at least 3.\n\n"
        << "\tAfter the scores have been sorted in ascending order, the\n"
        << "\tthe lowest of all scores is dropped, and the average score\n"
        << "\twill be calculated. Having finished entering your scores,\n"
        << "\tyou can choose option '3' in the menu to view the scores in\n"
        << "\tsorted order and the average score that has been calculated.\n\n";
}

/* **********************************************************
   Definition: getTestScores

   This function accepts testScores and numScores, containing
   the number of elements to be stored in the array, as its
   arguments. It gets the scores to be stored by way of input
   from the user.
   ********************************************************** */

void getTestScores(double *testScores, const int numScores)
{
      for (int index = 0; index < numScores; index++)
      {
         cout << "\tScore #" << (index + 1) << ": ";
         cin >> *(testScores + index);

         /* Validate Input */
         while ((*(testScores + index) <= 0) ||
                (*(testScores + index) > 100.0))
         {
            cout << "\n\t\tYou entered an invalid score!\n\n";
            cout << "\tScore #" << (index + 1) << ": ";
            cin >> *(testScores + index);
         }
      }
      cout << "\n";
}

/* **********************************************************
   Definition: dropLowestScore

   This function accepts testScores and numScores as its
   arguments, containing the number of elements in the array.
   It drops the lowest score and returns the new number of
   elements indicated by numScores. The fact that the lowest
   score is already placed at subscript position 0 after
   sorting is used to advantage here.
   ********************************************************** */

int dropLowestScore(double *testScores, int numScores)
{
   int index = 0;

   numScores--;
   *(testScores + index) = *(testScores + numScores);

   return numScores;
}

/* **********************************************************
   Definition: sortScores

   This function accepts testScores and numScores, containing
   the number of elements stored in the array, as arguments.
   An ascending-order selection sort is performed on the
   elements stored in the array.
   ********************************************************** */

void sortScores(double *testScores, const int numScores)
{
   int startScan = 0,
       minIndex = 0,
       index = 0;

   double minElem = 0.0;

   for (startScan = 0; startScan < (numScores - 1); startScan++)
   {
      minIndex = startScan;
      minElem = *(testScores + startScan);

      for (index = startScan + 1; index < numScores; index++)
      {
         if (*(testScores + index) < minElem)
         {
            minElem = *(testScores + index);
            minIndex = index;
         }
      }

      *(testScores + minIndex) = *(testScores + startScan);
      *(testScores + startScan) = minElem;
   }
}

/* **********************************************************
   Definition: calcAverage

   This function accepts testScores and numScores as its
   argument. It steps through the array to total the scores,
   then calculates and returns the average.
   ********************************************************** */

double calcAverage(double *testScores, const int numScores)
{
   double total = 0.0,
          average = 0.0;

   for (int count = 0; count < numScores; count++)
   {
      total += *(testScores + count);
   }

   /* Calculates and returns the average */
   return average = total / numScores;
}

/* **********************************************************
   Definition: displayResults

   This function accepts testScores, averageScore and
   numScores as its argument. It displays the scores in
   sorted order and the average score.
   ********************************************************** */

void displayResults(const double *testScores, const double averageScore,
                    const int numScores)
{
   int index = 0;

   cout << fixed << showpoint << setprecision(2);

   cout << "\n\n\tTHE SCORES IN SORTED ORDER\n";

      for (index = 0; index < numScores; index++)
      {
         cout << "\n\t\tSCORE #" << (index + 1) << ":\t"
              << setw(5) << right << *(testScores + index)
              << " ";
      }
      cout << "\n\t-------------\n"
           << "\tAVERAGE SCORE:\t\t" << averageScore << "\n";
}

Example Output:





No comments:

Post a Comment