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.
Metadata
Release files for RedenPy 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| redenpy-0.1.0.tar.gz | 9.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| redenpy-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.1 kB
Release files / redenpy-0.1.0.tar.gz
| Download URL | redenpy-0.1.0.tar.gz |
|---|---|
| Size | 9.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d6e526fd889ccd495360e38847a6a5e0576970a68b3cd404e184a8af418217f
|
|
BLAKE2b-256 checksum How to use checksums |
4c2ed6a28711abc096d98cc918b817d5ee6e46eae558dab20b889a5aff81991b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / redenpy-0.1.0-py3-none-any.whl
| Download URL | redenpy-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
82f2457bafc357d07258b643616cbe5177796648cfb83ae28edcaafcfc7756cd
|
|
BLAKE2b-256 checksum How to use checksums |
3946f4988516f000f28890bae0da8fd076d0dc25b5a52d712b3e70c1599b609e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|