Recipes, measurements, and mathematical calculations often involve exact ratios that lose precision when converted to decimals. The Fraction module represents rational numbers as numerator/denominator pairs, automatically simplifying results and maintaining perfect accuracy.

Math Operations

Using fractions with math functions:

create.py
# Create Fraction

from fractions import Fraction
import math

# Create Fraction
print("Create Fraction:")

# From integers (numerator, denominator)
f1 = Fraction(3, 4)
print(f"From ints (3, 4): {f1}")

# From float
f2 = Fraction(0.75)
print(f"From float (0.75): {f2}")

# From string
f3 = Fraction('3/4')
print(f"From string ('3/4'): {f3}")

f4 = Fraction('0.75')
print(f"From string ('0.75'): {f4}")

# From Decimal
from decimal import Decimal
d = Decimal('0.75')
f5 = Fraction(d)
print(f"From Decimal: {f5}")

# Whole numbers
f6 = Fraction(5)
print(f"From int (5): {f6}")

# Negative fractions
f7 = Fraction(-3, 4)
print(f"Negative (-3, 4): {f7}")

f8 = Fraction(3, -4)
print(f"Negative (3, -4): {f8}")

# Automatic simplification
print("\nAutomatic simplification:")
f9 = Fraction(6, 8)
print(f"6/8 simplified: {f9}")

f10 = Fraction(12, 16)
print(f"12/16 simplified: {f10}")

f11 = Fraction(100, 200)
print(f"100/200 simplified: {f11}")

# Numerator and denominator
print("\nNumerator and denominator:")
f = Fraction(3, 4)
print(f"Fraction: {f}")
print(f"Numerator: {f.numerator}")
print(f"Denominator: {f.denominator}")

# Zero
print("\nZero:")
zero = Fraction(0)
print(f"Zero: {zero}")
print(f"Numerator: {zero.numerator}")
print(f"Denominator: {zero.denominator}")

# From float (precision note)
print("\nFrom float (precision):")
f12 = Fraction(0.1)
print(f"Fraction(0.1): {f12}")  # Shows float precision issues

f13 = Fraction('0.1')
print(f"Fraction('0.1'): {f13}")  # Exact

# limit_denominator
print("\nlimit_denominator:")
f14 = Fraction(0.1)
print(f"Original: {f14}")
print(f"Limited to 10: {f14.limit_denominator(10)}")
print(f"Limited to 100: {f14.limit_denominator(100)}")

# Approximate pi
print("\nApproximate pi:")
pi_frac = Fraction(str(math.pi))
print(f"Pi as fraction: {pi_frac}")
print(f"Pi limited to 1000: {pi_frac.limit_denominator(1000)}")
print(f"Pi limited to 100: {pi_frac.limit_denominator(100)}")

# from_float and from_decimal
print("\nfrom_float and from_decimal:")
f15 = Fraction.from_float(0.75)
print(f"from_float(0.75): {f15}")

f16 = Fraction.from_decimal(Decimal('0.75'))
print(f"from_decimal('0.75'): {f16}")

# Convert to other types
print("\nConvert to other types:")
f = Fraction(3, 4)
print(f"Fraction: {f}")
print(f"float: {float(f)}")
print(f"int (truncate): {int(f)}")
print(f"Decimal: {Decimal(f.numerator) / Decimal(f.denominator)}")

# Common fractions
print("\nCommon fractions:")
fractions = [
    (1, 2), (1, 3), (1, 4), (1, 5),
    (2, 3), (3, 4), (3, 5), (4, 5)
]
for num, den in fractions:
    f = Fraction(num, den)
    print(f"{num}/{den} = {f} = {float(f):.4f}")

arithmetic.py
# Arithmetic operations

from fractions import Fraction

# Arithmetic
a = Fraction(3, 4)
b = Fraction(2, 5)

print(f"a = {a}")
print(f"b = {b}")
print()

# Addition
print("Addition:")
print(f"a + b = {a + b}")
print(f"  = {a.numerator * b.denominator + b.numerator * a.denominator}/{a.denominator * b.denominator}")

