Thursday, January 12, 2017

Programming Challenge 6.17 - Transient Population

/* Transient Population - This program is a modification of Programming
   Challenge 6.16. It considers the effect on population caused by people
   moving into our out of a geographic area.
 
   The following is taken as input:
 
      * The starting population size
      * The annual birth rate
      * The annual death rate
      * The number of individuals who typically move into the area each year
      * The number of individuals who typically leave the area each year

   In addition to the above, the user is asked to enter the number of
   years he or she wishes to acquire data for. The program then calculates
   what the projected population will be after several years.

   Main functions:

      * pjtPopulationGrowth()
      * transientPopulationGrowth()

   Additional functions:

      * getData()
      * showIntroduction()
      * displayFinalData()

   Input Validation: No numbers less than 2 for the starting size, no
   negative numbers for birth rate, death rate, arrivals, or departures
   is allowed. */

#include "Utility.h"

/* Prototype: Get data, Show introduction, transient population growth,
              Projected population growth, displayFinalData */
void getData();
void showIntroduction();

void transientPopulationGrowth(long double, long double, int);
long double pjtPopulationGrowth(long double, long double, long double,
                                long double, long double, int);

void displayFinalData(int, long double, long double);

int main()
{
   /* Call: getData */
   getData();

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: getData

   This function displays a menu and an introduction if the
   user wishes to learn more about this program, it gets data
   by way of input from the user, which is passed to the
   following functions:
 
      * transientPopulationGrowth()
      * pjtPopulationGrowth()
      * displayFinalData()

   which further process the data and display the result of
   their respective calculations.
   ********************************************************** */

void getData()
{
   /* Constants: Menu items */
   const int INTRODUCTION = 1,
             BEGIN_AGAIN = 2,
             QUIT = 3;

   /* Variables: Population starting size, Annual birth rate, Annual death
                 rate, Moving in, Moving out */
   long double popStartSize = 0.0,
               birthRate = 0.0,
                 deathRate = 0.0,
               movingIn = 0.0,
               movingOut = 0.0,
               pjtTotalGrowth = 0.0;

   /* Variable: Menu selection, Number of years */
   int menuSelection = 0,
       numYears = 0;

   /* While the selected menu item is not quit, the user is asked to
      enter data to get different figures of population increase and
      decrease over a number of years, he or she then gets the result
      of the calculations, as well as the final result */
   do
   {
      cout << "\t\t\tTransient Population\n\n"
           << "1. Introduction\n"
           << "2. Begin / Try Again?\n"
           << "3. Quit\n\n"
           << "Your choice: ";
      cin >> menuSelection;

      while (menuSelection < 1 || menuSelection > 3)
      {
         cout << "\nThe menu item you selected does not exist.\n"
              << "Your choice: ";
         cin >> menuSelection;
      }

      switch (menuSelection)
      {
         case INTRODUCTION:
            showIntroduction();
         break;

      case BEGIN_AGAIN:
      cout << "\nWhat is the starting size of the population? ";
      cin >> popStartSize;

      while (popStartSize < 2)
      {
         cout << "\nYour input was invalid. The starting size of the\n"
              << "population must be at least 2 or above.\n\n"
              << "What is the starting size of the population? ";
         cin >> popStartSize;
      }

      cout << "What is the annual birth rate of the population? % ";
      cin >> birthRate;

      while (birthRate < 0 || birthRate > 100)
      {
         cout << "\nYour input was invalid. The birth rate can not be 0\n"
            << "or above 100.\n"
            << "Valid Input Example: % 2.48\n\n"
            << "What is the annual birth rate of the population? % ";
         cin >> birthRate;
      }

      cout << "What is the annual death rate of the population? % ";
      cin >> deathRate;

      while (deathRate < 0 || deathRate > 100)
      {
         cout << "\nYour input was invalid. The number of deaths can not\n"
              << "be lower than 0 or above 100%.\n"
              << "Valid Input Example: % 1.15\n\n"
              << "What is the annual death rate of the population? % ";
         cin >> deathRate;
      }

      cout << "How many residents enter the area on average each year? % ";
      cin >> movingIn;

      while (movingIn < 0 || movingIn > 100)
      {
         cout << "\nYour input was invalid. The number of new arrivals has\n"
              << "to be a positive value above 0.\n"
              << "Valid Input Example: % (0).4\n\n"
              << "How many residents enter the area on average each year? % ";
         cin >> movingIn;
      }

      cout << "How many residents leave the area on average each year? % ";
      cin >> movingOut;

      while (movingOut < 0 || movingOut > 100)
      {
         cout << "\nYour input was invalid. The number of residents leaving\n"
              << "the area has to be greater than 0 and at least % 0.1\n"
              << "Valid Input Example: % (0).2\n\n"
              << "How many residents leave the area on average each year? % ";
         cin >> movingOut;
      }

      cout << "For how many years should the population change? ";
      cin >> numYears;

      while (numYears < 0)
      {
         cout << "\nYour input was invalid. You have to enter a positive\n"
              << "value for the number of years to pass.\n"
              << "For how many years should the population change? ";
         cin >> numYears;
      }

      /* Call: transientPopulationGrowth */
      transientPopulationGrowth(movingIn, movingOut, numYears);

      /* Call: pjtPopulationGrowth */
      pjtTotalGrowth = pjtPopulationGrowth(popStartSize, birthRate, deathRate,
                                           movingIn, movingOut, numYears);
    
      /* Call: displayFinalData */
      displayFinalData(numYears, pjtTotalGrowth, popStartSize);
      break;

      case QUIT:
         pauseSystem();
         cout << "\nThank you for using this software! Have a nice day!\n\n";
         break;
      }
   } while (menuSelection != QUIT);
}

/* **********************************************************
   function: showIntroduction

   This function introduces the program to the user, and
   gives an example input and expected outcome after the
   calculations done in transientPopulationGrowth and
   pjtPopulationGrowth.
   ********************************************************** */

void showIntroduction()
{
   cout << "\n\t\t\tTransient Population\n\n"
        << "This program calculates and shows the effect of demographic\n"
        << "change in a population with constant birth and death rates,\n"
        << "by introducing new arrivals and departures as factors that\n"
        << "alter the demographic figures of an area over a period of\n"
        << "years.\n\n"
        << "The area is assumed to be ideal, meaning that there are no\n"
        << "natural disasters or famine etc. enough natural resources\n"
        << "to support the original population, as well as newcomers,\n"
        << "so that an undisturbed natural growth takes place.\n\n"
        << "Consider the following numbers:\n\n"
        << "* Starting Population:      1000\n"
        << "* Birth Rate:\t\t% 2.48\n"
        << "* Death Rate:\t\t% 1.15\n"
        << "* Arrivals:\t\t% 0.4\n"
        << "* Departures:\t\t% 0.2\n\n"
        << "These numbers would lead to an increase in your population\n"
        << "to 1232 after 10 years, all factors considered.\n"
        << "You can alter the above values for any number of times to\n"
        << "get different results. For instance, you can start with a\n"
        << "very low number in both birth and death rates, arrivals\n"
        << "and departures, and then increase these by entering a\n"
        << "birth and arrival rate in % (percent), to get a growth\n"
        << "in the hundreds of millions in only a very short amount\n"
        << "of time!\n\n";
}

/* **********************************************************
   Definition: ď˝”ransientPopulationGrowth

   This function accepts the following arguments:

      * Number of people moving into the area
      * Number of people moving out of the area
      * Number of years of change

   It calculates the increase by arrivals, the decrease by
   departures, and displays the results of the calculations.
   ********************************************************** */

void transientPopulationGrowth(long double movingIn, long double movingOut,
                               int numYears)
{
   /* Variables: Projected arrivals, Projected departures, Population
   increase, Population decrease, Projected total
   transience */
   long double pjtArrivals = movingIn,
      pjtDepartures = movingOut,
      populationIncrease = 0.0,
      populationDecrease = 0.0,
      pjtTransienceTotal = 0.0;

   /* Set up: Numeric output formatting */
   cout << fixed << showpoint << setprecision(2);

   /* Display: Table header */
   cout << "\n\t\t\tTransient Population Increase Total\n"
      << "\nIncrease Arrivals" << "\t "
      << " % " << "\t "
      << "Decrease Departures" << "\t "
      << "  % " << "\t "
      << "Net Increase" << "\t"
      << " %\n";

   cout << "............................................................."
      << ".....................................\n";

   /* The growth and decay rates are calculated as seperate entities,
   so as to have a better understanding by how much the population
   increases and decreases in both decimal numbers and percentage
   values, as well as the total Increase, arrivals and departures,
   also as percentage and decimal values */
   for (int yearsPassed = 0; yearsPassed < numYears; ++yearsPassed)
   {
      populationIncrease += pjtArrivals *
         (pow((1 + pjtArrivals / 100.0), yearsPassed) * 10.0);

      populationDecrease += pjtDepartures *
         (pow((1 - pjtDepartures / 100.0), yearsPassed) * 10.0);

      pjtTransienceTotal = populationIncrease - populationDecrease;

      /* Display: Output while the loop iterates */
      cout << setw(19) << right << populationIncrease
         << setw(8) << right << (populationIncrease / 100)
         << setw(25) << right << -populationDecrease
         << setw(8) << right << (populationDecrease / 100)
         << setw(12) << right << (pjtTransienceTotal)
         << setw(26) << right << (pjtTransienceTotal / 100) << "\n";
   }
   cout << endl;
}

/* **********************************************************
   Definition: pjtPopulationGrowth

   This function accepts six arguments:

      * Population starting size
      * Annual birth rate
      * Annual death rate
      * Annual arrivals
      * Annual departures
      * Number of years

   It calculates the population growth, displays the results
   of the calculations, and passes the result after numYears
   back to getData().
   ********************************************************** */

long double pjtPopulationGrowth(long double startingPopulation,
                                long double birthRate, long double deathRate,
                                long double nArrivals, long double nDepartures,
                                int numYears)
{
   /* Variables: Projected birth rate, Projected Death rate, Natural
                 increase rate in percent, Natural decrease rate,
                 Population increase, Population decrease, Natural
                 growth rate total */
   long double pjtBirthRate = birthRate,
               pjtDeathRate = deathRate,
               pjtMovingIn = nArrivals,
               pjtMovingOut = nDepartures,
               populationIncrease = 0.0,
               populationDecrease = 0.0,
               natGrowthTotal = 0.0;

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

   /* Display: Table header */
   cout << "\n\t\t\tProjected Population Increase Total\n"
      << "\nPopulation Increase" << "\t "
      << " % " << "\t "
      << "Population Decrease" << "\t "
      << "  % " << "\t "
      << "Net Population Increase" << "\t"
      << " % "
      << "\n(Births and Arrivals)" << "\t\t"
      << "(Deaths and Departures)" << "\t\t"
      << "(Total Population Growth)\n";

   cout << "............................................................."
      << ".....................................\n";

   /* The growth and decay rates are calculated as seperate entities,
      so as to have a better understanding by how much the population
      increases and decreases in both decimal numbers and percentage
      values, as well as the total Increase, births and deaths, as well
      as arrivals and departures, also as percentage and decimal values */
   for (int yearsPassed = 0; yearsPassed < numYears; ++yearsPassed)
   {
      populationIncrease += (pjtBirthRate + pjtMovingIn) *
         (pow((1 + pjtBirthRate / 100.0), yearsPassed) * 10.0);

      populationDecrease += (pjtDeathRate - pjtMovingOut) *
         (pow((1 - pjtDeathRate / 100.0), yearsPassed) * 10.0);

      natGrowthTotal = populationIncrease - populationDecrease;

      /* Display: Output while the loop iterates */
      cout << setw(19) << right << populationIncrease + startingPopulation
           << setw(8) << right << (populationIncrease / 100)
           << setw(25) << right << -populationDecrease
           << setw(8) << right << (populationDecrease / 100)
           << setw(12) << right << (natGrowthTotal + startingPopulation)
           << setw(26) << right << (natGrowthTotal / 100) << "\n";
   }
   cout << endl;

   /* Return: The natural growth rate */
   return natGrowthTotal;
}

/* **********************************************************
   Definition: displayFinalData

   This function takes three arguments:

      * The number of years a population should grow
      * The total growth in a given population
      * The population's starting size

   It displays the final result of the calculations done in
   both transientPopulationGrowth() and pjtPopulationGrowth
   which is the total growth in the population after a number
   of years passed as argument by the user in getData().
   ********************************************************** */

void displayFinalData(int numYears, long double popGrowthTotal,
                      long double popStartSize)
{
   /* Display: The final result of the calculations done in
               populationGrowth, the return value is demoted
               to long int to get a round number, and popGrowthTotal
               is converted to a %-value */
   cout << "\nAfter " << numYears
        << " years, the population grew to a size of "
        << (long int)(popGrowthTotal + popStartSize)
        << " or a total of % "
        << fixed << showpoint << setprecision(2) << (popGrowthTotal / 100)
        << "\n\n";

   pauseSystem();
}

Example Output



No comments:

Post a Comment