Friday, March 30, 2018

Temporary Discontinuation

Dear readers, 

It has been another couple of days with complete silence since the last solution was published. This time it is not because of any particular problem related to any one Challenge, or that this person has given up learning and decided to do quietly move on.

It is due to unfortunate events in real-life, that there will be a discontinuation of this project for quite some time. Until then, there may or may not follow sporadic solutions, but it is impossible to promise this. The only thing that is certain and can be promised as of the time of writing this, that once things are back to normal, there will follow solutions in regular order, and this book will be finished as planned.

As sad as it is, but this will then be the last occassion for what this person normally enjoyed the most: To thank all visitors for the continuous interest, and my followers, whom I thank very much for subscribing. It is hoped that you will come by regularly to see whether there is any news and/or updates, and that this humble blog will remain or become a source of some little help to all those who seek it.

Regards,
Yuki

Thursday, March 22, 2018

Programming Challenge 17.3 - Capital Quiz

Example Files: CapitalQuiz.7z

Notice: The original Ascii-Art was taken from http://www.chris.com/ascii/joan/www.geocities.com/SoHo/7373/flag.html © by Joan G. Stark. http://www.ascii-art.com/

FileLoader.h


#ifndef FILE_LOADER_H_
#define FILE_LOADER_H_

#include <fstream>
#include <map>
#include <string>

class FileLoader
{
    private:
        std::string      fileName;
        std::ifstream flagFile;
        std::ifstream quizFile;

        std::map<std::string, std::string> quiz;
      
    public:
        FileLoader();

        bool loadHeader();
        bool loadQuiz();

        std::map<std::string, std::string> getQuiz()
        { return quiz; }
};

#endif

FileLoader.cpp


#include "FileLoader.h"

#include <iostream>
#include <string>

/* **********************************************************
            FileLoader::FileLoader() - Constructor
   ********************************************************** */

FileLoader::FileLoader()
{
    loadHeader();
    loadQuiz();
}

/* **********************************************************
            FileLoader::loadHeader()
    If the file is opened successfully, a header graphic is
    loaded and displayed. Otherwise the function exits with
    an error message.
   ********************************************************** */

bool FileLoader::loadHeader()
{
    bool status = true;

    flagFile.open("Flag.txt");

    if (flagFile.fail())
    {
        std::cout << "\nFile Open Error: Unable to load flag file.\n";
        std::cout << "Please exit this program and try again ..." << std::endl;
        status = false;
    }
    else
    {
        std::string output{};

        while (getline(flagFile, output))
        {
            std::cout << output << "\n";
        }
    }

    flagFile.close();
    return status;
}

/* **********************************************************
            FileLoader::loadQuiz()
    If loaded successfully, a key value pair is read in from
    the file and inserted into the map. Otherwise an error
    message is displayed and the function exits.
   ********************************************************** */

bool FileLoader::loadQuiz()
{
    bool status = true;
    quizFile.open("Capitals.txt");

    if (quizFile.fail())
    {
        std::cout << "\nFile Open Error: Unable to load " << fileName << " file.\n";
        std::cout << "Please exit this program and try again ..." << std::endl;
        status = false;
    }
    else
    {
        std::string firstVal{};
        std::string secondVal{};

        while (getline(quizFile, firstVal, ':') && getline(quizFile, secondVal))
        {
            std::map<std::string, std::string>::iterator it = quiz.begin();
            quiz.insert(it, std::pair<std::string, std::string>(firstVal, secondVal));
        }
    }

    quizFile.close();
    return status;
}

Capital.h


#ifndef CAPITAL_QUIZ_H_
#define CAPITAL_QUIZ_H_

#include "FileLoader.h"

#include <map>
#include <string>

class Capital
{
    private:       
        FileLoader  loader;
        static int    points;

        std::map<std::string, std::string> capitals;
        std::map<std::string, std::string>::iterator it;

    public:
        Capital()
        { capitals = loader.getQuiz(); }