# Subtraction
print("\nSubtraction:")
print(f"a - b = {a - b}")

# Multiplication
print("\nMultiplication:")
print(f"a * b = {a * b}")
print(f"  = {a.numerator * b.numerator}/{a.denominator * b.denominator}")

# Division
print("\nDivision:")
print(f"a / b = {a / b}")
print(f"  = {a.numerator * b.denominator}/{a.denominator * b.numerator}")

# Floor division
print("\nFloor division:")
print(f"a // b = {a // b}")

# Modulo
print("\nModulo:")
print(f"a % b = {a % b}")

# Power
print("\nPower:")
f = Fraction(2, 3)
print(f"{f}^2 = {f ** 2}")
print(f"{f}^3 = {f ** 3}")
print(f"{f}^-1 = {f ** -1}")  # Reciprocal

# Negation
print("\nNegation:")
print(f"-a = {-a}")

# Absolute value
print("\nAbsolute value:")
neg = Fraction(-3, 4)
print(f"abs({neg}) = {abs(neg)}")

# Reciprocal
print("\nReciprocal:")
f = Fraction(3, 4)
print(f"Reciprocal of {f} = {1 / f}")
print(f"  = {Fraction(f.denominator, f.numerator)}")

# Mixed operations
print("\nMixed operations:")
print(f"Fraction + int: {a + 2}")
print(f"int + Fraction: {2 + a}")
print(f"Fraction * int: {a * 3}")
print(f"Fraction / int: {a / 2}")

# Chaining
print("\nChaining:")
result = Fraction(1, 2) + Fraction(1, 3) + Fraction(1, 6)
print(f"1/2 + 1/3 + 1/6 = {result}")

# Complex expression
print("\nComplex expression:")
expr = (Fraction(3, 4) * Fraction(2, 5) + Fraction(1, 2)) / Fraction(3, 8)
print(f"(3/4 * 2/5 + 1/2) / 3/8 = {expr}")

# Sum of series
print("\nSum of series:")
# 1/1 + 1/2 + 1/3 + 1/4 + 1/5
series_sum = sum(Fraction(1, i) for i in range(1, 6))
print(f"1/1 + 1/2 + 1/3 + 1/4 + 1/5 = {series_sum}")
print(f"  = {float(series_sum):.6f}")

# Harmonic series
print("\nHarmonic series (first 10 terms):")
harmonic = sum(Fraction(1, i) for i in range(1, 11))
print(f"H_10 = {harmonic}")
print(f"  ≈ {float(harmonic):.10f}")

# Factorial fractions
print("\nFactorial fractions:")
# 1/1! + 1/2! + 1/3! + 1/4!
import math
factorial_sum = sum(Fraction(1, math.factorial(i)) for i in range(1, 5))
print(f"1/1! + 1/2! + 1/3! + 1/4! = {factorial_sum}")
print(f"  = {float(factorial_sum):.10f}")
print(f"  (approaching e-1 = {math.e - 1:.10f})")

# Dividing whole cake
print("\nDividing cake:")
cake = Fraction(1)  # Whole cake
people = 
slice_size = cake / people
print(f"Cake for {people} people: {slice_size} each")
print(f"3 people get: {slice_size * 3}")

# Recipe scaling
print("\nRecipe scaling:")
original = Fraction(2, 3)  # 2/3 cup
scale_factor = Fraction(3, 2)  # 1.5x recipe
scaled = original * scale_factor
print(f"Original: {original} cup")
print(f"Scaled by {scale_factor}: {scaled} cup")
print(f"  = {float(scaled)} cup")

# Arithmetic operations

from fractions import Fraction

# Arithmetic
a = Fraction(3, 4)
b = Fraction(2, 5)

print(f"a = {a}")
print(f"b = {b}")
print()

# Addition
print("Addition:")
print(f"a + b = {a + b}")
print(f"  = {a.numerator * b.denominator + b.numerator * a.denominator}/{a.denominator * b.denominator}")

# Subtraction
print("\nSubtraction:")
print(f"a - b = {a - b}")

# Multiplication
print("\nMultiplication:")
print(f"a * b = {a * b}")
print(f"  = {a.numerator * b.numerator}/{a.denominator * b.denominator}")

