Created
December 21, 2021 09:33
-
-
Save haile01/fca07fc64865a99aa200eb9f80365afb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <math.h> | |
#include <iomanip> | |
#include <vector> | |
#include <string> | |
using namespace std; | |
class Helper { | |
private: | |
public: | |
static vector <string> exemptKeywords; | |
static bool isExempt (string name) { | |
for (string keyword: exemptKeywords) { | |
if (name.find(keyword) != -1) | |
return true; | |
} | |
return false; | |
} | |
static bool isImported (string name) { | |
return name.find("imported") != -1; | |
} | |
static double rounding (double value) { | |
return ceil(value * 20) / 20; // 20 = 1 / 0.05 | |
} | |
}; | |
class Good { | |
private: | |
string name; | |
double price; | |
public: | |
int taxRate; | |
Good () {} | |
Good (string _name, double _price) { | |
name = _name; | |
price = _price; | |
taxRate = 0; | |
/* | |
Even though I have made a different design during the interview, | |
I realized that splitting goods into 4 different category depending | |
whether or not they are exempted or imported is costly and counter-intuitive | |
because the tax rate for each case don't have other relation. Hence I only made | |
the only class Good instead and sequentially sum up the tax rate depeding on the condition. | |
*/ | |
if (!Helper::isExempt(_name)) { | |
taxRate += 10; | |
} | |
if (Helper::isImported(_name)) { | |
taxRate += 5; | |
} | |
} | |
// Values are readable, not writable | |
string getName () { | |
return name; | |
} | |
double getPrice () { | |
return price; | |
} | |
}; | |
class CartGood { | |
private: | |
Good good; | |
int amount; | |
string getName() { | |
return good.getName(); | |
} | |
// total = totalPrice + totalTax | |
double getTotalPrice () { | |
return good.getPrice() * amount; | |
} | |
double getTotalTax () { | |
return Helper::rounding(getTotalPrice() * good.taxRate / 100); | |
} | |
double getTotal () { | |
return getTotalPrice() + getTotalTax(); | |
} | |
public: | |
CartGood (int _amount, string _name, double _price) { | |
amount = _amount; | |
good = Good(_name, _price); | |
} | |
// Only let Cart access the details of each good in cart | |
friend class Cart; | |
}; | |
class Cart { | |
private: | |
vector <CartGood> goods; | |
double getTotal () { | |
double res = 0; | |
for (CartGood g: goods) | |
res += g.getTotal(); | |
return res; | |
} | |
double getTotalTax () { | |
double res = 0; | |
for (CartGood g: goods) | |
res += g.getTotalTax(); | |
return Helper::rounding(res); | |
} | |
public: | |
void input () { | |
int amount; | |
string name; | |
double price; | |
while (true) { | |
cout << "Input amount of product (0 to stop): "; | |
cin >> amount; | |
if (amount == 0) | |
break; | |
cout << "Input name of product: "; | |
cin.ignore(); | |
getline(cin, name); | |
cout << "Input price of product: "; | |
cin >> price; | |
cout << "Adding product to cart...\n"; | |
goods.push_back(CartGood(amount, name, price)); | |
} | |
} | |
void output () { | |
cout << "===RECEIPT===\n"; | |
for (CartGood g: goods) { | |
cout << g.amount << ", " << g.getName() << ", " << fixed << setprecision(2) << g.getTotal() << "\n"; | |
} | |
cout << "Sales Taxes: " << fixed << setprecision(2) << getTotalTax() << "\n"; | |
cout << "Total: " << fixed << setprecision(2) << getTotal() << "\n"; | |
} | |
}; | |
vector <string> Helper::exemptKeywords = { | |
"book", | |
"chocolate", | |
"pill" | |
// add more here | |
}; | |
int main () { | |
Cart cart; | |
cart.input(); | |
cart.output(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment