Need help with a grade processor assignment using arrays..

Pages: 1234
closed account (48T7M4Gy)
void getNumberOfScores(int &userNum);


Nope! This is not right and shows you need to come to grips with understanding how functions and passing parameters works. In this case you whole project, nearly, is all about passing parameters by reference.

See the tutorial http://www.cplusplus.com/doc/tutorial/functions/

in main you should have something like:
1
2
3
4
int no_of_scores = 0;
    
    getNumberOfScores(no_of_scores);
    cout << "No. of scores: " << no_of_scores << '\n';


And that means:
1. setup a variable named no_of_scores in main
2. send it to a function (by reference)
3. get a revised value for it
4. return to main and use the revised value
kemort,

So I need to define some more variables in main and put those in the different functions that I have? Like layering almost?

The only problem I am trying to understand is that why do I need a second cout statement, if in my getNumberOfScores function, I already have a cout statement..doesnt make sense to me..
closed account (48T7M4Gy)
You don't need a cout statement in generateScores, unless you are testing. The variables in main you need to pass to this function as parameters are called scores and no_of_variables by me. You send them off to the function, the function processes them, and the program returns to main.

displayScores does exactly what it says so why repeat it - by duplicating it you are wasting time and besides it means you could have errors - do it once is best. This function is void, it doesn't return anything so no new variables in main are required.

getNumberOfScores with a cout is not necessarily good programming but that's what you boss wants in that particular case so just do it that way and the other way for these last two. In this case I created a variable named no_of_scores in main.

Keep moving - times pressing on! :)

Hmm..so I'm assuming that every void function needs parameters? Do int functions as etc need new parameters too? Calling functions is just the function name right?

I'm assuming i need some sort of do while loop in my main, because i need to print off a termination message..is this correct?
closed account (48T7M4Gy)
I'd suggest you read up the tutorial I showed you and get the code sample I gave you working and understood. An hour or two on that will be time well spent.

You don't need a while loop necessarily or at all in this project, but you do need loops and while loops will work. For loops are there to be used too.

The parameters functions and return values are all in the hints you are given.
@Dmtg93 this http://www.cplusplus.com/forum/beginner/218769/2/#msg1009051 shows you how to call the functions and get them to operate

To chew it for you, it would mean you do it like this

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
const int MIN_VAL = 2;
const int MAX_VAL = 100;

// you might find this piece useful
void generateScores(int scoreList[], int numOfScores);

int main() {
	srand(time(0));

	cout << "Welcome to the Grade Processor Application " << endl;
	cout << "This app will generate the number of scores desired by the user" << endl;
	cout << "and then perform and display several functions on this data"<< endl;

    int userNum = 0;
	void getNumberOfScores(userNum);
    cout << "\Number of scores : " << userNum << endl << endl;
    
    int * list = new int[userNum];  // dynamically allocate memory for the list
    
	//int generateOneScore(); // this is inside generateScores so it has no use here
	
	void generateScores(list, userNum);
	
	void displayScores(list, userNum);
	
	delete []list; // free allocated memory

return 0;
}

// You might find this useful
void generateScores(int scoreList[], int numOfScores)
{
	std::default_random_engine generator(time(0));
	std::uniform_int_distribution<int> random(MIN_VAL, MAX_VAL);

	for (int i = 0; i < numOfScores; i++)
	{
		scoreList[i] = random(generator);
	}
}
Last edited on
Hello Dmtg93,

In your code which is the last message on page two for me http://www.cplusplus.com/forum/beginner/218769/2/#msg1009064 The code for "generateScores" is correct now.

"main" needs some work. lines 9 - 12 are function proto types that are best put above "int main()". These are not function calls. See kemort's message with the link to read about functions. It should not take you very long to read through it.

In "main" line 2 is correct and where it should be. Lines 4 - 6 are OK here. For me I put these lines in the "displayScores" function. Either place works. When I started working on this program I set up my "main" this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
	int n{ 0 };
	int list[100]{ 0};

	srand(time(NULL));
	rand();  //<--- Used on a Windows computer. Helps generate better random number.

	getNumberOfScores(n);
	generateScores(list, n);

        return 0;
}


