Thursday, December 29, 2016

Another Chapter Finished

Yes, it is accomplished, another chapters programming challenges are overcome, and a challenge it was indeed. When i started out with challenge 5.01 i was stumped. I felt like i learned nothing at all about loops when it was time to put into practice what i learned about and practiced during this chapter. Slowly things fell into place, and i started to see how to use which loop, and why indeed one is better to use in certain situation than the other, and how loops, and their logic work. Specifically the for loops, which only really become clear to me when it came to the hardest challenge of all, which was displaying patterns of +'s side by side.

Writing the for loop as such to display the patterns was not the problem, but once i saw that formatting the output like this:

cout << " ";

directly under the first two for loops displaying the first pattern, or

cout << "\t ";
cout << setw(12) << right;
...

which ALMOST worked, but had the ill side-effect of intending only the first couple of columns of pattern B to the right, the last two were always way to the left, I was lost. After doing some good hard thinking, and with the solution right in front of my eyes all the time, it dawned on me. Why, if you can use a loop to display both patterns, why not try and add another! And, yes! It worked! I virtually jumped for joy when i figured it out, and it actually worked the way it was supposed to! That was the moment when I felt actually having mastered what i have learned in the chapter by solving all the other challenges before.

One thing i also learned to love in particular, my debugger and how much clearer things become when going through it, setting break-points, and look at which variable gets which value, what actually happens when a number in a loop increments, and what other value then changes. And, back to the pattern display challenge, it became clear as day to me how the loops i have written logically "work together" and in what order. Because, as it is written, it seems counter intuitive seeing that the first two for loops decrement columns and rows, yet displaying +'s all the while.

Looking at it from the perspective of what it does, deducting rows and columns and display only 1 + instead of 10 rows and 10 columns of +'s, or the other way around, just like it would have in the programming challenge previous to the pattern A/B one, is clear. But actually seeing how it actually works, looking at it while running the program through the debugger is a totally different story, yet a very illuminating one, i learned very much from.

Apart from that, there were some programs to write that looked like they are going to be difficult, but almost felt like they wrote themselfs. Difficulties, speaking of which, there were many during the course of solving these challenges. Most didn't even have to-do with writing the code itself, but with the things that are asked for. For instance the Payroll Report, Savings Account Balance, or Student Line Up. Each came with a specific set of challenges that i knew little about. In case of the Payroll Report program, it was i guess not knowing how such a report is calculated, but sites like The Balance or Calculator Soup and Discovery Education among others, helped me in finding the necessary information, or formulae, that would (hopefully) lead to correct results once the programs run. So, the main source of my problems was seldom how to write the program, all the loops etc, but simply a lack of knowledge in certain areas that - as a positive side-effect, greatly increased, though are of little practical value in real life.

The last thing i learned from working on this chapter is that some code might be so much more easy to write, or so much shorter than it actually turned out to be, with knowledge of "tools" i do not yet posses, but will certainly follow in one of the next chapters.

In one of the reviews i read about the book Starting Out with C++ from Control Structures through Objects, someone was complaining that:

"The problems in each chapter can not be solved, just because some concepts haven't been learned."

Yet every challenge can be solved, even though it turns into one long code, as with the Mobile Service Provider challenge, and it is a valuable lesson in itself to realize that:

Even with the most limited set of keywords and programming concepts, one can write dozens and dozens of programs, some of actual practical value! Learn about loops and random number generation for instance, and you can calculate 200 sets of Lottery numbers easily, or write a statistical program, for whatever you need it to do, or your own household account managing software (if only in the console). Or some fun little game to help your child or children learn basic maths with. How about that!    

And then finally, there is stupidity ... Imagine how I read what is asked for in Challenge 5.24, which is all about reading in a set of numbers, calculating the sum, the average number of numbers, and then the sum of all numbers. What is the first thing i did? Guess ... You can't? I opened the text file, and clicked my way through the list, counting it myself to see how many numbers it contains, for getting the correct result once the file is read in and the loop begins to count numbers ... But such things do and will happen once and again, how about the practical value of Wordpad, simply displaying line numbers? Anyone? Which occurred only after having finished counting by hand all the numbers of numbers ... (Which I also, just to be sure that i counted correctly ...) S-T-U-P-I-D!

Anyway, it was a long journey so far, 5 chapters, thousands of lines of code written, dozens of challenges solved, and yet hundreds of pages and challenges in front of me. I totally look forward to overcome every single one, because every challenge mastered is a stepping stone on the way to mastery far ahead, and my goal: Realizing my own game, be it ever so humble.

With this I wish all of my fellow learners success on their path, fun while trying to solve the challenges ahead of you, and that you may be spared from all too numerous occurrences of AAAAAAAAAAARGH! and GRRRRRRRRRRRRR! moments, that probably everyone out there is familiar with.

Programming Challenge 5.26 - Using Files - Savings Account Balance

Example-File: FinalReport.txt

/* Using Files - Savings Account Balance - This program calculates the balance
   of a savings account at the end of a period of time. It asks the user for
   the annual interest rate, the starting balance, and the number of months that
   have passed since the account was established. A loop iterates once for every
   month, performing the following:

   * The user is asked for the amount deposited into the account during the
      month. This amount is added to the balance.

      Input Validation: No negative numbers are accepted.

   * The user is asked for the amount withdrawn from the account during the
     month. This amount is subtracted from the balance.

     Input Validation: No negative numbers are accepted.

   * Calculating the monthly interest:

     The monthly interest rate is the annual interest rate divided by twelve.
     The monhtly interest rate is multiplied by the balance, and the result is
     added to the balance.

     After the last iteration, the program display the ending balance, the total
     amount of deposits, the total amount of withdrawals, and the total interest
     earned.

     Notice: If, at any point, a negative balance is calculated, a message will
     be displayed, indicating that the account has been closed and the loop will
     terminate.

   Update:
   This is a modification of the program written for Programming Challenge 5.16
  
   The following has changed:
  
   * After the last iteration, the program stores the final report in a file
     called "FinalReport.txt". */

#include "Utility.h"

