We can change the state of an object by making an assignment to one of its instance variables.
For example, we could change the numerator of the fraction by assigning a new
value to self.num. Likewise, we could do the same thing for self.den.

One place where this type of modification makes sense is when we place a fraction in lowest terms. Lowest terms simply
means that the numerator and denominator do not share any common factors. For example, 12/16 is a fraction but it is
not in lowest terms since 2 can divide into both 12 and 16. We call 2 a common divisor. If we divide the numerator
and the denominator by a common divisor, we get an equivalent fraction. If we divide by the greatest common divisor,
we will get the lowest terms representation. In this case 4 would be the greatest common divisor and the lowest terms
representation would be 3/4.

There is a very nice iterative method for computing the greatest common divisor of two integers. Try to run the
function on a number of different examples.

Now that we have a function that can help us with finding the greatest common divisor, we can use that to implement
a fraction method called simplify. We will ask the fraction “to put itself in lowest terms”.

The simplify method will pass the numerator and the denominator to the gcd function to find the
greatest common divisor. It will then modify itself by dividing its num and its den by that value.

There are two important things to note about this implementation. First, the gcd function is not
a method of the class. It does not belong to Fraction. Instead it is a function that is used by Fraction
to assist in a task that needs to be performed. This type of function is often called a helper function. Second,
the simplify method does not return anything. Its job is to modify the object itself. This type of method is
known as a mutator method because it mutates or changes the internal state of the object.