Skip to main content

Exact fraction arithmetic, mixed fractions, and recurring decimal conversion.

Project description

fracpylib

PyPI - Version PyPI - Python Version

fracpylib is a small, dependency-free Python library for exact fraction arithmetic, mixed fractions, and recurring decimal conversion.

It keeps fractions normalized, supports natural operators, and can round-trip values such as 1.1(6) without losing precision to floats.

Contents

Highlights

Feature Example
Canonical immutable fractions Fraction(6, -8) becomes Fraction(-3, 4)
Integer-friendly operators 1 + Fraction(1, 2) == Fraction(3, 2)
Mixed fractions MixedFraction(1, 5, 4) becomes 2 1/4
Periodic decimal parsing Fraction.from_decimal("0.(09)") == Fraction(1, 11)
Periodic decimal rendering Fraction(1, 6).to_periodic() == "0.1(6)"
Decimal utility checks FracMisc.is_terminating(Fraction(1, 8))

Installation

pip install fracpylib

Quick Start

from fracpylib.fractionlib import Fraction, MixedFraction

a = Fraction(2, 4)
b = Fraction.from_decimal("1.1(6)")

print(a)          # 1/2
print(b)          # 7/6
print(a + b)      # 5/3
print(2 * a)      # 1
print(float(b))   # 1.1666666666666667

mixed = MixedFraction(1, 5, 4)
print(mixed)             # 2 1/4
print(mixed.to_fraction())  # 9/4

Fraction API

Fraction stores every value in reduced form with a positive denominator. Values are immutable after construction, so equality, hashing, string output, and comparisons all use the same canonical representation.

from fracpylib.fractionlib import Fraction

x = Fraction(4, 8)
y = Fraction(3, 4)

assert x.as_tuple() == (1, 2)
assert x + y == Fraction(5, 4)
assert x - 1 == Fraction(-1, 2)
assert x * y == Fraction(3, 8)
assert x / y == Fraction(2, 3)
assert x ** -2 == Fraction(4, 1)

Helpful methods:

from fracpylib.fractionlib import Fraction, MixedFraction

half = Fraction(1, 2)

assert half.reciprocal() == Fraction(2, 1)
assert half.to_mixed() == MixedFraction(0, 1, 2)
assert half.to_periodic() == "0.5"

Mixed Fractions

MixedFraction accepts whole, numerator, and denominator pieces, then normalizes itself through an improper Fraction. Pass the sign on the whole part and keep the fractional numerator non-negative.

from fracpylib.fractionlib import Fraction, MixedFraction

mf = MixedFraction(1, 5, 4)

assert str(mf) == "2 1/4"
assert mf.to_fraction() == Fraction(9, 4)
assert mf + Fraction(1, 4) == Fraction(5, 2)
assert 3 - mf == Fraction(3, 4)

Negative values are normalized too:

assert str(MixedFraction.from_fraction(Fraction(-3, 2))) == "-1 1/2"
assert str(MixedFraction.from_fraction(Fraction(-1, 2))) == "-1/2"

Periodic Decimals

Use Fraction.from_decimal() when you already have a decimal string. Repeating digits go in parentheses.

from decimal import Decimal
from fracpylib.fractionlib import Fraction

assert Fraction.from_decimal("0.(3)") == Fraction(1, 3)
assert Fraction.from_decimal("1.1(6)") == Fraction(7, 6)
assert Fraction.from_decimal("-0.1(6)") == Fraction(-1, 6)
assert Fraction.from_decimal(".125") == Fraction(1, 8)
assert Fraction.from_decimal(Decimal("1.20")) == Fraction(6, 5)

Use Fraction.from_periodic() when the whole, non-repeating, and repeating parts are already separated:

assert Fraction.from_periodic(whole=1, non_repeating="1", repeating="6") == Fraction(7, 6)
assert Fraction.from_periodic(whole=0, non_repeating="1", repeating="6", sign=-1) == Fraction(-1, 6)

Render exact decimals with to_periodic():

assert Fraction(1, 2).to_periodic() == "0.5"
assert Fraction(1, 3).to_periodic() == "0.(3)"
assert Fraction(1, 6).to_periodic() == "0.1(6)"
assert Fraction(-22, 7).to_periodic() == "-3.(142857)"

Utilities

FracMath exposes arithmetic helpers for users who prefer function calls over operators. FracMisc contains common fraction predicates.

from fracpylib.fractionlib import Fraction, FracMath, FracMisc

assert FracMath.add(Fraction(1, 2), Fraction(1, 3)) == Fraction(5, 6)
assert FracMisc.is_proper(Fraction(2, 3)) is True
assert FracMisc.is_improper(Fraction(3, 2)) is True
assert FracMisc.is_terminating(Fraction(1, 8)) is True
assert FracMisc.has_repeating_decimal(Fraction(1, 3)) is True

The old camelCase utility names are still available:

assert FracMisc.isProper(Fraction(2, 3)) is True
assert FracMisc.isImproper(Fraction(3, 2)) is True

Development

Create or activate a virtual environment, then run:

python -m pip install -e . pytest
python -m pytest -q

Build the package locally with:

python -m build

License

fracpylib is distributed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fracpylib-2.1.1.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fracpylib-2.1.1-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file fracpylib-2.1.1.tar.gz.

File metadata

  • Download URL: fracpylib-2.1.1.tar.gz
  • Upload date:
  • Size: 11.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for fracpylib-2.1.1.tar.gz
Algorithm Hash digest
SHA256 269dae18698085cd9c2ce0be21bb4ef9581bd8db27c24c2dc1bb28f04a3e933e
MD5 e00e4c46daf8d9a5734163e622b8c303
BLAKE2b-256 dc4472d98f9c53f54edf65a7d40ef4a22caa179cdb5aae6f4c6b4eb09b54273d

See more details on using hashes here.

File details

Details for the file fracpylib-2.1.1-py3-none-any.whl.

File metadata

  • Download URL: fracpylib-2.1.1-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for fracpylib-2.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b3afeb2c9b41256509d68ee05432fe68de898d02aa33faf7335403b0231ee786
MD5 66a9718950dabea4e12f9451ab0fb581
BLAKE2b-256 d11a7609d6d30dca7d4fec23ff52e2f1ef136130bc1801658f47783a19740716

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page