Building a Fraction Type

In case you *really* want to learn about fractions.

If you're trying to learn to code, leveraging the 
math you already know, you've come to the right 

def main():
  "demo the Q type (rational number type)"
  q = Q(1,2)
  p = Q(2,5)
  print("p:    =", p)
  print("q:    =", q)
  print("p+q   =", p+q)
  print("p/q   =", p/q)
  print("p*q   =", p*q)
  print("p-q   =", p-q)
  print("q*q*q =", q*q*q)
  print("gcd(10,15) = ", Q._gcd(10, 15))
class Q:

  def __init__(self, n, d):
    gcd = self._gcd(n, d) # reduce to
    self.numer = n // gcd # lowest
    self.denom = d // gcd # terms
  def _gcd(a, b):
    "Euclid's Method"
    while b:
      a, b = b, a%b 
    return a
  def __add__(self, other):
    return Q(self.numer * other.denom 
        + other.numer * self.denom, 
          self.denom * other.denom)
  def __neg__(self):
    return Q(-self.numer, self.denom)
  def __sub__(self, other):
    "add the additive inverse"
    return self + -other
  def __mul__(self, other):
    return Q(self.numer * other.numer, 
             self.denom * other.denom)
  def __invert__(self):  # same as "reciprocate"
    return Q(self.denom, self.numer)
  def __truediv__(self, other):
    "multiply by 1/other i.e. ~other"
    return self * ~other
  def __str__(self):
    return "({}/{})".format(self.numer, self.denom)
  def __repr__(self):
    return "Q({},{})".format(self.numer, self.denom)