int main()
{
    /* Update::Declare: Output file stream object variable */
    ofstream finalReport;

    /* Constant: Maximum annual interest rate */
    const double ANNUAL_INTEREST_MAX = 15;

    /* Variable: Months (counter variable), Months passed */
    int months = 1,
        monthsPassed = 0;

    /* Variables: Starting Balance, Annual interest rate, Monthly interest
       rate, Account Balance (accumulator variable), Account balance total,
       Monthly deposits, Monthly deposits total, Monthly withdrawals total
       (accumulator variable), Monthly balance total, (accumulator variable),
       Monthly interest earned, Deposits total, Withdrawals total, Interest
       earned total */
    double startingBalance = 0,
           annualInterestRate = 0,
           accountBalance = 0,
           accountBalanceTotal = 0,
           monthlyInterest = 0,
           interestRate = 0,
           monthlyInterestRate = 0,
           monthlyDeposits = 0,
           monthlyDepositsTotal = 0,
           monthlyWithdrawals = 0,
           monthlyWithdrawalsTotal = 0,
           monthlyInterestEarned = 0,
           monthlyBalanceTotal = 0,
           depositsTotal = 0,
           withdrawalsTotal = 0,
           interestEarnedTotal = 0;

    /* Display: Information */
    cout << "\t\tAshikaga Bank: Personal Account Balance Manager\n\n";

    /* Input::Ask the user for: The starting balance of the users bank
       account, the annual interest rate, the number of months have passed
       since the account was established */
    cout << "What was the starting balance of your account?\n"
        << "Starting Balance: $ ";
    cin >> accountBalance;

    /* While loop::Input Validation: As long as the starting balance entered
       by the user is below or equal to 0, this loop will iterate */
    while (accountBalance <= 0)
    {
        /* Display: Error message */
        cout << "Error: The Starting Balance has to be a positive value.\n";

        /* Ask again: */
        cout << "Starting Balance: $ ";
        cin >> accountBalance;
    }

    cout << "What is the annual interest rate?\n"
         << "Annual Interest Rate: % ";
    cin >> annualInterestRate;

    /* While loop::Input Validation: While the annual interest rate entered
    by the user is below or equal to 0, or above ANNUAL_INTEREST_MAX (4.25),
    this loop will iterate */
    while (annualInterestRate <= 0 || annualInterestRate > ANNUAL_INTEREST_MAX)
    {
        /* Display: Error message */
        cout << "Error: The Annual Interest Rate has to be a positive value\n"
             << "above 0 and below or equal to %4.25.\n";

        /* Ask again: */
        cout << "Starting Balance: $ ";
        cin >> annualInterestRate;
    }

    cout << "How much time has passed since your account was established?\n"
        << "Months Passed: ";
    cin >> monthsPassed;

    /* While loop::Input Validation: While months passed entered by the user
       is below or equal to 0, this loop will iterate */
    while (monthsPassed <= 0)
    {
        /* Display: Error message */
        cout << "Error: The amount of months passed can not be negative!\n";

        /* Ask again: */
        cout << "Months Passed: ";
        cin >> monthsPassed;
    }

    /* For loop: As long as months is lower than or equal to months passed,
       this loop will iterate */
    for (months; months <= monthsPassed; months++)
    {
        /* Nested While loop: While months is smaller than or equal to
           months passed, and the account balance is not negative,
           this loop will iterate */
        while (months <= monthsPassed && (!(accountBalance < 0)))
        {
            /* Input::Ask the user for: His or her monthly deposits, his or
            her monthly withdrawals */
            cout << "\nHow much money have you deposited in month " << months
                << " in total?\n"
                << "Monthly Deposit: $ ";
            cin >> monthlyDeposits;

            /* Nested While loop: While the customer enters a negative
               number for his or her monthly deposits, this loop will
               iterate */
            while (monthlyDeposits < 0)
            {
                /* Display: Error message */
                cout << "\nError: Monthly deposits have to be positive,\n"
                    << "or above, or equal to 0, if no deposits were\n"
                    << "made in the month you wish to enter data for.\n";

                /* Ask again: */
                cout << "\nHow much money have you deposited in month " << months
                    << " in total?\n"
                    << "Monthly Deposit: $ ";
                cin >> monthlyDeposits;
            }

            cout << "\nHow much money have you withdrawn in month " << months
                << " in total?\n"
                << "Monthly Withdrawals: $ ";
            cin >> monthlyWithdrawals;

            /* Nested While loop: While the customer enters a negative
               number for his or her monthly deposits, this loop will
               iterate */
            while (monthlyWithdrawals < 0)
            {
                /* Display: Error message */
                cout << "\nError: Monthly withdrawals have to be positive,\n"
                    << "or above, or equal to 0, if no withdrawals have\n"
                    << "occured in the month you wish to enter data for.\n";

                /* Ask again: */
                cout << "\nHow much money have you withdrawn in month "
                     << months << " in total?\n"
                     << "Monthly Withdrawals: $ ";
                cin >> monthlyWithdrawals;
            }

            /* Accumulating: Monthly deposits (add to the account balance),
               Monthly withdrawals (deduct from the account balance) */
            accountBalance += monthlyDeposits;
            accountBalance -= monthlyWithdrawals;

            /* Calculations: Monthly interest rate:
               To get the fraction of the total interest rate, 4.25 = 0.0425,
               the annual interest rate is divided by 100 and by the amount
               of months in a year */
            monthlyInterestRate = (annualInterestRate / 12.0) / 100.0;

            /* Interest rate formula: Monthly interest rate = account balance *
               monthly interest rate * (months passed / 12.0) / 100.0 */
            interestRate = accountBalance * monthlyInterestRate *
                (monthsPassed / 12.0);
            monthlyInterest = accountBalance * monthlyInterestRate *
                (monthsPassed / 12.0);

            /* Accumulating: Total monthly deposits, Total monthly withdrawals,
               Total monthly interest earned, Total monthly balance */
            monthlyDepositsTotal += monthlyDeposits;
            monthlyWithdrawalsTotal -= monthlyWithdrawals;
            monthlyInterestEarned += monthlyInterest;
            monthlyBalanceTotal = accountBalance + monthlyInterestEarned;

            /* Accumulating: Total Deposits, Total withdrawals, Total
               Interest Earned, Total account balance */
            depositsTotal += monthlyDeposits;
            withdrawalsTotal -= monthlyWithdrawals;
            interestEarnedTotal += interestRate;
            accountBalanceTotal = accountBalance + interestEarnedTotal;

            /* If Statement: If the account balance is negative, or the
               total monthly balance is negative, this statement will be
               executed
              
               Update: One bad testing condition was removed from this if
               statement, because it was triggered even though there was
               no reason for it, and the other was changed so that it now
               checks the monhtly withdrawals against monthly deposits
               total + the account balance */
            if (accountBalance < 0 || monthlyBalanceTotal < 0 ||
                monthlyWithdrawals > (monthlyDepositsTotal + accountBalance))
            {
                cout << "\nValued customer,\n\n"
                    << "We are utmost sorry to have to inform you about the sad\n"
                    << "event, that your bank account was for some unknown reason\n"
                    << "overdrawn, and had to be terminated.\n"
                    << "If you wish to aquire further information about this event,\n"
                    << "or you feel that this was a failure on our side or a third\n"
                    << "party we have no control over, please do not hesitate to call\n"
                    << "us. Our hotlines are open for you 24/7.\n"
                    << "It would also be a pleasure for us, should you give us the\n"
                    << "opportunity to clarify this sad situation with you personally,\n"
                    << "to visit us during our regular service hours. We will see to it,\n"
                    << "that this problem will be resolved to your utmost satisfaction.\n"
                    << "Thank you for your understanding,\n\n"
                    << "Your Ashikaga Bank Team\n";

                pauseSystem();
                return 0;
            }

            /* Display: Formatted monthly output of the account balance sheet */
            cout << fixed << showpoint << setprecision(2);
            cout << "\n\t\tAshikaga Bank - Monthly Account Balance Sheet\n";
            cout << "--------------------------------------------------------------------\n";
            cout << "Month: " << months << "\n";
            cout << "\nMonthly Deposits Total:\t\t\t\t\t $ " << setw(9) << right
                << monthlyDepositsTotal << endl;
            cout << "Monthly Withdrawals Total:\t\t\t\t $ " << setw(9) << right
                << monthlyWithdrawalsTotal << endl;
            cout << "Monthly Interest Earned:\t\t\t\t $ " << setw(9) << right
                << monthlyInterestEarned << endl;
            cout << "--------------------------------------------------------------------\n";
            cout << "Monthly Balance Total:\t\t\t\t\t $ " << setw(9) << right
                << monthlyBalanceTotal << endl;
            cout << "--------------------------------------------------------------------\n";

            months++;
        }

        /* Display: The final report */
        cout << fixed << showpoint << setprecision(2);
        cout << "\n\n\t\tAshikaga Bank - Final Account Balance Sheet\n";
        cout << "--------------------------------------------------------------------\n";
        cout << "Account History: " << monthsPassed << " months\n";
        cout << "\nDeposits Total:\t\t\t\t\t $ " << setw(9) << right
            << depositsTotal << endl;
        cout << "Withdrawals Total:\t\t\t\t $ " << setw(9) << right
            << withdrawalsTotal << endl;
        cout << "Interest Earned Total:\t\t\t\t $ " << setw(9) << right
            << interestEarnedTotal << endl;
        cout << "--------------------------------------------------------------------\n";
        cout << "Account Balance Total:\t\t\t\t $ " << setw(9) << right
            << accountBalanceTotal << endl;
        cout << "--------------------------------------------------------------------\n";

        /* Update::Open: File "FinalReport.txt" */
        finalReport.open("FinalReport.txt");

        /* If statement::Error handling: If the file was opened successfully
           the data will be written */
        if (finalReport)
        {
            /* Output: Write the formatted  final output of the account balance sheet to the file "FinalReport.txt" */
            finalReport << fixed << showpoint << setprecision(2);
            finalReport << "\n\n\t\tAshikaga Bank - Final Account Balance Sheet\n";
            finalReport << "--------------------------------------------------------------------\n";
            finalReport << "Account History: " << monthsPassed << " months\n";
            finalReport << "\nDeposits Total:\t\t\t\t\t $ " << setw(9) << right
                << depositsTotal << endl;
            finalReport << "Withdrawals Total:\t\t\t\t $ " << setw(9) << right
                << withdrawalsTotal << endl;
            finalReport << "Interest Earned Total:\t\t\t\t $ " << setw(9) << right
                << interestEarnedTotal << endl;
            finalReport << "--------------------------------------------------------------------\n";
            finalReport << "Account Balance Total:\t\t\t\t $ " << setw(9) << right
                << accountBalanceTotal << endl;
            finalReport << "--------------------------------------------------------------------\n";
        }
        else
        {
            /* Update::Display: Error message */
            cout << "\nDear customer, an error occured!\n\n"
                 << "Your data could not be saved. This can happen because 'FinalReport.txt\n"
                 << "could not be opened or accessed for writing. Make sure that the program\n"
                 << "folder or the file is either damaged, one or the other is damaged, or\n"
                 << "one or both are set to read-only, preventing data storage.\n"
                 << "To check that that is not the case, right click on the file/folder,\n"
                 << "choose 'Properties,' uncheck 'Read-Only', then run the program again.\n\n"
                 << "Thank you for your understanding,\n"
                 << "Your Ashikaga Bank Team.\n";
        }

        /* Close: File "FinalReport.txt */
        finalReport.close();
    }

    pauseSystem();
    return 0;
}

