Average output is wrong help!

Hey all, i have a program here where I take in 4 test scores and drop them. then the letter grade is based off the average. Average 1 and average 5 work fine but the other ones are not working because when i do the calculations the numbers are off.
//7.11-12
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
//loop counter not running properly
const int size = 3;
int lowest1, lowest2, lowest3, lowest4, lowest5, word;
int M, k, e, r, t, j, i, p;
double average1 = 0, average2 = 0, average3 = 0, average4 = 0, average5 = 0;
double Testscore1[3], Testscore2[3], Testscore3[3], Testscore4[3], Testscore5[3];
double total1 = 0, total2 = 0, total3 = 0, total4 = 0, total5 = 0;
char Lettergrade[4];
string studentname[70];
string name;
cout << "This program will allow you to enter student names, test scores and retrieve a letter grade from these entries\n";
for (int i = 0; i < 5; i++)
{
cout << "\nEnter student\t" << (i + 1) << "\tname\n";
getline(cin, name);
studentname[i] = name;
}
for (int j = 0; j < 4;j++)
{
cout << "\nEnter the letter grade for student 1 for test score\t" << (j + 1) << ".\t";
cin >> Testscore1[j];
cout << "\nEnter the letter grade for student 2 for test score\t" << (j + 1) << ".\t";
cin >> Testscore2[j];
cout << "\nEnter the letter grade for student 3 for test score\t" << (j + 1) << ".\t";
cin >> Testscore3[j];
cout << "\nEnter the letter grade for student 4 for test score\t" << (j + 1) << ".\t";
cin >> Testscore4[j];
cout << "\nEnter the letter grade for student 5 for test score.\t" << (j + 1) << "\t";
cin >> Testscore5[j];
}
// student 1
lowest1 = Testscore1[0];//switch total and lowest test score?
for (int k = 1; k < size;k++)
{
if ( Testscore1[k] < lowest1)
lowest1 = Testscore1[k];
}
for (int k = 0; k < 4;k++)
{
total1 += Testscore1[k];
average1 = (total1 - lowest1) / 3;
}
//student 2
lowest2 = Testscore2[0];
for (int e = 1;e < size; e++)
{
if ( Testscore2[e] < lowest2)
{
lowest2 = Testscore2[e];
}
}
for (int e = 0;e < size; e++)
{
total2 += Testscore2[e];
average2 = (total2 - lowest2) / 3;
}
//student 3
lowest3 = Testscore3[0];
for (int r = 1; r < size;r++)
{
if ( Testscore3[r] < lowest3)
{
lowest3 = Testscore3[r];
}
}
for (int r = 0; r < 4;r++)
{
total3 += Testscore3[r];
average3 = (total3 - lowest3) / 3;
}
//student 4
lowest4 = Testscore4[0];
for (int t = 1; t < size; t++)
{
if ( Testscore4[t] < lowest4)
{
lowest4 = Testscore4[t];
}
}
for (int t = 0; t < 4; t++)
{
total4 += Testscore4[t];
average4 = (total4 - lowest4) / 3;
}
//student 5
lowest5 = Testscore5[0];
for (int p = 1; p < size; p++)
{
if ( Testscore5[p] < lowest5)
{
lowest5 = Testscore5[p];
}
}
for (int p = 0; p < 4; p++)
{
total5 += Testscore5[p];
average5 = (total5 - lowest5) / 3;
}
cout << "\nStudent 1 average is " << average1 << ".";
cout << "\nStudent 2 average is " << average2 << ".";
cout << "\nStudent 3 average is " << average3 << ".";
cout << "\nStudent 4 average is " << average4 << ".";
cout << "\nStudent 5 average is " << average5 << ".";
//obtain letter grade for student 1
if (average1 < 59)
{
Lettergrade[0] = 'F';
}
else if ( average1 >= 60 && average1 <= 69)
{
Lettergrade[0] = 'D';
}
else if (average1 >= 70 && average1 <= 79)
{
Lettergrade[0] = 'C';
}
else if (average1 >= 80 && average1 <= 89)
{
Lettergrade[0] = 'B';
}
else if (average1 >= 90)
{
Lettergrade[0] = 'A';
}
//obtain letter grade for student 2
if (average2 < 59)
{
Lettergrade[1] = 'F';
}
else if ( average2 >= 60 && average2 <= 69)
{
Lettergrade[1] = 'D';
}
else if (average2 >= 70 && average2 <= 79)
{
Lettergrade[1] = 'C';
}
else if (average2 >= 80 && average2 <= 89)
{
Lettergrade[1] = 'B';
}
else if (average2 >= 90)
{
Lettergrade[1] = 'A';
}
//obtain letter grade for student 3
if (average3 < 59)
{
Lettergrade[2] = 'F';
}
else if ( average3 >= 60 && average3 <= 69)
{
Lettergrade[2] = 'D';
}
else if (average3 >= 70 && average3 <= 79)
{
Lettergrade[2] = 'C';
}
else if (average3 >= 80 && average3 <= 89)
{
Lettergrade[2] = 'B';
}
else if (average3 >= 90)
{
Lettergrade[2] = 'A';
}
//obtain letter grade for student 4
if (average4 < 59)
{
Lettergrade[3] = 'F';
}
else if ( average4 >= 60 && average4 <= 69)
{
Lettergrade[3] = 'D';
}
else if (average4 >= 70 && average4 <= 79)
{
Lettergrade[3] = 'C';
}
else if (average4 >= 80 && average4 <= 89)
{
Lettergrade[3] = 'B';
}
else if (average4 >= 90)
{
Lettergrade[3] = 'A';
}
//obtain letter grade for student 5
if (average5 < 59)
{
Lettergrade[4] = 'F';
}
else if ( average5 >= 60 && average5 <= 69)
{
Lettergrade[4] = 'D';
}
else if (average5 >= 70 && average5 <= 79)
{
Lettergrade[4] = 'C';
}
else if (average5 >= 80 && average5 <= 89)
{
Lettergrade[4] = 'B';
}
else if (average5 >= 90)
{
Lettergrade[4] = 'A';
}
for (int m = 0; m < 5;m++)
{
cout << "\nStudent\t" << (m + 1) << " " << studentname[m] << " has a letter grade of " << Lettergrade[m] << ".\n";
}
cin.ignore();
return 0;
}
Hey there. I haven't read the ENTIRE piece of code yet, but I wonder if in this snippet (representative of each student) is off a little:

