Output problem

I am writing a program that takes exam and homework scores, and returns a median of those homework scores. I cannot get the output to display the median score correctly. I am new to C++ and have been working on this for some time now. Any help would be much appreciated.

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
#include <iostream>
#include <vector>
#include <cstdio>
#include <iomanip>
#include <algorithm>

using namespace std;

//Declaring Constants
const int ZERO = 0;
const int ONE_HUNDRED = 100;

int main()
{
	int firstExam, secondExam, thirdExam;
	int error;
	vector<int> scores;
	double median = 0.00;

	cout << "Dr. DoLittle's Grading Program ..... (by Kirk Kelley)" << endl;
	do
	{
		error = 0;
		cout << "Please enter in the score for the first exam: ";
		cin >> firstExam;
		if (firstExam < 0 || firstExam > 100)
		{
			cout << "Please enter a valid score between 0 and 100" << endl;
			cin >> firstExam;
			cin.clear();
		}
	} while (error);
	do
	{
		error = 0;
		cout << "Please enter in the score for the second exam: ";
		cin >> secondExam;
		if (secondExam < 0 || secondExam > 100)
		{
			cout << "Please enter a valid score between 0 and 100" << endl;
			cin >> secondExam;
			cin.clear();
		}
	} while (error);
	do
	{
		error = 0;
		cout << "Please enter in the score for the third exam: ";
		cin >> thirdExam;
		if (thirdExam < 0 || thirdExam > 100)
		{
			cout << "Please enter a valid score between 0 and 100" << endl;
			cin >> thirdExam;
			cin.clear();
		}
	} while (error);

	//declaring variable
	int homework;

	//initiating loop
	while (!cin.eof())
	{

		homework = EOF;

		cout << "\nEnter score for homework assignment (press Ctrl+Z to quit): ";

		cin >> homework;

		if (!cin.good())
			if (homework == EOF)
				break;
			else
			{
				cout << "\nInvalid Input. Entry must be an integer." << endl;
				cin.clear();
				cin.ignore(std::numeric_limits<streamsize> ::max(), '\n');
			}
		else
		{
			if (homework >= ZERO && homework <= ONE_HUNDRED)
			{
				scores.push_back(homework);
			}
			else
			{
				cout << "\nInvalid Input. Grade must be between 0-100." << endl;
				cin.clear();
				cin.ignore(std::numeric_limits<streamsize> ::max(), '\n');
			}
		}
	}
	for (unsigned int i = 0; i < scores.size(); i++)
		{
			cout << "Scores: " << scores[i] << '\n';
		}
	
	double findMedian(vector<int> & scores, int size);
	{
		double median = 0.00;
		size_t size = scores.size();
		nth_element(scores.begin(), scores.begin() + 5, scores.end());
		if (size % 2 == 0)
		{
			median = (scores[size / 2 - 1] + scores[size / 2]) / 2;
		}
		else
		{
			median = scores[size / 2 - 1];
		}
		return median;
	}
	cout << fixed << setprecision(2);
	cout << "Median: " << median << endl;
	cout << "First exam score: " << firstExam << endl;
	cout << "Second exam score: " << secondExam << endl;
	cout << "Third exam score: " << thirdExam << endl;
	system("Pause");
	return 0;
}
First, it looks like you're intending to define a function called findMedian() at lines 99 through 113 but you've actually created legal syntax that does something different! This code declares a function findMedian() and then it has a block of code that is still in function main() and that gets executed once. that block of code defines a NEW variable called median at line 101. This is DIFFERENT from the one defined at line 18. It computes a value for median (incorrectly). At line 113, the block of code ends and the new median variable is destroyed. At line 115 you print the original median variable that was defined at line 18. It's value is still zero.

It looks like you don't quite understand how nth element works. See the details here:
http://www.cplusplus.com/reference/algorithm/nth_element/
I think you want to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
double median = 0.00;
size_t mid = scores.size()/2;

if (scores.size()==0) return 0.0;   // change this to whatever it should be

// Make scores[mid] the mid'th element
nth_element(scores.begin(), scores.begin()+mid, scores.end());
if (size % 2 == 0) {
	// size is even.  Need to average of scores[mid] and scores[mid-1]
	nth_element(scores.begin(), scores.begin()+mid-1, scores.end());
	median = (scores[mid] + scores[mid-1]) / 2;
} else {
	median = scores[mid];
}


Now wrap that in a function. Put this before line 13. Note that you don't need to pass in the size. Also not that there is no semicolon at the end of the first line.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double findMedian(vector<int> &scores)
{
	size_t mid = scores.size()/2;

	if (scores.size()==0) return 0.0;   // change this to whatever it should be

	// Make scores[mid] the mid'th element
	nth_element(scores.begin(), scores.begin()+mid, scores.end());
	if (size % 2 == 0) {
		// size is even.  Need to average of scores[mid] and scores[mid-1]
		nth_element(scores.begin(), scores.begin()+mid-1, scores.end());
		median = (scores[mid] + scores[mid-1]) / 2;
	} else {
		median = scores[mid];
	}
}


Finally replace lines 99-113 with a call to your function:
median = findMedian(scores);
Lines 99-113 probably don't do what you think they do. Line 99 declares a function called findMedian() but doesn't define it. In other words, it just says "somewhere in the program is a function called findMedian(). Since the function is never called this causes no error.

Lines 101-113 are still part of function main. Those lines run and then at line 112 you return from main(). So none of the output occurs.

The code in lines 102-111 doesn't compute the median quite right. It looks to me like you don't quite understand how nth_element works. Check the reference here: http://www.cplusplus.com/reference/algorithm/nth_element/

To fix all this, replace lines 99-113 with this:
1
2
3
4
5
6
7
8
9
size_t mid = scores.size() / 2;   // get the mid point

// Get the midpoint element
nth_element(scores.begin(), scores.begin() + mid, scores.end());
median = scores[mid];
if (scores.size() % 2 == 0) {
	nth_element(scores.begin(), scores.begin() + mid-1, scores.end());
	median = (median + scores[mid-1]) / 2.0;
}


Note that you can't do this when the size is even:
1
2
3
nth_element(scores.begin(), scores.begin() + mid, scores.end());
nth_element(scores.begin(), scores.begin() + mid-1, scores.end());
median = (scores[mid] + scores[mid-1]) / 2.0;

The reason is that n_element can rearrange all of the other elements. So second call might move the element at scores[mid] that you so carefully put there.

Okay thank you for the help understanding it a little better, I took into account your first block of help and it is giving me the correct median with even numbers but with the odd numbers it is not. Here is what I have so far.

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
#include <iostream>
#include <vector>
#include <cstdio>
#include <iomanip>
#include <algorithm>

using namespace std;

//Declaring Constants
const int ZERO = 0;
const int ONE_HUNDRED = 100;
double median = 0.00;
vector<int> scores;
size_t mid = scores.size() / 2;
int size;


double findMedian(vector<int> &scores)
{
	size_t mid = scores.size() / 2;

	if (scores.size() == 0) 
		return 0.0;   
	// change this to whatever it should be
	// Make scores[mid] the mid'th element
	nth_element(scores.begin(), scores.begin() + mid, scores.end());
	if (size % 2 == 0) 
	{
		// size is even.  Need to average of scores[mid] and scores[mid-1]
		nth_element(scores.begin(), scores.begin() + mid - 1, scores.end());
		median = (scores[mid] + scores[mid - 1]) / 2;
	}
	else {
		median = scores[mid];
	}
}

int main()
{
	int firstExam, secondExam, thirdExam;
	int error;

	cout << "Dr. DoLittle's Grading Program ..... (by Kirk Kelley)" << endl;
	do
	{
		error = 0;
		cout << "Please enter in the score for the first exam: ";
		cin >> firstExam;
		if (firstExam < 0 || firstExam > 100)
		{
			cout << "Please enter a valid score between 0 and 100" << endl;
			cin >> firstExam;
			cin.clear();
		}
	} while (error);
	do
	{
		error = 0;
		cout << "Please enter in the score for the second exam: ";
		cin >> secondExam;
		if (secondExam < 0 || secondExam > 100)
		{
			cout << "Please enter a valid score between 0 and 100" << endl;
			cin >> secondExam;
			cin.clear();
		}
	} while (error);
	do
	{
		error = 0;
		cout << "Please enter in the score for the third exam: ";
		cin >> thirdExam;
		if (thirdExam < 0 || thirdExam > 100)
		{
			cout << "Please enter a valid score between 0 and 100" << endl;
			cin >> thirdExam;
			cin.clear();
		}
	} while (error);

	//declaring variable
	int homework;

	//initiating loop
	while (!cin.eof())
	{

		homework = EOF;

		cout << "\nEnter score for homework assignment (press Ctrl+Z to quit): ";

		cin >> homework;

		if (!cin.good())
			if (homework == EOF)
				break;
			else
			{
				cout << "\nInvalid Input. Entry must be an integer." << endl;
				cin.clear();
				cin.ignore(std::numeric_limits<streamsize> ::max(), '\n');
			}
		else
		{
			if (homework >= ZERO && homework <= ONE_HUNDRED)
			{
				scores.push_back(homework);
			}
			else
			{
				cout << "\nInvalid Input. Grade must be between 0-100." << endl;
				cin.clear();
				cin.ignore(std::numeric_limits<streamsize> ::max(), '\n');
			}
		}
	}
	for (unsigned int i = 0; i < scores.size(); i++)
		{
			cout << "Scores: " << scores[i] << '\n';
		}
	double median = 0.00;
	size_t mid = scores.size() / 2;

	if (scores.size() == 0) 
		return 0.0;   
	// change this to whatever it should be
	// Make scores[mid] the mid'th element
	nth_element(scores.begin(), scores.begin() + mid, scores.end());
	if (size % 2 == 0) 
	{
		// size is even.  Need to average of scores[mid] and scores[mid-1]
		nth_element(scores.begin(), scores.begin() + mid - 1, scores.end());
		median = (scores[mid] + scores[mid - 1]) / 2;
	}
	else {
		median = scores[mid];
	}
	cout << fixed << setprecision(2);
	cout << "Median: " << median << endl;
	cout << "First exam score: " << firstExam << endl;
	cout << "Second exam score: " << secondExam << endl;
	cout << "Third exam score: " << thirdExam << endl;
	system("Pause");
	return 0;
}
read my second post. It explains exactly why that code doesn't work. Sorry for the confusion. I thought the first post didn't go through.
I see my fault, thank you for your help!
Topic archived. No new replies allowed.