Programming Challenge 5.25 - Using Files - Student Line Up

Example File: LineUp.txt

/* Using Files - Student Line Up - This is a modified version of the
   program written for Programming Challenge 5.14. In this version,
   the names are stored in, and retrieved from, the file "LineUp.txt".

   Once all the names have been read in, the program reports which student
   would be at the front of the line and which one would be at the end of
   the line. For testing purposes, names should be added, or changed.
  
   Example: Put Abel between Bill and Mary */

#include "Utility.h"

int main()
{
    /* Declare: File stream variable */
    ifstream studentLineUp;

    /* Variable: Student name, Line up first, Line up last */
    string studentName = " ",
           lineUpFirst = " ",
           lineUpLast = " ";
   
    /* Variable: Student counter (counter variable), Update (counter
       variable) */
    int studentCounter = 0;
    int update = 1;

    /* Open: File "LineUp.txt" */
    studentLineUp.open("LineUp.txt");

    /* If statement::Error handling: If the file was opened successfully,
       the file will be processed */
    if (studentLineUp)
    {
        /* For loop: As long as student names are read in from "LineUp.txt"
           this loop will iterate */
        for (studentCounter; studentLineUp >> studentName; studentCounter++)
        {
                /* Nested While loop: While update is true, and student
                   names are read in from "LineUp.txt", this loop will
                   iterate */
                while (update == 1)
                {   
                    /* lineUpFirst and lineUpLast get studentName */
                    lineUpFirst = studentName;
                    lineUpLast = studentName;
                   
                    update++;
                }
               
                /* Conditional statement: Is the student currently first in line
                   smaller than the name read in from "LineUp.txt"? If so, first
                   in line will get student name */
                lineUpFirst = lineUpFirst < studentName ? lineUpFirst : studentName;

                /* Conditional statement: Is the student name currently last in
                   line greater than the name read in from "LineUp.txt"? If so,
                   last in line will get student name */
                lineUpLast = lineUpLast > studentName ? lineUpLast : studentName;
        }

        /* Display: Information */
        cout << "\t\tStudent Line Up\n\n"
             << "This program helps you to determine which student has to\n"
             << "stand at which position during roll call every morning.\n\n";

        /* Display: The name of the student who stands first in line, and
           the name of the student standing last in line every morning at
           roll call */
        cout << "Every morning, " << lineUpFirst << " will stand first in line.\n";
        cout << "Every morning, " << lineUpLast << " will stand last in line.\n";
    }

    else
    {
        /* Display: Error message */
        cout << "Error: For some reason the file 'LineUp.txt' could not be\n"
             << "opened. Please make sure that the file exists, that it has\n"
             << "the correct filename, and that it has not been accidentally\n"
             << "moved or has been deleted from the program folder.\n"
             << "Please close the program, check that the above conditions\n"
             << "are met, and start this program again.\n";
    }

    /* Close: File "LineUp.txt" */
    studentLineUp.close();

    pauseSystem();
    return 0;
}

