Usage
Basic Usage
Creating Money Objects
The core of the library is the Money class, which represents a monetary amount in a specific currency:
from moneyx import Money
# Create money objects
amount1 = Money("19.99", "USD") # From string
amount2 = Money(19.99, "USD") # From float (will be converted to Decimal)
amount3 = Money(1999, "JPY") # JPY has 0 decimal places
Currency Formatting
Format money with currency symbols and locale-specific formatting:
from moneyx import Money
price = Money("1234.56", "USD")
# Default formatting
print(price.format()) # $1,234.56
# Locale-specific formatting
print(price.format_locale("en_US")) # $1,234.56
print(price.format_locale("de_DE")) # 1.234,56 $
print(price.format_locale("fr_FR")) # 1 234,56 $
print(price.format_locale("ja_JP")) # $1,234.56
Arithmetic Operations
Addition and Subtraction
Add and subtract Money objects with the same currency:
from moneyx import Money
price = Money("19.99", "USD")
tax = Money("1.60", "USD")
# Using methods
total = price.add(tax) # $21.59
change = Money("50.00", "USD").subtract(total) # $28.41
# Using operators
total = price + tax # $21.59
change = Money("50.00", "USD") - total # $28.41
# Error if currencies don't match
try:
usd = Money("10.00", "USD")
eur = Money("10.00", "EUR")
usd.add(eur) # Raises ValueError: Currency mismatch
except ValueError as e:
print(e)
Multiplication
Multiply a Money object by a number:
from moneyx import Money
price = Money("19.99", "USD")
# Calculate total for 3 items
total = price.multiply(3) # $59.97
# Using operators
total = price * 3 # $59.97
# Apply a discount
discount = price.multiply(0.20) # $4.00 (20% of price)
discounted = price.subtract(discount) # $15.99
Working with Cents
Many financial applications store monetary values in the smallest currency unit (cents, pence, etc.). Here’s how to work with cents in moneyx:
from decimal import Decimal
from moneyx import Money
# Converting from cents to dollars
cents_amount = 1299 # $12.99 in cents
price = Money(cents_amount / 100, "USD")
print(price.format()) # $12.99
# For more precision, use Decimal
cents_amount = 1299
price = Money(Decimal(cents_amount) / Decimal("100"), "USD")
print(price.format()) # $12.99
# Converting a Money object to cents
dollars = Money("45.67", "USD")
cents = int(dollars.amount * 100) # 4567
print(f"Amount in cents: {cents}")
# Working with currencies that have 0 decimal places
yen_amount = 1000 # ¥1000 (JPY has 0 decimal places)
jpy = Money(yen_amount, "JPY")
print(jpy.format()) # ¥1,000
Note that moneyx handles the smallest currency unit internally, but converting to/from cents may be necessary when interfacing with other systems or databases that store monetary values as integers.
Rounding Strategies
Moneyx provides multiple rounding strategies for different financial scenarios:
from moneyx import Money, RoundingMode
# Default rounding (HALF_UP)
m1 = Money("2.5", "USD") # Rounds to 3 when needed
# Banker's rounding (HALF_EVEN)
m2 = Money("2.5", "USD", rounding=RoundingMode.BANKERS) # Rounds to 2 when needed
m3 = Money("3.5", "USD", rounding=RoundingMode.BANKERS) # Rounds to 4 when needed
# Other rounding modes
m4 = Money("2.5", "USD", rounding=RoundingMode.HALF_ODD) # Rounds to 3
m5 = Money("2.5", "USD", rounding=RoundingMode.HALF_TOWARDS_ZERO) # Rounds to 2
m6 = Money("2.5", "USD", rounding=RoundingMode.HALF_AWAY_FROM_ZERO) # Rounds to 3
m7 = Money("2.5", "USD", rounding=RoundingMode.DOWN) # Rounds to 2
m8 = Money("2.5", "USD", rounding=RoundingMode.UP) # Rounds to 3
m9 = Money("2.5", "USD", rounding=RoundingMode.CEILING) # Rounds to 3
m10 = Money("2.5", "USD", rounding=RoundingMode.FLOOR) # Rounds to 2
Currency Operations
Working with Currencies
Access and manage currency information:
from moneyx import Money
from moneyx.currency import Currency
# Currency information
usd = Money("100.00", "USD")
print(f"Symbol: {usd.currency.symbol}") # $
print(f"Name: {usd.currency.name}") # US Dollar
print(f"Decimals: {usd.currency.decimals}") # 2
print(f"Countries: {usd.currency.countries}") # List of countries
# Find currencies by country
swiss_currencies = Currency.get_by_country("SWITZERLAND")
for curr in swiss_currencies:
print(f"{curr.code}: {curr.name}") # CHF, CHE, CHW
# Find currency by numeric code
eur = Currency.get_by_number("978")
print(f"{eur.code}: {eur.name}") # EUR: Euro
Currency Conversion
Convert between currencies with specified rates:
from moneyx import Money
# Convert USD to EUR
usd = Money("100.00", "USD")
eur = usd.convert_to("EUR", rate=0.85) # €85.00
# Convert back
usd_again = eur.convert_to("USD", rate=1.18) # $100.30 (may differ due to rounding)
Advanced Features
Allocation
Allocate a money amount according to specified ratios:
from moneyx import Money
total = Money("100.00", "USD")
# Allocate by ratio
allocated = total.allocate([1, 2, 3, 4]) # Divide in ratio 1:2:3:4
for i, amount in enumerate(allocated):
print(f"Person {i+1} gets: {amount.format()}")
# Outputs:
# Person 1 gets: $10.00
# Person 2 gets: $20.00
# Person 3 gets: $30.00
# Person 4 gets: $40.00
# Split evenly
shared = total.split_evenly(3) # Divide equally among 3 people
for i, amount in enumerate(shared):
print(f"Person {i+1} pays: {amount.format()}")
# Outputs:
# Person 1 pays: $33.34
# Person 2 pays: $33.33
# Person 3 pays: $33.33
Tax Calculations
Calculate tax or extract tax from inclusive amounts:
from moneyx import Money
price = Money("100.00", "USD")
# Add 7% tax
with_tax = price.with_tax(7)
print(f"Price with tax: {with_tax.format()}") # $107.00
# Extract tax from inclusive amount
tax_info = with_tax.extract_tax(7)
print(f"Base amount: {tax_info['base'].format()}") # $100.00
print(f"Tax amount: {tax_info['tax'].format()}") # $7.00
Serialization
Serialize and deserialize money objects:
from moneyx import Money
import json
price = Money("99.99", "USD")
# To/from JSON
json_str = price.to_json()
print(json_str) # {"amount": "99.99", "currency": "USD", ...}
# Recreate from JSON
restored = Money.from_json(json_str)
print(restored.format()) # $99.99
# To/from dictionary
data = price.to_dict()
print(data) # {'amount': '99.99', 'currency': 'USD', ...}
# Recreate from dictionary
restored = Money.from_dict(data)
print(restored.format()) # $99.99
Best Practices
Always use strings for input: When creating Money objects, prefer using strings for the amount to avoid floating-point precision issues.
# Good Money("19.99", "USD") # Avoid Money(19.99, "USD")
Check currencies before operations: Ensure that operations are performed between Money objects of the same currency.
Use appropriate rounding modes: Choose the correct rounding mode for your financial context.
Be aware of currency precision: Different currencies have different decimal precisions.
Money("100", "JPY") # JPY has 0 decimal places Money("100.00", "USD") # USD has 2 decimal places Money("100.000", "BHD") # BHD has 3 decimal places
Validate inputs: Catch potential exceptions from invalid inputs.
try: amount = Money(user_input, currency_code) except (ValueError, PrecisionError, InvalidCurrencyError) as e: print(f"Invalid input: {e}")