# Division
print("\nDivision:")
print(f"a / b = {a / b}")
print(f"  = {a.numerator * b.denominator}/{a.denominator * b.numerator}")

# Floor division
print("\nFloor division:")
print(f"a // b = {a // b}")

# Modulo
print("\nModulo:")
print(f"a % b = {a % b}")

# Power
print("\nPower:")
f = Fraction(2, 3)
print(f"{f}^2 = {f ** 2}")
print(f"{f}^3 = {f ** 3}")
print(f"{f}^-1 = {f ** -1}")  # Reciprocal

# Negation
print("\nNegation:")
print(f"-a = {-a}")

# Absolute value
print("\nAbsolute value:")
neg = Fraction(-3, 4)
print(f"abs({neg}) = {abs(neg)}")

# Reciprocal
print("\nReciprocal:")
f = Fraction(3, 4)
print(f"Reciprocal of {f} = {1 / f}")
print(f"  = {Fraction(f.denominator, f.numerator)}")

# Mixed operations
print("\nMixed operations:")
print(f"Fraction + int: {a + 2}")
print(f"int + Fraction: {2 + a}")
print(f"Fraction * int: {a * 3}")
print(f"Fraction / int: {a / 2}")

# Chaining
print("\nChaining:")
result = Fraction(1, 2) + Fraction(1, 3) + Fraction(1, 6)
print(f"1/2 + 1/3 + 1/6 = {result}")

# Complex expression
print("\nComplex expression:")
expr = (Fraction(3, 4) * Fraction(2, 5) + Fraction(1, 2)) / Fraction(3, 8)
print(f"(3/4 * 2/5 + 1/2) / 3/8 = {expr}")

# Sum of series
print("\nSum of series:")
# 1/1 + 1/2 + 1/3 + 1/4 + 1/5
series_sum = sum(Fraction(1, i) for i in range(1, 6))
print(f"1/1 + 1/2 + 1/3 + 1/4 + 1/5 = {series_sum}")
print(f"  = {float(series_sum):.6f}")

# Harmonic series
print("\nHarmonic series (first 10 terms):")
harmonic = sum(Fraction(1, i) for i in range(1, 11))
print(f"H_10 = {harmonic}")
print(f"  ≈ {float(harmonic):.10f}")

# Factorial fractions
print("\nFactorial fractions:")
# 1/1! + 1/2! + 1/3! + 1/4!
import math
factorial_sum = sum(Fraction(1, math.factorial(i)) for i in range(1, 5))
print(f"1/1! + 1/2! + 1/3! + 1/4! = {factorial_sum}")
print(f"  = {float(factorial_sum):.10f}")
print(f"  (approaching e-1 = {math.e - 1:.10f})")

# Dividing whole cake
print("\nDividing cake:")
cake = Fraction(1)  # Whole cake
people = 
slice_size = cake / people
print(f"Cake for {people} people: {slice_size} each")
print(f"3 people get: {slice_size * 3}")

# Recipe scaling
print("\nRecipe scaling:")
original = Fraction(2, 3)  # 2/3 cup
scale_factor = Fraction(3, 2)  # 1.5x recipe
scaled = original * scale_factor
print(f"Original: {original} cup")
print(f"Scaled by {scale_factor}: {scaled} cup")
print(f"  = {float(scaled)} cup")

# Arithmetic operations

from fractions import Fraction

# Arithmetic
a = Fraction(3, 4)
b = Fraction(2, 5)

print(f"a = {a}")
print(f"b = {b}")
print()

# Addition
print("Addition:")
print(f"a + b = {a + b}")
print(f"  = {a.numerator * b.denominator + b.numerator * a.denominator}/{a.denominator * b.denominator}")

# Subtraction
print("\nSubtraction:")
print(f"a - b = {a - b}")

# Multiplication
print("\nMultiplication:")
print(f"a * b = {a * b}")
print(f"  = {a.numerator * b.numerator}/{a.denominator * b.denominator}")