Programming Challenge 5.24 - Using Files - Numeric Processing

Example File: Random.txt

/* Using Files - Numeric Processing - The file "Random.txt" contains a
   long list of random numbers. This program opens the file, reads all
   the numbers from the file, and calculates the following:
  
   * The number of numbers in the file
   * The sum of all the numbers in the file
   * The average of all the numbers in the file

   The program displays:
  
   * The number of numbers found in the file
   * The sum of the numbers
   * The average of the numbers */

#include "Utility.h"

int main()
{
    /* Declare: File stream variable */
    ifstream randomNumbers;

    /* Variables: Count numbers (counter variable) */
    int countNumbers = 1;

    /* Variables: Numbers, Number of numbers, Sum of numbers, Average of
       numbers */
    double numbers = 0,
           numberOfNumbers = 0,
           sumOfNumbers = 0,
           averageOfNumbers = 0;

    /* Open: File "Random.txt" */
    randomNumbers.open("Random.txt");

    /* If statement::Error handling: If the file was opened successfully,
       it will be processed */
    if (randomNumbers)
    {
            /* For loop: As long as numbers are read in from "Random.txt",
               count numbers is incremented, counting the numbers */
            for (countNumbers; randomNumbers >> numbers; countNumbers++)
            {
                /* Number of numbers gets count numbers */
                numberOfNumbers = countNumbers;

                /* Calculations: Sum of numbers, Average number of numbers
                   (The average number is calculated by dividing the sum
                   of numbers = 105527 by the number of numbers = 200 */
                sumOfNumbers += numbers;
                averageOfNumbers = (sumOfNumbers / numberOfNumbers);
            }

        /* Display: Formatted Output of the total number of
           numbers, the sum of numbers, the average number of numbers */
        cout << "\t\tRandom File Processor\n\n"
             << "This program calculates and displays the following\n"
             << "items contained in the file 'Random.txt' for you:\n\n"
             << "* The number of numbers\n"
             << "* The sum of numbers\n"
             << "* The average number of numbers\n\n";

        cout << "The total number of numbers is: "
             << setw(8) << right << numberOfNumbers << endl;
        cout << "The sum total of all numbers is: "
             << setw(7) << right << sumOfNumbers << endl;
        cout << "The average number of numbers is: "
             << setw(10) << right << averageOfNumbers << endl;
    }

    else
    {
        /* Display: Error message */
        cout << "Error: The file 'Random.txt' could not be processed. This\n"
            << "error could be caused by one of the following reasons:\n\n"
            << "* Moving the file from the programs source folder\n"
            << "* A damaged source file\n"
            << "* An overwritten source file\n"
            << "* By accidentally renaming 'Random.txt'\n\n"
            << "To solve this problem, please close this program, check that\n"
            << "the file exists, that it is not damaged, is named 'Random.txt'\n"
            << "and that it is located in the source folder of your program.\n"
            << "Once you checked the above points, please run the program again!\n";
    }

    /* Close: File "Random.txt */
    randomNumbers.close();

    pauseSystem();
    return 0;
}

Wednesday, December 28, 2016

Programming Challenge 5.23 - Pattern Displays

/* Pattern Displays - This program uses a loop to display Pattern A below,
   followed by another loop that displays Pattern B

   -----------------------------------------------------------------
   Pattern A                        Pattern B
   -----------------------------------------------------------------
   +                                     ++++++++++
   ++                                   +++++++++
   +++                                 +++++++
   ++++                               ++++++
   +++++                             +++++
   +++++++                         ++++
   ++++++++                       +++
   +++++++++                     ++
   ++++++++++                   +
----------------------------------------------------------------- */

#include "Utility.h"

