I'm a beginner programmer and I was hoping someone would be able to review my program. Everything has been tested for user validation, error-checking and conforms to the specification with a few slight additions of my own. I want to know what I've done well, what I haven't done well, improvements I can make e.g. how can I can make code structure more efficient. Are there any parts of my program which can be simplified i.e. have I over-thought / over-complicated any parts of my program and if I have is there an easier way? I'll be absolutely grateful to anyone who does! There are five parts to my program, a struct "specification" and "implementation" for both "Item" (singular) and "Items" (plural), and the "Main.cpp". I've based my program on the following scenario...
A system that allows one to enter the items that they are selling, the quantity sold, the price of each of the items. They would like the program to be able to create suggestions based on the data provided.
Input:
Item name
Sale price
Quantity sold
Output:
Quantity of items sold
Total price of items sold
Most sold item
Least sold item
The difference in sales between the most and least sold items
Estimated operational cost (50% of sales)
Tax paid (20% of sales)
Profit (Total after tax and operational costs)
If any number of products constitutes less than 5% of sales individually, a warning should be displayed
Your program will also need to work within the following constraint:
There must be at least 5 products that can be entered
Sales System.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include "Item.hpp"
#include "Items.hpp"
//When called this asks the user how many items they would like to add and the item number has to be greater than 5.
//Through the parameter is passed a vector of items.
//The ContinueOptions() procedure is there to allow people to decide when they want to go back to the menu.
void ContinueOptions()
{
bool bValid = false;
char cInputCommandPrompt = 0;
do{
std::cout << "Press ""y"" to continue: ";
bValid = bool( std::cin >> cInputCommandPrompt );
if (bValid)
{
cInputCommandPrompt = std::toupper(static_cast<unsigned char>(cInputCommandPrompt));
bValid = cInputCommandPrompt == 'Y';
}
if (!bValid)
{
std::cin.clear();
std::cin.ignore(100, '\n');
std::cout << "Please try again.\n";
}
} while(!bValid );
std::cout << "\n";
}
void DisplayMenu()
{
std::cout << "What would you like to do?\nChoose a number from the Menu...\n";
std::cout << "\t1. Add another item\n";
std::cout << "\t2. Display items\n";
std::cout << "\t3. Total quantity of items sold\n";
std::cout << "\t4. Total price of items sold\n";
std::cout << "\t5. Most sold item\n";
std::cout << "\t6. Least sold item\n";
std::cout << "\t7. Difference in sales between the most and least sold items\n";
std::cout << "\t8. Estimated operational cost (50% of sales)\n";
std::cout << "\t9. Show Tax paid (20% of sales)\n";
std::cout << "\t10.Profit (Total after tax and operational costs)\n";
std::cout << "\t11. Show additional options\n";
std::cout << "\t0. Quit.\n";
std::cout << "\n";
}
void DisplayAdditionalMenu()
{
std::cout << "What would you like to do?\nChoose a number from the Additional Menu...\n";
std::cout << "\t1. Delete an item\n";
std::cout << "\t2. Search for specific item\n";
std::cout << "\t0. Back to main menu\n";
std::cout << "\n";
}
void AdditionalMenu(Items &Items)
{
bool bExitAdditionalMenu = false;
do
{
DisplayAdditionalMenu();
int iAdditionalMenuSelection = 0;
std::cout << "Enter a number from the additional menu: ";
std::cin >> iAdditionalMenuSelection;
if(std::cin.good())
{
switch(iAdditionalMenuSelection)
{
case 1:
Items.DeleteAnItem();
ContinueOptions();
break;
case 0:
bExitAdditionalMenu = true;
default:
std::cout << "Invalid input. Try again!\n";
continue;
}
}
else
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "Sorry, invalid input input. Try again!";
std::cout << "\n";
ContinueOptions();
}
}while(bExitAdditionalMenu == false);
}
int main()
{
Items Items;
bool bExitProgram = false;
int iMenuSelection = 0;
int iIndexOfMostSoldItem = 0;
int iIndexOfLeastSoldItem = 0;
//If this variable is greater than 1 (which will increment within the do / while) then a continue option will display.
int iNumber = 1;
std::cout << "===================================\n";
std::cout << "\t\tSales System\n";
std::cout << "===================================\n";
Items.GetItemInformation();
Items.DisplayWarning();
do{
iNumber++;
if (iNumber > 1)
{
ContinueOptions();
}
DisplayMenu();
std::cout << "Enter a number from the menu: ";
std::cin >> iMenuSelection;
if(std::cin.good())
{
std::cout << "\n";
switch (iMenuSelection)
{
case 1:
std::cout << "You've chosen option 1.\n";
std::cin.ignore();
Items.AddNewItem();
break;
case 2:
std::cout << "You've chosen option 2.\n";
Items.PrintItems();
break;
case 3:
std::cout << "You've chosen option 3.\n";
std::cout << "The total quantity sold is: " << Items.CalculateQuantitySold() << ".\n";
break;
case 4:
std::cout << "You've chosen option 4.\n";
std::cout << "Total Amount of Items Sold: £" << Items.CalculateTotalSales() << "\n";
break;
case 5:
std::cout << "You've chosen option 5.\n";
std::cout << "Displaying most sold item...\n";
iIndexOfMostSoldItem = Items.MostSoldItem();
Items.DisplayVectorOfItemsAtIndex(iIndexOfMostSoldItem);
break;
case 6:
std::cout << "You've chosen option 6.\n";
std::cout << "Displaying least sold item...\n";
iIndexOfLeastSoldItem = Items.LeastSoldItem();
Items.DisplayVectorOfItemsAtIndex(iIndexOfLeastSoldItem);
break;
case 7:
std::cout << "You've chosen option 7.\n";
std::cout << "The difference between the most and least is by: ";
std::cout << Items.CalculateDifferenceBetweenLeastAndMostSold() << ".\n";
break;
case 8:
std::cout << "You've chosen option 8.\n";
std::cout << "Estimated operational cost (50% of sales): ";
std::cout << Items.CalculateEstimatedOperationalCost() << ".\n";
break;
case 9:
std::cout << "You've chosen option 9.\n";
std::cout << "Tax paid (20% of sales): ";
std::cout << Items.CalculateTaxPaid() << ".\n";
break;
case 10:
std::cout << "You've chosen option 10.\n";
std::cout << "Profit (Total after tax and operational costs): ";
std::cout << Items.CalculateProfit() << ".\n";
case 11:
AdditionalMenu(Items);
break;
case 0:
std::cout << "You have exited the program.\n";
bExitProgram = true;
break;
default:
std::cout << "Invalid command prompt. Try again!\n";
continue;
}
}
//This will essentially clear the invalid characters the user entered and will prompt them to try again by re-looping back to the start.
else
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "Sorry, invalid input input. Try again!";
std::cout << "\n";
ContinueOptions();
}
}while(bExitProgram == false);
std::cout << "\n";
}
Item.hpp Sale System
#ifndef Item_hpp
#define Item_hpp
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <stdio.h>
//This struct models as a basic item which includes its name, price and quantity sold.
struct Item{
private:
std::string sItemName;
double dSalePrice;
int iQuantitySold;
public:
Item(std::string s, double d, int i);
std::string GetItemName()const;
double GetItemSalePrice()const;
int GetItemQuantity()const;
double GetItemSale();
};
#endif /* Item_hpp */
Item.cpp Sale System
#include "Item.hpp"
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
Item::Item(std::string s, double d, int i):sItemName(s),dSalePrice(d),iQuantitySold(i){
}
std::string Item::GetItemName()const{return sItemName;}
double Item::GetItemSalePrice()const{return dSalePrice;}
int Item::GetItemQuantity()const{return iQuantitySold;}
double Item::GetItemSale()
{
return dSalePrice * iQuantitySold;
}
Items.hpp Sale System This is the specification of the "Items" (plural) struct
#ifndef Items_hpp
#define Items_hpp
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include "Item.hpp"
struct Items{
//The vector<Items>ItemsVec is private so only member functions/procedures have access to it.
private:
std::vector<Item>ItemsVec;
public:
//The ContinueOptions() procedure is there to allow people to decide when they want to go back to the menu.
//Memeber functions/procedures of Items prototypes ()
bool CheckIfItemExists(std::string sInputName);
void AddNewItem(); //PROTOTYPE of procedure that adds a new item to the vecto
void GetItemInformation();//PROTOTYPE that allows user to enter in the amount of items (and number of how many will be the amount of times the for loop iterates to add desired number of items through means of push_back)
int CalculateQuantitySold();//PROTOTYPE of function that calculates the total quantity sold for all items
int MostSoldItem(); //PROTOTYPE of function that calculates most item using a For Loop.
int LeastSoldItem(); //PROTOTYPE of function that calculates least item using a For Loop.
void DisplayVectorOfItemsAtIndex(int iIndex); //PROTOTYPE that expects iIndex as a parameter to ascertain which index to display in vector.
double CalculateDifferenceBetweenLeastAndMostSold();//PROTOTYPE for calculating difference between the least amount sold and the highest.
double CalculateTotalSales(); //PROTOTYPE for calculating the total sales
double CalculateEstimatedOperationalCost(); //PROTOTYPE for calculating the estimated operational cost
double CalculateTaxPaid(); //PROTOTYPE for calculating amount of tax paid.
double CalculateProfit(); //PROTOTYPE for calculating total profit
bool PrintItems()const; //PROTOTYPE for printing items in vector
void DisplayWarning(); //PROTOTYPE for displaying a warning
bool DeleteAnItem(); //PROTOTYPE for deleting an item from the vector
};
#endif /* Items_hpp */
Items.cpp Sale System
#include "Items.hpp"
#include "Item.hpp"
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
//This procedure allows the user to type in the name of the item, and if the item exists, will subseqently be deleted.
bool Items::DeleteAnItem()
{
std::string sNameOfItemToBeDeleted;
std::cout << "Input name of item that you wish to delete: ";
std::cin.ignore(); //This ignores anything that is in the cin buffer.
std::getline(std::cin,sNameOfItemToBeDeleted);
for (int iCount = 0; iCount < ItemsVec.size();iCount++)
{
if (ItemsVec.at(iCount).GetItemName() == sNameOfItemToBeDeleted)
{
ItemsVec.erase(ItemsVec.begin() + iCount);
std::cout << sNameOfItemToBeDeleted << " has been deleted.\n";
std::cin.clear();
return true;
}
}
std::cout << "We couldn't find the item you're trying to delete\n";
return false;
}
bool Items::CheckIfItemExists(std::string sInputName)
{
for(int iCount = 0; iCount < ItemsVec.size();iCount++)
{
if (ItemsVec.at(iCount).GetItemName() == sInputName)
{
std::cout << "Try again! There's already an item with that name.\n";
return false;
}
}
return true;
}
void Items::AddNewItem()
{
bool bValid = false;
std::string sInputName;
double dInputSalePrice = 0;
int iInputQuantity = 0;
do{
std::cout << "Enter information for new item..." << std::endl;
std::cout << "\tName: ";
std::cin.clear();
std::getline(std::cin,sInputName);
bValid = CheckIfItemExists(sInputName);
}while(bValid == false);
bool bSalePriceValid = false;
do{
std::cout << "\tSale price: £";
std::cin >> dInputSalePrice;
if(!std::cin)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "\n";
std::cout << "Sorry, invalid input input. Try again!\n";
std::cout << "\n";
}
else
{
bSalePriceValid = true;
}
}while(bSalePriceValid == false);
bool bQuantityValid = false;
do{
std::cout << "\tQuantity sold: ";
std::cin >> iInputQuantity;
if(!std::cin)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "\n";
std::cout << "Sorry, invalid input input. Try again!\n";
std::cout << "\n";
}
else
{
bQuantityValid = true;
}
}while(bQuantityValid == false);
Item NewItem(sInputName, dInputSalePrice, iInputQuantity);
ItemsVec.push_back(NewItem);
std::cout << "=======================================================================\n";
std::cout << "You've succesfully added a " << "'" << sInputName << "' as an item.\n";
std::cout << "=======================================================================\n";
}
void Items::GetItemInformation()
{
bool bValid = false;
int iInputItemSize = 0;
std::string sItem;
do{
std::cout << "How many items would you like to add?: ";
std::cin >> iInputItemSize;
if(std::cin.good())
{
if(iInputItemSize < 5)
{
std::cout << "\n";
std::cout << "Try again, number must be greater than 5!\n";
}
else
{
bValid = true;
}
}
else
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "Sorry, invalid input input. Try again!";
std::cout << "\n";
}
} while(bValid == false);
for (int iCount = 0; iCount < iInputItemSize;iCount++)
{
std::cin.ignore();
AddNewItem();
std::cout << "\n";
}
std::cout << "You've successfully added " << iInputItemSize <<" items\n";
}
int Items::CalculateQuantitySold(){
int iTotalQuantitySold = 0;
for (int iCount = 0; iCount < ItemsVec.size();iCount++){
iTotalQuantitySold += ItemsVec.at(iCount).GetItemQuantity();
}
return iTotalQuantitySold;
}
int Items::MostSoldItem()
{
Item MostSoldItem("",0,0);
int iIndexOfMostSoldItem = 0;
for (int iCount = 0; iCount < ItemsVec.size();iCount++)
{
if ( ItemsVec.at(iCount).GetItemQuantity() > MostSoldItem.GetItemQuantity() )
{
MostSoldItem = ItemsVec.at(iCount);
iIndexOfMostSoldItem = iCount;
}
}
return iIndexOfMostSoldItem;
}
int Items::LeastSoldItem()
{
Item LeastSoldItem("",0,0);
int iIndexOfLeastSoldItem = 0;
for (int iCount = 0; iCount < ItemsVec.size();iCount++)
{
if (ItemsVec.at(iCount).GetItemQuantity() < LeastSoldItem.GetItemQuantity())
{
LeastSoldItem = ItemsVec.at(iCount);
iIndexOfLeastSoldItem = iCount;
}
}
return iIndexOfLeastSoldItem;
}
void Items::DisplayVectorOfItemsAtIndex(int iIndex)
{
std::cout << "==========================================\n";
std::cout <<"\tName: " << ItemsVec.at(iIndex).GetItemName() << "\n";
std::cout <<"\tSale Price: £" << ItemsVec.at(iIndex).GetItemSalePrice() << "\n";
std::cout <<"\tQuantity Sold: " << ItemsVec.at(iIndex).GetItemQuantity() << "\n";
std::cout << "==========================================\n";
std::cout << "\n";
}
double Items::CalculateDifferenceBetweenLeastAndMostSold()
{
int iDifferenceBetweenMostLeast = 0;
int iMostSoldIndex = MostSoldItem();
int iLeastSoldIndex = LeastSoldItem();
iDifferenceBetweenMostLeast = ItemsVec.at(iMostSoldIndex).GetItemQuantity() - ItemsVec.at(iLeastSoldIndex).GetItemQuantity();
return iDifferenceBetweenMostLeast;
}
double Items::CalculateTotalSales()
{
double dTotalSales = 0;
for (auto Item : ItemsVec)
{
dTotalSales += Item.GetItemSale();
}
return dTotalSales;
}
double Items::CalculateEstimatedOperationalCost()
{
double dTotalSales = CalculateTotalSales();
double dEstimatedOperationalCost = dTotalSales * 0.5;
return dEstimatedOperationalCost;
}
double Items::CalculateTaxPaid()
{
double dTaxPaid = CalculateTotalSales() * 0.2;
return dTaxPaid;
}
double Items::CalculateProfit()
{
double dTotalProfit = 0;
double dTotalSales = CalculateTotalSales();
dTotalProfit = dTotalSales - CalculateTaxPaid() - CalculateEstimatedOperationalCost();
return dTotalProfit;
}
bool Items::PrintItems()const
{
int iCountNumber = 1;
if (ItemsVec.size() == 0)
{
std::cout << "There are no items to display.\n";
return false;
}
else
{
for (const auto &Item : ItemsVec)
{
std::cout << "Displaying information for item " << iCountNumber++ << "...\n";
std::cout << "==========================================\n";
std::cout << "\tName: " << Item.GetItemName() << "\n";
std::cout << "\tSale Price: £" << Item.GetItemSalePrice() << "\n";
std::cout << "\tQuantity Sold: " << Item.GetItemQuantity() << "\n";
std::cout << "==========================================\n";
std::cout << "\n";
}
}
return true;
}
void Items::DisplayWarning()
{
double dTotalSales = CalculateTotalSales();
double FivePercentOfTotalSales = dTotalSales * 0.05;
bool bWarning = false;
for (int iCount = 0; iCount < ItemsVec.size();iCount++)
{
if (ItemsVec.at(iCount).GetItemSale() <= FivePercentOfTotalSales)
{
bWarning = true;
}
else
{
bWarning = false;
}
}
if (bWarning == true)
{
std::cout << "Warning! You have products that constitutes less than 5% of sales individually.\n";
}
else
{
std::cout << "Well done! All your products constitutes to more than 5% of sales individually.\n";
}
}