**Implement methods in grades
**

Introduction

In this assignment, you will update your Grade class again, this time eschewing inheritance to use a Template. I require your Rational class to test your Grade class and list the necessary methods below. In this version, Rational is passed as a template to Grade and will likely require additional overloaded operators to implement the methods in Grade.

Read the provided header file documentation for instructions on how the methods should work.

**Points:**

Correctness | Base Submission |

1. Grade::Grade: 1.05 points | compilation of each test (ten tests above): 0.1 points each hw5/src/grade.cc style: 0.5 points |

2. Grade::ToLetter: 1.75 points | hw5/inc/grade.h style: 0.5 points hw5/src/rational.cc style: 0.5 points hw5/inc/rational.h style: 0.5 |

3. Grade::CalcAverage: 1.5 points | |

4. operator<<(Rational): 1.75 points | |

5. Rational::operator==(): 1.45 points |

**Total = 7.5 Points**

**Solution:**

**Grades:**

```
template < class t="">
Grade
```::Grade(T score) {
this->score_ = score;
}
template < class t="">
T Grade::score() const {
return this->score_;
}
template < class t="">
std::string Grade::ToLetter(unsigned int threshold) const {
double offset = threshold / 10.0;
bool withPlusGrade = threshold != 100;
if (withPlusGrade && CheckGreaterOrEqual(90.0 + offset)) {
return "A+";
} else if (CheckGreaterOrEqual(90.0)) {
return "A";
} else if (withPlusGrade && CheckGreaterOrEqual(80.0 + offset)) {
return "B+";
} else if (CheckGreaterOrEqual(80.0)) {
return "B";
} else if (withPlusGrade && CheckGreaterOrEqual(70.0 + offset)) {
return "C+";
} else if (CheckGreaterOrEqual(70.0)) {
return "C";
} else if (withPlusGrade && CheckGreaterOrEqual(60.0 + offset)) {
return "D+";
} else if (CheckGreaterOrEqual(60.0)) {
return "D";
} else {
return "F";
}
}
template < class t="">
Grade Grade::CalcAverage(std::vector vec) {
T average = vec[0];
for (std::size_t i = 1; i < vec.size(); i++) {
average = average + vec[i];
}
return Grade(average / vec.size());
}
template < class t="">
bool Grade::CheckGreaterOrEqual(double threshold) const {
double diff = this->score() - threshold;
return (this->score() > threshold) ||
(std::abs(diff) < std::abs(this->score() * 1e-6));
}

**Rational:**

```
#include < cassert>
#include < iostream>
// GCD: Find the Greatest Common Divisor
int Rational::gcd(int a, int b) {
if (a == 0) return b;
return gcd(b % a, a);
}
// Rational: Represents the signed quotient of two integers. The integers may
// be stored unsigned, but their signed-ness must be maintained by the
// mechanisim of your choice.
// constructor (int, int)
//
// * Initializes object with two integer parameters; first is numerator,
// second is denominator
// * Precondition: second parameter is not 0. You may assert.
// * Is explicit if second param has default value.
Rational::Rational(int num, int den) : num_(num), den_(den) {
assert(den != 0);
if (den < 0) {
num_ = -num_;
den_ = -den_;
}
}
// num: accessor method for numerator
//
// * Returns numerator as an integer
// * Does not modify calling instance; const method.
int Rational::num() const {
return num_;
}
// den: accessor method for the denominator
//
// * Returns denominator as an integer
// * Does not modify calling object; const method.
unsigned int Rational::den() const {
return (unsigned int)den_;
}
// returns true or false depending on the equality of the
// ratio of the calling object and a parameter Rational object, e.g.
// Rational(-1, 2).Equals(Rational(-2, 4))
// returns true, while
// Rational(1, 2).Equals(Rational(1, 4))
// returns false.
bool Rational::operator==(const Rational& ratio) const {
if (this->num() / std::abs(this->num()) !=
ratio.num() / std::abs(ratio.num())) {
return false;
}
int g1 = gcd(std::abs(this->num()), this->den());
int g2 = gcd(std::abs(ratio.num()), ratio.den());
return (this->num() / g1 == ratio.num() / g2) &&
(this->den() / g1 == ratio.den() / g2);
}
bool Rational::operator>(const double num) const {
double lhs = this->num();
double rhs = this->den() * num;
return lhs > rhs;
}
Rational Rational::operator+(const Rational& ratio) {
int num = this->num() * ratio.den() + ratio.num() * this->den();
int den = this->den() * ratio.den();
int factor = gcd(num, den);
return Rational(num / factor, den / factor);
}
double Rational::operator-(const double ratio) {
return this->num() * 1.0 / this->den() - ratio;
}
double Rational::operator*(const double ratio) {
return this->num() * 1.0 / this->den() * ratio;
}
Rational Rational::operator/(const int factor) {
return Rational(this->num(), this->den() * factor);
}
// appends the contents of rhs to lhs as follows:
// n/d when num_ != 0 and den_ != 1
// n when den_ == 1
// 0 when num_ == 0
// and returns lhs
std::ostream& operator<<(std::ostream& lhs, const Rational& rhs) {
if ((rhs.num() != 0) && (rhs.den() != 1)) {
lhs << rhs.num() << "/" << rhs.den();
} else if (rhs.den() == 1) {
lhs << rhs.num();
} else if (rhs.num() == 0) {
lhs << "0";
}
return lhs;
}
```