statistics and average rainfall data



Hi everyone I need help with the use of the Enumerated Data Type

• Using the Enumerated Data Type, shown below as an example, I need to make a program that will take the following average rainfall data in Oakland California, and determine the following statistics from it.

• my program should display the following results:

• The Total rainfall.

• The overall average monthly rainfall.

• The month when the rainfall is the Maximum for the year, as well as the amount.

• The month when the rainfall is the Minimum for the year, as well as the amount.

• I will need to expand the use of the enumerator data type in order to compute and display the Minimum and Maximum rainfall statistics.

I know I may need to make another function containing switch statements which returns the appropriate month rather than simply displaying it. But as a noon I don't know where to start with this

Average Monthly Rainfall Data for Oakland CA in inches

January 4.72

February 4.49

March 3.39

April 1.42

May 0.79

June 0.12

July 0.00

August 0.08

September 0.24

October 1.38

November 2.87

December 4.49


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
// This program demonstrates an enumerated data type.
#include <iomanip>
#include <iostream>
using namespace std;
enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY };
// Function prototype
 void displayDayName(Day);
int main()
{
const int NUM_DAYS = 5; // The number of days
 double sales[NUM_DAYS]; // To hold sales for each day
 double total = 0.0; //Accumulator
 Day workDay; // Loop counter

// Get the sales for each day.
for (workDay= MONDAY; workDay<= FRIDAY;
workDay= static_cast<Day>(workDay+ 1))
{
cout<< "Enter the sales for day ";
displayDayName(workDay);
cout<< ": ";
cin>> sales[workDay];
}
// Calculate the total sales
for (workDay= MONDAY; workDay<= FRIDAY;
workDay= static_cast<Day>(workDay+ 1))
total += sales[workDay];
// Display the total
cout<< "The total sales are $" << setprecision(2)
<< fixed << total << endl;
return 0;
}
//**********************************************************//
//Definition of the displayDayNamefunction *
// This function accepts an argument of the Day type and
// displays the corresponding name of the day. *//
//
**********************************************************
void displayDayName(Day d)
{
switch(d)
{
case MONDAY : cout<< "Monday";
break;
case TUESDAY : cout<< "Tuesday";
break;
case WEDNESDAY : cout<< "Wednesday";
break;
case THURSDAY : cout<< "Thursday";
break;
case FRIDAY : cout<< "Friday";
}
}
Enums are simple.
- it is a way to group constant integers.
- you can't print the text version of the integer any more than you can any other variable name, but for enums, you often want to. this is how you do it in a simpler way:


enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, MAXDAY }; //sometimes it is useful to add a bogus named max value to the end, or middle values, you can do some neat tricks with them...