        void presentQuestion();
        void getAnswer();
        void evaluateAnswer(std::string);
        void removeQuestion();

        int getMapSize() const
        { return capitals.size(); }

        int getPoints() const
        { return points; }

        bool operator < (const Capital &) const;
};

#endif

Capital.cpp


#include "Capital.h"

#include <algorithm>
#include <iostream>

int Capital::points = 0;

/* **********************************************************
            Capital::presentQuestion()
    This function selects a random question and outputs it to
    screen.
   ********************************************************** */

void Capital::presentQuestion()
{
    std::advance(it = capitals.begin(), rand() % capitals.size());
    std::cout << "\nWhat is the capital of " << it->first << "?\n";
}

/* **********************************************************
            Capital::getAnswer()
    The user is asked to enter his or her answer. The answer
    is evaluated by call to the appropriate function.
   ********************************************************** */

void Capital::getAnswer()
{
    std::string answer{};

    std::cout << "Your answer: ";
    getline(std::cin, answer);

    evaluateAnswer(answer);
}

/* **********************************************************
            Capital::evaluateAnswer() : std::string
    This function evaluates the answer passed to it by value.
    If it is correct, 5 points are assigned to the player's
    score, and the question is removed from the map. Otherwise
    a point is deducted, iff the score is greater 0, and the
    question remains in the queue.
   ********************************************************** */

void Capital::evaluateAnswer(std::string answer)
{
    if (it->second == answer)
    {
        std::cout << "\nCorrect (^-^)\n";
        points += 5;
        removeQuestion();
    }
    else
    {
        std::cout << "\nWrong (;-;)\n";
        std::cout << "The capital of " << it->first << " is " << it->second << "\n\n";

        points > 0 ? points -= 1 : points = 0;
    }
}

/* **********************************************************
            Capital::removeQuestion()
    Erases a key value pair from the map.
   ********************************************************** */

void Capital::removeQuestion()
{
    if (capitals.size() > 0)
    {
        capitals.erase(it);
    }
}

/* **********************************************************
            Overloaded < operator   
   ********************************************************** */

bool Capital::operator < (const Capital &right) const
{
    bool status = false;

    if (capitals < right.capitals)
    {
        status = true;
    }
    return status;
}

CapitalQuiz.cpp


#include "Capital.h"

#include <iostream>
#include <ctime>

int main()
{
    Capital capitalQuiz;

    char choice{};

    srand((unsigned int)time(NULL));

    do
    {
        capitalQuiz.presentQuestion();
        capitalQuiz.getAnswer();

        if (capitalQuiz.getMapSize() > 0)
        {
            std::cout << "Do you wish to continue? (y/N): ";
            std::cin >> choice;
            std::cin.ignore();

            while (toupper(choice) != 'Y' && toupper(choice) != 'N')
            {
                std::cin.sync();
                std::cout << "Do you wish to continue? (y/N): ";
                std::cin >> choice;
                std::cin.ignore();
            }

            if (toupper(choice) == 'N')
            {
                std::cout << "\nWell Done! You earned " << capitalQuiz.getPoints() << " points!\n";
                std::cout << "Thank you for playing this quiz!" << std::endl;           
            }
        }
        else
        {
            std::cout << "\nWell Done! You answered all questions and earned: "
                         << capitalQuiz.getPoints() << " points!\n";
            std::cout << "Thank you for playing this quiz!" << std::endl;
        }
    } while (toupper(choice) != 'N' && capitalQuiz.getMapSize() > 0);

    std::cin.ignore();
    return 0;
}

Example Output:




Tuesday, March 20, 2018

Programming Challenge 17.2 - Course Information

Example Files: CourseInformation.7z

CourseInformation.cpp


#include <iomanip>
#include <iostream>
#include <map>
#include <string>

void courseSearch(const std::map<std::string, std::string> &,
                        const std::map<std::string, std::string> &,
                        const std::map<std::string, std::string> &);

