C++ Tutorial
C++ Project: Grade Calculator
Convert numeric scores to letter grades, compute a GPA-style average, and print a report.
What you will build
A grade calculator takes numeric scores, maps each one to a letter, then prints a report with an average. The letter boundaries live in one function so the table and the average never disagree about what 89 means. Scores sit in a vector<int>.
Demo scores are hardcoded. Use Try it in C++ and /cpp/try. The Python and HTML try pages will not compile this.
Numeric score to letter
Walk the scale from the top. 90 and up is A, 80 is B, 70 is C, 60 is D, anything below is F. A score outside 0 through 100 still gets a letter here; you can clamp or reject those in practice.
Example
#include <iostream>
using namespace std;
char letterFrom(int score) {
if (score >= 90) {
return 'A';
} else if (score >= 80) {
return 'B';
} else if (score >= 70) {
return 'C';
} else if (score >= 60) {
return 'D';
}
return 'F';
}
int main() {
cout << 91 << " " << letterFrom(91) << endl;
cout << 84 << " " << letterFrom(84) << endl;
cout << 59 << " " << letterFrom(59) << endl;
return 0;
}Output is A, then B, then F. 90 is the first A; 89 is still a B.
Average of a vector
Sum the scores as a double, then divide by size(). Integer division of the sum would drop the fraction. An empty vector has no average; return 0 and let the caller print a message.
Example
#include <iostream>
#include <vector>
using namespace std;
double average(const vector<int>& scores) {
if (scores.empty()) {
return 0.0;
}
double sum = 0.0;
for (int s : scores) {
sum = sum + s;
}
return sum / scores.size();
}
int main() {
vector<int> scores;
scores.push_back(91);
scores.push_back(84);
scores.push_back(76);
cout << average(scores) << endl;
return 0;
}Compile at /cpp/try with Try it in C++. The average of 91, 84, and 76 is 83.666… g++ will print something like 83.6667 until you set precision.
GPA-style points
A GPA-style average maps letters to 4.0, 3.0, 2.0, 1.0, and 0.0, then averages those points. That is not the same as averaging the raw percents. Both numbers are useful; this project prints each.
Example
#include <iostream>
using namespace std;
char letterFrom(int score) {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
}
double pointsFrom(char letter) {
if (letter == 'A') return 4.0;
if (letter == 'B') return 3.0;
if (letter == 'C') return 2.0;
if (letter == 'D') return 1.0;
return 0.0;
}
int main() {
cout << pointsFrom(letterFrom(91)) << endl;
cout << pointsFrom(letterFrom(84)) << endl;
return 0;
}91 becomes A and 4.0. 84 becomes B and 3.0.
Complete grade report
Print every score with its letter, then the percent average and the GPA-style average, both with two decimal places. Names are optional here; the vector is scores only so the arithmetic stays obvious.
Example
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
char letterFrom(int score) {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
}
double pointsFrom(char letter) {
if (letter == 'A') return 4.0;
if (letter == 'B') return 3.0;
if (letter == 'C') return 2.0;
if (letter == 'D') return 1.0;
return 0.0;
}
int main() {
vector<int> scores;
scores.push_back(91);
scores.push_back(84);
scores.push_back(76);
scores.push_back(68);
scores.push_back(95);
cout << "Score Letter" << endl;
double sum = 0.0;
double pointSum = 0.0;
for (int s : scores) {
char L = letterFrom(s);
cout << setw(5) << s << " " << L << endl;
sum = sum + s;
pointSum = pointSum + pointsFrom(L);
}
cout << fixed << setprecision(2);
cout << "Average percent: " << (sum / scores.size()) << endl;
cout << "GPA-style: " << (pointSum / scores.size()) << endl;
return 0;
}Five rows print first. The percent average is 82.80. The GPA-style average uses A, B, C, D, A which is (4+3+2+1+4) / 5 = 2.80.
Common mistakes
- Testing F first with
score < 60and then usingifinstead ofelse iffor the rest. A 95 is less than nothing in a broken chain and can fall through. Start from A and go down, or use exclusive ranges. - Averaging with
int sumandsum / scores.size(). Both sides integer-like means you lose the fraction before you print. - Calling
letterFromin the report and a second copy of the scale in the GPA function. One function for the letter; one function from letter to points. - Dividing by
size()without checking for an empty vector. Guard that case.
Practice
- Treat 90–100 as A, and print
invalidfor a score below 0 or above 100 instead of a letter. - Count how many A grades appear and print that count under the report.
- Add plus/minus letters: 87–89 is B+, 83–86 is B, 80–82 is B−, and similar bands for A and C.
Last project: a shopping cart with a receipt and a money total.