vector<string> Daytxt = {"Monday", "Tuesday" ... //fill this on out};
...
cout << Daytxt[d]; //this works: enums are ints, and ints are array index, and your array is indexed to match... much easier to manage than that switch statement.

The same thing works for months.

this will get you the text of the day. You can do whatever with it, you don't have to cout?
or if you want the day itself, it IS the enum... if day == 0 then its monday.
are you asking something else?


honestly those instructions don't make sense, did your paraphrase your assignment or was your professor high at the time? There isnt any point to an enum in the question, and the last bullet is nonsense.
Last edited on
hahaha yeah his instructions don't make sense u can see it here https://gofile.io/d/3PC7ei
I have no idea what he means by extending the enum type.

So, you should just do the best you can with it.
I see that you have structs already.
I would just make a struct of an enum (a month, here) and a double (the rainfall for that month) and then make an array or vector of THOSE with your data in it.
then spew the answers... search the array for the largest one, print that month with what I said above, same for smallest, and so on.

I don't know that it does what the question is asking, but it should get you a partial grade worst case.

if your professor has talked about the enum class, its another story, but I don't think he wants that...
Last edited on
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
/**
 * @author blongho
 * @since 2020-12-03
 * @brief Attempt to solve  http://cplusplus.com/forum/beginner/274543/#msg1184949
 */
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <map>

/**
data.txt

January 4.72
February 4.49
March 3.39
April 1.42
May 0.79
June 0.12
July 0.00
August 0.08
September 0.24
October 1.38
November 2.87
December 4.49
*/
enum class Month {
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
};
static std::map<Month, std::string> monthMap = {
        {Month::JAN, "January"},
        {Month::FEB, "February"},
        {Month::MAR, "March"},
        {Month::APR, "April"},
        {Month::MAY, "May"},
        {Month::JUN, "June"},
        {Month::JUL, "July"},
        {Month::AUG, "August"},
        {Month::SEP, "September"},
        {Month::OCT, "October"},
        {Month::NOV, "November"},
        {Month::DEC, "December"},
};

struct MonthRainFall {
    Month month;
    double rainFall;

    MonthRainFall() = default;

    friend std::ostream &operator<<(std::ostream &os, const MonthRainFall &data) {
        os << monthMap[data.month] << " " << data.rainFall;
        return os;
    }

    friend std::istream &operator>>(std::istream &os, MonthRainFall &data) {
        std::string m;
        os >> m >> data.rainFall;
        const std::string sub(m.substr(0, 3));
        if (sub == "Jan") {
            data.month = Month::JAN;
        } else if (sub == "Feb") {
            data.month = Month::FEB;
        } else if (sub == "Mar") {
            data.month = Month::MAR;
        } else if (sub == "Apr") {
            data.month = Month::APR;
        } else if (sub == "May") {
            data.month = Month::MAY;
        } else if (sub == "Jun") {
            data.month = Month::JUN;
        } else if (sub == "Jul") {
            data.month = Month::JUL;
        } else if (sub == "Aug") {
            data.month = Month::AUG;
        } else if (sub == "Sep") {
            data.month = Month::SEP;
        } else if (sub == "Oct") {
            data.month = Month::OCT;
        } else if (sub == "Nov") {
            data.month = Month::NOV;
        } else if (sub == "Dec") {
            data.month = Month::DEC;
        }
        return os;
    }
};

/**
 * Read the data file
 * @return  a vector<MonthRainFall> with values or an empty vector if the file is not read
 */
std::vector<MonthRainFall> readData();

int main() {
    auto monthRainFalls = readData();

    if (monthRainFalls.empty()) {
        std::cerr << "No data has been read\n";
        EXIT_FAILURE; // end the program
    }

    // Test to see that the data has been read successfully
   /* for (const auto &d: monthRainFalls) {
        std::cout << d << std::endl;
    }
    */

    double sum = 0.0;
    MonthRainFall highest(monthRainFalls[0]);
    MonthRainFall lowest(monthRainFalls[0]);

    // Compute the sum, max and min here
    for (const auto &monthRainFall : monthRainFalls) {
        if (monthRainFall.rainFall > highest.rainFall) {
            highest = monthRainFall;
        }
        if (monthRainFall.rainFall < lowest.rainFall) {
            lowest = monthRainFall;
        }
        sum += monthRainFall.rainFall;
    }
    std::cout << "Sum of all rainFall is " << sum << std::endl;
    std::cout << "Average rainfall is " << sum / monthRainFalls.size() << std::endl;
    std::cout << "The month with the lowest rainfall is " << monthMap[lowest.month] << std::endl;
    std::cout << "The month with the highest rainfall is " << monthMap[highest.month] << std::endl;

    return 0;
}


std::vector<MonthRainFall> readData() {
    std::ifstream file("data.txt");
    std::vector<MonthRainFall> data;
    if (file) {
        std::string line;
        MonthRainFall tmp{};
        std::string month;
        while (std::getline(file, line)) {
            std::istringstream os(line);
            while (os >> tmp) { // this is possible if the std::ostream &operator<<() has been overloaded for the class
                data.push_back(tmp);
            }
        }
    } else {
        std::cerr << "Error reading data file\n";
    }
    return data;
}


Sum of all rainFall is 23.99
Average rainfall is 1.99917
The month with the lowest rainfall is July
The month with the highest rainfall is January
Last edited on
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
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
#include <iostream>
#include <fstream>
#include <sstream>
#include <unordered_map>
#include <limits>
#include <iomanip>

enum class Month:unsigned {JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC, BAD };

static_assert(static_cast<unsigned>(Month::BAD) == 13);

const std::unordered_map<Month, std::string> monthMap = {
		{Month::JAN, "January"},
		{Month::FEB, "February"},
		{Month::MAR, "March"},
		{Month::APR, "April"},
		{Month::MAY, "May"},
		{Month::JUN, "June"},
		{Month::JUL, "July"},
		{Month::AUG, "August"},
		{Month::SEP, "September"},
		{Month::OCT, "October"},
		{Month::NOV, "November"},
		{Month::DEC, "December"},
		{Month::BAD, "Unknown"}
};

struct MonthRainFall {
	Month month {};
	double rainFall {};
};

Month getMonth(std::string mon)
{
	if (const auto ret {std::find_if(monthMap.begin(), monthMap.end(), [&mon](auto m) {return m.second.substr(0, 3) == mon.substr(0, 3); })}; ret != monthMap.end())
		return ret->first;

	return Month::BAD;
}

std::string monName(Month m)
{
	if (const auto ret = monthMap.find(m); ret != monthMap.end())
		return ret->second;

	return "Unknown";
}

std::istream& operator>>(std::istream& is, MonthRainFall& mrf)
{
	std::string mon;

	mrf.month = (is >> mon >> mrf.rainFall) ? mrf.month = getMonth(mon) : Month::BAD;
	return is;
}

int main()
{
	std::ifstream monData("rainfall.txt");

	if (!monData.is_open())
		return (std::cout << "Cannot open data file\n"), 1;

	double sum {}, dataSize {};
	double low {std::numeric_limits<int>::max()}, high {std::numeric_limits<int>::min()};
	Month lmon {}, hmon {};

	for (MonthRainFall mrf; monData >> mrf; ++dataSize) {
		sum += mrf.rainFall;

		if (mrf.rainFall > high) {
			high = mrf.rainFall;
			hmon = mrf.month;
		}

		if (mrf.rainFall < low) {
			low = mrf.rainFall;
			lmon = mrf.month;
		}
	}

	std::cout << std::fixed << std::setprecision(2);
	std::cout << "Sum of all rainFall is " << sum << '\n';
	std::cout << "Average rainfall is " << sum / dataSize << '\n';
	std::cout << "The month with the lowest rainfall is " << monName(lmon) << '\n';
	std::cout << "The month with the highest rainfall is " << monName(hmon) << '\n';
}



Sum of all rainFall is 23.99
Average rainfall is 2.00
The month with the lowest rainfall is July
The month with the highest rainfall is January


There's no need to store the data. The required info can be obtained just by processing each red line.
Last edited on
yeah his instructions don't make sense

What exactly don't you understand?

Did you type in the example "starting" point program?

Do you understand how that program is working?

The instructions make sense to me. You are to use program 11-11 (that starts on page 8) as an example to do the assignment given on page 2.

• Using the Enumerated Data Type, shown in Program 11-11 as an example,
write a program that will take the following average rainfall data in
Oakland California
, and determine the following statistics from it.


• Your program should display the following results:

• The Total rainfall.

• The overall average monthly rainfall.

• The month when the rainfall is the Maximum for the year, as well as the amount.

• The month when the rainfall is the Minimum for the year, as well as the amount.


The first two bullets above are basically the same as the example program 11-11.

To do the last two bullets you need to take into account the "Hint:"

• Hint: You may need to create another function containing switch statements which
returns the appropriate month rather than simply displaying it.


So it looks like your going to need a function to return the name of the month using the current "Month number" (hint: enum).

To me the "Hint:" tells you what the instructor meant by "You will need to expand the use of the enumerator data type".

So your first step should be to type in the example program, run it to make sure you understand what is happening. You may wan to single step through the program watching the variables as you step to reinforce what the example should be showing you.


Don't overthink this. Modify the sample program
- change enum Day to enum Month
- change daily sales numbers to monthly rainfall numbers.
- modify the output as needed.

Don't use a std::map to map months to their names. An array will do just fine.
Definitely don't use an unordered map when the data is ordered and an array will work.
Here's what I mean. This is a simplistic translation of the sample program to the problem at hand. I literally started by doing a search/replace of Day -> Month and Work ->Rain.=, then made the other changes, which were obvious, by hand. Just add code to compute the average, min and max and you're done.
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
// This program demonstrates an enumerated data type.
#include <iomanip>
#include <iostream>
using namespace std;
enum Month{ January, February, March, April, May, June,
	    July, August, September, October, November, December };

// Function prototype
void displayMonthName(Month);

int
main()
{
    const int NUM_MONTHS = 12;	// The number of months
    double rainfall[NUM_MONTHS];	// To hold rainfall for each month
    double total = 0.0;		//Accumulator
    Month rainMonth;		// Loop counter

    // Get the rainfall for each month.
    for (rainMonth = January; rainMonth <= December; rainMonth = static_cast < Month > (rainMonth + 1)) {
	cout << "Enter the rainfall for month ";
	displayMonthName(rainMonth);
	cout << ": ";
	cin >> rainfall[rainMonth];
    }

    // Calculate the total sales
    for (rainMonth = January; rainMonth <= December; rainMonth = static_cast < Month > (rainMonth + 1))
	total += rainfall[rainMonth];

    // Display the total
    cout << "The total rainfall is" << setprecision(2)
	<< fixed << total << endl;
    return 0;
}

//**********************************************************//
// Definition of the displayMonthNamefunction *
// This function accepts an argument of the Month type and
// displays the corresponding name of the month. *//
//

void
displayMonthName(Month d)
{
    switch (d) {
    case January:
	cout << "January";
	break;
    case February:
	cout << "February";
	break;
    case March:
	cout << "March";
	break;
    case April:
	cout << "April";
	break;
    case May:
	cout << "May";
	break;
    case June:
	cout << "June";
	break;
    case July:
	cout << "July";
	break;
    case August:
	cout << "August";
	break;
    case September:
	cout << "September";
	break;
    case October:
	cout << "October";
	break;
    case November:
	cout << "November";
	break;
    case December:
	cout << "December";
	break;
    }
}

Topic archived. No new replies allowed.