Skip to main content

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

Publishing is automated by GitHub Actions on pushes to main and version tags. Add a repository secret named PYPI_API_TOKEN; the workflow checks the project files, runs hatch run test, then runs hatch run publish.

License

fracpylib is distributed under the terms of the MIT license.

find me on daily.dev:

Brickboss's Dev Card

Metadata

Release files for fracpylib 2.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fracpylib 2.2.1
File Size Uploaded
fracpylib-2.2.1.tar.gz 12.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fracpylib 2.2.1
File Interpreter ABI Platform
fracpylib-2.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 22.8 kB

Release files / fracpylib-2.2.1.tar.gz

Download URL fracpylib-2.2.1.tar.gz
Size 12.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f4c41ce13acaee9d519a8d3ccf2d921009bc84e2095d6ae65d0ddc79a92a0378
BLAKE2b-256 checksum
How to use checksums
888f3c452bd63a4ded30fad320be1bb1bcd58abf420624e6d493a1ef9e15c5c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / fracpylib-2.2.1-py3-none-any.whl

Download URL fracpylib-2.2.1-py3-none-any.whl
Size 10.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5efd9a4933bd0c384463762a2db725b001ea496b77d88d710dd09f1cde21dcfe
BLAKE2b-256 checksum
How to use checksums
9488cc23aa005a02dba8d1818e4adfa52fba55715a96fae2e4d1f262051b3c54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

2.2.1 This release

2 release files

2.2.0

2 release files

2.1.2

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page