diff --git a/meridian/analysis/formatter.py b/meridian/analysis/formatter.py index 721024a..a20f516 100644 --- a/meridian/analysis/formatter.py +++ b/meridian/analysis/formatter.py @@ -110,6 +110,24 @@ def bar_chart_width(num_bars: int) -> int: return (c.BAR_SIZE + c.PADDING_20) * num_bars +def format_percent(percent: float) -> str: + """Formats a percentage value into a string format. + + Percentage values between 0 and 1 are formatted with 1 decimal place. + Percentage values greater than 1 are formatted with 0 decimal places. + + Args: + percent: The percentage value to format. + + Returns: + A formatted string. + """ + if percent >= 0.01: + return '{:.0%}'.format(percent) + else: + return '{:.1g}%'.format(percent * 100) + + def compact_number(n: float, precision: int = 0, currency: str = '') -> str: """Formats a number into a compact notation to the specified precision. diff --git a/meridian/analysis/formatter_test.py b/meridian/analysis/formatter_test.py index b54bb4e..44fb0c3 100644 --- a/meridian/analysis/formatter_test.py +++ b/meridian/analysis/formatter_test.py @@ -41,6 +41,16 @@ def test_bar_chart_width(self): width = formatter.bar_chart_width(num_bars) self.assertEqual(width, 186) + @parameterized.named_parameters( + ('zero_percent', 0.0, '0%'), + ('less_than_one_percent', 0.0005, '0.05%'), + ('one_percent', 0.01, '1%'), + ('greater_than_one_percent', 0.4257, '43%'), + ) + def test_format_percent_correct(self, percent, expected): + formatted_percent = formatter.format_percent(percent) + self.assertEqual(formatted_percent, expected) + def test_compact_number_expr_default(self): expr = formatter.compact_number_expr() self.assertEqual(expr, "replace(format(datum.value, '.3~s'), 'G', 'B')") diff --git a/meridian/analysis/summarizer.py b/meridian/analysis/summarizer.py index 395bd23..57fc123 100644 --- a/meridian/analysis/summarizer.py +++ b/meridian/analysis/summarizer.py @@ -227,8 +227,8 @@ def _slice_table_by_evaluation_set(eval_set: str) -> Sequence[str]: ] row_values = [ '{:.2f}'.format(sliced_table_by_eval_set[c.R_SQUARED].item()), - '{:.0%}'.format(sliced_table_by_eval_set[c.MAPE].item()), - '{:.0%}'.format(sliced_table_by_eval_set[c.WMAPE].item()), + formatter.format_percent(sliced_table_by_eval_set[c.MAPE].item()), + formatter.format_percent(sliced_table_by_eval_set[c.WMAPE].item()), ] return row_values