# Thread: Lowest Score Drop - reference parameter variable, values, etc.

1. ## Lowest Score Drop - reference parameter variable, values, etc.

Hey, everyone. I'm having a problem with a program and I'm hoping someone could help me out. The instructions are as follows:

Write a program that calculates the average of a group of test scores, where the lowest score in the group is dropped. It should use the following functions:

* void getScore() should as the user for a test score, store it in a reference parameter variable, and validate it. The function should be called by main once for each of the five test scores.
* void calcAverage() should calculate and display the average of the four highest scores. This function should be called just once by main, and should be passed the five test scores.
* int findLowest() should find and return the lowest of the five scores passed to it. It should be called by calcAverage, which uses the function to determin which of the five scores to drop.

Input validation: do not accept test scores lower than 0 or higher than 100.

My problem is as follows: after I get the scores in getScore() and pass them to calcAverage, they show up in e notation. I was wondering if my getScore() function is messed up, as I'm unsure about how to use the reference parameter. I've done the whole program myself - I just need help with that part to complete it. I would really appreciate any insight! (By the way, we are not at arrays yet so I would not know how to use them.)

Here is the code:

Code:
```#include <iostream>
using namespace std;

void intro();
void getScore(double&);
void calcAverage(double, double, double, double, double);
int findLowest(double, double, double, double, double);

int main()
{
double score1,
score2,
score3,
score4,
score5;

intro();
getScore(score1);
getScore(score2);
getScore(score3);
getScore(score4);
getScore(score5);
calcAverage(score1, score2, score3, score4, score5);

system("pause");
return 0;
}

void intro()
{
cout << "This program will take five test scores from the user and calculate\n";
cout << "their average after dropping the lowest score.\n\n";
}

void getScore(double &score)
{
static double tScore;
tScore++;

cout << "Please enter a test score. ";
cin >> tScore;

while (tScore < 0 || tScore > 100)
{
cout << "Valid test scores range from 0 - 100.\n";
cout << "Please enter a test score. ";
cin >> tScore;
}
}

void calcAverage(double grd1, double grd2, double grd3, double grd4, double grd5)
{
double lowest;
double sum;
double average;

cout << grd1;

lowest = findLowest(grd1, grd2, grd3, grd4, grd5);
sum = (grd1 + grd2 + grd3 + grd4 + grd5);
average = (sum - lowest);

cout << "The average of the four highest test scores is "<<
average << ".\n\n";
}

int findLowest(double tScore1, double tScore2, double tScore3, double tScore4, double tScore5)
{
double lowest = tScore1;

if (lowest > tScore2)
lowest = tScore2;
if (lowest > tScore3)
lowest = tScore3;
if (lowest > tScore4)
lowest = tScore4;
if (lowest > tScore5)
lowest = tScore5;
}```

2. Code:
```cout << "The average of the four highest test scores is "<<
fixed << average << ".\n\n";```
That fixes the e notation.

3. King Mir, thanks for responding. I made the edit you suggested, but when I run the program it displays "The average of the four highest test scores is " and crashes. Any ideas?

4. I accidentally had two << after the string. There should only be one. Though if you got that to compile, then that's not your problem.

No ideas, other than that you should make sure that the code you have matches what I posted.

5. There seems to be a number of issues in the code.

Code:
```void getScore(double &score)
{
static double tScore; // why do you need this variable at all?
tScore++; // why do you increment this value, when you're just overwriting it below

cout << "Please enter a test score. ";
cin >> tScore;

while (tScore < 0 || tScore > 100)
{
cout << "Valid test scores range from 0 - 100.\n";
cout << "Please enter a test score. ";
cin >> tScore;
}
}```
In this code your only modifying "tScore", but you should only be modifying "score". Remove "tScore" and read/validate "score" instead.

