# Fractions in Python

Five out of four people have trouble with fractions, Steven Wright.

A fraction is a fancy way of representing the division of a whole into parts, for example, half of a pizza (1⁄2), a quarter of an apple (1⁄4), etc.

# Fraction module in Python

The fractions module provides support for rational number arithmetic. We can create fractions from integers, floats, decimals, and strings.

Hi@Welcome:~ python
Python 3.8.6 (default, May 27 2021, 13:28:02)
>>> from fractions import Fraction # Firstly, we need to import the fractions module.
>>> print(Fraction()) # A fraction is formed by a pair of integers as numerator and denominator. The default values for the numerator and denominator are 1 and 0 respectively.
0
>>> print(Fraction(0.25)) # The class Fraction accepts floating point numbers as arguments.
1/4
>>> print(Fraction(8, 20)) # It creates a new fraction and it will be automatically normalized, i.e., it calculates the irreducible fraction.
2/5
>>> print(Fraction(6, 14))
3/7
>>> import math
>>> print (math.gcd(8, 20)) # The Highest Common Factor (gcd) can be obtained in Python using a single function offered by the math module.
4


820 = 8: gcd(8,20)20: gcd(8, 20) = 8: 420: 4= 25

>>> print (math.gcd(6, 14))
2
>>> print(Fraction(2, 0))
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.10/fractions.py", line 156, in __new__
raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
ZeroDivisionError: Fraction(2, 0)


Fraction raises a ZeroDivisionError exception when the argument passed as denominator is 0.

>>> print(Fraction("7/8"))
7/8
>>> print(Fraction(0.75))
3/4
>>> print(Fraction(2.3))
2589569785738035/1125899906842624


What’s going on? In base 10 which you’re likely to be comfortable with, you can’t express 1/3 exactly. It’s 0.3333333… (recurring). The same goes with 2.3 in base 2 = 10.0100110011001100110011001100110011001100110011001100110011…2. In other words, some decimal numbers cannot be represented exactly in binary.

>>> (2.3).as_integer_ratio()
# Returns a pair of integers whose ratio is exactly equal to the original float and with a positive denominator.


(2589569785738035, 1125899906842624)

# Operations on Rational Numbers

>>> Fraction(2, 3) + Fraction(4, 5) # Doing arithmetic with rational numbers is as easy as pie.
Fraction(22, 15)
>>> Fraction(2, 3) + 5
Fraction(17, 3)
>>> Fraction(2, 3) + 5 -0.2
5.466666666666667
>>> Fraction(2, 3) - Fraction(4, 5)
Fraction(-2, 15)
>>> Fraction(2, 3) - 5
Fraction(-13, 3)
>>> Fraction(2, 3) * Fraction(4, 5)
Fraction(8, 15)
>>> Fraction(2, 3) * 7
Fraction(14, 3)
>>> Fraction(2, 3) / Fraction(4, 5)
Fraction(5, 6)
>>> Fraction(2, 3) / 7
Fraction(2, 21)
>>> Fraction(2, 3)**2

We can raise fractions to a power, (23)2 = 49.
Fraction(4, 9)
>>> Fraction(2, 3) < Fraction(4, 5) # We can see how Python's comparison operators work on fractions.
True
>>> Fraction(2, 3) > 5.2
False


# Writing a Fraction Class

# It is necessary to overload
from __future__ import division

def gcd(a, b):
""" It returns the greatest common divisor of a and b."""
while b:
a, b = b, a % b
return a

class Fraction:
## A Fraction instance is constructed from a pair of integers.
# @param n is the numerator of the fraction (default is 0)
# @param d is the denominator of the fraction (default is 1)
def __init__(self, n = 0, d = 1):
if (not isinstance(n, int)):
raise TypeError("The numerator of a Fraction must be an integer")
if (not isinstance(d, int)):
raise TypeError("The denominator of a Fraction must be an integer")

self.numerator = int(n / gcd(abs(n), abs(d)))
# It creates a new fraction and it will be automatically normalized, i.e., it calculates the irreducible fraction.
# print(Fraction(8, 20)) returns 2/5.
self.denominator = int(d / gcd(abs(n), abs(d)))
if self.denominator < 0:
self.denominator = abs(self.denominator)
self.numerator = -1*self.numerator
# The denominator cannot be zero, so it raises a ZeroDivisionError if denominator = 0.
elif self.denominator == 0:
raise ZeroDivisionError("Denominator cannot be zero")

@classmethod
def from_string(cls, text):
""" It generates a Fraction object from a string representation of two integers separated by '/'.
>> print(Fraction.from_string('4/9')) return 4/9. Credits: jonrsharpe, codereview.stackexchange.com"""
return cls(*[int(i) for i in text.split('/')])

## It implements the addition of two fractions.
# @params other is the fraction from which self is to be added.
# @return the new Fraction object that is the result of self + other.
if isinstance(other, int):
other = Fraction(other)
num = self.numerator * other.denominator + self.denominator * other.numerator
den = self.denominator * other.denominator
return Fraction (num, den)



radd is called if the left object does not have an add method or that method does not know how to add the two objects, e.g., f1 = Fraction(1, 3), print(2 + f1).

    ## It implements the subtraction of two fractions.
# @params other is the fraction from which self is to be subtracted.
# @return the new Fraction object that is the result of self - other.
def __sub__(self, other):
if isinstance(other, int):
other = Fraction(other)
num = self.numerator * other.denominator - self.denominator * other.numerator
den = self.denominator * other.denominator
return Fraction (num, den)

def __rsub__(self, other):
return Fraction(other) - self

## It determines if this fraction is equal to another fraction.
# @params other is the right-hand side fraction.
# @return True if both fractions (self and other) are equal. Otherwise, it returns False.
def __eq__(self, other):
return (self.numerator == other.numerator and self.denominator == other.denominator)

def __lt__(self, other):
# We can implement the __lt__ method by putting self and other in common terms and then comparing the numerators.
return (self.numerator * other.denominator < self.denominator * other.numerator)

def __ne__(self, other):
return not self == other

def __le__(self, other):
return self < other or self == other

def __gt__(self, other):
return other < self

def __ge__(self, other):
return self > other or self == other

## It implements the multiplication of two fractions.
# @params other is the fraction from which self is to be multiplied.
# @return the new Fraction object that is the result of self multiplied by other.
def __mul__(self, other):
if isinstance(other, int):
other = Fraction(other)
return Fraction(self.numerator * other.numerator, self.denominator * other.denominator)

__rmul__ = __mul__

## It implements the division of two fractions.
# @params other is the fraction from which self is to be divided.
# @return the new Fraction object that is the result of self divided by other.
def __truediv__(self, other):
if isinstance(other, int):
other = Fraction(other)
return Fraction(self.numerator * other.denominator, self.denominator * other.numerator)

def __rtruediv__(self, other):
return Fraction(other)/self

def __float__(self):
return self.numerator / self.denominator

## It converts the object into a string.
# @return a string in the format numerator/denominator. If the object represents an improper function (it has a numerator that is greater
# than the denominator), it returns the fraction as a mixed fraction written as the sum of a whole number and a proper fraction.
def __str__(self):
if self.denominator == 1:
return str(self.numerator)
elif abs(self.numerator) > self.denominator:
if self.numerator > 0:
a = self.numerator // self.denominator
b = self.numerator % self.denominator
return "{} {}/{}".format(a, b, self.denominator)
else:
a = - (abs(self.numerator) // self.denominator)
b = - (abs(self.numerator) % self.denominator)
return "{} {}/{}".format(a, -b, self.denominator)

else:
return str(self.numerator) + "/" + str(self.denominator)
def main():
print(Fraction(2, -1)) # -2
print(Fraction(8, 20)) # 2/5
print(Fraction(5, 4)) # 1 1/4
print(Fraction.from_string('4/9')) # 4/9
f0 = Fraction.from_string('3/4')
print(2+f0) # 2 3/4
print(2-f0) # 1 1/4
print(2*f0) # 1 1/2
print(2/f0) # 2 2/3
f1 = Fraction(5, 3)
f2 = Fraction(3, -4)

try:
f3 = Fraction(3, 0)
except ZeroDivisionError:
print("Oops! Denominator cannot be zero")

f3 = f1 + f2
print(f1, "+", f2, "=", f3) # 1 2/3 + -3/4 = 11/12
f3 = f1 - f2
print(f1, "-", f2, "=", f3) # 1 2/3 - -3/4 = 2 5/12
f3 = f1 * f2
print(f1, "*", f2, "=", f3) # 1 2/3 * -3/4 = -1 1/4
f3 = f1 / f2
print(f1, "/", f2, "=", f3) 1 2/3 / -3/4 = -2 2/9
f3 = Fraction(4, 6)
print("Is", f3, " = ", f1, "?=", f3 == f1) # Is 2/3  =  1 2/3 ?= False
print("Is", f3, " < ", f1, "?=", f3 < f1) # Is 2/3  <  1 2/3 ?= True
print("Is", f3, " >= ", f2, "?=", f3 >= f2) # Is 2/3  >=  -3/4 ?= True
print("Is", f3, " != ", f2, "?=", f3 != f2) # Is 2/3  !=  -3/4 ?= True
print(f3, "=", "{:.2f}".format(round(float(f3), 2)), "=",  round(float(f3)*100, 2), "%") # 2/3 = 0.67 = 66.67 %
f4 = Fraction(1, 3)
print(f4, "=", "{:.2f}".format(round(float(f4), 2)), "=",  round(float(f4)*100, 2), "%") # 1/3 = 0.33 = 33.33 %
if __name__ == '__main__':
main()

Bitcoin donation