void print(const std::map<std::string, std::string>::const_iterator,
                      std::map<std::string, std::string>,
                      std::map<std::string, std::string>);

int main()
{
    std::map<std::string, std::string> rooms =
    { { "CS101", "3004" }, { "CS102", "4501" }, { "CS103", "6755" },
      { "NT110", "1244" }, { "CM241", "1411" } };

    std::map<std::string, std::string> instructors =
    { { "CS101", "Haynes" }, { "CS102", "Alvarado" }, { "CS103", "Rich" },
      { "NT110", "Burke" }, { "CM241", "Lee" } };

    std::map<std::string, std::string> timetables =
    { { "CS101", "08:00 a.m." }, { "CS102", "09:00 a.m." }, { "CS103", "10:00 a.m." },
      { "NT110", "11:00 a.m" }, { "CM241", "01:00 p.m." } };

    char again{};

    std::cout << "M.I.T. COMPUTER SCIENCE DEPARTMENT COURSE SEARCH\n";

    do
    {
        courseSearch(rooms, instructors, timetables);

        std::cout << "\nDo you wish to repeat your search? (Y/N): ";
        std::cin >> again;

        while (toupper(again) != 'Y' && toupper(again) != 'N')
        {
            std::cout << "\nPlease repeat your input: ";
            std::cin >> again;
        }
    } while (toupper(again) != 'N');

    std::cout << "\nM.I.T. - The Union Of Knowledge And Mechanical Arts.";

    std::cin.ignore();
    std::cin.ignore();
    return 0;
}

/* **********************************************************
            courseSearch() : const map &, const map &,
                                  const map &
    The user is asked to enter a course number. If it exists
    in the map, it will be output. Otherwise the user is
    informed, that the course does not exist.
   ********************************************************** */

void courseSearch(const std::map<std::string, std::string> &rooms,
                       const std::map<std::string, std::string> &instructors,
                       const std::map<std::string, std::string> &timetables)
{
    std::string courseID{};

    std::cout << "\nEnter a course ID: ";
    std::cin >> courseID;

    std::map<std::string, std::string>::const_iterator it = rooms.find(courseID);

    if (it != rooms.end())
    {
        print(it, instructors, timetables);
    }
    else
    {
        std::cout << courseID << " does not exist ..." << std::endl;
    }
}

/* **********************************************************
            print() : const map<>::iterator, map, map
    The user is asked to enter a course number. If it exists
    in the map, it will be output. Otherwise the user is
    informed, that the course does not exist.
   ********************************************************** */

void print(const std::map<std::string, std::string>::const_iterator it,
                      std::map<std::string, std::string> instructors,
                      std::map<std::string, std::string> timetables)
{
    std::cout << "\n" << std::setw(15) << std::left << "Course:"
                            << std::setw(12) << std::left << "Room:"
                            << std::setw(23) << std::left << "Instructor:"
                            << std::setw(5) << std::left << "Time:\n";
   
    std::cout << std::setw(14) << std::left
                 << std::setw(15) << std::left << it->first
                 << std::setw(12) << std::left << it->second
                 << std::setw(23) << std::left << instructors[it->first]
                 << std::setw(18) << std::left << timetables[it->first] << std::endl;
}

Example Output:



Sunday, March 18, 2018

Programming Challenge 17.1 - Unique Words

Example Files: UniqueWords.7z
                           short.txt
                           night.txt

UniqueWords.cpp


#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <fstream>
#include <set>
#include <string>

bool createList(const std::string, std::set<std::string> &);
void printList(const std::set<std::string> &);

int main()
{
    std::string                 filename{};
    std::set<std::string> uniqueWords{};

    std::cout << "UNIQUE WORDS\n\n";
    std::cout << "This program lets you create and display list of unique words\n";
    std::cout << "from a text stored in a file.\n\n";
    std::cout << "Enter the name of the file you wish to open:\n";

    getline(std::cin, filename);

    if (createList(filename, uniqueWords))
    {
        printList(uniqueWords);
        std::cout << "\nThank you for trying this program! Have a nice day!" << std::endl;
    }

    std::cin.ignore();
    return 0;
}