int main()
{
    /* Constants: Minimum number of pattern symbols, Maximum number
    of pattern symbols */
    const int PATTERN_SYM_MIN = 1,
              PATTERN_SYM_MAX = 10;

    /* Variables: Pattern rows (counter variable), Pattern columns A
       (counter variable), Pattern columns B (counter variable),
       Window width (counter variable) */
    int patternRows = 0,
        columnsPatternA = 0,
        columnsPatternB = 0,
        windowWidth = 0;

    /* Display: Header - Pattern A - PATTERN B */
    cout << "-----------------------------------------\n";
    cout << "PATTERN A" << "         PATTERN B"
        << "\n-----------------------------------------\n";

    /* For loop: Pattern rows gets PATTERN_SYM_MAX, as long patternRows
       is greater than or equal to PATTERN_SYM_MIN, this loop iterates
       and decrements pattern rows */
    for (patternRows = PATTERN_SYM_MAX; patternRows >= PATTERN_SYM_MIN;
        patternRows--)
    {
        /* Nested For loop: Columns pattern A gets PATTERN_SYM_MAX, as
           long as columns pattern A is greater than or equal to pattern
           rows == PATTERN_SYM_MAX (at first), this loop decrements once,
           adding 1 +, decrementing to PATTERN_SYM_MAX - 1, decrements twice,
           getting PATTERN_SYM_MAX during every iteration, until pattern rows
           reaches PATTERN_SYM_MIN, by which time 10 + are displayed */
        for (columnsPatternA = PATTERN_SYM_MAX; columnsPatternA >= patternRows;
            columnsPatternA--)
        {
            cout << "+ ";
        }

        /* Nested For loop: Window width gets PATTERN_SYM_MIN, as long as
           window width is smaller than or equal to PATTERN_SYM_MAX +
           patternRows (ex. 20), this loop iterates, adding blank spaces -
           dividing up pattern A and pattern B horizontally */
        for (windowWidth = PATTERN_SYM_MIN;
            windowWidth <= (PATTERN_SYM_MAX + patternRows);
            windowWidth++)
        {
            cout << " ";
        }

        /* Nested For loop: Columns pattern B gets PATTERN_SYM_MIN, as long
           as columns pattern B is smaller than or equal to pattern Rows ==
           PATTERN_SYM_MAX (at first), this loop iterates, and increments
           PATTERN_SYM_MIN (ex. displaying 10 +'s), then gets PATTERN_SYM_MAX
           again until pattern rows == PATTERN_SYM_MIN, by which time only one
           + is shown at the bottom */
        for (columnsPatternB = PATTERN_SYM_MIN; columnsPatternB <= patternRows;
            columnsPatternB++)
        {
            cout << "+ ";
        }

        cout << endl;
    }

    /* Display table footer */
    cout << "-----------------------------------------\n";

    pauseSystem();
    return 0;
}

Tuesday, December 27, 2016

Programming Challenge 5.22 - Square Display

/* Square Display - This program asks the user for a positive integer no
   greater than 15. The program then displays a square on the screen using
   the character 'X'. The number entered by the user will be the length of
   each side of the square.
  
   Example:
  
   If the user enters 5, the program displays:
  
   XXXXX
   XXXXX
   XXXXX
   XXXXX
   XXXXX
  
   If the user enters 8, the program displays:

   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX */

#include "Utility.h"

int main()
{
    /* Constant: Minimum number of 'X' characters,
       Maximum number of 'X' characters */
    const int CHARACTERS_MIN = 2,
              CHARACTERS_MAX = 15;

    /* Variables: Pattern character */
    char pattern = 'X';

    /* Variables: Pattern length, Number of rows (counter variable),
       Number of columns (counter variable) */
    int patternLength = 0,
        numRows,
        numColumns;

    /* Display: Information */
    cout << "\t\tSQUARE DISPLAY\n\n"
         << "Please enter the number of squares for the pattern to\n"
         << "display. ( " << CHARACTERS_MIN
         << " is the lowest, " << CHARACTERS_MAX << " the highest).\n"
         << "Once done, press enter, and enjoy the created pattern.\n\n";    cout << "Number of squares: ";
    cin >> patternLength;

    /* While loop::Input Validation: If the number entered by the user
       is less than CHARACTERS_MIN, or greater than CHARACTERS_MAX, this
       statement will be executed */
    while (patternLength < CHARACTERS_MIN || patternLength > CHARACTERS_MAX)
    {
        /* Display: Error message */
        cout << "\nSorry, it seems that the number entered by you was\n"
             << "either below " << CHARACTERS_MIN
             << " or greater than " << CHARACTERS_MAX << ". Please try again.\n";

        /* Ask again */
        cout << "Number of squares: ";
        cin >> patternLength;
    }

    cout << endl;

    /* For loop: As long as number of rows is smaller than pattern length,
       this loop will iterate */
    for (numRows = 0; numRows < patternLength; numRows++)
    {
        /* Nested For loop: As long as the number of columns is smaller
           than pattern length, this loop will iterate */
        for (numColumns = 0; numColumns < patternLength; numColumns++)
        {       
            /* Display: pattern */
            cout << pattern;
        }
        cout << endl;
    }

    pauseSystem();
    return 0;
}

Programming Challenge 5.21 - Random Number Guessing Game Enhancement

/* Random Number Guessing Game Enhancement - This program generates a
   random number and asks the user to guess what the number is. If the
   user's guess is higher than the random number, the program displays
   "Too high, try again." If the users guess is lower than the random
   number, the program displays "Too low, try again." The program uses
   a loop that repeats until the user correctly guessed the random number.
 
   Enhancement: This program, written in Programming Challenge 5.20 now
   keeps count of the number of guesses. When the user correctly guesses
   the random number, the program displays the number of guesses. */

#include "Utility.h"