Code:
```int findLowest(double tScore1, double tScore2, double tScore3, double tScore4, double tScore5)
{
double lowest = tScore1;

if (lowest > tScore2)
lowest = tScore2;
if (lowest > tScore3)
lowest = tScore3;
if (lowest > tScore4)
lowest = tScore4;
if (lowest > tScore5)
lowest = tScore5;
}```
The function is declared to return a value, but your not returning anything. Since its declared to return "int", as your teacher told you, what he/she is expecting probably is for you to return the "index" of the score with lowest value. That is, if "score1" is the lowest, return "1", if "score2" is lowest, return 2. You cant return the value of the score ("return score1", etc) because its a float (a double) and the return value needs to be an "int". This is why I think the teacher wants you to return an "index". This suggests that you should use an array of 5 doubles, rather than 5 single doubles. This will make the program shorter (a lot less repeated code). For example, you would change this function to
Code:
```int findLowest(double scores[5])
{
double lowest = 100; // or 1.0, depending on what your entering)

int cnt;
for ( cnt = 0; cnt < 5; cnt++)
{
if ( lowest > scores[i] )
{
lowest = scores[i];
}
}

return cnt;
}```
So it returns the index of the score with lowest value. As you can see its already shorter. Since your using arrays, you should change "main" to create an array of 5 doubles, and use a for loop similar to this one, to call "getScore( scores[cnt] );" instead of writing the same 5 lines for the 5 different scores. Because of these changes, you must change the "calcAverage" function to accept an array similar to "findLowest", instead of 5 individual values (its still being passed the 5 elements, as the requirement states so this isnt a problem).

Now for the average function.
Code:
`     cout << grd1;`
Why are you doing this (above)? This isnt required.
Code:
```     sum = (grd1 + grd2 + grd3 + grd4 + grd5);
average = (sum - lowest);```
This is not what is being asked. You need to get the average of the scores, excluding the lowest score in the average. So if "findLowest" returns, say, 1, it means index 1 (the second score) is lowest, so the average would be
Code:
`(grd1+grd3+grd4+grd5)/4`
Of course since you (should) switch to using arrays, you would use a for loop the calculate this, so you dont have the variables "grd1", "grd2", etc., just "grd[cnt]". You can, again, use a for loop to iterate over the scores, but you skip the index returned by "findLowest".

If you used the logic you have above to calculate the average of the scores, say, 0, 1, 1, 1, 1, then your "average" would be 4 minus the lowest number, 0, which would be 4 which obviously isnt correct.

Hopefully this is clear... try it out and let us know if you have questions.

Thanks for taking the time to respond with such an in-depth post. Sorry about posting erroneous code - it had some things (the grd1) in it I was using to diagnose the problem with the e notation and I forgot to remove them before posting.

About your suggestions - they make things clearer for me, but we haven't reached arrays in my course so I don't think I can use that. I don't understand how I would rewrite the program in the ways you've suggested (for example, calcAverage). I'm sorry, I don't mean to be rude or troublesome, but is there a way I can write the program without the use of arrays?

7. No need to apologize, we're here to help!

You can definitely write the program with equivalent functionality with or without arrays, using the same idea I described above. However, without using arrays will require much more duplicated code and a less efficient program. The only benefit of writing this program is so that you will see how inefficient it actually is, once you cover and understand that topic. At that point, you will realize how useful and helpful arrays are.

If you cant use arrays, then all of your "main" seems to be fine and wont change. For starters, change the "findLowest" function the way I described above (of course without the array concept), but the idea is the same. Basically, you want the function to return the "index" of the score with lowest value. So if, say score2 has the lowest value, the function should return 2 (so that calcAverage knows to exclude score2 when making the calculation). This means that you need to keep track of two variables: the lowest (as you have) and the "index" of this lowest score. So a line like
Code:
```    if (lowest > tScore2)
lowest = tScore2;```
would become
Code:
```if (lowest > tScore2)
{
lowest = tScore2;
index = 2;
}```
of course after declaring "index". At the end of the function you return "index".

Then all thats left is "calcAverage". To calculate the average, you sum the 4 highest scores and divide by 4 (equivalent to "finding the average of the 5 scores with the lowest score dropped"). So you have to check what "findLowest" returned, and there will be 5 cases:
- if findLowest returns 1: average = (s2 + s3 + s4+ s5)/4
- if findLowest returns 2: average = // ... you can figure it out

