A Python library for currency redenomination
Project description
RedenPy
A simple, robust Python utility for currency redenomination.
RedenPy is designed to parse various money formats—including strings with currency symbols and different decimal/thousand separators—and apply a redenomination by a specified number of digits (e.g., converting 1,000,000 to 1,000).
✨ Features
- Handles Multiple Input Types: Accepts
int,float,Decimal, andstrinputs. - Robust String Parsing: Automatically cleans currency symbols (
$,Rp,€, etc.) and non-numeric characters. - International Format Support: Intelligently parses both US-style (
1,000.00) and EU-style (1.000,00) number formats. - Flexible Output: Returns the redenominated value as a
str,int,float, orDecimal. - Accurate Calculations: Uses the
Decimaltype internally for all calculations to avoid floating-point errors.
📦 Installation
Install RedenPy directly from PyPI:
pip install redenpy
🚀 Quick Start
from redenpy.core import RedenPy
# 1. Initialize the redenominator
# We want to remove 3 digits (e.g., 1,000 -> 1)
rd = RedenPy(digit=3, rule=None) # 'rule' is reserved for future rounding logic
# 2. Perform redenomination on various inputs
# --- Example 1: Handling International String Formats ---
val_str_us = "$ 1,575,505.75" # Dot as decimal
val_str_eu = "€ 1.575.505,75" # Comma as decimal
# Returns a 'Decimal' object
new_val_us = rd.redenomination(val_str_us, output_type=Decimal)
new_val_eu = rd.redenomination(val_str_eu, output_type=Decimal)
print(f"'{val_str_us}' -> {new_val_us}")
# Output: '$ 1,575,505.75' -> 1575.51
print(f"'{val_str_eu}' -> {new_val_eu}")
# Output: '€ 1.575.505,75' -> 1575.51
# --- Example 2: Controlling Output Type ---
old_val = 1575800
# Get a formatted string with fractions
val_str = rd.redenomination(old_val, fractional=True, output_type=str)
print(f"{old_val} -> '{val_str}' (as string)")
# Output: 1575800 -> '1575,80' (as string)
# Get an integer (truncates the decimal)
val_int = rd.redenomination(old_val, output_type=int)
print(f"{old_val} -> {val_int} (as integer)")
# Output: 1575800 -> 1575 (as integer)
# Get a float
val_float = rd.redenomination(old_val, output_type=float)
print(f"{old_val} -> {val_float} (as float)")
# Output: 1575800 -> 1575.8 (as float)
📖 API Reference
RedenPy(digit, rule)
Initializes the redenomination class.
- digit (int): The number of digits to remove (e.g., 3 for 1,000 -> 1). This is equivalent to dividing by $10^{digit}$.
- rule (any): A parameter intended for future, more complex rounding rules (e.g., specific central bank regulations). Note: This parameter is not currently used in the logic. All calculations default to ROUND_HALF_UP to 2 decimal places.
redenomination(money, fractional=False, output_type=str)
Performs the redenomination on a given money value.
-
money (str | int | float | Decimal): The amount to convert.
-
fractional (bool): This parameter only affects the output_type=str.
- True: Returns the value with a fractional part, separated by a comma (e.g., "1575,51").
- False: Returns only the whole number part (e.g., "1575").
-
output_type (type): The desired return type for the converted value.
- str: Returns a formatted string. Behavior is controlled by fractional.
- Decimal: Returns the redenominated value as a Decimal object, rounded to 2 decimal places.
- float: Returns the redenominated value as a float.
- int: Returns the redenominated value as an int (note: this truncates any decimal part after rounding, e.g., 1575.51 becomes 1575).
redenomination_with_rules(money, output_type=str)
accepts a comprehensive rule dictionary that allows full customization of the redenomination process. Below are all possible rules that can be configured.
Complete Rule Reference
1. digit_removal (Integer)
Overrides the default digit removal specified in the constructor.
| Property | Type | Description | Example |
|---|---|---|---|
digit_removal |
int |
Number of digits to remove from the right | 3 removes 3 zeros (1,000,000 → 1,000) |
Example:
rule = {"digit_removal": 6}
# 1,000,000 → 1 (removes 6 digits)
2. rounding (Object)
Controls how numbers are rounded during redenomination.
| Property | Type | Options | Default | Description |
|---|---|---|---|---|
method |
string |
"half_up", "half_down", "up", "down", "half_even", "ceiling", "floor", "truncate" |
"half_up" |
Rounding method to apply |
precision |
int |
0, 1, 2, 3, etc. |
2 |
Number of decimal places to keep |
Rounding Methods Explained:
"half_up": Round 0.5 up (1.5 → 2, -1.5 → -2)"half_down": Round 0.5 down (1.5 → 1, -1.5 → -1)"up": Always round away from zero (1.1 → 2, -1.1 → -2)"down": Always round toward zero (1.9 → 1, -1.9 → -1)"half_even": Banker's rounding - round to nearest even (1.5 → 2, 2.5 → 2)"ceiling": Always round up (1.1 → 2, -1.1 → -1)"floor": Always round down (1.9 → 1, -1.9 → -2)"truncate": Remove decimal part (1.9 → 1, -1.9 → -1)
Example:
rule = {
"rounding": {
"method": "down",
"precision": 0
}
}
# 1,234.56 → 1,234 (no decimals, always round down)
3. fractional_policy (Object)
Controls when and how fractional/decimal parts are displayed.
| Property | Type | Options | Default | Description |
|---|---|---|---|---|
always_show |
bool |
true, false |
false |
Always display decimals even if .00 |
threshold |
float or null |
Any decimal value | null |
Only show decimals if fractional part ≥ threshold |
context |
string |
"always", "never", "auto" |
"auto" |
When to show decimal part |
Context Options:
"always": Always show decimals (1 → 1.00)"never": Never show decimals (1.75 → 1)"auto": Show decimals only if non-zero (1.00 → 1, 1.50 → 1.50)
Example:
rule = {
"fractional_policy": {
"always_show": false,
"threshold": 0.50,
"context": "auto"
}
}
# 1.20 → 1 (below threshold)
# 1.60 → 1.60 (above threshold)
4. rounding_interval (Object)
Round to specific intervals (useful for cash transactions where smallest denomination is 5 or 10 cents).
| Property | Type | Options | Default | Description |
|---|---|---|---|---|
enabled |
bool |
true, false |
false |
Enable interval rounding |
interval |
int |
5, 10, 25, 50, 100, etc. |
1 |
Round to nearest interval |
apply_to |
string |
"whole", "fractional", "both" |
"whole" |
What part to apply rounding to |
Apply To Options:
"whole": Round the whole number part (123.45 with interval 10 → 120.45)"fractional": Round the fractional part (123.47 with interval 5 → 123.45)"both": Round the entire number (123.47 with interval 5 → 125)
Example:
rule = {
"rounding_interval": {
"enabled": True,
"interval": 5,
"apply_to": "fractional"
}
}
# 1.23 → 1.25 (rounded to nearest 0.05)
# 1.27 → 1.25
5. minimum_value (Object)
Handle very small values that should be eliminated or rounded to minimum denomination.
| Property | Type | Options | Default | Description |
|---|---|---|---|---|
enabled |
bool |
true, false |
false |
Enable minimum value handling |
threshold |
float |
Any decimal value | 0.01 |
Minimum acceptable value |
action |
string |
"round_to_zero", "round_to_minimum" |
"round_to_zero" |
What to do with sub-threshold values |
Action Options:
"round_to_zero": Values below threshold become 0"round_to_minimum": Values below threshold become the threshold value
Example:
rule = {
"minimum_value": {
"enabled": True,
"threshold": 0.10,
"action": "round_to_zero"
}
}
# 0.05 → 0 (below minimum)
# 0.15 → 0.15 (above minimum)
6. formatting (Object)
Controls the string output format (thousand separators, decimal separators).
| Property | Type | Options | Default | Description |
|---|---|---|---|---|
decimal_separator |
string |
",", "." |
"," |
Character to separate decimals |
thousand_separator |
string |
".", ",", " ", "" |
"." |
Character to separate thousands |
force_decimals |
bool |
true, false |
false |
Always show decimal separator |
Example:
rule = {
"formatting": {
"decimal_separator": ".",
"thousand_separator": ",",
"force_decimals": True
}
}
# 1234567.5 → 1,234,567.50 (US format)
rule = {
"formatting": {
"decimal_separator": ",",
"thousand_separator": ".",
"force_decimals": True
}
}
# 1234567.5 → 1.234.567,50 (European format)
Complete Rule Example
rule = {
"digit_removal": 3,
"rounding": {
"method": "half_up",
"precision": 2
},
"fractional_policy": {
"always_show": False,
"threshold": None,
"context": "auto"
},
"rounding_interval": {
"enabled": False,
"interval": 5,
"apply_to": "fractional"
},
"minimum_value": {
"enabled": False,
"threshold": 0.01,
"action": "round_to_zero"
},
"formatting": {
"decimal_separator": ",",
"thousand_separator": ".",
"force_decimals": False
}
}
r = RedenPy(digit=3, rule=rule)
result = r.redenomination_with_rules("$ 1,234,567.89")
print(result) # 1.234,57
Real-World Country Examples
🇮🇩 Indonesia 1965 (Removed 3 zeros)
rule = {
"digit_removal": 3,
"rounding": {"method": "half_up", "precision": 2},
"fractional_policy": {"context": "auto"},
"formatting": {
"decimal_separator": ",",
"thousand_separator": "."
}
}
🇹🇷 Turkey 2005 (Removed 6 zeros, cash rounding)
rule = {
"digit_removal": 6,
"rounding": {"method": "half_up", "precision": 2},
"rounding_interval": {
"enabled": True,
"interval": 5,
"apply_to": "fractional"
},
"fractional_policy": {"context": "always"}
}
🇧🇷 Brazil 1994 (No decimals, eliminate small values)
rule = {
"digit_removal": 3,
"rounding": {"method": "down", "precision": 0},
"fractional_policy": {"context": "never"},
"minimum_value": {
"enabled": True,
"threshold": 1,
"action": "round_to_zero"
}
}
🇿🇼 Zimbabwe 2009 (Removed 12 zeros)
rule = {
"digit_removal": 12,
"rounding": {"method": "half_up", "precision": 2},
"fractional_policy": {"context": "auto"}
}
🤝 Contributing
Contributions are welcome! Please feel free to open an issue or submit a pull request.
⚖️ License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file redenpy-0.1.0.tar.gz.
File metadata
- Download URL: redenpy-0.1.0.tar.gz
- Upload date:
- Size: 9.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d6e526fd889ccd495360e38847a6a5e0576970a68b3cd404e184a8af418217f
|
|
| MD5 |
3cfd424630f4c8275cac8bec0c2649f7
|
|
| BLAKE2b-256 |
4c2ed6a28711abc096d98cc918b817d5ee6e46eae558dab20b889a5aff81991b
|
File details
Details for the file redenpy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: redenpy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82f2457bafc357d07258b643616cbe5177796648cfb83ae28edcaafcfc7756cd
|
|
| MD5 |
9ffa6ed6337fed8cc954d8ea0d3ba94b
|
|
| BLAKE2b-256 |
3946f4988516f000f28890bae0da8fd076d0dc25b5a52d712b3e70c1599b609e
|