Program: Patriot Parties

Pages: 12
closed account (oG8qGNh0)
Program: Patriot Parties Billing System

The Patriot Parties Events and Catering Service has asked you to write a computer program to produce customers' bills based on a variety of factors. The program will be used by an employee of the service who is behind the desk when a customer comes to pay their bill after the event has occurred.

Data Collection:
Here is the complete list of everything the user should be prompted for (I would recommend doing calculations as you collect, not waiting until the end!):

Number of adults served
Number of children served
Type of meal (Deluxe or Standard - everyone at the party eats the same type)
The room (A, B, C, D, or E - prices described below)
The day of the week the party was held on
The number of days since the party was held
The amount of a deposit (money they had already paid up-front towards their bill in order to reserve the space) - this amount should be deducted from the bill as the last part of the calculation


Determining Charges:
The following charges will be assessed:

For adults, the deluxe meal will cost $15.80 per person and the standard meals will cost $11.75 per person, dessert included. Each children's meal will cost 60% of the cost of an adult meal. That will be either 60% of $15.80 or 60% of $11.75 depending on the meal type. Everyone at the party must be served the same type of meal (i..e only standard or only deluxe).

All customers will be charged the same rate for tip and tax, currently 18 percent. It is only applied to the cost of food.

There are five banquet halls. Room A rents for $55.00, room B rents for $75.00, room C rents for $85.00, room D rents for $100.00, and room E rents for $130.00.

A surcharge, currently 7 percent, is added to the total bill if the catering is to be done on a weekend (Friday, Saturday, or Sunday).

To persuade customers to pay promptly, a discount is offered if payment is made within 10 days. This discount depends on the amount of the total bill. If the bill is less than $100.00, the discount is 0.5 percent; if the bill is at least $100 but less than $400 the discount is 3 percent; if the bill is at least $400 but less than $800.00 the discount if 4 percent; and, if the bill is at least $800 the discount if 5 percent.

Here’s the same information as a little chart in case you find that helpful:


Additional Considerations:
Where possible, provide the user with a list of options

Though it is not realistic, you may assume for this project that the user will input a valid option from the list (i.e. there will be no input mistakes).

If you have the user enter a letter for option choice, accept and consider both upper and lowercase version of the letter as having entered the same option.

Strings make possible too many potential variations - it is best to stick with integer and char for input of menu items (If money amounts are inputted, like for the deposit, those can still be double.)

Make menu options have a logical correspondence to what you are asking for when possible; for example, D for deluxe meals, S for standard meals. When not possible to have distinct letters represent choices, use numbers (for example, the days of the week have Saturday and Sunday, so S would not clearly represent a single option).

Use constants to represent amounts and/or rates so that if the company decides to change these values in the near future, it is easy to alter them at the top of the program rather than finding the values throughout the code.

Please note that the overall discount, where applicable, will be applied after total of all fees is determined and the deposit amount will be subtracted last of all.

You should not have to recalculate based on all possible combinations. You should use some variables to accumulate totals as you go, and then add newly calculated amounts to them.

Test cases:
BEFORE YOU TURN THIS IN – take your trusty calculator and work through some examples by hand. See what you get on your calculator…then make sure your program comes up with the same value.

Try these:

Customer A: This customer is using room C on Tuesday night. The party includes 80 adults and 6 children. The standard meal is being served. The customer paid $60.00 deposit. The total bill payment was made 8 days after the party. Total due should be $1121.91

Customer B: This customer is using room A on Saturday night. Deluxe meals are being served to 15 adults. A deposit of $50.00 was paid. The total bill payment was made 20 days after the party. Total due should be $308.09

Customer C: This customer is using room D on Sunday afternoon. The party includes 30 children and 2 adults, all of whom are served the standard meal. The total bill payment was made the same day as the party. Total due should be $387.56
Last edited on
Anyone know how to work this c++ program into an A++?


Yes - but then we'd be the ones getting the marks and not you - which is sort of like cheating.

What part are you having difficulty with? You're told what input is required. Have you got this far?

You're asked to check your answer with a calculator. How do you get the required answer using a calculator? Write down the steps taken. Then produce a program design and then code from the design.