I started working on the "getNumberOfScores" function first and when that function was working the way I wanted I worked on the "generateScores" function followed by the "displayScores" function. The point is that I did not try to work on everything at once, but small pieces at a time.

When I was satisfied with the first two functions I put a comment on those two lines and changed the variables to this:

1
2
3
4
5
6
7
8
9
10
11
12
	int n{ 100 };
	int list[100]{
		62, 71, 64, 83, 60, 94, 83, 60, 74, 81,
		98, 70, 73, 25, 80, 84, 74, 74, 78, 75,
		48, 100, 92, 85, 72, 89, 86, 86, 89, 70,
		89, 75, 68, 79, 72, 96, 73, 73, 18, 73,
		67, 60, 88, 95, 93, 83, 14, 74, 95, 94,
		76, 89, 30, 78, 91, 78, 61, 32, 75, 77,
		76, 76, 68, 79, 28, 63, 66, 75, 11, 16,
		62, 84, 73, 91, 81, 71, 78, 64, 77, 72,
		73, 97, 68, 9, 86, 92, 68, 93, 64, 72,
		91, 77, 80, 74, 90, 18, 87, 71, 90, 90 };

The extra white space makes no difference to the compiler. It just makes it easier to read. This way as I worked on the other functions I had known values that the other functions should generate known values, so I would know if the function is working correctly.

This way I would proceed one function at a time until it was working correctly.

blongho's line 1 and 2 has merit. The only thing I would add to that isconst int MAXSIZE{ 100 };. This way you could define int list[MAXSIZE]{ 0 };. This way if you want to change the size of the array you only have to do it in one place and not have to hunt through the program where you define an array just to change the size. Not a problem here, but in the future it will be.

Hope that helps,

Andy
blongho,

thank you for your help. What do lines 18 and 26 mean as far as what they do in the code?

hi Andy,

Thank you. Right now I have generated whatever scores I ask it to so that's awesome. I am getting an error because I do not have c++11 so
1
2
 int n{ 0 };
	int list [100]{ 0};
is showing up as an error but it's still running fine so can I leave it?

I am working on displaying the average scores right now.
1
2
3
4
cout << "Average of all scores:  " << endl;
		calcAverage(list, userNum, drop1);
		cout << calcAverage<<endl;
		cout<<"\n";

My calc average function will always be true. EDIT2: My findLowest, and findHighest are also saying they will always be true. Also I need an else statement in here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
double calcAverage(int list[], int n, bool drop) {
	int sum = 0;
	for (int i = 0; i < n; i++) {
		sum += list[i];
	}
	if (drop) {
		sum -= findLowest(list, n);
		n--;
        else{
          sum+=list[i] //would this work? Im trying to make it say that if drop is false include all n scores
}
	}
	return static_cast<double>(sum) / n;
}


Thanks everyone for the help so far. I have everything I have written so far in // so I can work as I go like everyone is suggesting. I'm just really crunched for time and it's due before noon tomorrow so I am kinda stressing :/ Sorry for being slow at this..

EDIT: I changed my functions at the top before main so they look something like this:
1
2
3
4
5
6
7
8
9
10
11
int generateOneScore();
void getNumberOfScores(int&);
void generateScores(int [], int );
double calcAverage(int [], int , bool );
int findLowest(int [], int n);
int findHighest(int [], int n);
int countAboveAverage(int [], int , double);
void displayScores(int [], int n);
char findLetterGrade(double );
void displayHistogram(int [], int );
void displayDuplicateScores(int [], int );

Is this better?
Last edited on
Hello Dmtg93,

1
2
int n{ 0 };
int list [100]{ 0};


If this is a problem because of your compiler just use:

1
2
int n = 0;
int list [100];

and to initialize the list array:

1
2
for(int lc = 0; lc < 100; lc++)
    list[lc] = 0;


You could use the array without initializing it, but it is always good practice to initialize variables when they are defined.

In the second bit of code:
Line 1 is OK.
Line 2 will return a value, but you do not store it in anything.
Line 3 is half correct. If you finish the function call the function it will return the average that the cout can print.

The proto types that you have put above main should work fine. I believe they are all correct.

Now for your "calcAverage" function. I do nor grasp what you mean by "My calc average function will always be true." What part will always be true? And why do you think so.

The "calcAverage" functiois correct up to lines 9 and 10. First they are not needed and second the variable "i" has no value outside of the scope of the for loop. So if this does not give you a compiler problem it would at least give you a run time error.

Hope that helps,

Andy

Edit: In blongho's program line 18 will create storage for the list array while the program runs. You may not be up to this yet. Line 26 will delete the storage that line 18 created. The point of using "new" and "delete" is good programming practice and something you should remember for the future.
Last edited on
Dmtg93,
We cannot use pointers on this assignment! Do not use the asterisk reference next to list! Not trying to butt in here, but it won't be accepted as we haven't covered pointers in class yet. I'm still stuck on feeding the scores into generateScores function without pointers, but just wanted to give you a heads up.
Hello Dmtg93,

I was going to explain for (char lco = 'A', ss = 0; lco < 'G'; lco++, ss++), but decided that since you are short on time I would do this another time.

Here is a work around that works:

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
void DisplayHistogram(int aGrades[], int numOfGrades)
{
	int aCounters[5];
	int ss = 0;  // <--- Moved from the outer for loop.

        for (int lc = 0; lc < 5; lc++)
            aCounters[lc] = 0;

	std::cout << std::endl;
	std::cout << "\n\n   Displaying histogram for " << numOfGrades << " scores:" << std::endl;

	// This for loop will add to the "aCounters" array.
	for (int lc = 0; lc < numOfGrades; lc++)
	{
		if (aGrades[lc] <= 100 && aGrades[lc] >= 90) aCounters[0]++;
		// Other code here.
	}

	// for loops to print the letters and *s.
	for (char lco = 'A'; lco < 'G'; lco++)
	{
		std::cout << std::setw(3) << " " << lco << ": ";

		for (int lci = 0; lci < aCounters[ss]; lci++)
		{
			std::cout << '*';
		}

		if (lco == 'D') lco++;  // <--- Add 1 to lco to skip "D".
		std::cout << std::endl;

		ss++;  // <--- Moved from the outer forloop.
	}
	std::cout << std::endl;
}

I have tested this and it works.

Hope that helps,

Andy
Last edited on
Hello airek,

If you are still having problems start your own question/thread and I chn help you from there.

