Help with computeGPA function

We are currently working on step wise refinement in class. I created my psuedo code in the function computeGPA in gpa.cpp, but I am having trouble coding it. Anyone want to help out? Everything else is 100%, I just need to finish coding the computeGPA function. I don't understand Vectors at all, so anything would be helpful: Skeleton, is my psuedo code correct?, or just pointers in general. Thanks!

input would look like this:

6 6 18.0
A- 3
F 3
P 1
^Z

output should be:

Credits earned: 10
Attempted: 12
Grade Points: 29.10
Semester GPA: 1.85
Overall GPA: 2.43




Last edited on
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

//computeGPA.cpp

#include <iostream>
#include <sstream>
#include <iomanip>

#include "gpa.h"



/**
 * Driver for the GPA program.
 * Input is read from standard in and consists of student grade info.
 * This info begins with one line containing the student's credits earned,
 * graded credits attempted, and gradePoints so far.
 * This is followed by some number of lines (terminated by end of input)
 * each containing a grade code earned in some course this semester,
 * one or more blanks, then the number of credits for which the student
 * took that course.
 *
 * Output is written to standard out.
 *
 */

using namespace std;


void addGradeEntry (vector<std::string>& gradeCodes,
		    vector<bool>& affectsGPA,
		    vector<bool>& affectsCreditsEarned,
		    vector<double>& pointValues,
		    string gradeCode, bool affGPA,
		    bool affCredits, double pointVal)
{
  gradeCodes.push_back (gradeCode);
  affectsGPA.push_back (affGPA);
  affectsCreditsEarned.push_back (affCredits);
  pointValues.push_back (pointVal);
}

void initializeGradingScheme (vector<std::string>& gradeCodes,
			      vector<bool>& affectsGPA,
			      vector<bool>& affectsCreditsEarned,
			      vector<double>& pointValues)
{
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "A", true, true, 4.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "A-", true, true, 3.7);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "B+", true, true, 3.3);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "B", true, true, 3.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "B-", true, true, 2.7);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "C+", true, true, 2.3);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "C", true, true, 2.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "C-", true, true, 1.7);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "D+", true, true, 1.3);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "D", true, true, 1.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "D-", true, true, 0.7);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "F", true, false, 0.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "P", false, true, 0.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "F*", false, false, 0.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "I", false, false, 0.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "W", false, false, 0.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "WF", true, false, 0.0);
  addGradeEntry (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
		 "Z", false, false, 0.0);
}



void readSemesterGrades (istream& in,
			 vector<string>& gradeReported,
			 vector<int>& creditsRegisteredFor)
{
  string line;
  getline (in, line);
  while (!!in)
    {
      istringstream lineReader (line);
      string gradeCode;
      int credits;
      lineReader >> gradeCode >> credits;
      gradeReported.push_back (gradeCode);
      creditsRegisteredFor.push_back (credits);
      getline (in, line);
    }
}




void studentGradeSummary (istream& in)
{
  vector<std::string> gradeCodes;
  vector<bool> affectsGPA;
  vector<bool> affectsCreditsEarned;
  vector<double> pointValues;

  initializeGradingScheme(gradeCodes, affectsGPA,
			  affectsCreditsEarned, pointValues);

  int creditsEarned;
  int gradedCreditsAttempted;
  double gradePoints;
  in >> creditsEarned >> gradedCreditsAttempted >> gradePoints;
  string garbage;
  getline (in, garbage);

  vector<std::string> gradeReported;
  vector<int> creditsRegisteredFor;
  readSemesterGrades (in, gradeReported, creditsRegisteredFor);


  int newCreditsEarned = -1;
  int newGradedCreditsAttempted = -1;
  double newGradePoints = -1.0;
  double semesterGPA = -1.0;
  double overallGPA = -1.0;

  computeGPA  (gradeCodes, affectsGPA, affectsCreditsEarned, pointValues,
	       creditsEarned, gradedCreditsAttempted, gradePoints,
	       gradeReported, creditsRegisteredFor,
	       newCreditsEarned, newGradedCreditsAttempted, newGradePoints,
	       semesterGPA, overallGPA);

  cout << "Credits earned:\t" << newCreditsEarned
       << "\nAttempted:\t" << newGradedCreditsAttempted
       << "\nGrade Points:\t"
       << setiosflags(ios::fixed) << setprecision(2) << newGradePoints
       << endl;

  cout << "Semester GPA:\t"
       << setiosflags(ios::fixed) << setprecision(2) << semesterGPA
       << endl;

  cout << "Overall GPA:\t"
       << setiosflags(ios::fixed) << setprecision(2) << overallGPA
       << endl;

}




