// ---------------------------------------------------------------------------------- // Learning Team D // Members: // Tyson DeWitt // Ryan Edwards // Andrew Soren // Pablo Urbanowicz // Richard Williams // CS 1410 8 am // Learning Team Assignment # 2 // Mr. Rague // Due: 03/03/09 // Version: 1.3 // ---------------------------------------------------------------------------------- // This program allows the user to input various data relating to a // possible student's schedule in a possible university. // ---------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------- // Change Control Section // ---------------------------------------------------------------------------------- // Team Member: Andrew Soren // Version: 1.0 // Date: 02/28/09 // Created class CCourse or Part One of the assignment. // // Team Member: Ryan Edwards // Version: 1.1 // Date: 02/28/09 // Created and added class CDocument or Part Two of the assignment to code. // // Team Member: Richard Williams // Version: 1.2 // Date: 03/01/09 // Created and added class CView or Part Three of the assignment to code. // // Team Member: Pablo Urbanowicz // Version: 1.3 // Date: 03/02/09 // Created and added main function or Part Four of the assignment to code. // Also modified CView class by adding a constructor to accept CDocument object // // Team Member: Pablo Urbanowicz // Version: 1.4 // Date: 03/03/09 // Added comments throughout the code, general tidying up. // // Team Member: Andrew Soren // version: 1.5 // Date: 03/03/09 // Modified the inCCourse method to call strCourse (thus receiving a string), test // the received string, and to go back through the loop (so the user can re-enter // the data) if the string exceeds 80 characters. // ---------------------------------------------------------------------------------- // // Required libraries #include #include #include #include #include #include using namespace std; // ----------------------------------------------------------------- // This class represents a course that can is taught at a university. // It holds information about each course, such as the year and time // being taught, etc. // // Version 1.1 // ----------------------------------------------------------------- class CCourse { private: int year, // Stores the calendar year room, // Room number beginTime, // Start time endTime, // End time meetingDays; // Days class meets on string term, // Term of course courseNumber, // Sourse number sectionNumber, // Section number building; // Building name string & toUPPER(string & str); // Convert strings to all upper case int checkAP(int & h, int & m, char & t); // Used to check validity of entered times void inBTime(); // Inputs beginning time void inETime(); // Inputs end time string dispMeetDay(); // Converts/displays meetingDays into string/human readable form. string dispTime(int mTime); // Converts beginTime and endTime to a string - used when displaying public: CCourse(int yr = 2009, int rm = 100, int bT = 1200, int eT = 1200, int mD = 0, string trm = "SPRING", string cNum = "def101", string sNum = "def", string b = "Office") :year(yr), room(rm), beginTime(bT), endTime(eT), term(trm), courseNumber(cNum), sectionNumber(sNum), building(b), meetingDays(mD) {} // Constructor - sets defaults for everything string inCCourse(); // Input method which calls all other input methods void inYear(); // Prompt asks for user to input a year void inYear(int yer); // Allows the programmer/developer to use a different method than the above void inRoom(); // Prompt asks for user to input a room number void inRoom(int rom); // Allows programmer/developer to use different method than the above void inTime(); // Prompt akss user to input start and end times void inTime(int bTime, int eTime); // Allows programmer to use alternate method than above void inMeetDays(); // Prompt asks user to input days for class void inMeetDays(int days); // Allows programmer to use alternate method than above (not recommended - at all) void inTerm(); // Prompt asks user for term void inTerm(string tr); // Allows use of alternate method than above void inCNum(); // Prompt asks user for course number void inCNum(string crsNum); // Alternate from above available void inSNum(); // Prompt asks user for section number void inSNum(string secNum); // Alternate from above void inBuilding(); // Prompt user for building name void inBuilding(string build); // Alternate method void dispCourse(); // Display the CCourse data to the console string strCourse(); // Convert CCourse data into an 80 character string }; // ----------------------------------------------------------------- // This class represents a list of courses that are taught at a // university. // // Version 1.2 // ----------------------------------------------------------------- class CDocument { public: CDocument(): list() {} //Default constructor vector list; //Vector to hold the list of courses(strings) void createList(); //Initializes the list to being clear void insertItem(string, int); //Allows user to insert a course in the list bool deleteItem(int); //Allows user to delete a course in the list int frontOfList(); //Returns location of first course in the list int backOfList(); //Returns location of last course in the list bool moveToNextItem(int); //Determines whether user switch to next item or not bool moveToPrevItem(int); //Determines whether the user can switch to previous item or not void showCurrentItem(int); //Displays the current item on the list }; // ----------------------------------------------------------------- // This class allows the list of courses to be displayed on the // screen // // Version 1.1 // ----------------------------------------------------------------- class CView { private: vector cvlist; //Holds the list of courses public: CView(CDocument list) : cvlist(list.list) {}; //Constructor, sets cvlist to the list in the CDocument class void ViewPage(); //Shows first page of list and gives user menu to switch between pages void NextPage(int); //Goes to the next page of the document }; // ----------------------------------------------------------------- // This function displays a menu when it is called from the // main function // // Version 1.0 // ----------------------------------------------------------------- void showMenu() { //Display menu cout << "\n(I) Insert a new course in the list" << endl; cout << "(E) Delete a course from the list" << endl; cout << "(F) Move to the beginning of the list" << endl; cout << "(B) Move to the end of the list" << endl; cout << "(N) Move to the next course in the list" << endl; cout << "(P) Move to the previous course in the list" << endl; cout << "(R) Display the current course in the list" << endl; cout << "(S) Save changes and return to the main menu" << endl << endl; } // ----------------------------------------------------------------- // This function uses the CCourse, CDocument, and CView classes to // manage and view the contents of a list of CCourse type items. // // Version 1.2 // ----------------------------------------------------------------- int main() { string data; //Holds information about the course inputted by user int countCourses = 0; //Keeps track of how many courses are on the list int userChoice; //Holds user's choice for root menu char command='x'; //Holds user's choice for build course menu CCourse course; //Creates an instance of CCourse to hold course's information CDocument theList; //Creates an instance of CDocument to hold courses in a list theList.createList(); //Clears the contents of the list just created int lineNum = -1; //Holds the current line being worked on bool response; //Holds boolean value of whether it was possible to move to the next or previous line in the list bool response2; //Holds boolean value of whether it was possible to move to delete a line in the list //Display an introduction cout << "This program allows a user to create a list of courses offered at a university," << endl; cout << "including information about each course,such as: the year and term being taught,course number, time, etc." << endl << endl; do { //Root menu, prompt user for choice cout << "1) Build course list" << endl; cout << "2) View course list" << endl; cout << "3) Quit application" << endl << endl; cout << "Please select an option: "; cin >> userChoice; switch(userChoice) { case 1: { //Shows "build course list" menu showMenu(); //While the command is not 's' or stop while(command != 's') { //Prompt user cout << "If at any time you would like to see the menu again, type the letter M below" << endl; cout << "Please select an option by typing the letter next to the choice: "; cin >> command; switch (command) { case 'I': case 'i': { //No more than 100 courses can be inputted if(countCourses <= 99) { cout << "\nYou will now be prompted to enter the course information.\n" << endl; //Get information of course from user, and return all data put in as a string data = course.inCCourse(); //Calls CCourse function to return string of all data put in a single line // data = course.strCourse(); //Insert the string just received into the list theList.insertItem(data,lineNum); cout << endl; //Add one to the number courses on the list countCourses +=1; //Add one to the current line number lineNum += 1; } //When user has tried to input more than 100 courses if(countCourses > 99) cout << "Sorry, but you have exceeded the maximum of 100 courses." << endl << endl; break; } case 'E': case 'e': { //Get boolean value to see if it was possible to remove the course from the list or not response2 = theList.deleteItem(lineNum); //If it was removed if(response2==true) { //Subtract one from the current line lineNum-=1; //Subtract one from the total courses on the list countCourses -=1; } break; } case 'F': case 'f': { //Current line value gets switched with first position on the list lineNum = theList.frontOfList(); //Display confirmation movement has occurred cout << "\nMovement to front of the list done" << endl << endl; break; } case 'B': case 'b': { //Current line value gets switched with last position on the list lineNum = theList.backOfList(); //Display confirmation that movement has occurred cout << "\nMovement to end of the list done" << endl << endl; break; } case 'N': case 'n': { //Get boolean value to see if it is possible to move to next course on the list response = theList.moveToNextItem(lineNum+1); if(response==true) { //Add one to current line to point to next item lineNum +=1; //Display confirmation cout << "\nMovement to next item on list done" << endl << endl; } break; } case 'P': case 'p': { //Get boolean value to see if it is possible to move to previous course on the list response = theList.moveToPrevItem(lineNum-1); if(response==true) { //Subtract from current line to point to previous item lineNum -=1; //Display confirmation cout << "\nMovement to previous item on list done" << endl << endl; } break; } case 'R': case 'r': { //Show the item which the current line number points to theList.showCurrentItem(lineNum); break; } case 'M': case 'm': { //Display menu on screen showMenu(); break; } case 'S': case 's': { //Print a space, command is stop cout << endl; break; } default: { //If not a valid choice cout << "Invalid choice. Please try again" << endl; break; } } } command='x'; break; } case 2: { cout << endl; //Create an instance of the CView class with the CDocument theList CView list2(theList); //Call funcction in CView to view pages list2.ViewPage(); cout << endl; break; } case 3: //Quit program break; default: //Invalid choice cout << "\nInvalid choice. You must select a value in the range of 1-3" << endl << endl; break; } } while(userChoice != 3); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// string & CCourse::toUPPER(string & str) // converts strings to all upper case { for(unsigned int i=0; i < str.length(); i++) { str[i] = toupper(str[i]); } return str; } string CCourse::inCCourse() // input method used to call all input methods at once { int error=0; string data; while(error==0) { inYear(); // Input year inTerm(); // Input Term inCNum(); // Input course Number inSNum(); // Input sectionNumber inBuilding(); // Input building name inRoom(); // Input room number inTime(); // Input beginning and end time inMeetDays(); // Input meeting days data = strCourse(); // if all the data above added together as a string is less than 80 characters if(data.length() < 80){ // unset the error flag, to exit the loop. // cout << "Data is good" << endl; error=1;} else // else, inform the user that the data exceeds 80 characters, and have them re-enter the data { cout << "The total characters you have entered exceeds the maximum allowed " << endl; cout << "of 80 characters. Please re-input the data." << endl; error=0; } } return data; } void CCourse::inYear() // Year input method (simple, I know. Could be better?) { cout << "Input the calendar year: "; cin >> year; } void CCourse::inYear(int yer) { year = yer; } void CCourse::inRoom() // Room input (see Year) { cout << "Input the room number: "; cin >> room; } void CCourse::inRoom(int rom) { room=rom; } void CCourse::inBTime() // Input beginningTime { int hour, min, check=0; // initilize error flag char time; while(check==0) { cout << "Input the beginning time (ex: '10:00a'): "; cin >> hour >> time >> min >> time; if(hour>12 || min>59) // Minor error checking for hours and minutes { cout<< "Invalid time. Please try again." << endl; hour=0; min=0; continue; } beginTime = checkAP(hour, min, time); // Checks the status of 'time' (AM or PM) if(beginTime < 2400) // CheckAP returns 2400 if there is an error check=1; // if there's an error, don't unset the error flag } } void CCourse::inETime() // Same as above, but replace "beginTime" with "endTime" { int hour, min, check=0; char time; while(check==0) { cout << "Input the end time (ex: '12:00p'): "; cin >> hour >> time >> min >> time; if(hour>12 || min>59){ cout<< "Invalid time. Please try again." << endl; hour=0; min=0; continue; } endTime = checkAP(hour, min, time); if(endTime < 2400) check=1; } } void CCourse::inTime(int bTime, int eTime) { beginTime = bTime; endTime = eTime; } void CCourse::inTime() // Calls input methods for beginTime and endTime { inBTime(); inETime(); } void CCourse::inTerm() // Input method for term - minor error checking { int error=0; while(error==0) // Loop until correct data provided { cout << "Input the term: "; cin >> term; term = toUPPER(term); if(!(term.compare("WINTER")) || !(term.compare("SPRING")) || !(term.compare("SUMMER")) || !(term.compare("FALL"))) error=1; // unset error flag if term matches WINTER, SPRING, SUMMER, or FALL else cout << "Please use valid terms (WINTER, SPRING, SUMMER, FALL)" << endl; } // cout << term << endl; } void CCourse::inTerm(string tr) { term=tr; } void CCourse::inCNum() // Input course number (simple, I know. Does it need improvement?) { cout<< "Input the course number: "; cin >> courseNumber; } void CCourse::inCNum(string crsNum) { courseNumber = crsNum; } void CCourse::inSNum() // Input section number (see inCNum) { cout << "Input the section number: "; cin >> sectionNumber; } void CCourse::inSNum(string secNum) { sectionNumber=secNum; } void CCourse::inBuilding() // Input building name. This should also clear the buffer. { cout << "Input the building name: "; cin.clear(); cin.ignore(25, '\n'); getline(cin, building); } void CCourse::inBuilding(string build) { building=build; } void CCourse::inMeetDays() // this is largely gathered by talking with my dad (excluding error checking) { // the display uses bit compares, thus my method of storage string input; // User input is stored by this string char days[] = "MTWRFS"; // char array. User input is compared against this. meetingDays = 0; // Make sure that you start with a clean slate (it has problems otherwise) int counter, error=0; // error flag while(error==0) // loop until correct data is received { cout << "Input the days the class meets (ex:'MWF' or 'tr'): "; cin >> input; input = toUPPER(input); // convert to upper case for(unsigned int i=0; i < input.length(); i++) { counter = 0; while(counter < 7) // Used a while loop instead of for loop due to error checking { if(counter>=6) // if counter reaches 6, the character being checked (from user input) does not match a day of the week) { cout << "Invalid day" << endl; meetingDays=0; // reset meetingDays in preparation to receive new user input error=0; // set error flag (just to be sure) break; // exit the loop now } else if(input[i]==days[counter]) { meetingDays += static_cast(pow(2.0,(static_cast(counter)))); error=1; // receive good data, disable the error flag break; // exit the loop (don't increase the counter) } counter++; } if(error==0) // exit the loop so the user can input good data break; } // cout << input << " " << days << " " << meetingDays << endl; } } void CCourse::inMeetDays(int days) { meetingDays=days; } string CCourse::dispMeetDay() // used to display meetingDays { string days=""; // create an empty string if((1 & meetingDays) == 1) // if bit '1' is on, days += 'M'; // add "M" to days if((2 & meetingDays) == 2) // if bit '2' is on, days += 'T'; // add "T" to days if((4 & meetingDays) == 4) // if bit '4' is on, days += 'W'; // add "W" to days if((8 & meetingDays) == 8) // if bit '8' is on days += 'R'; // add "R" (thuRsday) to days if((16 & meetingDays) == 16) // if bit '16' is on, days += 'F'; // add "F" to days if((32 & meetingDays) == 32) // if bit 32 is on, days += 'S'; // add "S" (Saturday, just in case) to days // cout << days << endl; return days; } void CCourse::dispCourse() // Simply outputs to the console { cout << year << " " << term << " " << courseNumber << " " << sectionNumber << " " << building << " " << room << " " << dispTime(beginTime) << " " << dispTime(endTime) << " " << dispMeetDay() << endl; } string CCourse::strCourse() // This outputs all the CCourse data/variables into a string { stringstream out; string courseData; out << year << ", " << term << ", " << courseNumber << ", " << sectionNumber << ", " << building << ", " << room << ", " << dispTime(beginTime) << ", " << dispTime(endTime) << ", " << dispMeetDay(); courseData = out.str(); // courseData.resize(79); return courseData; } int CCourse::checkAP(int & h, int & m, char & t) // used for checking whether it's morning or afternoon { int checker; switch(t) { case 'a': // If AM, case 'A': checker = h*100; // convert to military time checker+=m; // add minutes if(checker>=1200) // If user entered 12am, checker-=1200; // then subtract 1200, to get 12 midnight break; case 'p': // if PM, case 'P': h+=12; // add 12 hours checker = h*100; // so that conversion to military time is correct checker+=m; // add minutes if(checker>=2400) // If user entered 12pm, checker-=1200; // subtract 1200 to get 12 noon. break; default: // User did not enter a valid "AM" or "PM" specifier cout << "You didn't specify am or pm" << endl; return 2400; // It should never reachre 2400 or higher normally, so use this as the error flag break; } return checker; } string CCourse::dispTime(int mTime) // Displays beginTime and endTime (which are stored in military time) { // into standard time format (with AM and PM specifiers) stringstream out; int hour, min; // string time should be changed somewhere in here. If it remains string time="If you see this, that's bad"; // unchanged, something went wrong. This should not happen. if(mTime < 100) // If mTime < 100 (thus less than 1 am) { mTime += 1200; // add 1200 to it to convert back to 12 midnight min = mTime % 100; // get minutes by getting remainder hour = mTime / 100; // get hours by division out << hour << ":" << setfill('0') << setw(2) << min << "a"; // output to stringstream object (with an "am" designation), to insert into a string later } else if(mTime >= 1300) // If mTime >= 1300 (thus more than or equal to 1 pm) { mTime -= 1200; // subtract 1200, to convert it back to standard time units min = mTime % 100; // same as above (line 354) hour = mTime / 100; // same as above (line 355) out << hour << ":" << setfill('0') << setw(2) << min << "p"; // same as above (line 356), with a "pm" designation } else if(mTime >= 100 && mTime < 1200) // if mTime is greater than or equal to 1 am, but less than 12 pm { // it's already in the correct units, min = mTime % 100; // but still needs minutes hour = mTime / 100; // and hours out << hour << ":" << setfill('0') << setw(2) << min << "a"; // same as above (line 356) } else if(mTime >= 1200 && mTime < 1300) // If it's 12 in the afternoon, or later (but not yet 1 pm or later) { // do essentially the same as above min = mTime % 100; hour = mTime / 100; out << hour << ":" << setfill('0') << setw(2) << min << "p"; // but designate as "pm" } time = out.str(); return time; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CDocument::createList() { //Clear all values on the list list.clear(); } void CDocument::insertItem(string courseData, int line) { //Insert an item on the list list.insert(list.begin()+(line+1),courseData); } bool CDocument::deleteItem(int line) { //If the size of the list is less than or equal to 0 or the line is less than 0 //a course can't be deleted if((line-1)<0 && list.size()<=0) { cout << "\nThere are no courses to delete" << endl << endl; return false; } //Delete a course from the list and display which line was deleted else { list.erase(list.begin()+(line)); cout << "\nLine #" << line+1 << " was deleted" << endl << endl; return true; } } int CDocument::frontOfList() { //Position of first course return 0; } int CDocument::backOfList() { //Position of last course return ((int)list.size()-1); } bool CDocument::moveToNextItem(int line) { //If the current line is larger than the size of the list or the size of the list is less than or equal to 0 //then you can't move to a next line (return false) if(line>(int)list.size()-1 || (int)list.size()<=0) { cout << "\nYou're at the end of the list\n" << endl; return false; } //It is possible to go to the next course in list else return true; } bool CDocument::moveToPrevItem(int line) { //If current is less than then you can't go to previous line if(line < 0) { cout << "\nYou're at the beginning of the list\n" << endl; return false; } //It is possible to go to previous course in list else return true; } void CDocument::showCurrentItem(int line) { //If current is greater than 0 then display course in that position if(line >= 0) { cout << "\n" << list[line] << "\n" << endl; } //If current line is less than 0 and the size of the list is greater than 0 //then display course in that position if(line < 0 && list.size() > 0) { cout << "\n" << list[line+1] << "\n" << endl; } //If current line is less than 0 and the size of the list is less than or equal to 0 //then there are no courses to display if(line<0 && list.size()<=0) { cout << "\nThere are no courses in the list" << endl << endl; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CView::ViewPage() { //Set the size of the list to 100 lines cvlist.resize(100); //Set initial page #1 int page = 1; //Print what's on page 1 NextPage(page); //Holds user's choice for menu options char command = 'x'; while(command != 'Q' && command != 'q') { cout << "\n(N) Move to next page on the list" << endl; cout << "(P) Move to the previous page on the list" << endl; cout << "(Q) Return to the main menu" << endl << endl; cout << "Please select an option: "; cin >> command; cin.ignore(); //If the page number is ever greater than 5, then it's set back to 5 //as it can't be greater than 5 if(page > 5) page = 5; //If the page number is ever less than 0, then it's set back to 1 //as it can't be less than 1 if(page < 0) page = 1; switch(command) { case 'N': case 'n': { //Add one to page page++; cout << endl; //Display contents of page NextPage(page); break; } case 'P': case 'p': { //Subtract one from page page--; cout << endl; //Display contents of page NextPage(page); break; } case 'Q': case 'q': { //Go back to root menu break; } } } } void CView::NextPage(int page) { //Display courses 1-20 if(page <= 1) { cout << "You are currently on the first page (Courses 1-20)" << endl; for(int i = 0; i <= 19; i++) { //If there isn't a course on that line then skip if(cvlist[i]=="\0") continue; //Otherwise print info else cout << cvlist[i] << endl; } } //Display courses 20-39 if(page == 2) { cout << "You are currently on the second page (Courses 21-40)" << endl; for(int i = 20; i <= 39; i++) { //If there isn't a course on that line then skip if(cvlist[i]=="\0") continue; //Otherwise print info else cout << cvlist[i] << endl; } } //Display courses 40-59 if(page == 3) { cout << "You are currently on the third page (Courses 41-60)" << endl; for(int i = 40; i <= 59; i++) { //If there isn't a course on that line then skip if(cvlist[i]=="\0") continue; //Otherwise print info else cout << cvlist[i] << endl; } } //Display courses 61-80 if(page == 4) { cout << "You are currently on the fourth page (Courses 61-80)" << endl; for(int i = 60; i <= 79; i++) { //If there isn't a course on that line then skip if(cvlist[i]=="\0") continue; //Otherwise print info else cout << cvlist[i] << endl; } } //Display courses 81-100 if(page >=5) { cout << "You are currently on the last page (Courses 81-100)" << endl; for(int i = 80; i <= 99; i++) { //If there isn't a course on that line then skip if(cvlist[i]=="\0") continue; //Otherwise print info else cout << cvlist[i] << endl; } } }