In this project, you will build an application that enables waiters to take customer orders for food and drinks and generate a bill upon order completion. Each bill will have a unique number, and once an order is finalized, the bill will be saved in a separate file named according to its bill number.
| Milestone | Revision | Comments | Walkthrough |
|---|---|---|---|
| MS1 | V1.0 | video | |
| MS2 | V1.1 | ms2.cpp had a typo and it is fixed | video |
| MS3 | V1.0 | video | |
| MS4 | V1.0 | Fixed bugs, updated makeBillFileName | |
| MS5 | V1.1 | Added ms56.cpp tester for m56 submission |
For this project, you will develop an application that enables waiters to take customer orders for food and drinks and generate a bill upon order completion.
Each bill will be numbered, and after an order is finalized, a copy of the bill will be saved in a separate file titled with the corresponding bill number.
This project consists of five milestones, each with a specific due date. The due dates are based on the workload required for each milestone.
| Milestone | Mark | Due Date | Submission Policy |
|---|---|---|---|
| MS1 | 10% | Mar 9 | Mandatory to submit by Apr 15. Full marks awarded if submitted within one week late. 0% after the due date. |
| MS2 | 10% | Mar 16 | Mandatory to submit by Apr 15. Full marks awarded if submitted within one week late. 0% after the due date. |
| MS3 | 10% | Mar 26 | Mandatory to submit by Apr 15. Full marks awarded if submitted within one week late. 0% after the due date. |
| MS4 | 10% | Apr 3 | Mandatory to submit by Apr 15. Full marks awarded if submitted within one week late. 0% after the due date. |
| MS5 | 60% | Apr 10 | See details below. |
To facilitate the final project submission and allow partial submissions, Milestone 5 is divided into six smaller submissions. Each submission is worth 10% of the project mark.
Your project will only be marked if you have submitted all four milestones and at least one of the six submissions of Milestone 5.
| Submission | Mark | Due Date | Submission Policy |
|---|---|---|---|
| m51 (List Food and Drink) | 10% | Apr 10 | 10% penalty per day late, up to 5 days. |
| m52 (Order Drink) | 10% | Apr 10 | 10% penalty per day late, up to 5 days. |
| m53 (Order Food) | 10% | Apr 10 | 10% penalty per day late, up to 5 days. |
| m54 (Display Bill) | 10% | Apr 10 | 10% penalty per day late, up to 5 days. |
| m55 (Reset, Exit, and Save Bill) | 10% | Apr 10 | 10% penalty per day late, up to 5 days. |
| m56 (Foolproofing and Bad Data File) | 10% | Apr 10 | 10% penalty per day late, up to 5 days. |
The first four milestones will not be marked based on code correctness but rather on successful submission and timeliness.
You may modify or debug your previous code as you progress through the milestones.
Only Milestone 5 will be evaluated based on code quality.
If you require feedback on any of the first four milestones, you must request it from your professor.
NOTE:
- Your entire project will not receive a mark and is considered incomplete if any of the first four milestones are not submitted by the rejection date.
- For your project to be marked, you must submit all four milestones and at least one of the six submissions of Milestone 5 before the rejection date.
You can check the due date of each milestone using the -due flag in the submission command:
~profname.proflastname/submit 2??/prj/m? -due- Replace
2??with the subject code. - Replace
m?with the milestone number.
When submitting your work, all files must include full student information and citation details. See the following example:
/* Citation and Sources...
Final Project Milestone ?
Module: Whatever
Filename: Whatever.cpp
Version 1.0
Author: John Doe, StNo: 123123123, Email: jdoe@myseneca.ca
Revision History
-----------------------------------------------------------
Date Reason
2024/?/? Preliminary release
2024/?/? Debugged DMA
-----------------------------------------------------------
I have done all the coding by myself and only copied the code
that my professor provided to complete my workshops and assignments.
-----------------------------------------------------------
OR
-----------------------------------------------------------
Write exactly which part of the code is given to you as help and
who gave it to you, or from what source you acquired it.
-----------------------------------------------------------*/Failure to include the above citation in any of your files will result in a mark of zero for that submission.
If you borrow any functions or code snippets from another source (even your professor), you must add a citation comment for the specific function or code in addition to the Citation and Sources comment at the beginning of the file.
// The following code is copied from Professor John Doe's class notes.
/// <summary>
/// Reads an unlimited number of characters from an input stream dynamically, resizing as needed.
/// </summary>
/// <param name="istr">Reference to the input stream to read from.</param>
/// <returns>Pointer to a dynamically allocated C-string containing the read characters.</returns>
char* Utils::read(istream& istr) const {
...
return temp;
}You do not need to cite functions provided as part of the project template.
All code must be compiled using the following command on Matrix:
g++ -Wall -std=c++11 -g -o ws file1.cpp file2.cpp ...-Wall: Reports all warnings.-std=c++11: Uses the C++11 standard.-g: Includes debugging symbols for bettervalgrindreports.-o ws: Names the compiled applicationws.
To check for possible memory leaks, run:
valgrind --show-error-list=yes --leak-check=full --show-leak-kinds=all --track-origins=yes ws-
All code written in this project should be within the
senecanamespace. -
You are free and encouraged to add any attributes (member variables), functions, and methods (member functions) you find necessary to complete your code. If you are unsure about your strategy for adding functionalities and properties to your classes, ask your professor for advice.
-
If you add methods that are not called outside the scope of the class, make sure they are private.
-
Unless you are given a specific definition, name variables and functions yourself. Use meaningful names and follow the naming conventions instructed by your professor. Using misleading or unclear names will result in a penalty.
-
When creating methods (member functions), ensure they are marked
constif they do not modify the class. -
When passing an object or variable by address or reference, if it is not meant to be modified, pass it as a constant pointer or reference.
-
If an empty state is required for an object, it is considered an "invalid" empty state, and objects in this state should be rendered unusable.
-
A module called
Utilsis included in the project. It contains a few predefined methods that you can use.- You are allowed to add your own custom functions and classes to the
Utilsmodule for use throughout the project.
- You are allowed to add your own custom functions and classes to the
-
You may reuse and copy any code provided by your professor, functions from workshops, previous projects, or other subjects in the
Utilsmodule with no mark reduction, but you must include a citation.
The project is divided into six main modules and a main module that launches the application:
- Utils
- Menu
- Billable
- Food
- Drink
- Ordering
- main
This module should include utility functions used throughout the project to simplify development. For example:
- Functions for dynamic memory allocation for C-strings.
- Foolproof input handling functions (e.g., to ensure valid data entry).
- Other common helper functions to prevent code duplication.
In this module, unlike the other modules you have created, there are two classes:
MenuItemClass: Represents individual items on the menu.MenuClass: Manages a collection ofMenuItemobjects and allows the user to select items from the menu.
You will implement member functions and operators that handle adding, removing, and displaying MenuItem objects and facilitate user interaction for selection.
MenuItem and Menu. The Menu class owns a series of MenuItem objects and provides selection facilities for the user.
Abstract Base Class: This class serves as a foundation for all items that can be billed (e.g., food and drinks).
It will define common interfaces (pure virtual functions) that derived classes must implement.
Derived Class: Inherits from Billable and represents a food item. This class should allow for different portion sizes, such as:
- Child portion
- Adult portion
Derived Class: Inherits from Billable and represents a drink item. It should support various sizes:
- Small
- Medium
- Large
- Extra Large
This module manages the ordering process and will include methods for:
- Loading available foods and drinks from data files.
- Displaying food and drink lists separately.
- Taking customer orders (interacting with the Menu class).
- Generating and printing the bill.
- Saving a copy of the bill to a file named after the bill number.
The main module should initialize and coordinate the program by:
- Creating an Ordering object.
- Handling user interactions (as the waiter) to navigate the ordering process.
- Calling methods from the Ordering class to execute actions based on user input.
Note: As we move forward through the milestones of this project, remember that, like in any real-life project, we may need to revisit previous implementations to make changes or corrections to accommodate future requirements.
This header file is used to hold all the constant values used in the project. For now, add the following constant value:
MaximumNumberOfMenuItemsset to 20. (preferably unsigned)
Initially, we will implement this class as a standalone class. We will test it and make sure it works correctly. In Milestone 2, we will implement the Menu class, which is a composition of MenuItem objects.
When creating a menu formatted like the one below, the title, the numbered rows, and even the prompt for data entry at the end are considered MenuItem objects:
Seneca Resturant <---- title
1- Order <---- numbered row
2- Print Bill
3- Start a New Bill <---- numbered row
4- List Foods
5- List Drinks <---- numbered row
0- End Program
> <---- the prompt
In a module called Menu (i.e., Menu.h and Menu.cpp), create a class called MenuItem.
The MenuItem class must have a minimum of four attributes:
- A character pointer to hold the MenuItem content dynamically.
- An integer (preferably unsigned) to keep track of the number of indentations.
- An integer (preferably unsigned) to keep track of the size of each indentation in characters.
- An integer to be used for the numbering of MenuItem objects.
The MenuItem should be constructed using the following four values:
- A C-string holding the content. This should be stored dynamically in the MenuItem content.
- The number of indentations.
- The size of each indentation.
- An integer for the row number (only used for numbered menu items).
If any of the following conditions occur, the MenuItem should be set to a safe empty state:
- The content is nullptr, empty, or consists only of whitespace characters.
- Any of the indentation or indentation size values exceed 4.
- The row value is greater than
MaximumNumberOfMenuItems.
The Rule of Three must be applied to MenuItem to ensure it is not copyable or assignable to another MenuItem, and that the memory is properly deallocated when a MenuItem is destroyed.
If a MenuItem is cast to a bool, it should return false if it is in a safe empty state and true if it is a valid MenuItem.
The MenuItem class should have a display member function that outputs the formatted content of the MenuItem to an ostream. This function should be defined as follows:
ostream& display(ostream& ostr) const;- The function should output the formatted content of the
MenuItemto the givenostream. - If the
MenuItemis valid (m_content is not null), the function should:- Display the content with proper indentation based on the
indentation numberand theindentation size. - Include the
rownumber formatted as a two-character-wide value followed by"- "if row is non-negative. - Display the content without any leading whitespace. (skip the spaces in conent)
- Display the content with proper indentation based on the
- If the MenuItem is in an invalid or safe empty state (e.g., m_content is null), the function should output
"??????????".
- Indentation should be added to align the content appropriately.
- The row number, if present, should be right-aligned and followed by
"- ". - If the content is invalid, display
"??????????"instead.
If you would like to successfully complete the project and be on time, start early and try to meet all the due dates of the milestones.
Upload your source code and the tester program (Utils.cpp, Utils.h, Menu.h , Menu.cpp and ms1.cpp) to your matrix account. Compile and run your code using the g++ compiler as shown in the introduction and make sure that everything works properly.
Then, run the following command from your account (replace profname.proflastname with your professor’s Seneca userid):
~profname.proflastname/submit 2??/prj/m1
and follow the instructions.
- 2?? is replaced with your subject code
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Add a class to the Menu module called Menu. The Menu class must own the MenuItem class as part of its composition. To enforce this, the MenuItem class should only be accessible by the Menu class.
To achieve this, remove the public keyword from the MenuItem class and make it fully private.
Forward declare the Menu class above the MenuItem class and add Menu as a friend of the MenuItem class.
With this change, only the Menu class can instantiate MenuItem objects.
-
Add three integer (preferably unsigned) attributes to track:
- The indentation number and size for
MenuItemobjects. - The number of
MenuItemobjects currently held in theMenu.
- The indentation number and size for
-
Add three
MenuItemattributes for the title, exit option, and selection entry prompt of theMenu. SinceMenuItemdoes not have a default constructor, these attributes must be initialized in the member initializer list. Ensure that the initialization order matches the order in which the attributes are declared in theMenuclass, as some compilers may issue warnings if the order is inconsistent.The row number of the
exit optionshould be set to zero. -
Add an array of
MenuItempointers, sized according to the constantMaximumNumberOfMenuItems. When adding MenuItem objects, they should be dynamically allocated and stored in this array. Ensure that the number ofMenuItemobjects does not exceed the size of the array.
Create a Menu constructor with the following four arguments:
- A C-string for the title.
- A C-string for the exit option content, defaulted to
"Exit". - An indentation number, defaulted to
0. - An indentation size, defaulted to
3.
Initialize the corresponding attributes with these arguments and initialize the selection entry prompt MenuItem to "> ".
Set all elements of the pointer array to nullptr.
Implement the << operator overload for the Menu class to dynamically add new MenuItem objects.
- The operator should take a
const char*representing thecontentof a newMenuItem. - Check if the current number of
MenuItemobjects is less thanMaximumNumberOfMenuItemsbefore adding a new item. - If the condition is met:
- Dynamically create a new
MenuItemusing the providedmenuItemcontent, the current indentation level, the indentation size, and the row number (calculated asnumber-of-menu-items + 1). - Store the new
MenuItempointer in theMenuItempointer array. - Increment
number-of-menu-itemsto reflect the addition.
- Dynamically create a new
- Return
*thisto allow chaining of the operator.
- Ensure that
number-of-menu-itemsdoes not exceedMaximumNumberOfMenuItems. If the array is full, the operation should not add a new item or incrementnumber-of-menu-items.
This operator overload enables the use of the << operator to add MenuItem objects to a Menu, enhancing readability and simplifying the process of building a menu.
Copying and assignment of a Menu object should be explicitly prevented. While this is inherently enforced by making MenuItem attributes private to the Menu class, explicitly deleting the copy constructor and copy assignment operator in comments enhances code maintainability and clarity.
Implement a destructor that iterates through the array of MenuItem pointers, deletes each non-null pointer, and sets them to nullptr to safely release allocated memory.
size_t select() const;Implement the select method for the Menu class to perform the following actions:
- Display the Title: If the
Menuobject has a title, display it first. - Display
MenuItems: Iterate through allMenuItemobjects stored in theMenuand display them one by one. - Display the Exit Option: Display the
exit option MenuItemafter listing the mainMenuItemobjects. - Display the Selection Prompt: Display the
selection promptMenuItemto indicate that user input is expected. - Return the User's Selection: Obtain and return a validated integer input representing the user's choice. The input should only be valid if it falls within the range of
0(representing the exit option) to the number ofMenuItemobjects currently in theMenu. See thegetIntfunction suggestion below.
- The method should output the full menu structure in a readable format and handle user selection.
- It should ensure that the selection is a valid integer within the specified range before returning it.
Two example menus:
The first has zero indentation, the second has one level of indentation.
Seneca Restaurant
1- Order
2- Print Bill
3- Start a New Bill
4- List Foods
5- List Drinks
0- End Program
> 1
Order Menu
1- Food
2- Drink
0- Back to main menu
>
Create an operator<< overload for the Menu class:
size_t operator<<(std::ostream& ostr, const Menu& m);- The operator should handle output to an
ostream. - When
ostriscout(check their address to confirm), the operator should invoke theselect()method of theMenuclass and return the user's selection. - The return value should be the result of the
select()method, representing the user's choice from the menu. - If the
ostreamis notcout, do not perform the selection operation; simply return0.
- The operator should display the
Menuoncoutand allow the user to make a selection, returning the valid selection as asize_t. - Ensure that the operator returns
0when used with anyostreamother thancout.
Note: Unlike typical insertion overloads, this operator does not return an
ostreamreference.
The following will be tested in milestone 5.
To ensure foolproof data entry, implement two functions in the Utils module and use them within your select method.
int getInt();Create a method in the Utils class to handle integer input with the following requirements:
- Prompt for Valid Input: Continuously prompt the user until a valid integer is entered.
- Handle Empty Input: If the user presses Enter without typing anything, display:
You must enter a value: - Validate Integer Input: If the user enters non-integer data, display:
Clear the error state before prompting again.
Invalid integer: - Check for Trailing Characters: If extra characters follow the integer, display:
Prompt the user again.
Only an integer please: - Clear Input Buffer: After processing the input, clear any remaining characters to prepare for the next entry.
The method should only return a valid integer after ensuring proper validation.
int getInt(int min, int max);- Range Validation: Prompt the user until a valid integer within the range
[min, max]is entered. - Use
getInt(): Utilize the basic validation logic fromgetInt(). - Handle Out-of-Range Values: If input is outside the range, display:
Replace
Invalid value: [min <= value <= max], try again:minandmaxwith the respective values.
The function should return a valid integer within the specified range after enforcing all validation rules.
1<ENTER>
0<ENTER>
2<ENTER>
2<ENTER>
0<ENTER>
0<ENTER>
0<ENTER>
Will be tested in milstone 6
<ENTER>
abc<ENTER>
123abc<ENTER>
-1<ENTER>
4<ENTER>
0<ENTER>
Also try running option 3 for the Final Milestone Application Demo and see how it works.
Milestone 2
1- Run Test 1
2- Run Test 2
3- Final Milestone Application Demo
0- Exit
>
You must enter a value: abc
Invalid integer: 123abc
Only an integer please: -1
Invalid value: [0<= value <=3], try again: 4
Invalid value: [0<= value <=3], try again: 0
Have a good day!
If you would like to successfully complete the project and be on time, start early and try to meet all the due dates of the milestones.
Upload your source code and the tester program (Utils.cpp, Utils.h, Menu.h , Menu.cpp and ms2.cpp) to your matrix account. Compile and run your code using the g++ compiler as shown in the introduction and make sure that everything works properly.
Then, run the following command from your account (replace profname.proflastname with your professor’s Seneca userid):
~profname.proflastname/submit 2??/prj/m2
and follow the instructions.
- 2?? is replaced with your subject code
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Note:
In this milestone, as before, you should simplify your code by implementing helper functions in theUtilsmodule. This module should provide utilities for tasks such as dynamic memory allocation, foolproof data entry, and string manipulation.
The Billable class serves as an abstract base for items that can be added to a customer’s bill. It contains attributes and methods that define shared functionality among all billable items.
-
Attributes:
m_name: A dynamically allocated C-string to hold the name or description of the item.m_price: Adoublerepresenting the base price of the item.
-
Protected Methods:
void price(double value): Sets the item’s price.void name(const char* name): Sets the item’s name, handling dynamic allocation.
-
Public Methods and Overloads:
-
Constructors and Destructor:
- A default constructor initializes an empty
Billableitem. - Copy constructor and assignment operator to handle deep copies of dynamic members.
- A virtual destructor ensures proper cleanup of derived objects.
- A default constructor initializes an empty
-
Virtual Methods:
double price() const: Returns the item’s price, allowing derived classes to override if needed.
-
Pure Virtual Methods (to be implemented in derived classes):
ostream& print(ostream& ostr=cout)const: Displays item information in a formatted way.bool order(): Takes customer order for details of the item (e.g., size, customizations).bool ordered()const: Returns true if details have been set, indicating the item is ordered.ifstream& read(ifstream& file): Reads item details from an input file.
-
Operator Overloads:
double operator+(double money, const Billable& B); double& operator+=(double& money, const Billable& B);
+and+=are overloaded to allow adding an item’s price to a total amount (of typedouble), enabling easy bill calculations.- Conversion Operator (
operator const char*()const): Provides access to the name for display or comparison.
-
The Drink class inherits from Billable and represents a drink item. It adds functionality to manage the drink size and customizes price based on size.
-
Attributes:
m_size: Acharindicating the size of the drink (e.g.,'S'for small,'M'for medium,'L'for large, and'X'for extra large). Ifm_sizeis unset, it defaults to a safe empty state, and"....."will display for the size.
-
Public Methods:
-
print: OverridesBillable’s print to display or save the drink’s name, size, and price.The
printmethod outputs the drink in the following format:- name: Up to 25 characters in 28 spaces, left-justified and padded with dots (
'.'). - size: Displays as
"SML..","MID..","LRG..","XLR.."for small, medium, large, and extra large sizes, respectively. If size is unset (i.e.,!ordered()), it displays as".....". - price: Right-justified in 7 spaces, padded with spaces and displayed with 2 decimal places.
- name: Up to 25 characters in 28 spaces, left-justified and padded with dots (
-
order: OverridesBillable’s order as follows: Displays a menu for drink size selection with 3 indentations:Drink Size Selection 1- Small 2- Medium 3- Large 4- Extra Large 0- Back >Sets the order size to its acceptable values or leaves it unset if "Back" is selected.
The method returns
trueif the size was selected (indicating it was ordered) orfalseif not. -
ordered: OverridesBillable’s ordered, returningtrueif a size has been selected. -
read: OverridesBillable’s read. Reads the drink’s details from a comma-separated input file in the following format:name of drink,priceExample:
Orange Juice,3.5<Newline>If the read is successful
- the details are set to corresponding values
- m_size is set to its default value
Otherwise, nothing changes.
-
price: Adjusts the base price based onm_sizeas follows:- Returns
Billableprice if size is large or if item is not ordered. - For small, returns half of the price; for medium, returns 3/4 of the price; and for extra large, returns 1.5 times the original price.
- Returns
-
-
Since this class does not manage resources outside of its scope, it does not require implementing the rule of three. The object is always created in a safe empty state.
The Food class, derived from Billable, represents a food item and includes functionality for customization and portion type.
-
Attributes:
m_ordered: A boolean flag indicating whether the item has been ordered.m_child: A boolean representing if the food is a child portion, which affects pricing.m_customize: A dynamically allocated C-string for storing customization notes (e.g., "No onions").
-
Public Methods and Overloads:
-
Constructors and Destructor: The copy constructor, assignment operator, and destructor manage dynamic allocation for
m_customize. The no-argument constructor leaves the object in a safe empty state. -
print: OverridesBillable’s print to display or save the food item’s details, including portion type. Customizations are printed only if theostreamobject iscout:- name: Up to 25 characters in 28 spaces, left-justified and padded with dots (
'.'). - portion type: Displays
"Child"or"Adult"ifordered()istrueandm_childis set. Otherwise, it displays".....". - price: Right-justified in 7 spaces, padded with spaces, and displayed with 2 decimal places.
- customizations: If
m_customizeis not null andostreamiscout, it prints" >> "followed by the first 30 characters ofm_customize. Otherwise, nothing is printed.
- name: Up to 25 characters in 28 spaces, left-justified and padded with dots (
-
order: OverridesBillable’s order as follows: Displays a menu for food portion selection with 3 indentations:Food Size Selection 1- Adult 2- Child 0- Back >Sets the order portion to its acceptable values, setting
m_orderedtotrue. If "Back" is selected, the portion remains unset, m_ordered is set to false and m_customize is deallocated.If a portion is ordered, the user is prompted for customization:
Special instructions >If the user just presses enter, no customization is added, and
m_customizeis deallocated and set to nullptr. Otherwise, customization instructions are stored inm_customize(you may refer to theUtilsfunctions for dynamic memory allocation here).The method returns
trueif a portion is ordered, orfalseif not. -
ordered: OverridesBillable’s ordered, returning them_orderedflag. -
read: OverridesBillable’s read. Reads the food’s details from a comma-separated input file in the following format:name of Food,priceExample:
Pasta with Tomato sauce,3.5<Newline>If the read is successful
- the details are set to corresponding values
- m_child and m_order are set to thier default values
- m_customize is deleted and set to nullptr
Otherwise, the object remains unchanged.
-
price: OverridesBillable’s price. Returns half the price if ordered andm_childis true, indicating a child portion; otherwise, it returns the originalBillableprice.
-
Follow the instructions of the tester
If you would like to successfully complete the project and be on time, start early and try to meet all the due dates of the milestones.
Upload your source code and the tester program (Utils.cpp, Utils.h, Menu.h , Menu.cpp, Billable.h, Billable.cpp, Drink.h, Drink.cpp, Food.h, Food.cpp and ms3.cpp) to your matrix account. Compile and run your code using the g++ compiler as shown in the introduction and make sure that everything works properly.
Then, run the following command from your account (replace profname.proflastname with your professor’s Seneca userid):
~profname.proflastname/submit 2??/prj/m3
and follow the instructions.
- 2?? is replaced with your subject code
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Continue developing the system by implementing the Ordering module. This module encapsulates and organizes all the tasks involved in taking orders. The methods of this class will be invoked when the options of the main menu are selected by the waiter, assisting with taking customer orders at the restaurant.
The Ordering module includes attributes to track the number of food and drink items in the menu and the number of billable items added to a bill. These attributes ensure proper organization and management of the ordering process:
- Food Counter: An integer (preferably unsigned) to keep track of the number of food items loaded from the food data file.
- Drink Counter: An integer (preferably unsigned) to keep track of the number of drink items loaded from the drink data file.
- Billable Counter: An integer (preferably unsigned) to track the number of
Billableitems added to the bill from the food and drink menu.
- Bill Serial Number: An integer (preferably unsigned) representing the bill serial number, starting from 1. This number increments each time a new bill is generated. It is also used to create a unique file name for each completed bill saved to the file system.
Note:
Use the following function,makeBillFileNameand add it to theUtilsmodule to generate unique file names. This function receives a bill number and creates a file name in the formatbill_[billNo].txt.
char* Utils::makeBillFileName(char* filename, size_t billNo)const {
char billFileName[21] = "bill_";
size_t temp = billNo;
int cnt = 5;
int length;
// Calculate the number of digits
do {
cnt++;
temp /= 10;
} while (temp > 0);
length = cnt;
// Convert each digit to character from the end
while (billNo > 0) {
billFileName[--cnt] = (billNo % 10) + '0';
billNo /= 10;
}
// Handle the case when billNo is 0
if (billFileName[cnt - 1] == '\0') {
billFileName[--cnt] = '0';
}
// Attach .txt to the end of the file name
for (int i = 0; ".txt"[i]; i++) {
billFileName[length++] = ".txt"[i];
}
billFileName[length] = '\0';
strcpy(filename, billFileName);
return filename;
}
- Food Array: A
Foodpointer used to store a dynamically allocated array of food items loaded from the food data file. - Drink Array: A
Drinkpointer used to store a dynamically allocated array of drink items loaded from the drinks data file.
- Bill Items: An array of
Billablepointers, with a size defined by theMaximumNumberOfBillItemsconstant inconstants.h. When a food or drink item is about to be ordered, a dynamic copy of the selected item is created and stored in the next available spot in this array. The item is then customized to match the customer’s order.
This method prints a header for a bill.
-
Parameters:
- A reference to an
ostreamobject.
- A reference to an
-
Description:
The method prints the bill title in the following format, using theBill Numberattribute. For example, if the bill number is35, the output would look like:Bill # 035 =============================<NEWLINE>
This method prints the footer for a bill.
-
Parameters:
- A reference to an
ostreamobject. - A
doublevalue representing the total amount.
- A reference to an
-
Description:
The method prints the total, applicable tax, and the grand total into the providedostreamobject using theTaxconstant value defined inconstants.h. For example, if the total value is16.88, the output would be:Total: 16.88 Tax: 2.19 Total+Tax: 19.07 ========================================<NEWLINE>
This function calculates the number of records in a file by counting the newline characters.
-
Parameters:
- A constant character pointer (
const char*) representing the file name.
- A constant character pointer (
-
Return Value:
- Returns the count of newline characters (
size_t), representing the number of records in the file.
- Returns the count of newline characters (
-
Implementation:
Use the following pseudocode to implement this function:set a newline counter to zero open an ifstream using the file argument value while the file is not in a failure state read one character if the file is not in failure state and character is a newline add one to the newline counter end while return the newline counter -
Purpose:
This method is essential for determining the size of dynamically allocated arrays for food and drink items by counting the number of records in their respective files.
The Ordering class is constructed using two C-strings representing the drinks and foods data file names.
Steps for Implementation:
-
Count Records:
- Determine the number of records in the drinks and foods data files by using the
countRecordsmethod. Store these counts in two local variables.
- Determine the number of records in the drinks and foods data files by using the
-
Open Files for Reading:
- Open the drinks and foods data files using
ifstream.
- Open the drinks and foods data files using
-
Dynamic Array Allocation:
- Create two dynamic arrays:
- A
Foodarray, pointed to by the corresponding attribute of theOrderingclass. - A
Drinkarray, pointed to by the corresponding attribute of theOrderingclass.
- A
- Create two dynamic arrays:
-
Reading Data:
- If both files are successfully opened:
- Loop through the drinks array, calling the
readmethod on each element until one of the following occurs:- The number of reads matches the number of records in the file.
- A read operation fails.
- Repeat the same process for the foods array.
- Loop through the drinks array, calling the
- If both files are successfully opened:
-
Validation and Cleanup:
- If the number of successfully read records does not match the number of records in either file:
- Revert the operation by deleting both arrays.
- Set the pointers for both arrays to
nullptr(safe empty state).
- Otherwise:
- Set the corresponding attributes of the
Orderingclass to the number of records successfully read.
- Set the corresponding attributes of the
- If the number of successfully read records does not match the number of records in either file:
The destructor ensures proper cleanup of dynamically allocated memory to prevent memory leaks.
Steps for Implementation:
-
Delete Dynamic Arrays:
- Delete the dynamic arrays for foods and drinks by using the
delete[]operator.
- Delete the dynamic arrays for foods and drinks by using the
-
Delete Billable Items:
- Loop through the
Billablearray of pointers, deleting each element up to the number of items currently in the bill.
- Loop through the
Note: Queries cannot change the state of the class.
This operator provides a safe empty state indicator.
- Description:
- This method does not modify the class.
- Returns
trueif both the drinks and foods dynamic arrays are notnullptr.
Method name: 'noOfBillItems'
- Description:
- Create a method to return the number of items currently in the bill.
- This value is stored in the
Billablecounter attribute of the class.
Method name: hasUnsavedBill
- Description:
- Create a method that returns a boolean value.
- This method should return
trueif the number of bill items (tracked by theBillablecounter attribute) is greater than zero.
These methods handle specific tasks based on the options selected in the main application's menu.
Method name: listFoods
- Description:
- Prints the following header:
List Of Avaiable Meals ========================================<NEWLINE> - Loops through the
foodsdynamic array and prints each item on a separate line using itsprintmethod. - Prints the following footer:
========================================<NEWLINE>
- Prints the following header:
Method name: listDrinks
- Description:
- Works exactly like the
List Foodmethod but operates on thedrinksdynamic array.
- Works exactly like the
Method name: orderFood
- Description:
- Creates a
Menuobject with:- Title:
"Food Menu" - Exit Option:
"Back to Order" - Indentations:
2
- Title:
- Populates the
Menuobject with the names of the food items from thefoodsdynamic array. - Displays the menu and receives the waiter's selection.
- If the selection is not zero:
- Creates a dynamic copy of the selected food item and assigns it to the next available element in the
Bill Itemsarray (i.e. theBillablearray of pointers). - Calls the
ordermethod on theBillableitem to customize the order. - If
orderreturnstrue, increments thenumber of bill itemsattribute. - If
orderreturnsfalse, deletes the dynamically created food item to revert the operation.
- Creates a dynamic copy of the selected food item and assigns it to the next available element in the
- Creates a
Method name: orderDrink
- Description:
- Similar to the
Order Foodmethod but for drinks:- Creates a
Menuobject with:- Title:
"Drink Menu" - Exit Option:
"Back to Order" - Indentations:
2
- Title:
- Populates the
Menuobject with the names of the drink items from thedrinksdynamic array. - Displays the menu and receives the waiter's selection.
- If the selection is not zero:
- Creates a dynamic copy of the selected drink item and assigns it to the next available element in the
Bill Itemsarray. - Calls the
ordermethod on theBillableitem to customize the order. - If
orderreturnstrue, increments thenumber of bill itemsattribute. - If
orderreturnsfalse, deletes the dynamically created drink item to revert the operation.
- Creates a dynamic copy of the selected drink item and assigns it to the next available element in the
- Creates a
- Similar to the
Method name: printBill
-
Parameters:
- Receives a reference to an
ostreamobject.
- Receives a reference to an
-
Description:
- Creates a
doublevariable to track the total price of the bill. - Prints the bill title using the
Bill Title Printmethod. - Loops through the elements in the
Bill Itemsarray:- Prints each item in a separate line using its
printmethod. - Adds the price of each item to the total.
- Prints each item in a separate line using its
- Prints the totals using the
Print Totalsmethod.
- Creates a
Method name: resetBill
- Description:
- Uses the
makeBillFileNamefunction from theUtilsmodule to generate a unique file name for the current bill using thebill numberattribute. - Opens a file for writing using the generated file name (
ofstream). - Prints the current bill into the opened file using the
Print Billmethod. - Displays the following message (for example, if the current bill number is 20):
Saved bill number 20 Starting bill number 21 - Deletes all dynamically created elements in the
Bill Itemsarray. - Increments the
bill numberattribute by one. - Resets the
number of bill itemsattribute to zero.
- Uses the
Follow the instructions of the tester
If you would like to successfully complete the project and be on time, start early and try to meet all the due dates of the milestones.
Upload your source code and the tester program (Utils.cpp, Utils.h, Menu.h , Menu.cpp, Billable.h, Billable.cpp, Drink.h, Drink.cpp, Food.h, Food.cpp, Ordering.h, Ordering.cpp and ms4.cpp) to your matrix account. Compile and run your code using the g++ compiler as shown in the introduction and make sure that everything works properly.
Then, run the following command from your account (replace profname.proflastname with your professor’s Seneca userid):
~profname.proflastname/submit 2??/prj/m4
and follow the instructions.
- 2?? is replaced with your subject code
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.In this milestone, you will use all the modules you have created so far to build a complete application for the "Dine-In Digital" system. This milestone brings together the logic for menu navigation, order processing, bill handling, and dynamic memory management.
The goal is to create a program that mimics the behavior demonstrated in the appDemo() function provided earlier. Follow the instructions below to structure your program and meet the milestone's requirements.
Your program should use the Menu and Ordering modules to create a fully functioning application that supports the following tasks:
-
Data Files:
- Your program must load the food and drink data from two CSV files:
"drinks.csv"for drinks."foods.csv"for food items.
- Pass the file names to the
Orderingclass during initialization.
- Your program must load the food and drink data from two CSV files:
-
Validation:
- If the
Orderingobject fails to load the data (i.e., it enters a safe empty state), display an error message:Failed to open data files or the data files are corrupted! - Terminate the program if the data files are not loaded successfully.
- If the
- Menu Title:
"Seneca Restaurant" - Exit Option:
"End Program" - Menu Options:
- Order
- Print Bill
- Start a New Bill
- List Foods
- List Drinks
- Menu Title:
"Order Menu" - Exit Option:
"Back to main menu" - Menu Options:
- Food
- Drink
- Menu Title:
"You have bills that are not saved. Are you sure you want to exit?" - Exit Option:
"No" - Menu Option:
- Yes
-
Order Food
- When the "Food" option is selected from the order sub-menu:
- Call the
orderFoodmethod of theOrderingobject to handle food ordering.
- Call the
- When the "Food" option is selected from the order sub-menu:
-
Order Drink
- When the "Drink" option is selected from the order sub-menu:
- Call the
orderDrinkmethod of theOrderingobject to handle drink ordering.
- Call the
- When the "Drink" option is selected from the order sub-menu:
-
Print Bill
- When the "Print Bill" option is selected from the main menu:
- Call the
printBillmethod of theOrderingobject to print the current bill to the console.
- Call the
- When the "Print Bill" option is selected from the main menu:
-
Start a New Bill
- When the "Start a New Bill" option is selected:
- Call the
resetBillmethod of theOrderingobject to save the current bill to a file and start a new one.
- Call the
- When the "Start a New Bill" option is selected:
-
List Foods
- When the "List Foods" option is selected:
- Call the
listFoodsmethod of theOrderingobject to display all food items.
- Call the
- When the "List Foods" option is selected:
-
List Drinks
- When the "List Drinks" option is selected:
- Call the
listDrinksmethod of theOrderingobject to display all drink items.
- Call the
- When the "List Drinks" option is selected:
-
Unsaved Bills Warning:
-
If the user attempts to exit the program (selects "End Program") while there are unsaved items in the bill:
- Display a confirmation menu asking:
You have bills that are not saved. Are you sure you want to exit? - The menu should have the following options:
- Yes
- No
- Display a confirmation menu asking:
-
If the user selects "No," return to the main menu.
-
If the user selects "Yes," terminate the program.
-
-
Normal Exit:
- If there are no unsaved bills, allow the program to terminate without additional prompts.
Your program should use foolproof input handling for all menu interactions. This ensures the program does not crash due to invalid user input. Follow these steps for validation:
Seneca Restaurant
1- Order
2- Print Bill
3- Start a New Bill
4- List Foods
5- List Drinks
0- End Program
><ENTER>
You must enter a value: abc<ENTER>
Invalid integer: 1 abc<ENTER>
Only an integer please: -1<ENTER>
Invalid value: [0<= value <=5], try again: 6<ENTER>
Invalid value: [0<= value <=5], try again: 0<ENTER>
Given the following menu:
Seneca Restaurant
1- Order
2- Print Bill
3- Start a New Bill
4- List Foods
5- List Drinks
0- End Program
>
If the user inputs invalid data, the program should respond as follows and wait for re-entry:
- Empty Input:
You must enter a value: - Non-Integer Input:
Invalid integer: - Trailing Characters After Integer:
Only an integer please: - Out of Range Input:
Invalid value: [0 <= value <= 5], try again:
0 and 5 are lower and upper acceptable limits in this case
The program should continue prompting the user until a valid integer within the menu range is entered.
- Error Handling: Follow the input validation process outlined above.
- Consistency: Ensure menu titles, exit options, and functionality are consistent with this specification.
No tester program; use your own main.cpp.
4 <ENTER>
5 <ENTER>
0 <ENTER>
To submit your work:
-
Upload Source Code:
Ensure you upload the following files to yourmatrixaccount:- Utils.cpp, Utils.h
- Menu.h, Menu.cpp
- Billable.h, Billable.cpp
- Drink.h, Drink.cpp
- Food.h, Food.cpp
- Ordering.h, Ordering.cpp
- main.cpp
- foods.csv, drinks.csv
-
Compile and Test:
Compile and run your code using theg++compiler as outlined in the introduction. Ensure your program runs correctly and matches the expected output. -
Submit Your Work:
From yourmatrixaccount, run the following command (replaceprofname.proflastnamewith your professor’s Seneca user ID):~profname.proflastname/submit 2??/prj/m51
- 2?? is replaced with your subject code
Follow the instructions provided by the submission command.
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Order Drink
No tester program; use your own main.cpp.
1 <ENTER>
2 <ENTER>
2 <ENTER>
3 <ENTER>
2 <ENTER>
0 <ENTER>
2 <ENTER>
1 <ENTER>
0 <ENTER>
2 <ENTER>
3 <ENTER>
1 <ENTER>
0 <ENTER>
0 <ENTER> <-- this is the last execution line check by the submitter, you can exit the program anyway you like after this
1 <ENTER>
To submit your work:
-
Upload Source Code:
Ensure you upload the following files to yourmatrixaccount:- Utils.cpp, Utils.h
- Menu.h, Menu.cpp
- Billable.h, Billable.cpp
- Drink.h, Drink.cpp
- Food.h, Food.cpp
- Ordering.h, Ordering.cpp
- main.cpp
- foods.csv, drinks.csv
-
Compile and Test:
Compile and run your code using theg++compiler as outlined in the introduction. Ensure your program runs correctly and matches the expected output. -
Submit Your Work:
From yourmatrixaccount, run the following command (replaceprofname.proflastnamewith your professor’s Seneca user ID):~profname.proflastname/submit 2??/prj/m52
- 2?? is replaced with your subject code
Follow the instructions provided by the submission command.
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Order Food
No tester program; use your own main.cpp.
1 <ENTER>
1 <ENTER>
1 <ENTER>
0 <ENTER>
1 <ENTER>
1 <ENTER>
1 <ENTER>
well done <ENTER>
0 <ENTER>
0 <ENTER> <-- this is the last execution line check by the submitter, you can exit the program anyway you like after this
1 <ENTER>
To submit your work:
-
Upload Source Code:
Ensure you upload the following files to yourmatrixaccount:- Utils.cpp, Utils.h
- Menu.h, Menu.cpp
- Billable.h, Billable.cpp
- Drink.h, Drink.cpp
- Food.h, Food.cpp
- Ordering.h, Ordering.cpp
- main.cpp
- foods.csv, drinks.csv
-
Compile and Test:
Compile and run your code using theg++compiler as outlined in the introduction. Ensure your program runs correctly and matches the expected output. -
Submit Your Work:
From yourmatrixaccount, run the following command (replaceprofname.proflastnamewith your professor’s Seneca user ID):~profname.proflastname/submit 2??/prj/m53
- 2?? is replaced with your subject code
Follow the instructions provided by the submission command.
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Display Bill
No tester program; use your own main.cpp.
1 <ENTER>
1 <ENTER>
1 <ENTER>
2 <ENTER>
well done <ENTER>
2 <ENTER>
2 <ENTER>
1 <ENTER>
1 <ENTER>
6 <ENTER>
1 <ENTER>
<ENTER>
0 <ENTER>
2 <ENTER>
0 <ENTER> <-- this is the last execution line check by the submitter, you can exit the program anyway you like after this
1 <ENTER>
To submit your work:
-
Upload Source Code:
Ensure you upload the following files to yourmatrixaccount:- Utils.cpp, Utils.h
- Menu.h, Menu.cpp
- Billable.h, Billable.cpp
- Drink.h, Drink.cpp
- Food.h, Food.cpp
- Ordering.h, Ordering.cpp
- main.cpp
- foods.csv, drinks.csv
-
Compile and Test:
Compile and run your code using theg++compiler as outlined in the introduction. Ensure your program runs correctly and matches the expected output. -
Submit Your Work:
From yourmatrixaccount, run the following command (replaceprofname.proflastnamewith your professor’s Seneca user ID):~profname.proflastname/submit 2??/prj/m54
- 2?? is replaced with your subject code
Follow the instructions provided by the submission command.
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Reset Exit and Save Bill Message
No tester program; use your own main.cpp.
1 <ENTER>
2 <ENTER>
2 <ENTER>
2 <ENTER>
0 <ENTER>
2 <ENTER>
0 <ENTER>
0 <ENTER>
3 <ENTER>
0 <ENTER>
To submit your work:
-
Upload Source Code:
Ensure you upload the following files to yourmatrixaccount:- Utils.cpp, Utils.h
- Menu.h, Menu.cpp
- Billable.h, Billable.cpp
- Drink.h, Drink.cpp
- Food.h, Food.cpp
- Ordering.h, Ordering.cpp
- main.cpp
- foods.csv, drinks.csv
-
Compile and Test:
Compile and run your code using theg++compiler as outlined in the introduction. Ensure your program runs correctly and matches the expected output. -
Submit Your Work:
From yourmatrixaccount, run the following command (replaceprofname.proflastnamewith your professor’s Seneca user ID):~profname.proflastname/submit 2??/prj/m55
- 2?? is replaced with your subject code
Follow the instructions provided by the submission command.
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Fool-Proofing and Bad Data File
<ENTER>
-1 <ENTER>
4 <ENTER>
abc <ENTER>
123abc <ENTER>
0 <ENTER>
To submit your work:
-
Upload Source Code:
Ensure you upload the following files to yourmatrixaccount:- Utils.cpp, Utils.h
- Menu.h, Menu.cpp
- Billable.h, Billable.cpp
- Drink.h, Drink.cpp
- Food.h, Food.cpp
- Ordering.h, Ordering.cpp
- ms56.cpp
- foods.csv, drinks.csv
-
Compile and Test:
Compile and run your code using theg++compiler as outlined in the introduction. Ensure your program runs correctly and matches the expected output. -
Submit Your Work:
From yourmatrixaccount, run the following command (replaceprofname.proflastnamewith your professor’s Seneca user ID):~profname.proflastname/submit 2??/prj/m56
- 2?? is replaced with your subject code
Follow the instructions provided by the submission command.
~prof_name.prof_lastname/submit DeliverableName [-submission options]<ENTER>
[-submission option] acceptable values:
"-due":
Shows due dates only
This option cannot be used in combination with any other option.
"-skip_spaces":
Do the submission regardless of incorrect horizontal spacing.
This option may attract penalty.
"-skip_blank_lines":
Do the submission regardless of incorrect vertical spacing.
This option may attract penalty.
"-feedback":
Check the program execution without submission.Your message is mostly clear but has a couple of small grammatical and formatting issues. Here’s the refined version:
The reflection submission is optional.
You can use it to:
- Share your thoughts about the project or provide feedback to your professor.
- Highlight any additional work or enhancements you have implemented that you would like your professor to notice.
Feel free to include any insights, challenges you faced, or suggestions for improving the project in future iterations.
-
Write Your Reflection:
- Create a file named
reflect.txtand include your reflection.
- Create a file named
-
Upload to Matrix:
-
Upload your the reflection file to matrix
-
Use the following command to submit your reflection:
~profname.proflastname/submit 2??/prj/mref
- Replace
2??with your subject code.
- Replace
-
-
Follow Instructions:
- Complete the submission process as prompted by the command.