Skip to content

wilfredinni/dinero

Repository files navigation

Dinero

Make exact monetary calculations.

PyPI Build Status CodeQL Status Codecov License

This project is inspired by the excellent dinero.js library.

Python Decimal instances are enough for basic monetary calculations, but when you face more complex use-cases they often show limitations and are not so intuitive to work with. Dinero provides a cleaner and easier to use API while still relying on the standard library. So it's still Decimal, but easier.

Read the Documentation

Install

pip install dinero

The problem

Using floats to do exact calculations in Python can be dangerous. When you try to find out how much 2.32 x 3 is, Python tells you it's 6.959999999999999. For some calculations, that’s fine. But if you are calculating a transaction involving money, that’s not what you want to see. Sure, you could round it off, but that's a little hacky.

>>> 2.32 * 3 == 6.96
False
>>> 2.32 * 3
6.959999999999999

You can read How to Count Money Exactly in Python to get a better idea.

Why Dinero?

A Dinero object represent a specific monetary value. It comes with methods for creating, parsing, manipulating, testing and formatting.

>>> from dinero import Dinero
>>> from dinero.currencies import USD
>>>
>>> Dinero(2.32, USD) * 3 == Dinero(6.96. USD)
True

Currencies

Dinero give you access to more than 100 different currencies:

>>> from dinero.currencies import USD, EUR, GBP, INR, CLP
>>> amount = Dinero(2.32, EUR)
>>> amount.format(symbol=True, currency=True)
'€2.32 EUR'
>>>
>>> amount.raw_amount
Decimal('2.32')

More about currencies.

Operations

Operations can be performed between Dinero objects or between Dinero objects and numbers:

>>> total = Dinero(456.343567, USD) + 345.32 *  3
>>> print(total)
# 1,492.30
>>> total = (Dinero(345.32, USD).multiply(3)).add(456.343567)
>>> print(total)
# 1,492.30

More about operations.

Comparisons

Dinero objects can be compared to each other by using Python comparison operators:

>>> Dinero(100, EUR) == Dinero(100, EUR)
True
>>> Dinero(100, EUR).equals_to(Dinero(100, EUR))
True

More about comparisons.

Tools

Dinero give you access to some useful tools that allow you to perform common monetary calculations, like percentages, VAT, simple and compound interests, etc.

from dinero import Dinero
from dinero.currencies import USD
from dinero.tools import calculate_compound_interest

principal = Dinero("2000", USD)
total_interest = calculate_compound_interest(
    principal=principal,
    interest_rate=5,
    duration=10,
    compound_frequency=12,
)
total_interest.format(symbol=True, currency=True)
'$1,294.02 USD'

See all the available tools in the tools section.

Custom currencies

You can easily create custom currencies:

from dinero import Dinero

BTC = {
    "code": "BTC",
    "base": 10,
    "exponent": 2,
    "symbol": "₿",
}

Dinero(1000.5, BTC)
Dinero(amount=1000.5, currency={'code': 'BTC', 'base': 10, 'exponent': 2, 'symbol': '₿'})

More about custom currencies.