#include #include #include #include #include using namespace std; const int MIN_SCORE = 0; const string usage = "\ usage: grade [-n, --by-name] [-p, --by-points] [-v, --verbose]"; struct student { string name; int lab_score; int exam_score; int final_score; string letter_grade; }; typedef struct student student; ostream & operator<<(ostream & os, const student & s) { os << "name: '" << s.name << ", final score: " << s.final_score << ", grade: " << s.letter_grade; return os; } bool sort_by_name(const student & a, const student & b) { return a.name < b.name; } bool sort_by_score(const student & a, const student & b) { return a.final_score > b.final_score; } struct grade { int max_score; int min_late_days; int max_late_days; }; typedef struct grade grade; struct result { int score; int late_days; }; typedef struct result result; result collect_grade(string name, int score_max, int late_min, int late_max, bool verbose); string determine_letter_grade(int score); int main(int argc, char * argv[]) { bool verbose = false; bool by_points = false; bool by_name = false; for(int i = 0; i < argc; i++) { string cur_arg = argv[i]; if(cur_arg == "--verbose" or cur_arg == "-v") { verbose = true; } if(cur_arg == "--by-points" or cur_arg == "-p") { by_points = true; } if(cur_arg == "--by-name" or cur_arg == "-n") { by_name = true; } if(cur_arg == "--help" or cur_arg == "-h") { cout << usage << endl; return 0; } } if (by_points and by_name) { cerr << "only specify one sort order" << endl; return -1; } map labs = { {"Lab01", {20, -2, 2}}, {"Lab02", {20, -2, 2}}, {"Lab03", {30, -3, 3}}, {"Lab04", {30, -3, 3}}, {"Lab05", {30, -3, 3}}, {"Lab06", {30, -3, 3}}, {"Lab07", {30, -3, 3}}, {"Lab08", {30, -3, 3}}, {"Lab09", {20, -2, 2}}, {"Lab10", {20, -2, 2}}, {"Lab11", {40, -4, 4}}, {"exam1", {100, 0, 3}}, {"exam2", {100, 0, 3}}, {"final", {100, 0, 3}}, }; vector students; while (!cin.eof()) { if(verbose) cerr << "Please enter name of student: "; string name; getline(cin, name); if (!name.empty()) { int total_lab_points = 0; int total_exam_points = 0; for(pair l: labs) { string n = l.first; grade g = l.second; try { result cur_result = collect_grade(n, g.max_score, g.min_late_days, g.max_late_days, verbose); total_lab_points += cur_result.score; if (n.substr(0, 3) == "lab") total_lab_points -= 5 * cur_result.late_days; else if (n.substr(0, 4) == "exam" or n.substr(0, 4) == "final") total_exam_points -= 20 * cur_result.late_days; } catch (string e) { cerr << e << endl; return 1; } } int final_score = total_lab_points + total_exam_points; student s = {name, total_lab_points, total_exam_points, final_score, determine_letter_grade(final_score)}; students.push_back(s); } } if(by_name) { sort(students.begin(), students.end(), sort_by_name); } else if (by_points) { sort(students.begin(), students.end(), sort_by_score); } for(student s: students) { cout << s << endl; } return 0; } result collect_grade(string name, int score_max, int late_min, int late_max, bool verbose=false) { int score = 0; if(verbose) { cerr << "Please enter score for " << name << "[" << MIN_SCORE << ", " << score_max << "]: "; } cin >> score; if (!(MIN_SCORE <= score and score <= score_max)) { ostringstream s; s << score << " is not in accepted range: [" << MIN_SCORE << ", " << score_max << "]" << endl; throw s.str(); } int late_days; if (verbose) { cerr << "Please enter late days [" << late_min << ", " << late_max << "]: "; } cin >> late_days; if (!(late_min <= late_days and late_days <= late_max)) { ostringstream s; s << late_days << " is not in accepted range: [" << late_min << ", " << late_max << "]" << endl; throw s.str(); } result r = {score, late_days}; return r; } string determine_letter_grade(int score) { string letter_grade; if(score >= 570) letter_grade = "A"; if(score < 570 && score >=540) letter_grade = "A-"; if(score < 540 && score >= 522) letter_grade = "B+"; if(score < 522 && score >= 498) letter_grade = "B"; if(score < 498 && score >= 480) letter_grade = "B-"; if(score < 480 && score >= 462) letter_grade = "C+"; if(score < 462 && score >= 438) letter_grade = "C"; if(score < 438 && score >= 420) letter_grade = "C-"; if(score < 420 && score >= 402) letter_grade = "D+"; if(score < 402 && score >= 378) letter_grade = "D"; if(score < 378 && score >= 360) letter_grade = "D-"; if(score < 360) letter_grade = "E"; return letter_grade; }