Post the code you have and then we'll be able to comment further.
closed account (oG8qGNh0)
Funny thing actually, umm this is my first day of AP Computer Programming. I had to switch classes. so technically i have no idea on what to do. besides all i have been learning is python and java script many years ago. THis is the first day learning about c++ or c
Last edited on
If you make a start and ask questions as you do, you'll receive help. But it's unlikely someone's going to do the work for you.
closed account (oG8qGNh0)
my teacher doesnt care because im new to the class and c/c++. She's nice enough to borrow info from anyone. this is just the one time what she said
Maybe someone do it for a fee, if you post it in the job section:

http://www.cplusplus.com/forum/jobs/
closed account (oG8qGNh0)
I am honestly soo confused
She's nice enough to borrow info from anyone. this is just the one time what she said


Well just this once....... Note you need to compile as C++17.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <limits>
#include <iostream>
#include <iomanip>

#include "keyinp.hpp"

int main()
{
	constexpr auto delux {15.80};							// Delux meal
	constexpr auto standard {11.75};						// Standard meal
	constexpr auto child {60};							// Child discount percent
	constexpr auto chdelux {delux * child / 100.0};					// Child delux meal
	constexpr auto chstand {standard * child / 100.0};				// Child standard meal
	constexpr auto tiptax {18};							// Tip & tax percent. Applies food only
	constexpr auto surcharge {7};							// Surcharge percent for total bill if Friday, Saturday, Sunday
	constexpr auto prompt {10};							// Days for discount
	constexpr auto maxdisc {5};							// Maximum discount allowed
	constexpr auto surday {4};							// First week day surcharge applied
	constexpr auto discday {10};							// Discount within days

	constexpr double roomrate[5] {55.0, 75.0, 85.0, 100.0, 130.0};			// Room rates
	constexpr double discount[][2] {{100.0, 0.5}, {400.0, 3.0}, {800.0, 4.0}};	// Discount rates

	const auto AdServ = getNum("Number of adults served", 1, std::numeric_limits<int>::max());
	const auto ChldServ = getNum("Number of children served", 0, std::numeric_limits<int>::max());
	const auto type = getChar("Type of meal - (D)elux, (S)standard", "DS", 'S');
	const auto room = getChar("Room letter", "ABCDE");
	const auto day = getNum("Day of week number - Monday(1)..Sunday(7)", 1, 7);
	const auto elapse = getNum("Number of days elapsed since held", 0, 365);
	const auto deposit = getNum<double>("Deposit", 0, std::numeric_limits<double>::max());

	const auto mealcost = (type == 'D') * (delux * AdServ + chdelux * ChldServ) + (type == 'S') * (standard * AdServ + chstand * ChldServ);
	auto total = roomrate[room - 'A'] + mealcost * (1.0 + tiptax / 100.0);

	if (day > surday)
		total += total * surcharge / 100.0;

	if (elapse < discday) {
		bool apply {false};

		for (const auto& d : discount)
			if (total < d[0]) {
				total -= total * d[1] / 100;
				apply = true;
				break;
			}

		if (apply == false)
			total -= total * maxdisc / 100.0;
	}

	total -= deposit;

	std::cout << std::fixed << std::setprecision(2) << "\nAmount payable is $" << total << std::endl;
}


and keyinp.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#pragma once

#include <string>
#include <type_traits>
#include <algorithm>
#include <optional>
#include <iostream>
#include <sstream>
#include <cctype>
#include <charconv>
#include <limits>

template<typename T = int>
[[nodiscard]] auto stonum(const std::string& str)
{
    static_assert(std::is_arithmetic_v<T>);

    constexpr char white[] {" \n\r\t"};
    bool ok {false};
    T num {};

    if (const auto fl {str.find_last_not_of(white)}; fl != std::string::npos) {
        const auto end {str.data() + fl + 1};
        const auto first {str.data() + str.find_first_not_of(white)};

        ok = (end != first) && (std::from_chars(first, end, num).ptr == end);
    }

    return ok ? std::optional<T>{num} : std::optional<T> {};
}