Get started on that and let us know when a problem arises--dont forget to include the exact problem/error message and any updated code.

Okay, I can totally understand that. Thanks. I've done what you suggested, but somewhere along the way I made a mistake and I have two problems: 1.) findLowest always returns 2, and 2.) the scores in calcAverage are all zeroes. Grd1, grd2, etc. are not even consistent with s1, s2, etc.

Thanks for all your patience thus far. I'm actually a design major and am taking this course for fun, but lately I've found myself struggling with it.

Here's findLowest:
Code:
```int findLowest(double tScore1, double tScore2, double tScore3, double tScore4, double tScore5)
{
double lowest = 100;
int index;

if (lowest > tScore1)
{
lowest = tScore1;
index = 1;
}
else if (lowest > tScore2)
{
lowest = tScore2;
index = 2;
}
else if (lowest > tScore3)
{
lowest = tScore3;
index = 3;
}
else if (lowest > tScore4)
{
lowest = tScore4;
index = 4;
}
else if (lowest > tScore5)
{
lowest = tScore5;
index = 5;
}

return index;
}```
And calcAverage:
Code:
```void calcAverage(double grd1, double grd2, double grd3, double grd4, double grd5)
{
double s1, s2, s3, s4, s5;
double lowest, average;

lowest = findLowest(grd1, grd2, grd3, grd4, grd5);

cout << lowest << endl << endl; //for debugging

if (lowest = 1)
{
average = (s2 + s3 + s4+ s5)/4;
cout << "Four highest test scores: " << fixed << s2 << ", " << s3 << ", " << s4 << ", " << s5 << endl;
cout << "Average: " << fixed << average << endl;
}
else if (lowest = 2)
{
average = (s1 + s3 + s4+ s5)/4;
cout << "Four highest test scores: " << fixed << s1 << ", " << s3 << ", " << s4 << ", " << s5 << endl;
cout << "Average: " << fixed << average << endl;
}
else if (lowest = 3)
{
average = (s1 + s2 + s4+ s5)/4;
cout << "Four highest test scores: " << fixed << s1 << ", " << s2 << ", " << s4 << ", " << s5 << endl;
cout << "Average: " << fixed << average << endl;
}
else if (lowest = 4)
{
average = (s1 + s2 + s3+ s5)/4;
cout << "Four highest test scores: " << fixed << s1 << ", " << s2 << ", " << s3 << ", " << s5 << endl;
cout << "Average: " << fixed << average << endl;
}
else if (lowest = 5)
{
average = (s1 + s2 + s3+ s4)/4;
cout << "Four highest test scores: " << fixed << s1 << ", " << s2 << ", " << s3 << ", " << s4 << endl;
cout << "Average: " << fixed << average << endl;
}
}```

9. bleah. use a static array of 5 doubles and loop.

Code:
```int findLowest(double (&scores)[5])
{
unsigned int lowest =0;
for(int i=1;i<5;++i)
{
if(scores[i]<scores[lowest])
{
lowest=i;
}
}
return lowest;
}

void calcAverage(double (&scores)[5])
{
double average = 0;
for(unsigned int i=0;i<5;++i)
{
sum+=scores[i];
}
average-=scores[findLowest(scores)];
average/=4;
}```

repetitive code like you have above seldom works.

10. I understand that but we haven't gotten that far in my course.

11. bleah. use a static array of 5 doubles and loop.
I suggested that earlier, but apparently the requirement is to not use arrays (for whatever inefficient reason).

Now, in "findLowest" all of those should be "if" statements, not "if/else if/else" statements. For example, if the scores are 4, 5, 1, 1, 1, the function compares "100 > 4" and sets "lowest" to 4, with index 1, and it stops and returns this value. However, this only compared one of the 5 numbers, so its obviously not correct. You need to keep comparing the numbers after, so basically use all "if" statements. Also, I guess you can start with initializing lowest to the first score, and index to the first index. Then just compare scores 2, 3, 4, 5. This gets rid of one if statement (and actually removes a bug in the current logic--it may not be obvious, but there is one; if your interested I can describe it).