# Division
print("\nDivision:")
print(f"a / b = {a / b}")
print(f"  = {a.numerator * b.denominator}/{a.denominator * b.numerator}")

# Floor division
print("\nFloor division:")
print(f"a // b = {a // b}")

# Modulo
print("\nModulo:")
print(f"a % b = {a % b}")

# Power
print("\nPower:")
f = Fraction(2, 3)
print(f"{f}^2 = {f ** 2}")
print(f"{f}^3 = {f ** 3}")
print(f"{f}^-1 = {f ** -1}")  # Reciprocal

# Negation
print("\nNegation:")
print(f"-a = {-a}")

# Absolute value
print("\nAbsolute value:")
neg = Fraction(-3, 4)
print(f"abs({neg}) = {abs(neg)}")

# Reciprocal
print("\nReciprocal:")
f = Fraction(3, 4)
print(f"Reciprocal of {f} = {1 / f}")
print(f"  = {Fraction(f.denominator, f.numerator)}")

# Mixed operations
print("\nMixed operations:")
print(f"Fraction + int: {a + 2}")
print(f"int + Fraction: {2 + a}")
print(f"Fraction * int: {a * 3}")
print(f"Fraction / int: {a / 2}")

# Chaining
print("\nChaining:")
result = Fraction(1, 2) + Fraction(1, 3) + Fraction(1, 6)
print(f"1/2 + 1/3 + 1/6 = {result}")

# Complex expression
print("\nComplex expression:")
expr = (Fraction(3, 4) * Fraction(2, 5) + Fraction(1, 2)) / Fraction(3, 8)
print(f"(3/4 * 2/5 + 1/2) / 3/8 = {expr}")

# Sum of series
print("\nSum of series:")
# 1/1 + 1/2 + 1/3 + 1/4 + 1/5
series_sum = sum(Fraction(1, i) for i in range(1, 6))
print(f"1/1 + 1/2 + 1/3 + 1/4 + 1/5 = {series_sum}")
print(f"  = {float(series_sum):.6f}")

# Harmonic series
print("\nHarmonic series (first 10 terms):")
harmonic = sum(Fraction(1, i) for i in range(1, 11))
print(f"H_10 = {harmonic}")
print(f"  ≈ {float(harmonic):.10f}")

# Factorial fractions
print("\nFactorial fractions:")
# 1/1! + 1/2! + 1/3! + 1/4!
import math
factorial_sum = sum(Fraction(1, math.factorial(i)) for i in range(1, 5))
print(f"1/1! + 1/2! + 1/3! + 1/4! = {factorial_sum}")
print(f"  = {float(factorial_sum):.10f}")
print(f"  (approaching e-1 = {math.e - 1:.10f})")

# Dividing whole cake
print("\nDividing cake:")
cake = Fraction(1)  # Whole cake
people = 
slice_size = cake / people
print(f"Cake for {people} people: {slice_size} each")
print(f"3 people get: {slice_size * 3}")

# Recipe scaling
print("\nRecipe scaling:")
original = Fraction(2, 3)  # 2/3 cup
scale_factor = Fraction(3, 2)  # 1.5x recipe
scaled = original * scale_factor
print(f"Original: {original} cup")
print(f"Scaled by {scale_factor}: {scaled} cup")
print(f"  = {float(scaled)} cup")

convert.py
# Converting and formatting

from fractions import Fraction
from decimal import Decimal
import math

# Convert to other types
print("Convert to other types:")
f = Fraction(3, 4)

print(f"Fraction: {f}")
print(f"float: {float(f)}")
print(f"int (truncate): {int(f)}")
print(f"str: {str(f)}")
print()

# To Decimal
print("To Decimal:")
dec = Decimal(f.numerator) / Decimal(f.denominator)
print(f"{f} as Decimal: {dec}")

# Different fractions
print("\nDifferent fractions to float:")
fractions = [Fraction(1, 2), Fraction(1, 3), Fraction(1, 4), Fraction(2, 3)]
for frac in fractions:
    print(f"{frac} = {float(frac):.10f}")

# Formatting
print("\nFormatting:")
f = Fraction(22, 7)  # Approximation of pi
print(f"Default: {f}")
print(f"Float: {float(f):.6f}")
print(f"Percentage: {float(f) * 100:.2f}%")