[[nodiscard]] auto getStr(const std::string& prmpt, bool noblank = true)
{
    constexpr char term[] {": "};
    std::string str;

    while ((std::cout << prmpt << term) && (!std::getline(std::cin, str) || (noblank && str[0] < ' '))) {
        std::cout << "Invalid input" << std::endl;
        std::cin.clear();
    }

    return str;
}

template<typename T = int>
[[nodiscard]] auto getNum(const std::string& prmpt)
{
    static_assert(std::is_arithmetic_v<T>);

    decltype(stonum<T>("")) optval;

    do {
        optval = stonum<T>(getStr(prmpt, true));
    } while (!optval && (std::cout << "Bad input" << std::endl));

    return *optval;
}

template<typename T = int>
[[nodiscard]] auto getNum(const std::string& prmpt, T nmin, T nmax)
{
    static_assert(std::is_arithmetic_v<T>);

    if ((nmin == std::numeric_limits<T>::lowest()) && (nmax == std::numeric_limits<T>::max()))
        return getNum<T>(prmpt);

    const auto defs = [nmin, nmax]() {
        std::ostringstream os;

        os << " (";

        if ((nmin != std::numeric_limits<T>::lowest()) || std::is_unsigned<T>::value)
            os << nmin;

        os << " - ";

        if (nmax != std::numeric_limits<T>::max())
            os << nmax;

        os << ")";

        return os.str();
    } ();

    T num {};
    const std::string pr {prmpt + defs};

    do {
        num = getNum<T>(pr);
    } while (((num < nmin) || (num > nmax)) && (std::cout << "Input out of range" << defs << std::endl));

    return num;
}

[[nodiscard]] auto getChar(const std::string& prmpt, int noblank = true)    // NOTE int not bool for overload resolution
{
    std::string str;
    bool bad {true};

    do {
        str = getStr(prmpt, noblank);
        if (bad = (noblank && str.size() != 1) || (!noblank && str.size() > 1); bad)
            std::cout << "Bad input" << std::endl;

    } while (bad);

    return str.empty() ? char(0) : str[0];
}

[[nodiscard]] auto getChar(const std::string& prmpt, char def)
{
    using namespace std::string_literals;

    const auto ispr = std::isprint(def);
    const auto ch = getChar(prmpt + (ispr ? " ["s + def + "]"s : ""s), !ispr);

    return ch ? ch : def;
}

[[nodiscard]] auto getChar(const std::string& prmpt, const std::string& val, char def = {}){
    if (val.empty())
        return getChar(prmpt, def);

    std::string vs {" ("};

    for (size_t i = 0; i < val.size(); vs += val[i++])
        if (i) vs += '/';

    vs += ')';

    char ch;

    do {
        ch = (char)std::toupper(getChar(prmpt + vs, def));
    } while ((val.find(ch) == std::string::npos) && (std::cout << "Input not a valid value" << vs << std::endl));

    return ch;
}


All the hard input work is done in keyinp.hpp. You probably won't understand it and your teacher will know you haven't written it - but it greatly simplifies the actual program!

For the given examples:

A

Number of adults served (1 - ): 80
Number of children served (0 - ): 6
Type of meal - (D)elux, (S)standard (D/S) [S]:
Room letter (A/B/C/D/E): c
Day of week number - Monday(1)..Sunday(7) (1 - 7): 2
Number of days elapsed since held (0 - 365): 8
Deposit (0 - ): 60

Amount payable is $1121.91


B

Number of adults served (1 - ): 15
Number of children served (0 - ): 0
Type of meal - (D)elux, (S)standard (D/S) [S]: d
Room letter (A/B/C/D/E): a
Day of week number - Monday(1)..Sunday(7) (1 - 7): 6
Number of days elapsed since held (0 - 365): 20
Deposit (0 - ): 50

Amount payable is $308.09


C

Number of adults served (1 - ): 2
Number of children served (0 - ): 30
Type of meal - (D)elux, (S)standard (D/S) [S]:
Room letter (A/B/C/D/E): d
Day of week number - Monday(1)..Sunday(7) (1 - 7): 7
Number of days elapsed since held (0 - 365): 0
Deposit (0 - ): 0

Amount payable is $387.56

Last edited on
closed account (oG8qGNh0)
Well then const, i understand , if, else, else if understand, well some i do understand.