/* **********************************************************
            bool createList() : const string, std::set<string>
    This function reads in words from a file into a set.
   ********************************************************** */

bool createList(const std::string filename, std::set<std::string> &temp)
{
    std::string     word{};
    std::fstream inFile{};
    bool         status{};
   
    inFile.open(filename, std::ios::in);
   
    if (inFile)
    {
        while (inFile >> word)
        {
            transform(word.begin(), word.end(), word.begin(), ::tolower);
            word.erase(remove_if(word.begin(), word.end(), ::ispunct), word.end());

            temp.insert(word);
        }   
        status = true;
    }
    else
    {
        std::cout << "\nFile open error ...\n";
        std::cout << "Please close this program and try again." << std::endl;

        status = false;
    }
    inFile.close();
   
    return status;
}

/* **********************************************************
            printList() : const std::set<string>
    Outputs the list of unique words.
   ********************************************************** */

void printList(const std::set<std::string> &words)
{
    std::cout << "\nUNIQUE WORDS:\n";
    for (auto printWords : words)
    {
        std::cout << printWords << "\n";
    }
}

Example Output:




Monday, March 12, 2018

Another Update



It is no shame to admit that this person is currently unable to make significant progress in solving Programming Challenge 16.12. As there is no way of telling how much longer it will take a decision had to be made. Instead of investing all energy into this one project, while there are still five chapters left to work through and many more Challenges waiting to be solved, this person has decided to continue on to the next chapter for now. 

Numerous possibilites were taken into consideration to determine what happens with Programming Challenge 16.12 in the meantime. For now the work on it will continue on the side. If it isn't taking away time and energy from the learning process, it will be kept up, until the problem is solved. Otherwise it will have to wait until the end of the book has been reached. This is for the reason that, since the newest revision of this book has some additional Programming Challenges in earlier chapters, solutions for these Challenges may also find their way to this blog. It is some additional exercise, so it would fit in well to come back to this as yet unsolved Challenge by that time.

For now, it is time to keep on learning, to make some progress, and to hopefully be able to finish this one Challenge soon. As always it is a pleasure to thank all visitors for the continued interest in this person's humble blog, a special pleasure to thank my followers for subscribing! To my fellow students, who may not have the luxury to move on, for whom there are grades at stake if they do not manage to solve a problem in time, don't despair and keep giving your best. When you are ready, get back to it and work on a solution in your own time, then solve it. Persistence is key!

Wednesday, March 7, 2018

Update

Dear readers, you may have noticed that there is a gap in numbers in between Programming Challenges 16.11 and 16.13. The reason is not that this person has skipped Challenge 16.12, quite the contrary. It is a very difficult challenge, thus it will take some more time to arrive at a solution, so instead this person decided to solve what felt to be a very easy last challenge of this chapter, then return to work on the more difficult one. This person will work hard to get it done soon, so as to be able to continue on to Chapter 17.

With this little update information out of the way, it is time for this person to take a small break to gather new mental energy, to finally also get done with Challenge 16.12. In the meantime I wish my readers, visitors old and new, and my fellow students all the best in their attempt to solve any problem however difficult it may seem! Give your best!

Programming Challenge 16.13 - Exceptions Project

Example Files: ExceptionsProject.7z

Employee.h


#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_

#include <iostream>
#include <string>

class Employee
{
    private:
        int            employeeID;
        std::string employeeName;
        std::string employeeHireDate;

    public:
        class InvalidEmployeeID
        {
            private:   
                int invalidEmployeeID;

            public:
                InvalidEmployeeID(int invalidEmpID) : invalidEmployeeID(invalidEmpID)
                { }

                int getInvalidEmployeeID() const
                { return invalidEmployeeID; }
        };