int main()
{
    /* Constants: Smallest number to guess, Largest number to guess */
    const int SMALLEST_NUMBER = 1,
              LARGEST_NUMBER = 100;

    /* Variables: Random number, Guess, Guessing counter
    (counter variable) */
    int randomNumber = 0,
        guess = 0,
        guessingCounter = 0;

    /* Enhancement: Number of guesses (counter variable), initialized to 1,
       (to account for the first priming read of guess, that takes place
       outside the for loop */
    int    numGuesses = 1;

    /* Get the system time and seed the random number generator */
    srand((unsigned int)time(NULL));

    /* Generate random number */
    randomNumber = (rand() % (LARGEST_NUMBER - SMALLEST_NUMBER + 1)) +
        SMALLEST_NUMBER;

    /* Display: Welcome message */
    cout << "\t\tRANDOM NUMBER GUESSING GAME\n\n"
        << "Welcome, Brave Hero, I challenge thee!\n"
        << "Guess the right number between 1 to "
        << LARGEST_NUMBER << ",\n"
        << "and you might be set free!\n";

    /* Ask for a first guess */
    cout << "\nGuess my number: ";
    cin >> guess;

    /* While loop::Input Validation: While the guess the user entered is
    lower than SMALLEST_NUMBER (1), or higher than LARGEST_NUMBER,
    this loop will iterate */
    while (guess < SMALLEST_NUMBER || guess > LARGEST_NUMBER)
    {
        /* Display: Error message */
        cout << "\nIt seems thou art not listening to me! The number\n"
            << "to guess is greater than 0, and up to "
            << LARGEST_NUMBER << ", you see?\n";

        /* Ask again: */
        cout << "\nGuess my number: ";
        cin >> guess;

        /* Enhancement::Counter: The number of guesses is decremented
           by -1 so that, whenever the number entered is out of bounds,
           and this loop is executed, the guess will not be counted */
        guessingCounter -= 1;
    }

    /* If Statement::Enhancement: If the number was guessed correctly,
       and the number of guesses is equal to 1, this statement will be
       executed */
    if (guess == randomNumber && numGuesses == 1)
    {
           /* Display: A congratulatory message and crown the user as new
               king or queen */
        cout << "\nShouldst I believe it?! Hardly can I!\n"
            << "The number " << randomNumber << " was right,"
            << " after only " << numGuesses << " try!\n"
            << "Thou art the master, and i can't deny,\n"
            << "the crown and the kingdom is yours now, my\n"
            << "humblest goodbye!\n";
    }

    /* For loop: As long as the guess is not equal to the random number,
       this loop will execute */
    for (guessingCounter; (!(guess == randomNumber)); guessingCounter++)
    {
        /* Nested While loop: While the number is too low, this statement is
        executed */
        while (guess < randomNumber)
        {
            cout << "\nWhat meets my cat's eyes? Your guess was too low,\n"
                << "yet very nice! Aim high, and give it another try!\n";

            /* Ask for the next guess */
            cout << "Guess my number: ";
            cin >> guess;

            /* Nested While loop::Input Validation: While the guess the user
            entered is lower than SMALLEST_NUMBER (1), or higher than
            LARGEST_NUMBER, this loop will iterate */
            while (guess < SMALLEST_NUMBER || guess > LARGEST_NUMBER)
            {
                /* Display: Error message */
                cout << "\nIt seems thou art not listening to me! The number\n"
                    << "to guess is greater than 0, and up to "
                    << LARGEST_NUMBER << ", you see?\n";

                /* Ask for the next guess */
                cout << "Guess my number: ";
                cin >> guess;

                /* Enhancement::Counter: The number of guesses is decremented
                by -1 so that, whenever the number entered is out of bounds,
                and this loop is executed, the guess will not be counted */
                numGuesses -= 1;
            }

            /* Enhancement::Counter: The number of guesses is incremented
               by +1, every time this nested while loop executes */
            numGuesses += 1;
        }

        /* Nested While loop: While the guess is too high, this statement
        is executed*/
        while (guess > randomNumber)
        {
            /* Display: Message that the guess was too high */
            cout << "\nWith your guess you were aiming too high,\n"
                << "how about another try?\n";

            /* Ask for the next guess */
            cout << "Guess my number: ";
            cin >> guess;

            /* Nested While loop::Input Validation: While the guess the
            user entered is lower than SMALLEST_NUMBER (1), or higher
            than LARGEST_NUMBER, this loop will iterate */
            while (guess < SMALLEST_NUMBER || guess > LARGEST_NUMBER)
            {
                /* Display: Error message */
                cout << "\nIt seems thou art not listening to me! The number\n"
                    << "to guess is greater than 0, and up to "
                    << LARGEST_NUMBER << ", you see?\n";

                /* Ask for the next guess */
                cout << "Guess my number: ";
                cin >> guess;

                /* Enhancement::Counter: The number of guesses is decremented
                by -1 so that, whenever the number entered is out of bounds,
                and this loop is executed, the guess will not be counted */
                numGuesses -= 1;
            }

            /* Enhancement::Counter: The number of guesses is incremented
            by +1, every time this nested while loop executes */
            numGuesses += 1;
        }

        /* If Statement: If the number was guessed correctly, this
        statement will execute

        If Statement::Enhancement: If the number was guessed correctly,
        and the number of guesses is greater than or equal to 1, or
        number of guesses is lower than or equal to 5, this statement
        will be executed */
        if (guess == randomNumber && numGuesses <= 5)
        {
            /* Display: A congratulatory message */
            cout << "\nFire and Brimstone!\n"
                << "The number " << randomNumber << " was right!\n"
                << "Yet in only " << numGuesses << " guesses,"
                << " there's something fishy,\n"
                << "i can feel it inside!\n"
                << "Thou must be a witch or a witcher, cursed be thy"
                << " third eye ...\n"
                << "For now you are free, though, if e'er thou'll comethst back,\n"
                << "the challenge'll be harder, believe thou me that  ... !\n";
        }

        /* Else If Statement::Enhancement: If number was guessed correctly, and
        the number of guesses is higher than or equal to 10, this statement
        will be executed */
        else if (guess == randomNumber && numGuesses >= 10)
        {
            /* Display: A message to "try harder" */
            cout << "\nTo guess my number " << randomNumber
                 << " took thee " << numGuesses << " tries!\n"
                 << "Now the doors are wide open, so get out of my eyes!\n"
                 << "Though before thou leavest, and knoweth what's best for thee,\n"
                 << "harken these words of advice, for they are free!\n"
                 << "If thou dost not try harder, shouldst thou ever return,\n"
                 << "thy cell will be waiting, 'til on the pyre thou'll burn.\n";
        }
    }

    pauseSystem();
    return 0;
}

Monday, December 26, 2016

Programming Challenge 5.20 - Random Number Guessing Game

/* Random Number Guessing Game - This program generates a random number
   and asks the user to guess what the number is. If the user's guess is
   higher than the random number, the program displays "Too high, try
   again." If the users guess is lower than the random number, the program
   displays "Too low, try again." The program uses a loop that repeats
   until the user correctly guessed the random number. */

#include "Utility.h"

int main()
{
    /* Constants: Smallest number to guess, Largest number to guess */
    const int SMALLEST_NUMBER = 1,
              LARGEST_NUMBER = 100;

    /* Variables: Random number, Guess, Guessing counter
       (counter variable) */
    int randomNumber = 0,
        guess = 0,
        guessingCounter = 0;

    /* Get the system time and seed the random number generator */
    srand((unsigned int)time(NULL));

    /* Generate random number */
    randomNumber = (rand() % (LARGEST_NUMBER - SMALLEST_NUMBER + 1)) +
                    SMALLEST_NUMBER;

    /* Display: Welcome message */
    cout << "\t\tRANDOM NUMBER GUESSING GAME\n\n"
         << "Welcome, Brave Hero, I challenge thee!\n"
         << "Guess the right number between 1 to "
         << LARGEST_NUMBER << ",\n"
         << "and you might be set free!\n";

    /* Ask for a first guess */
    cout << "\nGuess my number: ";
    cin >> guess;

    /* While loop::Input Validation: While the guess the user entered is
       lower than SMALLEST_NUMBER (1), or higher than LARGEST_NUMBER,
       this loop will iterate */
    while (guess < SMALLEST_NUMBER || guess > LARGEST_NUMBER)
    {
        /* Display: Error message */
        cout << "\nIt seems thou art not listening to me! The number\n"
             << "to guess is greater than 0, and up to "
             << LARGEST_NUMBER << ", you see?\n";

        /* Ask again: */
        cout << "\nGuess my number: ";
        cin >> guess;
    }

    /* For loop: As long as the guess is not equal to the random number, this
       loop will execute */
    for (guessingCounter; (!(guess == randomNumber)); guessingCounter++)
    {  
        /* Nested While loop: While the number is too low, this statement is
           executed */
        while (guess < randomNumber)
        {
            cout << "\nWhat meets my cat's eyes? Your guess was too low,\n"
                 << "yet very nice! Aim high, and give it another try!\n";

            /* Ask for the next guess */
            cout << "Guess my number: ";
            cin >> guess;

            /* Nested While loop::Input Validation: While the guess the user
               entered is lower than SMALLEST_NUMBER (1), or higher than
               LARGEST_NUMBER, this loop will iterate */
            while (guess < SMALLEST_NUMBER || guess > LARGEST_NUMBER)
            {
                /* Display: Error message */
                cout << "\nIt seems thou art not listening to me! The number\n"
                     << "to guess is greater than 0, and up to "
                     << LARGEST_NUMBER << ", you see?\n";

                /* Ask again: */
                cout << "\nGuess my number: ";
                cin >> guess;
            }
        }

        /* Nested While loop: While the guess is too high, this statement
           is executed*/
        while (guess > randomNumber)
        {
            /* Display: Message that the guess was too high */
            cout << "\nWith your guess you were aiming too high,\n"
                 << "how about another try?\n";

            /* Ask for the next guess */
            cout << "Guess my number: ";
            cin >> guess;

            /* Nested While loop::Input Validation: While the guess the
               user entered is lower than SMALLEST_NUMBER (1), or higher
               than LARGEST_NUMBER, this loop will iterate */
            while (guess < SMALLEST_NUMBER || guess > LARGEST_NUMBER)
            {
                /* Display: Error message */
                cout << "\nIt seems thou art not listening to me! The number\n"
                    << "to guess is greater than 0, and up to "
                    << LARGEST_NUMBER << ", you see?\n";

                /* Ask again: */
                cout << "\nGuess my number: ";
                cin >> guess;
            }
        }

        /* If statement: If the number was guessed correctly, this
           statement will execute */
        if (guess == randomNumber)
        {
            /* Display: A congratulatory message */
            cout << "\nFire and Brimstone!\n"
                 << "The number, " << randomNumber
                 << " was right, yet I wonder why?!\n"
                 << "Thou must be a witch or a witcher with a third eye!\n"
                 << "For now, don't thank me, i'll tell you goodbye,\n"
                 << "but dare and come back, you'll end as fish fry ...!\n";
        }
    }

    pauseSystem();
    return 0;
}

Programming Challenge 5.19 - Budget Analysis

/* Budget Analysis - This program asks the user to enter the amount that
   he or she has budgeted for a month. A loop then prompts the user to
   enter each of his or her expenses for the month and keep a running
   total. When the loop finishes, the program displays the amount that
   the user is over or under budget. */

#include "Utility.h"