int main (int argc, char** argv)
{
  studentGradeSummary (cin);

  return 0;
}
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

//gpa.cpp

#include "gpa.h"
#include "vectorUtils.h"

using namespace std;



void computeGPA (/* University Info */
                 const std::vector<std::string>& gradeCodes,
		 const std::vector<bool>& affectsGPA,
		 const std::vector<bool>& affectsCreditsEarned,
		 const std::vector<double>& pointValues,

		 /* student history info */
		 int creditsEarned,
		 int gradedCreditsAttempted,
		 double gradePoints,

		 /* student semester grades */
		 const std::vector<std::string>& gradeReported,
		 const std::vector<int>& creditsRegisteredFor,

		 /* outputs */
		 int& updatedCreditsEarned,
		 int& updatedGradedCreditsAttempted,
		 double& updatedGradePoints,
		 double& semesterGPA,
		 double& overallGPA)

{
 //Calculate a student's current and overall GPA
 //*Calculate grade points;
 //*Calculate GPA;
 //**Calculate current GPA;
 //*** if attempted credits is 0, GPA is 0.0
 if (gradedCreditsAttempted == 0) semesterGPA = 0.0;
 //*** else compute GPA as grade points earned/# of graded credits attempted
 else semesterGPA = (gradePoints/gradedCreditsAttempted);
 //**Calculate overall GPA;
}






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

//gpa.h

#ifndef GPA_H_INCLUDED
#define GPA_H_INCLUDED

#include <string>
#include <vector>


void computeGPA (/* University Info */
                 const std::vector<std::string>& gradeCodes,
		 const std::vector<bool>& affectsGPA,
		 const std::vector<bool>& affectsCreditsEarned,
		 const std::vector<double>& pointValues,

		 /* student history info */
		 int creditsEarned,
		 int gradedCreditsAttempted,
		 double gradePoints,

		 /* student semester grades */
		 const std::vector<std::string>& gradeReported,
		 const std::vector<int>& creditsRegisteredFor,

		 /* outputs */
		 int& updatedCreditsEarned,
		 int& updatedGradedCreditsAttempted,
		 double& updatedGradePoints,
		 double& semesterGPA,
		 double& overallGPA);





#endif // GPA_H_INCLUDED


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
//vectorUtils.h

#ifndef VECTORUTILS_H_INCLUDED
#define VECTORUTILS_H_INCLUDED

#include <vector>




// Add value into vectr[index], shifting all elements already in positions
//    index..size-1 up one, to make room.

template <typename T>
void addElement (std::vector<T>& vectr, int& size, int index, T value)
{
  // Make room for the insertion
  int toBeMoved = vectr.size() - 1;
  vectr.push_back(value);

  // Shift elements up to make room
  while (toBeMoved >= index) {
    vectr[toBeMoved+1] = vectr[toBeMoved];
    --toBeMoved;
  }
  // Insert the new value
  vectr[index] = value;
}


// Assume the elements of the vector are already in order
// Find the position where value could be added to keep
//    everything in order, and insert it there.
// Return the position where it was inserted