Andy
Andy,
Yes, I wasn't looking for help here, just advising dmtg93 against this method. Thank you for your offer, however. I'm trying to pull myself through as much as possible before turning to the experts! Maybe you'll hear from me later as the assignment is due tomorrow :)
closed account (48T7M4Gy)
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
void displayHistogram( int list[], int n )
{
    string letter{"ABCDEF"};
    int group[5]{0};
    char grade;
    
    for(int i = 0; i < n; ++i)
    {
        grade = findLetterGrade(list[i]);
        
        switch(grade)
        {
            case 'A':
                ++group[0];
                break;
            case 'B':
                ++group[1];
                break;
            case 'C':
                ++group[2];
                break;
            case 'D':
                ++group[3];
                break;
            case 'F':
                ++group[4];
                break;
            default:
                cout << "Error in histogram processing\n";
                break;
        }
    }
    
    string histogram = "";
    for (int i = 0; i < 5; ++i)
    {
        histogram.assign(group[i], '*');
        cout << letter[i] << ": " << histogram << '\n';
    }
    
    cout << '\n';
}
closed account (48T7M4Gy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
char findLetterGrade(double grade)
{
    char letter_grade;
    
    if(grade >= MIN_A)
        letter_grade = 'A';
    else if(grade >= MIN_B)
        letter_grade = 'B';
    else if(grade >= MIN_C)
        letter_grade = 'C';
    else if(grade >= MIN_D)
        letter_grade = 'D';
    else
        letter_grade = 'F';
    
    return letter_grade;
}
Hi Andy,

Line 2 will return a value, but you do not store it in anything.

What does this mean? Will it make a difference if I change it to just drop or do i need another variable name? So change the function and recall it and it should work?

What part will always be true? And why do you think so.


Well from what I understand there's an if statement and not an else, I think there needs to be an else statement that includes all n scores in the array if drop is false and there isn't one. Just not sure how to write that part. Later on in the program I need to calculate the average when drop is true(so without the lowest score)

When I run the program I get this error warning: the address of 'double calcAverage(int*, int, bool)' will always evaluate as 'true' That's why I think I need an else statement.. or something.

EDIT: I am getting this error
1
2
 error: invalid types 'int[int]' for array subscript
   if (aGrades[lc] <= 100 && aGrades[lc] >= 90) aCounters[0]++;
for the histogram

Also thank you for being a lifesaver for the histogram. I really appreciate it. Our teacher is basically non existent so every time I try and message her for help its either like 3 days later or very vague and not that helpful.

Airek,
No idea you were in my class! Small world. Hi! I don't know why this assignment is giving me such a hard time but man i'm nervous for the next one when we have assignment 4 and the final due on the same day *sigh*..

kemort,

Thank you for your version of the histogram. We haven't gotten to strings yet, but that actually looks easy to understand!

Last edited on
closed account (48T7M4Gy)
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
void displayHistogram( int list[], int n )
{
   // string letter{"ABCDEF"};
    
    char letter[]{'A','B','C','D','E','F'}; // <--
    int group[5]{0};
    char grade;
    
    for(int i = 0; i < n; ++i)
    {
        grade = findLetterGrade(list[i]);
        
        switch(grade)
        {
            case 'A':
                ++group[0];
                break;
            case 'B':
                ++group[1];
                break;
            case 'C':
                ++group[2];
                break;
            case 'D':
                ++group[3];
                break;
            case 'F':
                ++group[4];
                break;
            default:
                cout << "Error in histogram processing\n";
                break;
        }
    }
    
    string histogram = "";
    for (int i = 0; i < 5; ++i)
    {
        histogram.assign(group[i], '*');
        cout << letter[i] << ": " << histogram << '\n';
    }
    
    cout << '\n';
}
kemort,
There is still a string variable at the bottom line 36. Also what does line 39 mean?
closed account (48T7M4Gy)
line 39

assign is a string function that assembles the requisite number of asterisks instead of the (equally likeable) for loop to do the same. Bad luck that u can't use it. maybe there is an equivalent with <cstring> but it's probably getting too complicated to pursue that at this late stage so maybe give that aspect a miss.
closed account (48T7M4Gy)
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
void displayHistogram( int list[], int n )
{
   // string letter{"ABCDEF"};
    
    char letter[]{'A','B','C','D','E','F'};
    int group[5]{0};
    char grade;
    
    for(int i = 0; i < n; ++i)
    {
        grade = findLetterGrade(list[i]);
        
        switch(grade)
        {
            case 'A':
                ++group[0];
                break;
            case 'B':
                ++group[1];
                break;
            case 'C':
                ++group[2];
                break;
            case 'D':
                ++group[3];
                break;
            case 'F':
                ++group[4];
                break;
            default:
                cout << "Error in histogram processing\n";
                break;
        }
    }
    
    //string histogram = "";
    for (int i = 0; i < 5; ++i)
    {
        //histogram.assign(group[i], '*');
        cout << letter[i] << ": " ; // << histogram << '\n';
        for(int j = 0; j < group[i]; ++j)
            cout << '*';
        cout << '\n';
    }
    
    cout << '\n';
}
Pages: 1234