The STL and professional C++ · Lesson 21 of 21
Project: a grade book
Classes, vectors, maps, algorithms and exceptions in one program.
We'll build a small grade book for a SeaCode course that brings together everything we've learned. Read and run the code first, then complete the three tasks below, each building on the last.
#include <algorithm>
#include <iostream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
class GradeBook {
public:
void add(const std::string& student, int score) {
if (score < 0 || score > 100) throw std::out_of_range("score must be 0-100");
scores_[student].push_back(score);
}
double average(const std::string& student) const {
auto it = scores_.find(student);
if (it == scores_.end()) throw std::invalid_argument("unknown student " + student);
const std::vector<int>& s = it->second;
int sum = 0;
for (int x : s) sum += x;
return static_cast<double>(sum) / s.size();
}
std::vector<std::string> students() const {
std::vector<std::string> names;
for (const auto& entry : scores_) names.push_back(entry.first);
return names;
}
private:
std::map<std::string, std::vector<int>> scores_;
};
int main() {
GradeBook book;
book.add("Laila", 90);
book.add("Laila", 80);
book.add("Omar", 70);
book.add("Nour", 100);
book.add("Nour", 95);
for (const std::string& name : book.students()) {
std::cout << name << ": " << book.average(name) << "\n";
}
try {
book.add("Omar", 120);
} catch (const std::exception& e) {
std::cout << "rejected: " << e.what() << "\n";
}
return 0;
}- GradeBook
- scores_: map<string, vector<int>>
- "Laila" → [90, 80]
- "Nour" → [100, 95]
- "Omar" → [70]
- add() → validates, then push_back
- average() const → throws if unknown
- scores_: map<string, vector<int>>
Task 1: ranking students
Exercise
Add a ranking() method (const) returning student names sorted by average, highest first. Print them on one line separated by spaces.
Expected output: Nour Laila Omar
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>
class GradeBook {
public:
void add(const std::string& student, int score) { scores_[student].push_back(score); }
double average(const std::string& student) const {
const std::vector<int>& s = scores_.at(student);
int sum = 0;
for (int x : s) sum += x;
return static_cast<double>(sum) / s.size();
}
std::vector<std::string> ranking() const {
std::vector<std::string> names;
// fill and sort names here
return names;
}
private:
std::map<std::string, std::vector<int>> scores_;
};
int main() {
GradeBook book;
book.add("Laila", 90); book.add("Laila", 80);
book.add("Omar", 70);
book.add("Nour", 100); book.add("Nour", 95);
for (const std::string& n : book.ranking()) std::cout << n << " ";
std::cout << "\n";
return 0;
}Task 2: letter grades
Exercise
Write char letter(double avg): 90 and up is A, 80 is B, 70 is C, anything lower F. For each student (alphabetically) print name letter.
Ali C Laila B Nour A Omar F
#include <iostream>
#include <map>
#include <string>
#include <vector>
char letter(double avg) {
return '?';
}
int main() {
std::map<std::string, std::vector<int>> scores = {
{"Laila", {90, 80}}, {"Omar", {70, 60}}, {"Nour", {100, 95}}, {"Ali", {72, 78}}
};
for (const auto& entry : scores) {
int sum = 0;
for (int x : entry.second) sum += x;
double avg = static_cast<double>(sum) / entry.second.size();
std::cout << entry.first << " " << letter(avg) << "\n";
}
return 0;
}Task 3: course statistics
Exercise
From all scores {90, 80, 70, 100, 95, 55}: print the highest, the lowest, and how many are 60 or more, on one line as max 100 min 55 passed 5. Use the algorithms.
Expected output: max 100 min 55 passed 5
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> all = {90, 80, 70, 100, 95, 55};
return 0;
}Learn more from
Played 0 of 3 games
Sign in to save your progress and earn XP.