int main()
{
    /* Variables: Monthly budget, Expenses, Total expenses (accumulator),
       Over budget */
    double monthlyBudget = 0.0,
           expenses = 0.0,
           totalExpenses = 0.0,
           overBudget = 0.0;

    /* Variable: Running expenses (counter variable) */
    int runningExpenses = 1;

    /* Display: Information */
    cout << "\t\tPersonal Budget Butler\n\n"
        << "This program helps you in the task of keeping track of\n"
        << "your monthly budget and expenses. Please enter your\n"
        << "alloted budget for the month, and proceed to enter all\n"
        << "of your expenses. Once you finished entering data,\n"
        << "enter '-1'. The program will then tell you, whether or\n"
        << "not you are still within your monthly budget limit.\n";

    /* Ask the user for his or her budgeted amount of money for the
       current month */
    cout << "\nPlease enter your budget limit for this month\n";
    cout << "Monthly budget: $";
    cin >> monthlyBudget;

    /* While loop::Input validation: While the user enters a negative
       number for his or her monthly budget, this loop will iterate */
    while (monthlyBudget < 1)
    {
        /* Display: Error message */
        cout << "\nYour monthly budget can not be 0 or negative. Please\n"
             << "enter an amount greater than at least $1 and above.\n";

        /* Ask again */
        cout << "\nPlease enter the amount of money you budgeted for this"
             << " month.\n";
        cout << "Monthly budget: $";
        cin >> monthlyBudget;
    }

    /* Ask the user for his or her current expenses */
    cout << "\nEnter your monhtly expenses, then enter -1 to finish.\n";
    cout << "Expenses: $";
    cin >> expenses;

    /* While loop::Input Validation: If the user enters a value equal to
       0 or lower than -1, this loop will iterate */
    while (expenses < -1 || expenses == 0)
    {
        /* Display: Error message */
        cout << "\nYou seem to have entered a value of 0, or lower\n"
             << "than -1. Please remember, that the only\n"
             << "value below 0 that is allowed is '-1' to quit.\n";
           
        /* Ask again */
        cout << "Expenses: $";
        cin >> expenses;
     }

    /* For loop: As long as the user enters his or her budget, and doesn't
       enter -1 to quit entering data, this loop will iterate */
    while (expenses != -1)
    {
        /* Accumulating: Total monthly expenses */
        totalExpenses += expenses;
        runningExpenses++;

        /* Keep asking the user for his or her current expenses, until
           he or she enters -1 to exit the loop */
        cout << "Expenses: $";
        cin >> expenses;

        /* Nested While loop::Input Validation: If the user enters a value
           equal to 0 or lower than -1, this loop will iterate */
        while (expenses < -1 || expenses == 0)
        {
            /* Display: Error message */
            cout << "\nYou seem to have entered a value of 0, or lower\n"
                 << "than -1. Please remember, that the only\n"
                 << "value below 0 that is allowed is '-1' to quit.\n";

            /* Ask again */
            cout << "Expenses: $";
            cin >> expenses;
        }
    }

    /* Calculating: The amount exceeding the monthly budget limit */
    overBudget = totalExpenses - monthlyBudget;

    /* Formating the ouput */
    cout << fixed << showpoint << setprecision(2);

    /* Display: Table header */
    cout << "\nPersonal Budget Butler Final Report\n";
    cout << "-------------------------------------------------\n";

    /* If Statement: If the budget limit reached after all
    expenses have been entered? If so, the monhtly budget limit,
    the total expenses, and an information is displayed, warning
    the user that he has reached his budget limit */
    if (totalExpenses == monthlyBudget)
    {
        cout << "\nThis month you have budgeted:\t$ "
            << monthlyBudget << setw(6) << right
            << "\n-------------------------------------------------\n"
            << "\nYou spent:\t\t\t$ " << setw(6) << right << totalExpenses
            << "\n-------------------------------------------------\n"
            << "Warning! You hit your monthly budget limit!\n";
    }
    else
    {
        /* Conditional Statement: Are the total expenses greater than the
           monthly budget limit? If so, the monthly budget limit and total
           expenses are displayed, along with a message informing the user
           about the amount exceeding the budget limit. Else the monthly
           budget limit is displayed, and the user is told that he or she
           is still within budget for the current month. */
        totalExpenses > monthlyBudget ?
            cout << "\nThis month you have budgeted:\t\t$ "
            << setw(7) << right << monthlyBudget
            << "\nYou spent:\t\t\t\t$ "
            << setw(7) << right << totalExpenses
            << "\n-------------------------------------------------\n"
            << "This month you exceeded your budget by:\t$ "
            << setw(7) << right << overBudget << endl :
        cout << "\nThis month you have budgeted:\t\t$ "
            << setw(6) << right << monthlyBudget
            << "\nYou spent:\t\t\t\t$ "
            << setw(7) << right << totalExpenses
            << "\n-------------------------------------------------\n"
            << "Great! You are still within your budget limit.\n";
    }

    pauseSystem();
    return 0;
}

Programming Challenge 5.18 - Population Bar Chart

Example File: People.txt

 /* Population Bar Chart - This program produces a bar chart showing the
   population growth of Prairieville, a small town in the Midwest, at
   20-year intervals during the past 100 years.
  
   The program reads in the population figures (rounded to the nearest
   1,000 people) for 1900, 1920, 1940, 1960, 1980 and 2000 from a file.
  
   For each year it displays the date and a bar consisting of one asterisk
   for each 1,000 people. The data can be found, and is retrieved from,
   People.txt.
  
   Example output:

   PRAIRIEVILLE POPULATION GROWTH
   (each * represents 1,000 people)
   1900  **
   1290  ****
   1940  ***** */

#include "Utility.h"

int main()
{
    /* Declare: File stream variable */
    ifstream populationData;

    /* Variables: Date, Population growth, Rounding to nearest thousand,
       Population chart */
    int date = 0,
        populationGrowth = 0,
        roundingToNearest = 0,
        popChart = 0;

    /* Open: File "People.txt" */
    populationData.open("People.txt");

    /* If Statement::Error handling: If the file "People.txt" was opened
       successfully, this statement will be executed */
    if (populationData)
    {
        /* Display: Bar chart header */
        cout << "PRAIRIEVILLE POPULATION GROWTH\n"
            << "(each * represents 1,000 people)\n";

        /* While Loop: While date is lower than or euqal to 2000, this
           loop will itereate */
        while (date <= 2000)
        {
            /* Read-In::First set of Data: Date, Population growth data */
            populationData >> date >> populationGrowth;

            /* Calculations: To get to the nearest 1000, the remainder
               of each set of population growth data is determined, and
               the remainder then is subtracted from population growth */
                roundingToNearest = (populationGrowth % 1000);
                populationGrowth -= roundingToNearest;

                /* If Statement: If the remainder is greater than or
                   equal to 945, this statement will be executed, and
                   population growth is rounded by adding +1000 to
                   itself */
                if (roundingToNearest % 1000 >= 945)
                {
                    populationGrowth += 1000;
                }

                /* Calculation: For displaying the population growth data
                   equivalent in asterisk, population growth is divided
                   by 1000 */
                populationGrowth /= 1000;

                /* Display: Date */
                cout << "" << date << "  ";

            /* For loop: As long as popChart is smaller than, or equal to,
               populationGrowth, this loop will iterate */
            for (int popChart = 1; popChart <= populationGrowth; popChart++)
            {
                cout << '*';
            }
            cout << endl;

            /* Read-In::Next set of Data: Date (date +20), population
            growth data */
            populationData >> date >> populationGrowth;
        }
    }
    else
    {
        /* Display: Error message, if file could not be opened */
        cout << "A file openening error has occured. Please make sure that\n"
            << "the specified file is not damaged, has been accidentally\n"
            << "deleted, and that the file is located in the program folder.\n"
            << "Please close the program and try again.\n";
    }

    /* Close: "People.txt" */
    populationData.close();

    pauseSystem();
    return 0;
}