template <typename T>
int addInOrder (std::vector<T>& vectr, T value)
{
  // Make room for the insertion
  int toBeMoved = vectr.size() - 1;
  vectr.push_back(value);

  // Shift elements up to make room
  while (toBeMoved >= 0 && value < vectr[toBeMoved]) {
    vectr[toBeMoved+1] = vectr[toBeMoved];
    --toBeMoved;
  }
  // Insert the new value
  vectr[toBeMoved+1] = value;
  return toBeMoved+1;
}


// Search a vector for a given value, returning the index where
//    found or -1 if not found.
template <typename T>
int seqSearch(const std::vector<T>& list, T searchItem)
{
    int loc;

    for (loc = 0; loc < list.size(); loc++)
        if (list[loc] == searchItem)
            return loc;

    return -1;
}


// Search an ordered vector for a given value, returning the index where
//    found or -1 if not found.
template <typename T>
int seqOrderedSearch(const std::vector<T> list, T searchItem)
{
    int loc = 0;

    while (loc < list.size() && list[loc] < searchItem)
      {
       ++loc;
      }
    if (loc < list.size() && list[loc] == searchItem)
       return loc;
    else
       return -1;
}


// Removes an element from the indicated position in the vector, moving
// all elements in higher positions down one to fill in the gap.
template <typename T>
void removeElement (T* vectr, int& size, int index)
{
  int toBeMoved = index + 1;
  while (toBeMoved < size) {
    vectr[toBeMoved] = vectr[toBeMoved+1];
    ++toBeMoved;
  }
  --size;
}



// Search an ordered vector for a given value, returning the index where
//    found or -1 if not found.
template <typename T>
int binarySearch(const std::vector<T> list, T searchItem)
{
    int first = 0;
    int last = list.size() - 1;
    int mid;

    bool found = false;

    while (first <= last && !found)
    {
        mid = (first + last) / 2;

        if (list[mid] == searchItem)
            found = true;
        else
            if (searchItem < list[mid])
                last = mid - 1;
            else
                first = mid + 1;
    }

    if (found)
        return mid;
    else
        return -1;
}



#endif // VECTORUTILS_H_INCLUDED
Unfortunately, I think something is seriously wrong with your approach. Any function to compute a GPA should not require 14 parameters.

You should be using classes to represent the data, and then vectors of the classes where appropriate. I see the following:
- a Student has total number of credits earned, total taken for grades, overall GPA.
- a ClassGrade is a number of credits and the grade. This has methods to return the credits earned, credits taken for a grade, and numeric grade value.
- a GradeMap. This is a letter grade, whether it counts towards credits taken for grades, and the numeric equivalent of the grade for computing a GPA.

The program reads a Student, followed by a series of ClassGrades.

Add a method to update a Student record based on a ClassGrade:
Student::update(const ClassGrade &grade);

Now when you read each grade, call update().

What about the semester GPA? There's a trick there. Create a dummy Student instance and initialize it with no credits taken (actually, this is what the Student constructor should do). Then when you read the class grade, update BOTH the student record and the dummy record. When you're done, the dummy record will have the semester GPA.

I'm with you bro, and this is not how I would have wrote it. Unfortunately, it works and it's what our teacher gave us. He wants us to write psuedo code and create a function body for computeGPA() in the gpa.cpp class to get that certain output. I'm completely lost right now, I think he wants us to call the vectors which makes no sense because we haven't learned anything about them yet. =/
Last edited on
Ouch. This is really horrible code, but it guess you're stuck with it.

Okay, start with a pencil and paper. Given a letter grade and the number of credits in a course, write down how you'd update the 5 output parameters in computeGPA. Once you have that, you can start writing some code:
1
2
3
4
5
for (int i=0; i<gradeReported.size(); ++i) {
    // gradeReported[i] is the grade for the i'th class
    // creditsRegisteredFor[i] is the number of credits for the i'th class
    // update the output params based on these.
}


If you're still confused about vector<> then see the reference page and look at some examples here on the forum, just seach for "vector".
Thanks for all your help bro. It was much appreciated!
Topic archived. No new replies allowed.