The goal of the assignment is to assess your ability to write clear readable code demonstrating object oriented
programming concepts.
Assignment
Create a command-line program in an object-oriented language of your choice (C++, Java, Python) that
interacts with the user using stdin and stdout. You may use any standard libraries in your solution.
The user of the program is a hairdresser who needs to keep track of his or her haircut appointments.
The program will support the scheduling of two types of appointments:
Haircut: 30 minutes
Shampoo & Haircut: 1 hour
Upon running of the program, the program should prompt for user input. It should accept 3 command
types:
1. List: listing of all future appointments
2. Schedule: schedules either type of appointment (note that this command may take additional
parameters so that the hairdresser can distinguish one appointment from another).
3. Exit: the hairdresser is done with the program; upon exit, all existing state will be destroyed (i.e.
the program does not persist the appointments in between program runs)
For simplicity sake, the program may assume that appointments are always scheduled at 15-minute
offsets from the hour (e.g. 12:15pm, 4:00pm, 5:45pm, 6:30pm).
Steps
Start by creating an object-oriented design for the scheduler interface (i.e. public methods) and
the model classes for the schedule and the appointments.
Implement the method that lists existing appointments.
Implement the method that schedules a single appointment.
Wire the program together so that it can be run from the command line.
Submission
Write a short README that lists the source files and a short description of each source file (e.g. Javadocs
may be used in place of the description). In the README, also specify how to run the program and a log
of one or more test runs of the program. If applicable, include any design considerations that came up
during the design of the program. Respond to this email with a zip file of the README and the source
files for your solution. Please do not post your solution to GitHub or another public repository.
// Scheduler.h
#pragmaonce#include<iostream>#include<string>#include<unordered_map>#ifdefDBUILD#include<limits>inlinevoidpause() { cin.ignore(numeric_limits<streamsize>::max(),'\n'); }template<typenameT>inlinevoidprint2d(vector<vector<T>> &stuffs) { cout << endl;int count =0;for (auto i : stuffs) { cout << count++<<":";for (auto j : i) cout <<setw(2) << j <<" "; cout << endl; } cout << endl;}template<typenameT>inlinevoidprint(vector<T> &stuffs) { cout << endl;for (auto i : stuffs) cout << i <<" "; cout << endl; pause(); cout << endl;}#endifusingnamespace std;structTime {Time(short h,short m,bool morn) { hr = h; min = m; morning = morn; }Time(short h,short m) { hr = h; min = m; }Time() { hr = min =0; }Time(constTime&rhs) { hr =rhs.hr; min =rhs.min; morning =rhs.morning; }friendTimeoperator+(constTime&one,constTime&two);voidoperator +=(constTime& rhs);booloperator==(constTime&other) const;voidoperator=(constTime&rhs);short hr, min;bool morning;};Timeoperator+(constTime&one,constTime&two) { // add both minutesshort min_total =one.min +two.min;short hr_carry = min_total /60;short min_remaining = min_total - (hr_carry *60);short total_hours = hr_carry +one.hr +two.hr;short number_flips = total_hours /12;bool morn =one.morning; // odd indicates opposite daylight hrsif (number_flips %2!=0&& total_hours >=12) morn =!one.morning;returnTime((total_hours >12) ? total_hours %12: total_hours, min_remaining, morn);}void Time::operator+=(constTime& rhs){ // add both minutesshort min_total =rhs.min + min;short hr_carry = min_total /60;short min_remaining = min_total - (hr_carry *60);short total_hours = hr_carry +rhs.hr + hr;short number_flips = total_hours /12; hr = total_hours %12; min = min_remaining; // odd indicates opposite daylight hrsif (number_flips %2!=0&& total_hours >12) morning =!morning;}inlinebool Time::operator==(constTime& other) const{return (hr ==other.hr && min ==other.min&& morning ==other.morning);}inlinevoid Time::operator=(constTime& rhs){ hr =rhs.hr; min =rhs.min; morning =rhs.morning;}/* hash function */namespace std {template <>structhash<Time> { std::size_toperator()(constTime& k) const {return ((hash<short>()(k.hr)^ (hash<short>()(k.min) <<1)) >>1)^ (hash<bool>()(k.morning) <<1); } };}structActivity {Activity(string activity) {this->activity = activity; }bool active =false; string activity;};classScheduler{public:Scheduler() { Time start(12,0,1); // 12:00am Time incrementor; // 00:00 Time static_incrementor(0,15); // 00:15 // creates an empty schedule // there are 96, 15 min intervals from 12:00am to 11:45pmfor (int i =0; i <48; i++) { Time newTime(start + incrementor);newTime.morning =true; //cout << newTime.hr << ":" << newTime.min << newTime.morning << endl;schedule.insert(make_pair(Time(newTime.hr,newTime.min,newTime.morning),Activity(""))); incrementor += static_incrementor; } Time start2(12,0,0); // 12:00pm Time incrementor2; // 00:00for (int i =0; i <48; i++) { Time newTime(start2 + incrementor2);newTime.morning =false; //cout << newTime.hr << ":" << newTime.min << newTime.morning << endl;schedule.insert(make_pair(Time(newTime.hr,newTime.min,newTime.morning),Activity("")));schedule.insert(make_pair(newTime,Activity(""))); incrementor2 += static_incrementor; } };vector<string> appointmentTimes() {return activeAppoint; }boolappointHaircut(Time&time,conststring activity) { // check conflictionif (schedule.find(time)->second.active) returntrue; // 30 min - add to schedule Time incrementor(0,0);const Time incrementor_static(0,15);for (int i =0; i <2; i++) { Time hashTime(time + incrementor);schedule.find(hashTime)->second.active =true;schedule.find(hashTime)->second.activity = activity; incrementor += incrementor_static; } // add to active scheduleaddAppointment(time, activity);returnfalse; }boolappointShampooAndHairCut(Time&time,conststring activity) { // check conflictionif (schedule.find(time)->second.active) returntrue; // 1 hr Time incrementor(0,0);const Time incrementor_static(0,15);for (int i =0; i <4; i++) { Time hashTime(time + incrementor);schedule.find(hashTime)->second.active =1;schedule.find(hashTime)->second.activity = activity; incrementor += incrementor_static; } // add to active scheduleaddAppointment(time, activity);returnfalse; }boolisEmpty() {returnschedule.empty(); }private: unordered_map<Time, Activity> schedule; vector<string> activeAppoint;voidaddAppointment(Time&time,conststring&activity) { string appointment; // formating to 2 digits: e.g. 9:[00]amif (time.min <=9) { appointment =" "+to_string(time.hr) +":"++"0"+to_string(time.min) + std::string((time.morning) ? ("am") : ("pm")) + std::string(" - ") + std::string((activity =="shampoo") ? ("shampoo & haircut") : (activity));; }else { appointment =" "+to_string(time.hr) +":"+to_string(time.min) + std::string((time.morning) ? ("am") : ("pm")) + std::string(" - ") + std::string((activity =="shampoo") ? ("shampoo & haircut") : (activity)); }activeAppoint.push_back(appointment); }};
// Source.cpp
#include<iostream>#include<string>#include<vector>#include<cctype>//tolower()#include<sstream>//stringstream#include"Scheduler.h"usingnamespace std;stringtoLower(string);boolisIntegral(string&);vector<string> split(conststring&,char);boolisValid(constvector<string> &);TimegetTime(conststring&);intmain(){ string input;bool invalid, exit =false; Scheduler schedule; //input = "schedule shampoo & haircut 7:30pm";while (!exit) { cout <<"\n> ";getline(cin, input); input =toLower(input); vector<string> commands =split(input,' ');if (!isValid(commands)) { cout <<" Input command is invalid. Please try again"<< endl;continue; }if (commands[0] =="exit") { exit =true;continue; }elseif (commands[0] =="list") {if (schedule.isEmpty()) { cout <<"No appointments at this time."<< endl; }else { vector<string> appointments =schedule.appointmentTimes();for (string & s : appointments) cout << s << endl;continue; } } // is a scheduling commandelse { // ensure time is properly formated Time appointment = (getTime(commands[commands.size() -1])); //cout << getTime(commands[commands.size() - 1]).morning << endl;bool conflict;if (appointment.hr ==0&&appointment.min ==0) { cout <<" Appointment time has invalid format. Please try again"<< endl;continue; }elseif (commands[1] =="haircut") { conflict =schedule.appointHaircut(appointment,"haircut");if (conflict) cout <<" There is an conflict with appointment time."<< endl; }elseif (commands[1] =="shampoo") { conflict =schedule.appointShampooAndHairCut(appointment,"shampoo");if (conflict) cout <<" There is an conflict with appointment time."<< endl; } } }}stringtoLower(string str){for (char& c : str) c =tolower(c);return str;}boolisIntegral(string&num) {for (char& c : num) {if (!isdigit(c)) returnfalse; }returntrue;}vector<string> split(conststring&s,char delim){ vector<string> elems; stringstream ss;ss.str(s); string item;while (getline(ss, item, delim)) {elems.push_back(item); }return elems;}boolisValid(constvector<string> &commands){ // no command or too manyif (commands.empty() ||commands.size() >5) returnfalse; // list or exitelseif (commands.size() ==1) {return ((commands[0]) =="list"|| (commands[0]) =="exit"); } // scheduleelse { // haircutif (commands.size() ==3)return ((commands[0]) =="schedule"&& (commands[1]) =="haircut");else { // haircut and shampooreturn ((commands[0]) =="schedule"&& (commands[1]) =="shampoo"&& (commands[2]) =="&"&& (commands[3]) =="haircut"); } }returnfalse;}TimegetTime(conststring&str){ // XX:XXam or X:XXpmif (str.length() <6||str.length() >7) returnTime();int colon_index =0;for (int i =0; i <str.size(); i++) {if (str[i] ==':') { colon_index = i;break; } } string daylight =str.substr(str.size() -2,str.size());if (!(daylight =="am"|| daylight =="pm")) returnTime();if (colon_index ==1) { string one =str.substr(0,1);if (isIntegral(one) &&isIntegral(str.substr(2,2))) {int hr =atoi(str.substr(0,1).c_str());int min =atoi(str.substr(2,2).c_str()); // valid minutes and hour and 15 min intervalbool test = (daylight =="am") ? (true) : (false);if ((hr >=1&& hr <=12 ) && (min >=0&& min <=59) && min %15==0)returnTime(hr, min, test); } }elseif (colon_index ==2) {if (isIntegral(str.substr(0,2)) &&isIntegral(str.substr(3,2))) {int hr =atoi(str.substr(0,2).c_str());int min =atoi(str.substr(3,2).c_str());if ((hr >=1&& hr <=12) && (min >=0&& min <=59) && min %15==0)returnTime(hr, min, (daylight =="am") ? (true) : (false)); } }returnTime(); // 00:00}