// student 1
lowest1 = Testscore1[0];//switch total and lowest test score?
for (int k = 1; k < size;k++)
{
if ( Testscore1[k] < lowest1)
lowest1 = Testscore1[k];
}
for (int k = 0; k < 4;k++)
{
total1 += Testscore1[k];
average1 = (total1 - lowest1) / 3;
}


That is, you state lowest1 - Testscore1[0] which is fine, but in the for loop, your condition has it going from k = 1 to k < size, which means it will run when k = 1 and k = 2 only. That is only a total of 3 grades that are saved, right? But you want four. So size should be upped by one for this to work. I noticed at the top you even say "//loop counter not working properly", so did you know that already?

I also notice for the second student, the second for statement goes from 1 to size-1, whereas the second for statement in all the others goes from 1 to 4-1.

Basically what I would do in this case (don't know if you did this), is simply start with 1 case. Make sure that works, then duplicate it for the next case, test again. That is the only real way to do it if you are getting faulty results for what is supposed to be essentially the same thing over and over again. And use different test cases, of course.
Hey thanks for responding. I think you meant lowest = testscore1[0], i was doing this to set the array to 0 before searching it. And i fixed the count number and the run #.
Good point about doing "one" case at a time, at the moment this is what i have been trying to do.
// student 1
lowest1 = Testscore1[0];
lowest2 = Testscore2[0];
for (int k = 0; k < 4;k++)
{
if ( Testscore1[k] < lowest1)
lowest1 = Testscore1[k];
}
for (int k = 0; k < 4;k++)
{
total1 += Testscore1[k];
average1 = (total1 - lowest1) / 3;
}
cout << "\nStudent 1 average is " << average1 << ".";
//student 2
for (int e = 0; e < 4; e++)
{
if ( Testscore2[e] < lowest2)
lowest2 = Testscore2[e];
}
for (int e = 0;e < 4; e++)
{
total2 += Testscore2[e];
average2 = (total2 - lowest2) / 3;
}

My problem here is that student 1 is giving me wrong results, while student 2 case is giving me the right results. They look identical, I dont see where I went wrong.
I have been using the data with
Student 1: 65,69,67,1 = D
Student 2: 70 69, 70, 71 = C
Student 1 i keep getting a letter grade of 'F' when it should be 67% which equates to a letter grade of 'D'.

Another note: wheniever i take out student 2 and test for only 1 case, the result for student 1 is ALWAYS correct. not sure why this happens when i take out the case for student 2.
Last edited on
Before I respond, I want to start out by saying a good test here is to run the same data for each student and see if you come out with the correct results for both. e.g. use Student1 scores for both and then Student 2 scores for both.

Also, that doesn't set any array to 0. What it does is say that the lowest is defined as the first score - that way you don't have to include it in the for statement, although it really doesn't make much of a difference.

In any case, if your testing data that you posted is accurate, your scores for student 1 are:
65 69 67 1

The lowest grade should drop off, leaving 65, 69, and 67, added together and divided by 3 is 67. So, yep, we know the grade should be a D at 67.

Inspecting the code, you are calculating the average with each iteration.
You have:
for (int k = 0; k < 4;k++)
{
total1 += Testscore1[k];
average1 = (total1 - lowest1) / 3;
}


I'm sure you see what is going on here, but I will go ahead and run through the statements using the data given, reminder this is for student 1. (I am also sure total1 has been initialized to 0)

k = 0
total1 = 0 + 65 = 65
average1 = 65-1/3 = 64/3 = 21 1/3

k = 1
total1 = 65 + 69 = 134
average1 = (134 - 1) / 3 = 133/3 = 41 1/3

k = 2
total1 = 134 + 67 = 201
average1 = (201-1)/3 = 200/3 = 66 2/3

k = 3
total1 = 201 + 1 = 202
average1 = (202-1)/3 = 201/3 = 67

SO if all info is correct, you should be getting the correct answer. But you should take the averaging statement out of the for loop body for efficiency. Sorry I can't help more, but it all comes down to making sure typos are not present and so on. What is the grade you are getting back for student 1? Please share the entire program again so I can look at it deeper. Thanks. Also, if you would like me to post a solution snippet, I would be glad to.

EDIT: So another testing method you could try is to have something like:
cout << "lowest: " << lowest << endl;
or
cout << "total1: " << total1 << endl;

just after the calculation is made to make sure all your numbers are in order at each iteration (inside the loop).
Last edited on
There are 4 tests, but you've only allocated room for 3:
double Testscore1[3], Testscore2[3], Testscore3[3], Testscore4[3], Testscore5[3];
Thus you're getting junk for the 4th grade for each student.

Also when calculating the lowest, you're only checking 3 grades because size is 3:
1
2
3
4
5
6
lowest1 = Testscore1[0];//switch total and lowest test score?
for (int k = 1; k < size;k++)
{
if ( Testscore1[k] < lowest1)
lowest1 = Testscore1[k];
}


There are 5 students, but you've allocated room for only 4 letter grades:
char Lettergrade[4];

When it's working, it's purely by accident. In reality it doesn't work for any sudent.

You can greatly simplify this code by using functions. For example, here is one that drops the lowest score and computes the average, and another that converts a numeric grade to a letter grade:
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
// drop the lowest score and compute the average
double averageWithoutLowest(double testScores[], int numScores)
{
    double lowest = testScores[0];
    double total=0;
    for (int i=0; i<numScores; ++i) {
        total += testScores[i];
        if (testScores[i] < lowest) lowest = testScores[i];
    }
    return (total - lowest) / (numScores-1);
}

// Given a numeric grade, return the letter grade
char letterGrade(double numGrade)
{
    if (numGrade < 59) {
        return 'F';
    } else if (numGrade <= 69) {
        return 'D';
    } else if (numGrade <= 79) {
        return 'C';
    } else if (numGrade <= 89) {
        return 'B';
    } else {
        return 'A';
    }
}

With these, the computing part of the program becomes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Average scores
    average1 = averageWithoutLowest(Testscore1, 4);
    average2 = averageWithoutLowest(Testscore2, 4);
    average3 = averageWithoutLowest(Testscore3, 4);
    average4 = averageWithoutLowest(Testscore4, 4);
    average5 = averageWithoutLowest(Testscore5, 4);
    cout << "\nStudent 1 average is " << average1 << ".";
    cout << "\nStudent 2 average is " << average2 << ".";
    cout << "\nStudent 3 average is " << average3 << ".";
    cout << "\nStudent 4 average is " << average4 << ".";
    cout << "\nStudent 5 average is " << average5 << ".";

// Letter grades
    Lettergrade[0] = letterGrade(average1);
    Lettergrade[1] = letterGrade(average2);
    Lettergrade[2] = letterGrade(average3);
    Lettergrade[3] = letterGrade(average4);
    Lettergrade[4] = letterGrade(average5);


Have you learned about structures and/or classes yet? The code can be every shorter if you create a struct to represent a student and then make an array of these structures.
@ nickeeromo
I looked over the logic again and made sure everything was correct and is running now. I changed some of the logic flow and the program is running.

@dhayden
thanks for responding, when i first began the assignment I was thinking about using a function but I wanted to get the algorithm correct before I transfer it into a function form. And u are right, functions would make this program 50x more neat !

1) U said [3] is not enough for 4 students but i thought that the "0" element would count for a student thats why I did 3.

Im going to convert everything to a function form like u have shown above now that I got the main algorithm working properly.

Thanks again to every that responded, i apprecitate it a lot !!
Last edited on
U said [3] is not enough for 4 students but i thought that the "0" element would count for a student thats why I did 3.

A definition like double Testscore1[3] allocates an array of 3 elements. Legal indices are 0, 1, and 2. Put another way, "3" gives the size of the array, not the value of the largest index.
Topic archived. No new replies allowed.