thanks bro! don't worry from n ow on you won't hav e to do any work btw it was only 10 points
Last edited on
Enjoy your course. Have fun with programming.

As the code for keyinp.hpp is published here, it is public and not subject to any copyright restrictions or otherwise. Anyone is free to use/amend without any acknowledgements required.
closed account (oG8qGNh0)
umm seeplus. You did something wrong in both. It keeps giving me warning/error messages. For the first one

const auto AdServ = getNum("Number of adults served", 1, std::numeric_limits<int>::max());
const auto ChldServ = getNum("Number of children served", 0, std::numeric_limits<int>::max());
const auto type = getChar("Type of meal - (D)elux, (S)standard", "DS", 'S');
const auto room = getChar("Room letter", "ABCDE");
const auto day = getNum("Day of week number - Monday(1)..Sunday(7)", 1, 7);
const auto elapse = getNum("Number of days elapsed since held", 0, 365);
const auto deposit = getNum<double>("Deposit", 0,

getNum, getChar, "Deposit", <double>, "keyinp.hpp" are all underlined.
Last edited on
getNum is defined in keyinp.hpp which is included within the main code. The code for keyinp.hpp needs to be in the file keyinp.hpp located in the same folder as the other code.

What compiler/os are you using? You need to compile as C++17.

If you are having trouble with using #include files, comment out that line in the code and copy and paste the code from keyinp.hpp above in its place.

In case you have issues with multiple files, here's the complete program as one unit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <limits>
#include <iostream>
#include <iomanip>

//#include "keyinp.hpp"
#include <string>
#include <type_traits>
#include <algorithm>
#include <optional>
#include <iostream>
#include <sstream>
#include <cctype>
#include <charconv>
#include <limits>

template<typename T = int>
[[nodiscard]] auto stonum(const std::string& str)
{
	static_assert(std::is_arithmetic_v<T>);

	constexpr char white[] {" \n\r\t"};
	bool ok {false};
	T num {};

	if (const auto fl {str.find_last_not_of(white)}; fl != std::string::npos) {
		const auto end {str.data() + fl + 1};
		const auto first {str.data() + str.find_first_not_of(white)};

		ok = (end != first) && (std::from_chars(first, end, num).ptr == end);
	}

	return ok ? std::optional<T>{num} : std::optional<T> {};
}

[[nodiscard]] auto getStr(const std::string& prmpt, bool noblank = true)
{
	constexpr char term[] {": "};
	std::string str;

	while ((std::cout << prmpt << term) && (!std::getline(std::cin, str) || (noblank && str[0] < ' '))) {
		std::cout << "Invalid input" << std::endl;
		std::cin.clear();
	}

	return str;
}

template<typename T = int>
[[nodiscard]] auto getNum(const std::string& prmpt)
{
	static_assert(std::is_arithmetic_v<T>);

	decltype(stonum<T>("")) optval;

	do {
		optval = stonum<T>(getStr(prmpt, true));
	} while (!optval && (std::cout << "Bad input" << std::endl));

	return *optval;
}

template<typename T = int>
[[nodiscard]] auto getNum(const std::string& prmpt, T nmin, T nmax)
{
	static_assert(std::is_arithmetic_v<T>);

	if ((nmin == std::numeric_limits<T>::lowest()) && (nmax == std::numeric_limits<T>::max()))
		return getNum<T>(prmpt);

	const auto defs = [nmin, nmax]() {
		std::ostringstream os;

		os << " (";

		if ((nmin != std::numeric_limits<T>::lowest()) || std::is_unsigned<T>::value)
			os << nmin;

		os << " - ";

		if (nmax != std::numeric_limits<T>::max())
			os << nmax;

		os << ")";

		return os.str();
	} ();

	T num {};
	const std::string pr {prmpt + defs};

	do {
		num = getNum<T>(pr);
	} while (((num < nmin) || (num > nmax)) && (std::cout << "Input out of range" << defs << std::endl));

	return num;
}

[[nodiscard]] auto getChar(const std::string& prmpt, int noblank = true)    // NOTE int not bool for overload resolution
{
	std::string str;
	bool bad {true};

	do {
		str = getStr(prmpt, noblank);
		if (bad = (noblank && str.size() != 1) || (!noblank && str.size() > 1); bad)
			std::cout << "Bad input" << std::endl;

	} while (bad);

	return str.empty() ? char(0) : str[0];
}

[[nodiscard]] auto getChar(const std::string& prmpt, char def)
{
	using namespace std::string_literals;

	const auto ispr = std::isprint(def);
	const auto ch = getChar(prmpt + (ispr ? " ["s + def + "]"s : ""s), !ispr);

	return ch ? ch : def;
}

[[nodiscard]] auto getChar(const std::string& prmpt, const std::string& val, char def = {}) {
	if (val.empty())
		return getChar(prmpt, def);

	std::string vs {" ("};

	for (size_t i = 0; i < val.size(); vs += val[i++])
		if (i) vs += '/';

	vs += ')';

	char ch;

	do {
		ch = (char)std::toupper(getChar(prmpt + vs, def));
	} while ((val.find(ch) == std::string::npos) && (std::cout << "Input not a valid value" << vs << std::endl));

	return ch;
}


int main()
{
	char name[] = "user.txt";

	constexpr auto delux {15.80};										// Delux meal
	constexpr auto standard {11.75};									// Standard meal
	constexpr auto child {60};											// Child discount percent
	constexpr auto chdelux {delux * child / 100.0};						// Child delux meal
	constexpr auto chstand {standard * child / 100.0};					// Child standard meal
	constexpr auto tiptax {18};											// Tip & tax percent. Applies food only
	constexpr auto surcharge {7};										// Surcharge percent for total bill if Friday, Saturday, Sunday
	constexpr auto prompt {10};											// Days for discount
	constexpr auto maxdisc {5};											// Maximum discount allowed
	constexpr auto surday {4};											// First week day surcharge applied
	constexpr auto discday {10};										// Discount within days

	constexpr double roomrate[5] {55.0, 75.0, 85.0, 100.0, 130.0};				// Room rates
	constexpr double discount[][2] {{100.0, 0.5}, {400.0, 3.0}, {800.0, 4.0}};	// Discount rates

	const auto AdServ = getNum("Number of adults served", 1, std::numeric_limits<int>::max());
	const auto ChldServ = getNum("Number of children served", 0, std::numeric_limits<int>::max());
	const auto type = getChar("Type of meal - (D)elux, (S)standard", "DS", 'S');
	const auto room = getChar("Room letter", "ABCDE");
	const auto day = getNum("Day of week number - Monday(1)..Sunday(7)", 1, 7);
	const auto elapse = getNum("Number of days elapsed since held", 0, 365);
	const auto deposit = getNum<double>("Deposit", 0, std::numeric_limits<double>::max());

	const auto mealcost = (type == 'D') * (delux * AdServ + chdelux * ChldServ) + (type == 'S') * (standard * AdServ + chstand * ChldServ);
	auto total = roomrate[room - 'A'] + mealcost * (1.0 + tiptax / 100.0);

	if (day > surday)
		total += total * surcharge / 100.0;

	if (elapse < discday) {
		bool apply {false};

		for (const auto& d : discount)
			if (total < d[0]) {
				total -= total * d[1] / 100;
				apply = true;
				break;
			}

		if (apply == false)
			total -= total * maxdisc / 100.0;
	}

	total -= deposit;

	std::cout << std::fixed << std::setprecision(2) << "Amount payable is $" << total << std::endl;
}


This compiles OK with MS VS2019.
closed account (oG8qGNh0)
I am using repl.it software
closed account (oG8qGNh0)
this program won't work in repl.it. How would you change the program to make it work in repl.it?
OK. you're using an on-line compiler. repl.it uses clang - and clang isn't fully C++17 compliant, especially regarding character conversion to double!. Ah.....

However, I've modified the program so that for doubles it does the conversion a different way (specialising stonum for double that uses strtod() rather than from_chars() ). This compiles and runs with repl.it OK as I've tried it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#include <limits>
#include <iostream>
#include <iomanip>

//#include "keyinp.hpp"
#include <string>
#include <type_traits>
#include <algorithm>
#include <optional>
#include <sstream>
#include <cctype>
#include <charconv>
#include <cstdlib>

template<typename T = int>
[[nodiscard]] auto stonum(const std::string& str)
{
	static_assert(std::is_arithmetic_v<T>);

	constexpr char white[] {" \n\r\t"};
	bool ok {false};
	T num {};

	if (const auto fl {str.find_last_not_of(white)}; fl != std::string::npos) {
		const auto end {str.data() + fl + 1};
		const auto first {str.data() + str.find_first_not_of(white)};

		ok = (end != first) && (std::from_chars(first, end, num).ptr == end);
	}

	return ok ? std::optional<T>{num} : std::optional<T> {};
}

template<>
[[nodiscard]] auto stonum<double>(const std::string& str)
{
    constexpr char white[] {" \n\r\t"};
    bool ok {false};
    double num {};

    if (const auto fl {str.find_last_not_of(white)}; fl != std::string::npos) {
        const auto end {str.data() + fl + 1};
        const auto first {str.data() + str.find_first_not_of(white)};

        if (end != first) {
            std::string snum(first, end);
            char* ech;

            num = strtod(snum.c_str(), &ech);
            ok = (*ech == 0);
        }
    }

    return ok ? std::optional<double>{num} : std::optional<double> {};
}

[[nodiscard]] auto getStr(const std::string& prmpt, bool noblank = true)
{
	constexpr char term[] {": "};
	std::string str;

	while ((std::cout << prmpt << term) && (!std::getline(std::cin, str) || (noblank && str[0] < ' '))) {
		std::cout << "Invalid input" << std::endl;
		std::cin.clear();
	}

	return str;
}

template<typename T = int>
[[nodiscard]] auto getNum(const std::string& prmpt)
{
	static_assert(std::is_arithmetic_v<T>);

	decltype(stonum<T>("")) optval;

	do {
		optval = stonum<T>(getStr(prmpt, true));
	} while (!optval && (std::cout << "Bad input" << std::endl));

	return *optval;
}

template<typename T = int>
[[nodiscard]] auto getNum(const std::string& prmpt, T nmin, T nmax)
{
	static_assert(std::is_arithmetic_v<T>);

	if ((nmin == std::numeric_limits<T>::lowest()) && (nmax == std::numeric_limits<T>::max()))
		return getNum<T>(prmpt);

	const auto defs = [nmin, nmax]() {
		std::ostringstream os;

		os << " (";

		if ((nmin != std::numeric_limits<T>::lowest()) || std::is_unsigned<T>::value)
			os << nmin;

		os << " - ";

		if (nmax != std::numeric_limits<T>::max())
			os << nmax;

		os << ")";

		return os.str();
	} ();

	T num {};
	const std::string pr {prmpt + defs};

	do {
		num = getNum<T>(pr);
	} while (((num < nmin) || (num > nmax)) && (std::cout << "Input out of range" << defs << std::endl));

	return num;
}

[[nodiscard]] auto getChar(const std::string& prmpt, int noblank = true)    // NOTE int not bool for overload resolution
{
	std::string str;
	bool bad {true};

	do {
		str = getStr(prmpt, noblank);
		if (bad = (noblank && str.size() != 1) || (!noblank && str.size() > 1); bad)
			std::cout << "Bad input" << std::endl;

	} while (bad);

	return str.empty() ? char(0) : str[0];
}

[[nodiscard]] auto getChar(const std::string& prmpt, char def)
{
	using namespace std::string_literals;

	const auto ispr = std::isprint(def);
	const auto ch = getChar(prmpt + (ispr ? " ["s + def + "]"s : ""s), !ispr);

	return ch ? ch : def;
}

[[nodiscard]] auto getChar(const std::string& prmpt, const std::string& val, char def = {}) {
	if (val.empty())
		return getChar(prmpt, def);

	std::string vs {" ("};

	for (size_t i = 0; i < val.size(); vs += val[i++])
		if (i) vs += '/';

	vs += ')';

	char ch;

	do {
		ch = (char)std::toupper(getChar(prmpt + vs, def));
	} while ((val.find(ch) == std::string::npos) && (std::cout << "Input not a valid value" << vs << std::endl));

	return ch;
}


int main()
{
	char name[] = "user.txt";

	constexpr auto delux {15.80};										// Delux meal
	constexpr auto standard {11.75};									// Standard meal
	constexpr auto child {60};											// Child discount percent
	constexpr auto chdelux {delux * child / 100.0};						// Child delux meal
	constexpr auto chstand {standard * child / 100.0};					// Child standard meal
	constexpr auto tiptax {18};											// Tip & tax percent. Applies food only
	constexpr auto surcharge {7};										// Surcharge percent for total bill if Friday, Saturday, Sunday
	constexpr auto prompt {10};											// Days for discount
	constexpr auto maxdisc {5};											// Maximum discount allowed
	constexpr auto surday {4};											// First week day surcharge applied
	constexpr auto discday {10};										// Discount within days

	constexpr double roomrate[5] {55.0, 75.0, 85.0, 100.0, 130.0};				// Room rates
	constexpr double discount[][2] {{100.0, 0.5}, {400.0, 3.0}, {800.0, 4.0}};	// Discount rates

	const auto AdServ = getNum("Number of adults served", 1, std::numeric_limits<int>::max());
	const auto ChldServ = getNum("Number of children served", 0, std::numeric_limits<int>::max());
	const auto type = getChar("Type of meal - (D)elux, (S)standard", "DS", 'S');
	const auto room = getChar("Room letter", "ABCDE");
	const auto day = getNum("Day of week number - Monday(1)..Sunday(7)", 1, 7);
	const auto elapse = getNum("Number of days elapsed since held", 0, 365);
	const auto deposit = getNum<double>("Deposit", 0, std::numeric_limits<double>::max());

	const auto mealcost = (type == 'D') * (delux * AdServ + chdelux * ChldServ) + (type == 'S') * (standard * AdServ + chstand * ChldServ);
	auto total = roomrate[room - 'A'] + mealcost * (1.0 + tiptax / 100.0);

	if (day > surday)
		total += total * surcharge / 100.0;

	if (elapse < discday) {
		bool apply {false};

		for (const auto& d : discount)
			if (total < d[0]) {
				total -= total * d[1] / 100;
				apply = true;
				break;
			}

		if (apply == false)
			total -= total * maxdisc / 100.0;
	}

	total -= deposit;

	std::cout << std::fixed << std::setprecision(2) << "Amount payable is $" << total << std::endl;
}


This is the repl.it link https://repl.it/repls/RelievedYummyLight#main.cpp
Last edited on
closed account (oG8qGNh0)
OH MY GOSH! THIS IS EXACTLY WHAT WE ARE LEARNING!! Thank You!! Boolean, Const auto, Double; it all makes sense now THANKS SO MUCH !!!!!
closed account (oG8qGNh0)
Number of adults served
Number of children served
Type of meal (Deluxe or Standard - everyone at the party eats the same type)
The room (A, B, C, D, or E - prices described below)
The day of the week the party was held on
The number of days since the party was held
The amount of a deposit (money they had already paid up-front towards their bill in order to reserve the space) - this amount should be deducted from the bill as the last part of the calculation


For so little why so much work????? I mean there's no way im done
The bulk of the code is for the functions to obtain the data and validate it. These are not simple functions - stonum(), getStr(), getNum(), getChar().

However, these functions will come in very handy for your future programs - as they are general keyboard input functions. When ever you need input from the keyboard, use the appropriate one of these and forget about input validation! Just copy all the code from the beginning down to int main() into your new program and code a new main(). See how these are used at lines 185 - 191 which obtain all the required data.

Once you look at the code of main(), its really quite simple - especially without input validation!

PS try entering 0 for number of adults, or 1.5 for children or F for room or F for day of week or -10 for deposit etc.

Last edited on
Once you look at the code of main(), its really quite simple - especially without input validation!

PS try entering 0 for number of adults, or 1.5 for children or F for room or F for day of week or -10 for deposit etc.


While those functions will possibly make future programming much easier they are probably an overkill for this beginning assignment that doesn't require much if any input validation.

From the first post:
Though it is not realistic, you may assume for this project that the user will input a valid option from the list (i.e. there will be no input mistakes).

I already had them written - hence the #include on the first version posted.....
Pages: 12