        Employee(int, std::string, std::string);
        virtual ~Employee()
        { }

        // Mutator function
        void setEmployee(int, std::string, std::string);

        // Accessor function
        void invalidIDHandler() const;

        // Consider directly employing the overloaded operator and call it from the
        // Production worker class
        friend std::ostream &operator << (std::ostream &, const Employee &);
       
        virtual void print(std::ostream &) const;
};

#endif

Employee.cpp


#include "Employee.h"

#include <iomanip>

/* **********************************************************
            Employee::Employee() : int, string, string
            - Constructor
   ********************************************************** */

Employee::Employee(int empID, std::string empName, std::string empHired) :
    employeeID(empID), employeeName(empName), employeeHireDate(empHired)
{
    invalidIDHandler();
}

/* **********************************************************
            Employee::setEmployee() : int, string, string
    Sets the employee data.
   ********************************************************** */

void Employee::setEmployee(int empID, std::string empName, std::string empHired)
{
    employeeID = empID;
    employeeName = empName;
    employeeHireDate = empHired;

    invalidIDHandler();
}

/* **********************************************************
            Employee::invalidIDHandler()
    Evaluates the employeeID and throws an exception if found
    invalid.
   ********************************************************** */

void Employee::invalidIDHandler() const
{
    if (employeeID < 0 || employeeID > 9999)
    {
        throw InvalidEmployeeID(employeeID);
    }
}

/* **********************************************************
            Overloaded << function
   ********************************************************** */

std::ostream &operator << (std::ostream &strm, const Employee &obj)
{
    obj.print(strm);
    return strm;
}

/* **********************************************************
            Employee::print() : ostream &
    Outputs the employee data to screen.
   ********************************************************** */

void Employee::print(std::ostream &strm) const
{
    strm << std::left  << std::setw(12) << "Employee Name: "
          << std::right << employeeName << std::endl;
    strm << std::left << std::setw(15) << "Employee ID: "
          << std::right << employeeID << std::endl;
    strm << std::left  << std::setw(15) << "Hire Date: "
          << std::right << employeeHireDate << std::endl << std::endl;
}

ProductionWorker.h


#ifndef PRODUCTION_WORKER_H_
#define PRODUCTION_WORKER_H_

#include "Employee.h"

#include <iostream>
#include <string>

class ProductionWorker : public Employee
{
    private:
        int     shiftNumber;
        double hourlyPayrate;

    public:
        class InvalidPayrate
        {
            private:
                double invalidPayrate;

            public:
                InvalidPayrate(double invalidRate) : invalidPayrate(invalidRate)
                { }

                double getInvalidPayrate() const
                { return invalidPayrate; };
        };

        class InvalidShiftData
        {
            private:
                int invalidShiftID;

            public:
                InvalidShiftData(int invalidShift) : invalidShiftID(invalidShift)
                { }

                int getInvalidShiftID() const
                { return invalidShiftID; }
        };

        ProductionWorker(int, std::string, std::string, int, double);

        void setProductionWorker(int, double);

        void invalidShiftHandler() const;
        void invalidPayrateHandler() const;

        void print(std::ostream &) const override;
};

#endif

ProductionWorker.cpp


#include "ProductionWorker.h"

#include <iomanip>

/* **********************************************************
            ProductionWorker::ProductionWorker() : int, string,
            string, int, double - Constructor
   ********************************************************** */

ProductionWorker::ProductionWorker(int empID, std::string empName, std::string empHired,
                                              int shiftID, double payRate) :
                                              shiftNumber(shiftID),hourlyPayrate(payRate),
                                              Employee(empID, empName, empHired)
{
    invalidShiftHandler();
    invalidPayrateHandler();
}

/* **********************************************************
            ProductionWorker::setProductionWorker() int, double
    Sets the production worker data.
   ********************************************************** */

void ProductionWorker::setProductionWorker(int shiftID, double payRate)
{
    shiftNumber = shiftID;
    hourlyPayrate = payRate;

    invalidShiftHandler();
    invalidPayrateHandler();
}

/* **********************************************************
            ProductionWorker::shiftErrorHandler()
    Evaluates the shiftNumber and throws an exception if found
    invalid.
   ********************************************************** */

void ProductionWorker::invalidShiftHandler() const
{
    if (shiftNumber < 0 || shiftNumber > 2)
    {
        throw InvalidShiftData(shiftNumber);
    }
}

/* **********************************************************
            ProductionWorker::payRateErrorHandler()
    Evaluates the hourlyPayRate and throws an exception if
    found invalid.
   ********************************************************** */

void ProductionWorker::invalidPayrateHandler() const
{
    if (hourlyPayrate < 0.0)
    {
        throw InvalidPayrate(hourlyPayrate);
    }
}

/* **********************************************************
            ProductionWorker::print() : ostream &
    Outputs the production worker data to screen.
   ********************************************************** */

void ProductionWorker::print(std::ostream &strm) const
{
    Employee::print(strm);

    strm << "Shift #" << shiftNumber << ": ";

    shiftNumber == 1 ?
        strm << std::setw(16) << std::right << "Day-Shift"   << std::endl :
        strm << std::setw(16) << std::right << "Night-Shift" << std::endl;

    strm << std::fixed << std::setprecision(2) << std::fixed;
    strm << std::left  << std::setw(14) << "Pay Rate: "
          << std::right << "$ " << hourlyPayrate << std::endl;
}

ExceptionProject.cpp


#include "ProductionWorker.h"

#include <iostream>

void badValueCheck(int, std::string, std::string, int, double);

int main()
{
    std::cout << "TAKEUCHI MANUFACTURING CO. - EMPLOYEE DATA VALIDATION\n\n";
    std::cout << "The following tests will now be carried out:\n\n";

    std::cout << "Test 1: Employee Number\n";
    badValueCheck(99921, "Flanders Moll", "17/04/2013", 2, 86.80);
    std::cout << std::endl;

    std::cout << "Test 2: Shift ID\n";
    badValueCheck(1241, " Kakuta", "12/03/2015", -7, 85.99);
    std::cout << std::endl;

    std::cout << "Test 3: Hourly Payrate\n";
    badValueCheck(9411, "Vishneva Diana", "12/03/2015", 1, -190.55);
    std::cout << std::endl;

    std::cout << "Test 4: Correct Data\n";
    badValueCheck(4350, "Hiroshi Sato", "15/05/2005", 2, 99.75);
    std::cout << std::endl;

    std::cout << "You are now leaving the Database System ...\n\n";
    std::cout << "TAKEUCHI MANUFACTURING CO.\n"
             << "Unrivaled quality, products with a difference,\n"
             << "and fast development responding to the users' needs.";

    std::cin.get();
    return 0;
}

/* **********************************************************
            badValueCheck() : int, string, string, int, double
    This function tests various data items for validity. If an
    item is invalid, it is caught, and an error message is
    output. Otherwise the production worker data is output.
   ********************************************************** */

void badValueCheck(int empID, std::string empName, std::string empHired,
                         int shiftID, double payRate)
{
    try
    {
        ProductionWorker temp(empID, empName, empHired, shiftID, payRate);

        std::cout << temp;
    }
    catch (ProductionWorker::InvalidEmployeeID badEmployeeID)
    {
        std::cout << "Error! Invalid Employee ID: "
                     << badEmployeeID.getInvalidEmployeeID() << std::endl;
    }
    catch (ProductionWorker::InvalidShiftData badShiftID)
    {
        std::cout << "Error! Invalid Shift ID: "
                     << badShiftID.getInvalidShiftID() << std::endl;
    }
    catch (ProductionWorker::InvalidPayrate badPayrate)
    {
        std::cout << "Error! Invalid Hourly Payrate: $ "
                     << badPayrate.getInvalidPayrate() << std::endl;
    }
}

Example Output: