I have my coding idea laid out, but I think there is an easier way, plus I can't really get it to work, because I don't know how to accommodate for duplicated values.

Here is my data:

Enter name of file
students

StudentID    LastName    FirstName   Q1     Q2     Q3     Mid    Q4      Q5     Q6     Final    Avg.    Grade
--------------------------------------------------------------------------------------------
45256        Rodrigues   Joana       58     75     58     61     59      75     63      92      6969
37915        Wright      Michelle    98     83     56     62     63      90     57      67      7070
81984        Williams    Jenny       55     67     54     63     89      84     93      75      7575
73984        Phaneuf     Lesley      78     85     57     51     68      94     51      83      6969
80886        Laflamme    Nicole      76     51     71     94     69      78     87      91      8080
39473        Kenyon      Patricia    65     54     90     68     94      70     95      97      8282
Press any key to continue . . .

but, as you can see my avg is doubled somehow, and I would actually like it to be a double so that I can have that decimal point....here is my code

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

void CalculateAvg (ifstream& students, string studentid[60], string fname[60], string lname[60],
					int Q1[60], int Q2[60], int Q3[60], int MidTerm[60], int Q4[60], 
					int Q5[60], int Q6[60], int Final[60], int i);

void main()
{
	ifstream students;
	ofstream out;

	string fname[60];
	string studentid[60];
	string lname[60];
	string id[60];
	int Q1[60];
	int Q2[60];
	int Q3[60];
	int MidTerm[60];
	int Q4[60];
	int Q5[60];
	int Q6[60];
	int Final[60];

	string file;

	int i;

	cout << "Enter name of file" << endl;
	cin >> file; file += ".txt";

	students.open(file.c_str());
	if(students)
	{
		out.open("CompleteReport.txt");
		out << "Student Grade Report:" << endl;
		cout << fixed << setprecision(1);
		out << fixed << setprecision(1);
		cout << endl 
			<< "StudentID    LastName    FirstName   Q1     Q2     Q3     Mid    Q4      Q5     Q6     Final    Avg.    Grade" 
			<< endl;
		cout << "--------------------------------------------------------------------------------------------"
			<<endl;
		out << "StudentID    LastName    FirstName   Q1     Q2     Q3     Mid    Q4      Q5     Q6     Final    Avg.    Grade" 
			<< endl;
		out << "--------------------------------------------------------------------------------------------"
			<<endl;

		for (i = 0; i < 6; ++i )
		{
			if ( students >> studentid[i] >> fname[i] >> lname[i] >> Q1[i] >> Q2[i] >> Q3[i] >> MidTerm[i] 
					>> Q4[i] >> Q5[i] >> Q6[i] >> Final[i])
			{
				cout << left << setw(13) << studentid[i] << setw(12) << fname[i] << setw(12) << lname[i] << setw(7)
					<< Q1[i] << setw(7) << Q2[i] << setw(7) << Q3[i] << setw(7) << MidTerm[i] << setw(8)
					<< Q4[i] << setw(7) << Q5[i] << setw(8) << Q6[i] << setw(8) << Final[i]; 
					CalculateAvg (students, id, fname, lname, Q1, Q2, Q3, MidTerm, Q4, Q5, Q6, Final, i);
				out << left << setw(13) << studentid[i] << setw(12) << fname[i] << setw(8) << lname[i] << setw(7)
					<< Q1[i] << setw(7) << Q2[i] << setw(7) << Q3[i] << setw(7) << MidTerm[i] << setw(8)
					<< Q4[i] << setw(7) << Q5[i] << setw(8) << Q6[i] << setw(8) << Final[i]; 
					CalculateAvg (students, id, fname, lname, Q1, Q2, Q3, MidTerm, Q4, Q5, Q6, Final, i);

				cout << endl;
			}
			else
			{
				break;
			}
		}
		students.close();
	}
}

//double CalculateAvg (ifstream& students, string studentid[60], string fname[60], string lname[60], 
//					 int Q1[60], int Q2[60], int Q3[60], int MidTerm[60], int Q4[60], int Q5[60], 
//					 int Q6[60], int Final[60],int i)
//{
//    return ((Q1[i] + Q2[i] + Q3[i] + (MidTerm[i]*2) + Q4[i] + Q5[i] + Q6[i] + Final[i]) / 8);
//}


void CalculateAvg (ifstream& students, string studentid[60], string fname[60], string lname[60], 
					 int Q1[60], int Q2[60], int Q3[60], int MidTerm[60], int Q4[60], int Q5[60], 
					 int Q6[60], int Final[60],int i)
{	
	if ((Q1[i] < Q2[i] && Q3[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i]) &&
		(Q1[i] != Q2[i] && Q3[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i]))
		cout << (Q2[i] + Q3[i] + MidTerm[i] + Q4[i] + Q5[i] + Q6[i] + Final[i]) / 7;
	else if (Q2[i] < Q1[i] && Q3[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i])
		cout << (Q1[i] + Q3[i] + MidTerm[i] + Q4[i] + Q5[i] + Q6[i] + Final[i]) / 7;
	else if (Q3[i] < Q1[i] && Q2[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i])
		cout << (Q2[i] + Q3[i] + MidTerm[i] + Q4[i] + Q5[i] + Q6[i] + Final[i]) / 7;
	else if (Q4[i] < Q2[i] && Q3[i] && MidTerm[i] && Q1[i] && Q5[i] && Q6[i] && Final[i])
		cout << (Q2[i] + Q3[i] + MidTerm[i] + Q4[i] + Q5[i] + Q6[i] + Final[i]) / 7;
	else if (Q5[i] < Q2[i] && Q3[i] && MidTerm[i] && Q4[i] && Q1[i] && Q6[i] && Final[i])
		cout << (Q2[i] + Q3[i] + MidTerm[i] + Q4[i] + Q1[i] + Q6[i] + Final[i]) / 7;
}

//CalculateAvg (students, id, fname, lname, Q1, Q2, Q3, MidTerm, Q4, Q5, Q6, Final, i)

How can I fix this....and possibly make the function a little easier to follow?

Recommended Answers

All 15 Replies

Ouch. First off your code is not very readable. In fact there are statements
in your code that you probably think is doing something else than it does.

I think we need to take this step by step, for your sake and for my eyes.

So what is your main goal? You can't just dump some code and expect
us to know precisely what you want, you know?

Ouch. First off your code is not very readable. In fact there are statements
in your code that you probably think is doing something else than it does.

I think we need to take this step by step, for your sake and for my eyes.

So what is your main goal? You can't just dump some code and expect
us to know precisely what you want, you know?

My code is readable if you plug it into a compiler of some sort, but it isn't readable within the confines of the forum for some reason. I'm trying to follow the following guidline, in order to come up with the average:

"The grading scheme is as follows: On [sic] the six quizzes, one lowest grade is droppped and one highest grade is doubled. Midterm counts as two quizzes, and the Final counts as three. Eas student is assumed to have taken both the MidTerm and the Final. The average numeric grade is computed based on these assumptions".


The code that I have included above, was my attempt to weed out the lowest grade for the student, and then just add all other scores and divide by seven, just to ensure that I could produce an output within the array.

My code is readable if you plug it into a compiler of some sort, but it isn't readable within the confines of the forum for some reason. I'm trying to follow the following guidline, in order to come up with the average:

"The grading scheme is as follows: On [sic] the six quizzes, one lowest grade is droppped and one highest grade is doubled. Midterm counts as two quizzes, and the Final counts as three. Eas student is assumed to have taken both the MidTerm and the Final. The average numeric grade is computed based on these assumptions".


The code that I have included above, was my attempt to weed out the lowest grade for the student, and then just add all other scores and divide by seven, just to ensure that I could produce an output within the array.

I'm also trying to figure out why my average comes out as a double copy of the number...any ideas?

Within your block

for (i = 0; i < 6; ++i )
{
          if ( students >> studentid[i] >> fname[i] >> lname[i] >> Q1[i] >> Q2[i] >> Q3[i] >> MidTerm[i] >> Q4[i] >> Q5[i] >> Q6[i] >> Final[i])

you have cout << all your stuff
CalculateAverage() //prints out one average (no line break or spaces)
out << all your stuff //sends to file silently
CalculateAverage() //prints out the second avg

So bring back your average function that returns a double, tack that on the end of your << chain (for both cout and out, e.g cout << var1<<var2<< Final<<CalculateAverage()<<endl;) and you'll have your average once and getting sent to the right spots.

My code is readable if you plug it into a compiler of some sort, but it isn't readable within the confines of the forum for some reason.

If this happens, copy and paste to notepad (or another plain text), save the notepad file, and copy and paste from there.

Sorry to triple post

if ((Q1[i] < Q2[i] && Q3[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i]) &&
(Q1[i] != Q2[i] && Q3[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i]))

is one of those statements to which firstPerson was referring -- it needs to be if ((Q1[i] < Q2[i] && Q1[i]<Q3[i] && Q1[i] <MidTerm[i] && ....) && etc.

Sorry to triple post

if ((Q1[i] < Q2[i] && Q3[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i]) &&
(Q1[i] != Q2[i] && Q3[i] && MidTerm[i] && Q4[i] && Q5[i] && Q6[i] && Final[i]))

is one of those statements to which firstPerson was referring -- it needs to be if ((Q1[i] < Q2[i] && Q1[i]<Q3[i] && Q1[i] <MidTerm[i] && ....) && etc.

oh ok! So set Q1 (and other tests) against all other values in the array....but, what would the code be to drop the lowest score, if there are two of the same scores in the array. For example, there are two 58's on quizzes for the first student....How would I drop one, but still add the other into the total?

A couple days ago I worked on a similar problem in another language.

If it is within the current scope of your class and/or personal knowledge set, the solution for my problem was to create a multi-dimensional (2-dimensional, specifically) array rather than an array for each individual quiz/exam. The first dimension would be used similar to a studentId number, but the values would be zero (0) through studentCount-1 (in your example case, 6-1 = 5). The second dimension would be the particular student's quiz scores. My problem didn't have the double/triple value situation though, I'm afraid I'll need a little time to chew on that situation. You'll still need additional parallel arrays for the actual student ID and names though.

Another benefit is that if you put all of a particular student's scores into one array (or array dimension), you can sort them to make the subsequent operations easier. With them in one location and properly sorted, you don't need to use all those gigantic (but impressive) relational statements you currently are.

Within your block

for (i = 0; i < 6; ++i )
{
          if ( students >> studentid[i] >> fname[i] >> lname[i] >> Q1[i] >> Q2[i] >> Q3[i] >> MidTerm[i] >> Q4[i] >> Q5[i] >> Q6[i] >> Final[i])

you have cout << all your stuff
CalculateAverage() //prints out one average (no line break or spaces)
out << all your stuff //sends to file silently
CalculateAverage() //prints out the second avg

So bring back your average function that returns a double, tack that on the end of your << chain (for both cout and out, e.g cout << var1<<var2<< Final<<CalculateAverage()<<endl;) and you'll have your average once and getting sent to the right spots.

How would I accomodate the rules for the average though (i.e. dropping the lowest, doubling the midterm, etc.) when returning only ONE value.... inputting it the original funciton is good, but it doesn't take into account all those changes.

Then use your existing void function definition, change the return type of the function to double and instead of cout, return the value that you get for the average.

(not that you want to overhaul everything but in another post user "fbody" was recommending putting all the scores for one student in one array (or as one row of a 2D array) -- my take would be that way you could find the lowest member and its index, zero that one out and divide by 7 instead of 8)

Then use your existing void function definition, change the return type of the function to double and instead of cout, return the value that you get for the average.

(not that you want to overhaul everything but in another post user "fbody" was recommending putting all the scores for one student in one array (or as one row of a 2D array) -- my take would be that way you could find the lowest member and its index, zero that one out and divide by 7 instead of 8)

If I change it to double though, how I do I have that many returns?

if
 return X;
elseif
  return Y;
elseif
  return Z;

only one will be called -- actually you should probably have an else on that chain also)

start quote:

if
 return X;
elseif
  return Y;
elseif
  return Z;

only one will be called -- actually you should probably have an else on that chain also)

Would it make sense, then, to do something like this:

double CalculateAvg(...)
{
double average;

if (Q1[i] < Q2[i]
 average = .....;
else if (Q2[i] < Q3[i]
average = .....;


return average;
}

Or are you saying that I would have a function like this:

double CalculateAvg(...)
{
     double average1, average 2, average3, average4, average5, average 6;

     average1 = Q1[i] + Q2[i].......;
     average2 = Q2[i]+ Q3[i].....;

     if (Q1[i] < Q2[i].....)
      return average1;
     if (Q2[i] < Q3[i].....)
     return average2;
}

Thanks for all your help, jonsca, but it worked using the second method that I listed above...thanks to you!

double CalculateAvg(...)
{
      if (Q1[i] < Q2[i]
          return((Q2[i]+Q3[i]+...)/7);
     else if (Q2[i] < Q3[i]
          return ((Q1[i]+Q3[i]+...)/7);
     else
          return (something else indicative of an error);   -- just covering against the "all code paths do not return a value" 
}

or you could write it with the intermediate variable average like you did

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.