# Mixed number representation
print("\nMixed number representation:")
def to_mixed_number(frac):
    """Convert improper fraction to mixed number."""
    whole = frac.numerator // frac.denominator
    remainder = frac.numerator % frac.denominator
    if remainder == 0:
        return f"{whole}"
    elif whole == 0:
        return f"{remainder}/{frac.denominator}"
    else:
        return f"{whole} {remainder}/{frac.denominator}"

improper_fracs = [Fraction(7, 4), Fraction(11, 3), Fraction(5, 2), Fraction(8, 4)]
for f in improper_fracs:
    print(f"{f} = {to_mixed_number(f)}")

# Decimal to Fraction
print("\nDecimal to Fraction:")
decimals = [0.5, 0.25, 0.75, 0.125, 0.333]
for d in decimals:
    f = Fraction(d).limit_denominator(1000)
    print(f"{d} ≈ {f}")

# String to Fraction
print("\nString to Fraction:")
strings = ['1/2', '3/4', '0.5', '0.75', '22/7']
for s in strings:
    f = Fraction(s)
    print(f"'{s}' = {f} = {float(f):.6f}")

# Pi approximations
print("\nPi approximations:")
pi_approx = [
    Fraction(22, 7),
    Fraction(355, 113),
    Fraction(103993, 33102),
]
for f in pi_approx:
    error = abs(float(f) - math.pi)
    print(f"{f} = {float(f):.10f} (error: {error:.2e})")
print(f"Actual π = {math.pi:.10f}")

# Common percentages as fractions
print("\nCommon percentages:")
percentages = [10, 20, 25, 33.33, 50, 75, 100]
for pct in percentages:
    f = Fraction(str(pct / 100)).limit_denominator(100)
    print(f"{pct}% = {f} = {float(f):.4f}")

# Continued fractions (representation)
print("\nContinued fraction representation:")
def continued_fraction(frac, max_terms=10):
    """Get continued fraction representation."""
    terms = []
    n, d = frac.numerator, frac.denominator
    for _ in range(max_terms):
        if d == 0:
            break
        q, r = divmod(n, d)
        terms.append(q)
        n, d = d, r
        if r == 0:
            break
    return terms

f = Fraction(22, 7)
cf = continued_fraction(f)
print(f"{f}: {cf}")

f = Fraction(355, 113)
cf = continued_fraction(f)
print(f"{f}: {cf}")

# Reconstruct from numerator/denominator
print("\nReconstruct fraction:")
num, den = 3, 4
reconstructed = Fraction(num, den)
print(f"From {num}/{den}: {reconstructed}")

# Using with f-strings
print("\nF-string formatting:")
f = Fraction(3, 4)
print(f"Fraction: {f}")
print(f"As float: {float(f):.2f}")
print(f"As percentage: {float(f):.1%}")

comparison.py
# Comparison operations

from fractions import Fraction

# Comparison
a = Fraction(3, 4)
b = Fraction(2, 3)
c = Fraction(6, 8)  # Same as 3/4

print(f"a = {a}")
print(f"b = {b}")
print(f"c = {c}")
print()

# Equality
print("Equality:")
print(f"a == b: {a == b}")
print(f"a == c: {a == c}")
print(f"a != b: {a != b}")

# Ordering
print("\nOrdering:")
print(f"a < b: {a < b}")
print(f"a <= b: {a <= b}")
print(f"a > b: {a > b}")
print(f"a >= b: {a >= b}")

# Compare with numbers
print("\nCompare with numbers:")
f = Fraction(1, 2)
print(f"{f} == 0.5: {f == 0.5}")
print(f"{f} > 0.4: {f > 0.4}")
print(f"{f} < 1: {f < 1}")

# max and min
print("\nmax and min:")
fractions = [Fraction(1, 2), Fraction(1, 3), Fraction(2, 3), Fraction(1, 4)]
print(f"Fractions: {fractions}")
print(f"Max: {max(fractions)}")
print(f"Min: {min(fractions)}")

# Sort
print("\nSort:")
unsorted = [Fraction(2, 3), Fraction(1, 4), Fraction(3, 4), Fraction(1, 2)]
sorted_fracs = sorted(unsorted)
print(f"Unsorted: {unsorted}")
print(f"Sorted: {sorted_fracs}")

# Sort descending
print("\nSort descending:")
desc = sorted(unsorted, reverse=True)
print(f"Descending: {desc}")

# Find max in different forms
print("\nCompare different representations:")
vals = [Fraction(3, 4), 0.75, Fraction('0.75')]
print(f"Values: {vals}")
print(f"All equal: {vals[0] == vals[1] == vals[2]}")

# Range check
print("\nRange check:")
value = Fraction(1, 2)
lower = Fraction(1, 4)
upper = Fraction(3, 4)
in_range = lower <= value <= upper
print(f"{value} in [{lower}, {upper}]: {in_range}")

# Zero comparison
print("\nZero comparison:")
zero = Fraction(0)
pos = Fraction(1, 2)
neg = Fraction(-1, 2)

print(f"{zero} == 0: {zero == 0}")
print(f"{pos} > 0: {pos > 0}")
print(f"{neg} < 0: {neg < 0}")

# Proper vs improper fractions
print("\nProper vs improper fractions:")
proper = Fraction(3, 4)  # < 1
improper = Fraction(5, 4)  # > 1

print(f"{proper} is proper (< 1): {proper < 1}")
print(f"{improper} is improper (> 1): {improper > 1}")

# Compare fractions visually
print("\nCompare fractions:")
fracs = [Fraction(1, 2), Fraction(1, 3), Fraction(1, 4), Fraction(1, 5)]
for f in fracs:
    bar = '█' * int(f * 20)
    print(f"{str(f):>4} = {float(f):.4f} {bar}")

# Unit fractions (1/n)
print("\nUnit fractions (sorted):")
units = [Fraction(1, i) for i in range(2, 11)]
for f in units:
    print(f"1/{f.denominator} = {float(f):.6f}")

# Egyptian fractions comparison
print("\nEgyptian fractions (distinct unit fractions):")
# 5/6 = 1/2 + 1/3
frac = Fraction(5, 6)
decomp = Fraction(1, 2) + Fraction(1, 3)
print(f"{frac} == 1/2 + 1/3: {frac == decomp}")

# Tolerance comparison (not usually needed)
print("\nTolerance comparison (for demonstration):")
f1 = Fraction(1, 3)
f2 = Fraction(333, 1000)  # Approximate 1/3
diff = abs(f1 - f2)
tolerance = Fraction(1, 100)
approx_equal = diff <= tolerance
print(f"{f1} ≈ {f2} (tolerance {tolerance}): {approx_equal}")
print(f"Difference: {diff}")

math.py
# Mathematical operations

from fractions import Fraction
import math

# GCD and simplification
print("GCD and simplification:")

def show_gcd(a, b):
    """Show GCD and simplification."""
    g = math.gcd(a, b)
    print(f"gcd({a}, {b}) = {g}")
    print(f"  {a}/{b} = {a//g}/{b//g}")

show_gcd(6, 8)
show_gcd(12, 16)
show_gcd(100, 150)
print()

# LCM (least common multiple)
print("LCM for adding fractions:")
def show_lcm_addition(f1, f2):
    """Show LCM method for adding fractions."""
    lcm = (f1.denominator * f2.denominator) // math.gcd(f1.denominator, f2.denominator)
    print(f"{f1} + {f2}:")
    print(f"  LCM of {f1.denominator} and {f2.denominator} = {lcm}")
    print(f"  = {f1.numerator * (lcm // f1.denominator)}/{lcm} + {f2.numerator * (lcm // f2.denominator)}/{lcm}")
    print(f"  = {f1 + f2}")

show_lcm_addition(Fraction(1, 3), Fraction(1, 4))
show_lcm_addition(Fraction(2, 5), Fraction(3, 7))
print()

# Powers and roots
print("Powers:")
f = Fraction(2, 3)
for exp in range(1, 5):
    result = f ** exp
    print(f"({f})^{exp} = {result} = {float(result):.6f}")

print("\nNegative powers (reciprocals):")
for exp in range(1, 4):
    result = f ** -exp
    print(f"({f})^-{exp} = {result} = {float(result):.6f}")

print("\nSquare root (as float):")
f = Fraction(9, 16)
sqrt = math.sqrt(float(f))
print(f"√{f} = {sqrt}")
sqrt_frac = Fraction(3, 4)  # Manual
print(f"  = {sqrt_frac} (exact)")

# Series calculations
print("\nGeometric series:")
# Sum: a + ar + ar² + ar³ + ... (n terms)
def geometric_sum(a, r, n):
    """Sum of geometric series."""
    if r == 1:
        return a * n
    return a * (1 - r**n) / (1 - r)

a = Fraction(1, 2)
r = Fraction(1, 2)
for n in [3, 5, 10]:
    s = geometric_sum(a, r, n)
    print(f"Sum of {n} terms (a={a}, r={r}): {s} = {float(s):.10f}")

# Approaching limit
print("\nApproaching limit (1 - 1/2^n):")
for n in range(1, 11):
    limit = 1 - Fraction(1, 2**n)
    print(f"n={n:2}: {limit} = {float(limit):.10f}")

# Fibonacci with fractions
print("\nFibonacci ratios:")
def fibonacci_ratio(n):
    """Get ratio of consecutive Fibonacci numbers."""
    if n <= 1:
        return None
    a, b = Fraction(0), Fraction(1)
    for _ in range(n):
        a, b = b, a + b
    return b / a if a != 0 else None

golden = (1 + math.sqrt(5)) / 2
print("Ratio of consecutive Fibonacci numbers (approaching φ):")
for n in range(5, 16):
    ratio = fibonacci_ratio(n)
    if ratio:
        error = abs(float(ratio) - golden)
        print(f"F({n})/F({n-1}) = {ratio.limit_denominator(10000)} ≈ {float(ratio):.10f} (error: {error:.2e})")
print(f"Golden ratio φ = {golden:.10f}")

# Harmonic mean
print("\nHarmonic mean:")
def harmonic_mean(nums):
    """Calculate harmonic mean."""
    return len(nums) / sum(Fraction(1, x) for x in nums)

values = [Fraction(2), Fraction(3), Fraction(4)]
hm = harmonic_mean(values)
print(f"Harmonic mean of {[float(v) for v in values]}: {hm} = {float(hm):.6f}")

# Egyptian fractions
print("\nEgyptian fraction decomposition:")
def egyptian_fractions(frac, max_terms=10):
    """Decompose fraction into sum of unit fractions."""
    terms = []
    remaining = frac
    n = 2
    while remaining > 0 and len(terms) < max_terms:
        unit = Fraction(1, n)
        if unit <= remaining:
            terms.append(n)
            remaining -= unit
        n += 1
        if remaining == 0:
            break
    return terms

f = Fraction(5, 6)
decomp = egyptian_fractions(f)
print(f"{f} = {' + '.join(f'1/{d}' for d in decomp)}")
# Verify
verify = sum(Fraction(1, d) for d in decomp)
print(f"Verify: {verify}")

# Mediant
print("\nMediant (between two fractions):")
def mediant(f1, f2):
    """Calculate mediant of two fractions."""
    return Fraction(f1.numerator + f2.numerator, f1.denominator + f2.denominator)

a, b = Fraction(1, 3), Fraction(1, 2)
m = mediant(a, b)
print(f"Mediant of {a} and {b}: {m} = {float(m):.6f}")
print(f"Check: {float(a):.6f} < {float(m):.6f} < {float(b):.6f}")

Fraction A numeric type representing exact rational numbers as a ratio of two integers, with automatic simplification to lowest terms.
automatic simplification Fractions automatically reduce to lowest terms - Fraction(6, 8) becomes Fraction(3, 4).
limit_denominator() Finds the closest fraction with a denominator at or below a specified limit - useful for approximating floats as simple fractions.

Exercise: practical.py

Scale a recipe by a fraction and calculate total ingredient amounts