// Prog: grader.cpp // computes grade corresponding to number of points #include #include class grader { private: unsigned int p6; // 6.0 for at least p6 points unsigned int p4; // 4.0 for p4 points unsigned int p1; // 1.0 for at most p1 points // PRE: hi yields grade g // POST: returns the smallest number of points which // still yields grade g unsigned int from_here_to (unsigned int hi, double g) { assert (grade (hi) == g); unsigned int lo = hi; while (lo > 0 && grade (lo-1) == g) --lo; return lo; } public: // PRE: top > pass > flop // POST: grader is initialized with the number of points // - top (necessary to obtain grade 6.0) // - pass (sufficient to obtain grade at least 4.0) // - flop (up to this, grade 1.0 is obtained) grader (unsigned int top, unsigned int pass, unsigned int flop) : p6 (top), p4 (pass), p1 (flop) { assert (top > pass && pass > flop); } // POST: returns the grade obtained from p points, computed // through two different linear interpolations; one // between p_1 and p_4, and one between p_4 and p_6 double grade (unsigned int p) { if (p >= p6) return 6.0; if (p <= p1) return 1.0; double ug; // unrounded grade if (p >= p4) // p == p4 -> 4.0; p == p6 -> 6.0 ug = 4.0 + 2.0 * (p - p4) / (p6 - p4); else // p == p1 -> 2.0; p == p4 -> 4.0 ug = 1.0 + 3.0 * (p - p1) / (p4 - p1); // round down to next quarter grade unsigned int rg = 4 * ug; return 0.25 * rg; } // POST: prints the grading scale, where pm // is the maximum number of points that // can be achieved void print_grading_scale (unsigned int max) { double g = 6.0; unsigned int hi = max; for (;;) { // print range for grade g unsigned int lo = from_here_to (hi, g); std::cout << lo << " - " << hi << " : " << g << "\n"; if (lo > 0) { hi = lo - 1; g = grade (hi); } else return; } } }; int main() { const unsigned int max = 49; const unsigned int top = 46; const unsigned int pass = 27; const unsigned int flop = 5; grader g (top, pass, flop); g.print_grading_scale (max); return 0; }