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.0.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.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: fracpylib-2.1.0.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.0.tar.gz
Algorithm Hash digest
SHA256 f7a34955363777c0d21d2adb97c25db52a93ced1eaead2493591329b1face763
MD5 07b161f72f34337bf2d7899fff0591dd
BLAKE2b-256 f1e3f78291d934cfa77a789e9a7e9580c1ea10311f2b7458ed451d0d6595dcc5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: fracpylib-2.1.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 32317784f4605aed380d85821f3aed53c29cf59ea37f4c32fd54a9940b126c0e
MD5 636695e300326b42e36357446542067b
BLAKE2b-256 a7229c7e1ddab22b00e480a0e63df8909bbbdda9a14f755d69497c1687d95e72

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