In the average function, all of the "if (lowest = 1)" lines should use "==" not "=". "=" will assign the value and its boolean condition is much different from comparing the values using "==" which is what you want.

Also you can pull the " cout << "Average: " << fixed << average << endl;" line outside the if/else blocks, as each time its the exact same code. So just put that statement once, after the last else if block (so its just there once, not 5 times). The other lines inside the if blocks are (very slightly) different, so they cannot be pulled out.

Code:
```     double s1, s2, s3, s4, s5;
//...
average = (s2 + s3 + s4+ s5)/4;```
That is, your never assigning s1-s5 values, but your using them anyway. You dont need any of the s# variables, your supposed to use the arguments that were passed to the function.

I've made the corrections you've pointed out. Now findLowest consistently returns 5. Also, the program compiles, but crashes when it's going to output the test scores. When I remove fixed it runs fine, but displays the scores in e notation.

The updated findLowest:
Code:
```int findLowest(double tScore1, double tScore2, double tScore3, double tScore4, double tScore5)
{
double lowest = tScore1;
int index = 1;

if (lowest > tScore2)
{
lowest = tScore2;
index = 2;
}
if (lowest > tScore3)
{
lowest = tScore3;
index = 3;
}
if (lowest > tScore4)
{
lowest = tScore4;
index = 4;
}
if (lowest > tScore5)
{
lowest = tScore5;
index = 5;
}

return index;
}```
The updated calcAverage (I had the output hidden while I was trying to determine what was causing the crash):
Code:
```void calcAverage(double grd1, double grd2, double grd3, double grd4, double grd5)
{
double lowest, average;

lowest = findLowest(grd1, grd2, grd3, grd4, grd5);

cout << lowest << endl << endl; //for debugging

if (lowest == 1)
{
average = (grd2 + grd3 + grd4+ grd5)/4;
//cout << "Four highest test scores: " << fixed << grd2 << ", " << grd3 << ", " << grd4 << ", " << grd5 << endl;
}
else if (lowest == 2)
{
average = (grd1 + grd3 + grd4+ grd5)/4;
//cout << "Four highest test scores: " << fixed << grd1 << ", " << grd3 << ", " << grd4 << ", " << grd5 << endl;
}
else if (lowest == 3)
{
average = (grd1 + grd2 + grd4+ grd5)/4;
//cout << "Four highest test scores: " << fixed << grd1 << ", " << grd2 << ", " << grd4 << ", " << grd5 << endl;
}
else if (lowest == 4)
{
average = (grd1 + grd2 + grd3+ grd5)/4;
//cout << "Four highest test scores: " << fixed << grd1 << ", " << grd2 << ", " << grd3 << ", " << grd5 << endl;
}
else if (lowest == 5)
{
average = (grd1 + grd2 + grd3+ grd4)/4;
//cout << "Four highest test scores: " << fixed << grd1 << ", " << grd2 << ", " << grd3 << ", " << grd4 << endl;
}

//cout << "Average: " << fixed << average << endl;
}```

13. I dont really see anything wrong with "findLowest" (though my brains kinda fried right now). In the average function, change the type of lowest to "int", as youll have problems with it being a double Im pretty sure.

Also post the "main" your using, and a sample Input/output run of the program so we can see your numbers.

14. Here's main:
Code:
```int main()
{
double score1,
score2,
score3,
score4,
score5;

intro();
getScore(score1);
getScore(score2);
getScore(score3);
getScore(score4);
getScore(score5);
calcAverage(score1, score2, score3, score4, score5);

system("pause");
return 0;
}```
And an example run:

This program will take five scores from the user and calculate
their average after dropping the lowest score.

Please enter a test score. 1
Please enter a test score. 0
Please enter a test score. 3
Please enter a test score. 5
Please enter a test score. 4

Four highest test scores: 6.25228e+263, 4.24399e-314, 1.09495e-311, 5.28394e-308

Average: 1.56307e+263

15. Did you change the type to int, as in my previous post? Also, do whatever was suggested above to make the output not in scientific notation.