-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathw8p2.c
More file actions
376 lines (301 loc) · 8.84 KB
/
w8p2.c
File metadata and controls
376 lines (301 loc) · 8.84 KB
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
/*
*****************************************************************************
Workshop - #8 (P2)
Full Name : MD ARAFAT KOYES
Student ID#: XXXXXX
Email : XXXX@MYSENECA.CA
Section : XXX
Authenticity Declaration:
I declare this submission is the result of my own work and has not been
shared with any other student or 3rd party content provider. This submitted
piece of work is entirely of my own creation.
*****************************************************************************
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// User Libraries
#include "w8p2.h"
// Receives an integer by address and prompts the user to enter a positive integer.
// Validates the entered integer and repeats the process until a valid input is received.
int getIntPositive(int* int_ptr) {
int input;
int flag = 1;
do {
scanf("%d", &input);
if (input <= 0)
{
printf("ERROR: Enter a positive value: ");
}
else
{
flag = 0;
}
} while (flag);
if (int_ptr != NULL)
{
*int_ptr = input;
}
return input;
}
// Works similarly to 'getIntPositive' but receives and validates a positive double number.
double getDoublePositive(double* double_ptr) {
double input;
int flag = 1;
do {
scanf("%lf", &input);
if (input <= 0)
{
printf("ERROR: Enter a positive value: ");
}
else
{
flag = 0;
}
} while (flag);
if (double_ptr != NULL)
{
*double_ptr = input;
}
return input;
}
// 3. Opening Message
void openingMessage(const int seq_number) {
printf("Cat Food Cost Analysis\n");
printf("======================\n");
printf("\n");
printf("Enter the details for %d dry food bags of product data for analysis.\n", MAX_PRODUCTS);
printf("NOTE: A 'serving' is %dg\n", GRAMS_NUMBER);
printf("\n");
}
// 4. Get user input for the details of cat food product
struct CatFoodInfo getCatFoodInfo(const int seq_number) {
struct CatFoodInfo cfi;
int flag;
printf("Cat Food Product #%d\n", seq_number + 1);
printf("--------------------\n");
flag = 1;
// SKU
printf("SKU : ");
flag = 1;
do {
scanf("%d", &cfi.skuNumber);
if (cfi.skuNumber <= 0)
{
printf("ERROR: Enter a positive value: ");
}
else
{
flag = 0;
}
} while (flag);
// Price
printf("PRICE : $");
flag = 1;
do {
scanf("%lf", &cfi.productPrice);
if (cfi.productPrice <= 0)
{
printf("ERROR: Enter a positive value: ");
}
else
{
flag = 0; // flag
}
} while (flag);
// Weight
printf("WEIGHT (LBS) : ");
flag = 1;
do {
scanf("%lf", &cfi.productWeight);
if (cfi.productWeight <= 0)
{
printf("ERROR: Enter a positive value: ");
}
else
{
flag = 0;
}
} while (flag);
// Calories
printf("CALORIES/SERV.: ");
flag = 1;
do {
scanf("%d", &cfi.calories);
if (cfi.calories <= 0)
{
printf("ERROR: Enter a positive value: ");
}
else
{
flag = 0;
}
} while (flag);
printf("\n");
// Returning the Struct
return cfi;
}
void displayCatFoodHeader(void)
{
printf("SKU $Price Bag-lbs Cal/Serv\n");
printf("------- ---------- ---------- --------\n");
}
// 6. Display a formatted record of cat food data
void displayCatFoodData(int sku_number, double* product_price, int calorie_per_serving, double* product_weight_lbs)
{
printf("%07d %10.2lf %10.1lf %8d\n", sku_number, *product_price, *product_weight_lbs, calorie_per_serving);
}
// 7. convert lbs: kg (divide by 2.20462)
double convertLbsKg(const double* pounds, double* conversionResultToKg) {
double poundsToKg = (*pounds) / POUNDSTOKG;
if (conversionResultToKg != NULL)
{
*conversionResultToKg = poundsToKg;
}
return poundsToKg;
}
// 8. convert lbs: g (call convertKG, then * 1000)
int convertLbsG(const double* pounds, int* conversionResultToG) {
int poundsToG = ((*pounds) / POUNDSTOKG) * 1000;
if (conversionResultToG != NULL)
{
*conversionResultToG = poundsToG;
}
return poundsToG;
}
// 9. Convert lbs: kg and g
void convertLbs(const double* pounds, double* conversionResultToKg, int* conversionResultToG) {
double poundsToKg = (*pounds) / POUNDSTOKG;
int poundsToG = ((*pounds) / POUNDSTOKG) * 1000;
if (conversionResultToG != NULL && conversionResultToKg != NULL)
{
*conversionResultToG = poundsToG;
*conversionResultToKg = poundsToKg;
}
}
// 10. calculate: servings based on gPerServ
double calculateServings(const int servingSizeGrams, const int totalGrams, double* numberOfServings) {
double servings = ((double)totalGrams) / servingSizeGrams;
if (numberOfServings != NULL)
{
*numberOfServings = servings;
}
return servings;
}
// 11. calculate: cost per serving
double calculateCostPerServing(const double* price, const double* numberOfServings, double* result) {
double costPerServing = (*price) / (*numberOfServings);
if (result != NULL)
{
*result = costPerServing;
}
return costPerServing;
}
// 12. calculate: cost per calorie
double calculateCostPerCal(const double* price, const double* totalCalories, double* result) {
double costPerCal = (*price) / (*totalCalories);
if (result != NULL)
{
*result = costPerCal;
}
return costPerCal;
}
// 13. Derive a reporting detail record based on the cat food product data
struct ReportData calculateReportData(struct CatFoodInfo cfi) {
struct ReportData rd;
// Assigning Values
rd.skuNumber = cfi.skuNumber;
rd.productPrice = cfi.productPrice;
rd.productWeightPounds = cfi.productWeight;
rd.calories = cfi.calories;
// Assigning calculated values
rd.productWeightKilos = convertLbsKg(&rd.productWeightPounds, &rd.productWeightKilos);
rd.productWeightGrams = convertLbsG(&rd.productWeightPounds, &rd.productWeightGrams);
rd.servings = calculateServings(GRAMS_NUMBER, rd.productWeightGrams, &rd.servings);
// Total calories
double totalCalories = rd.calories * rd.servings;
rd.costPerServing = calculateCostPerServing(&rd.productPrice, &rd.servings, &rd.costPerServing);
rd.costCaloriesPerServing = calculateCostPerCal(&rd.productPrice, &totalCalories, &rd.costCaloriesPerServing);
// Returning the struct
return rd;
}
// 14. Display the formatted table header for the analysis results
void displayReportHeader(void)
{
printf("Analysis Report (Note: Serving = %dg)\n", GRAMS_NUMBER);
printf("---------------\n");
printf("SKU $Price Bag-lbs Bag-kg Bag-g Cal/Serv Servings $/Serv $/Cal\n");
printf("------- ---------- ---------- ---------- --------- -------- -------- ------- -------\n");
}
// 16. Display the formatted data row in the analysis table
void displayReportData(const struct ReportData rd, const int cheapestProductCheck) {
printf("%07d %10.2lf %10.1lf %10.4lf %9d %8d %8.1lf %7.2lf %7.5lf", rd.skuNumber, rd.productPrice, rd.productWeightPounds, rd.productWeightKilos, rd.productWeightGrams, rd.calories, rd.servings, rd.costPerServing, rd.costCaloriesPerServing);
}
// 15. Display the findings (cheapest)
void displayFinalAnalysis(const struct CatFoodInfo cfi) {
printf("Final Analysis\n");
printf("--------------\n");
printf("Based on the comparison data, the PURRR-fect economical option is:\n");
printf("SKU:%07d Price: $%5.2lf\n", cfi.skuNumber, cfi.productPrice);
printf("\n");
// Ending line
printf("Happy shopping!\n");
printf("\n");
}
// ----------------------------------------------------------------------------
// 16. Logic entry point
void start(void)
{
// Struct Arrays
struct ReportData rd[MAX_PRODUCTS] = { {0} };
struct CatFoodInfo cfi[MAX_PRODUCTS] = { {0} };
// Declaring variables
int i, cheapestIndex = 0;
// Printing the opening message
openingMessage(MAX_PRODUCTS);
// Filling the cfi array
for (i = 0; i < MAX_PRODUCTS; i++) {
cfi[i] = getCatFoodInfo(i);
rd[i] = calculateReportData(cfi[i]);
}
// Dsiplaying cat food header
displayCatFoodHeader();
// Displaying cat food data
for (i = 0; i < MAX_PRODUCTS; i++) {
displayCatFoodData(cfi[i].skuNumber, &cfi[i].productPrice, cfi[i].calories, &cfi[i].productWeight);
}
// Determining the cheapest product's sku and price
double cheapestProductPrice = rd[0].costPerServing;
for (i = 0; i < MAX_PRODUCTS; i++)
{
if (rd[i].costPerServing <= cheapestProductPrice)
{
cheapestProductPrice = rd[i].costPerServing;
cheapestIndex = i;
}
}
printf("\n");
// Displaying the report header
displayReportHeader();
// Displaying the report data
for (i = 0; i < MAX_PRODUCTS; i++)
{
displayReportData(rd[i], cheapestIndex);
if (cheapestIndex == i)
{
printf(" ***\n");
}
else
{
printf("\n");
}
}
printf("\n");
// Displaying final analysis
for (i = 0; i < MAX_PRODUCTS; i++)
{
if (i == cheapestIndex)
{
displayFinalAnalysis(cfi[i]);
}
}
}