From 977ddde9ecf7260b7345e1272da656f6042bb1d1 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Thu, 10 Apr 2025 14:34:48 -0400 Subject: [PATCH 1/4] Add compact= parameter to fmt_currency() --- great_tables/_formats.py | 42 +++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/great_tables/_formats.py b/great_tables/_formats.py index 616d4c343..e5bc108be 100644 --- a/great_tables/_formats.py +++ b/great_tables/_formats.py @@ -1116,6 +1116,7 @@ def fmt_currency( use_seps: bool = True, accounting: bool = False, scale_by: float = 1, + compact: bool = False, pattern: str = "{x}", sep_mark: str = ",", dec_mark: str = ".", @@ -1181,6 +1182,10 @@ def fmt_currency( All numeric values will be multiplied by the `scale_by` value before undergoing formatting. Since the `default` value is `1`, no values will be changed unless a different multiplier value is supplied. + compact + Whether to use compact formatting. This is a boolean value that, when set to `True`, will + format large numbers in a more compact form (e.g., `1,000,000` becomes `1M`). This is + `False` by default. pattern A formatting pattern that allows for decoration of the formatted value. The formatted value is represented by the `{x}` (which can be used multiple times, if needed) and all other @@ -1282,6 +1287,7 @@ def fmt_currency( use_seps=use_seps, accounting=accounting, scale_by=scale_by, + compact=compact, sep_mark=sep_mark, dec_mark=dec_mark, force_sign=force_sign, @@ -1302,6 +1308,7 @@ def fmt_currency_context( use_seps: bool, accounting: bool, scale_by: float, + compact: bool, sep_mark: str, dec_mark: str, force_sign: bool, @@ -1328,17 +1335,30 @@ def fmt_currency_context( # Format the value to decimal notation; this is done before the currency symbol is # affixed to the value - x_formatted = _value_to_decimal_notation( - value=x, - decimals=decimals, - n_sigfig=None, - drop_trailing_zeros=False, - drop_trailing_dec_mark=drop_trailing_dec_mark, - use_seps=use_seps, - sep_mark=sep_mark, - dec_mark=dec_mark, - force_sign=force_sign, - ) + if compact: + x_formatted = _format_number_compactly( + value=x, + decimals=decimals, + n_sigfig=None, + drop_trailing_zeros=False, + drop_trailing_dec_mark=drop_trailing_dec_mark, + use_seps=use_seps, + sep_mark=sep_mark, + dec_mark=dec_mark, + force_sign=force_sign, + ) + else: + x_formatted = _value_to_decimal_notation( + value=x, + decimals=decimals, + n_sigfig=None, + drop_trailing_zeros=False, + drop_trailing_dec_mark=drop_trailing_dec_mark, + use_seps=use_seps, + sep_mark=sep_mark, + dec_mark=dec_mark, + force_sign=force_sign, + ) # Create a currency pattern for affixing the currency symbol space_character = " " if incl_space else "" From ad68b299730f7bda336657b86c03ced11f1ee97d Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Thu, 10 Apr 2025 14:35:21 -0400 Subject: [PATCH 2/4] Add compact= arg to vals.fmt_currency() --- great_tables/_formats_vals.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/great_tables/_formats_vals.py b/great_tables/_formats_vals.py index 4d16f6b29..076c41ac0 100644 --- a/great_tables/_formats_vals.py +++ b/great_tables/_formats_vals.py @@ -1,13 +1,13 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any from pathlib import Path +from typing import TYPE_CHECKING, Any from typing_extensions import TypeAlias -from .gt import GT, _get_column_of_values from ._gt_data import GTData from ._tbl_data import SeriesLike, to_frame +from .gt import GT, _get_column_of_values if TYPE_CHECKING: from ._formats import DateStyle, TimeStyle @@ -541,6 +541,7 @@ def val_fmt_currency( accounting: bool = False, use_seps: bool = True, scale_by: float = 1, + compact: bool = False, pattern: str = "{x}", sep_mark: str = ",", dec_mark: str = ".", @@ -601,6 +602,10 @@ def val_fmt_currency( All numeric values will be multiplied by the `scale_by` value before undergoing formatting. Since the `default` value is `1`, no values will be changed unless a different multiplier value is supplied. + compact + Whether to use compact formatting. This is a boolean value that, when set to `True`, will + format large numbers in a more compact form (e.g., `1,000,000` becomes `1M`). This is + `False` by default. pattern A formatting pattern that allows for decoration of the formatted value. The formatted value is represented by the `{x}` (which can be used multiple times, if needed) and all other @@ -652,6 +657,7 @@ def val_fmt_currency( accounting=accounting, use_seps=use_seps, scale_by=scale_by, + compact=compact, pattern=pattern, sep_mark=sep_mark, dec_mark=dec_mark, From 60fbd5afcf78bb25abbd58714192099899fb2f52 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Thu, 10 Apr 2025 14:36:05 -0400 Subject: [PATCH 3/4] Add test of fmt_currency(compact=True) --- tests/test_formats.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_formats.py b/tests/test_formats.py index 12e5fcf7b..4a33b09c4 100644 --- a/tests/test_formats.py +++ b/tests/test_formats.py @@ -1172,6 +1172,7 @@ def test_fmt_scientific_case( (dict(placement="right"), ["1,234,567.00$", "−5,432.37$"]), (dict(placement="right", incl_space=True), ["1,234,567.00 $", "−5,432.37 $"]), (dict(incl_space=True), ["$ 1,234,567.00", "−$ 5,432.37"]), + (dict(compact=True), ["$1.23M", "−$5.43K"]), ] From 3f24901ae52089b23255028e52df471fbdb33c1a Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 6 May 2025 10:59:07 -0400 Subject: [PATCH 4/4] Refactor currency formatting based on code review --- great_tables/_formats.py | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/great_tables/_formats.py b/great_tables/_formats.py index e5bc108be..8aa735351 100644 --- a/great_tables/_formats.py +++ b/great_tables/_formats.py @@ -1333,32 +1333,24 @@ def fmt_currency_context( if currency_symbol == "$": currency_symbol = _context_dollar_mark(context=context) - # Format the value to decimal notation; this is done before the currency symbol is - # affixed to the value + # Choose the appropriate formatting function based on the `compact=` option if compact: - x_formatted = _format_number_compactly( - value=x, - decimals=decimals, - n_sigfig=None, - drop_trailing_zeros=False, - drop_trailing_dec_mark=drop_trailing_dec_mark, - use_seps=use_seps, - sep_mark=sep_mark, - dec_mark=dec_mark, - force_sign=force_sign, - ) + f_formatter = _format_number_compactly else: - x_formatted = _value_to_decimal_notation( - value=x, - decimals=decimals, - n_sigfig=None, - drop_trailing_zeros=False, - drop_trailing_dec_mark=drop_trailing_dec_mark, - use_seps=use_seps, - sep_mark=sep_mark, - dec_mark=dec_mark, - force_sign=force_sign, - ) + f_formatter = _value_to_decimal_notation + + # Perform formatting to decimal notation + x_formatted = f_formatter( + value=x, + decimals=decimals, + n_sigfig=None, + drop_trailing_zeros=False, + drop_trailing_dec_mark=drop_trailing_dec_mark, + use_seps=use_seps, + sep_mark=sep_mark, + dec_mark=dec_mark, + force_sign=force_sign, + ) # Create a currency pattern for affixing the currency symbol space_character = " " if incl_space else ""