Skip to content

Commit 07a5020

Browse files
committed
Add functions to format integers
1 parent 551e076 commit 07a5020

File tree

1 file changed

+104
-15
lines changed

1 file changed

+104
-15
lines changed

pointblank/validate.py

Lines changed: 104 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import commonmark
1818
import narwhals as nw
1919
from great_tables import GT, from_column, google_font, html, loc, md, style, vals
20+
from great_tables.gt import _get_column_of_values
2021
from great_tables.vals import fmt_integer, fmt_number
2122
from importlib_resources import files
2223
from narwhals.typing import FrameT
@@ -11483,7 +11484,9 @@ def get_tabular_report(
1148311484
# Create the label, table type, and thresholds HTML fragments
1148411485
label_html = _create_label_html(label=self.label, start_time="")
1148511486
table_type_html = _create_table_type_html(tbl_type=tbl_info, tbl_name=self.tbl_name)
11486-
thresholds_html = _create_thresholds_html(thresholds=thresholds, locale=locale)
11487+
thresholds_html = _create_thresholds_html(
11488+
thresholds=thresholds, locale=locale, df_lib=df_lib
11489+
)
1148711490

1148811491
# Compose the subtitle HTML fragment
1148911492
combined_subtitle = (
@@ -11796,6 +11799,7 @@ def get_tabular_report(
1179611799
interrogation_performed=interrogation_performed,
1179711800
active=active,
1179811801
locale=locale,
11802+
df_lib=df_lib,
1179911803
)
1180011804

1180111805
# ------------------------------------------------
@@ -11812,6 +11816,7 @@ def get_tabular_report(
1181211816
interrogation_performed=interrogation_performed,
1181311817
active=active,
1181411818
locale=locale,
11819+
df_lib=df_lib,
1181511820
)
1181611821

1181711822
validation_info_dict["fail"] = _transform_passed_failed(
@@ -11820,6 +11825,7 @@ def get_tabular_report(
1182011825
interrogation_performed=interrogation_performed,
1182111826
active=active,
1182211827
locale=locale,
11828+
df_lib=df_lib,
1182311829
)
1182411830

1182511831
# ------------------------------------------------
@@ -11999,7 +12005,9 @@ def get_tabular_report(
1199912005
# Create the label, table type, and thresholds HTML fragments
1200012006
label_html = _create_label_html(label=self.label, start_time=self.time_start)
1200112007
table_type_html = _create_table_type_html(tbl_type=tbl_info, tbl_name=self.tbl_name)
12002-
thresholds_html = _create_thresholds_html(thresholds=thresholds, locale=locale)
12008+
thresholds_html = _create_thresholds_html(
12009+
thresholds=thresholds, locale=locale, df_lib=df_lib
12010+
)
1200312011

1200412012
# Compose the subtitle HTML fragment
1200512013
combined_subtitle = (
@@ -14154,41 +14162,122 @@ def _create_label_html(label: str | None, start_time: str) -> str:
1415414162
)
1415514163

1415614164

14157-
def _create_thresholds_html(thresholds: Thresholds, locale: str) -> str:
14165+
def _format_single_integer_with_gt(value: int, locale: str = "en", df_lib=None) -> str:
14166+
"""Format a single integer using Great Tables GT object to avoid pandas dependency."""
14167+
if df_lib is None:
14168+
# Use library detection to select appropriate DataFrame library
14169+
if _is_lib_present("polars"):
14170+
import polars as pl
14171+
14172+
df_lib = pl
14173+
elif _is_lib_present("pandas"):
14174+
import pandas as pd
14175+
14176+
df_lib = pd
14177+
else:
14178+
raise ImportError("Neither Polars nor Pandas is available for formatting")
14179+
14180+
# Create a single-row, single-column DataFrame using the specified library
14181+
df = df_lib.DataFrame({"value": [value]})
14182+
14183+
# Create GT object and format the column
14184+
gt_obj = GT(df).fmt_integer(columns="value", locale=locale)
14185+
14186+
# Extract the formatted value using _get_column_of_values
14187+
formatted_values = _get_column_of_values(gt_obj, column_name="value", context="html")
14188+
14189+
return formatted_values[0] # Return the single formatted value
14190+
14191+
14192+
def _format_single_float_with_gt_custom(
14193+
value: float,
14194+
decimals: int = 2,
14195+
drop_trailing_zeros: bool = False,
14196+
locale: str = "en",
14197+
df_lib=None,
14198+
) -> str:
14199+
"""Format a single float with custom options using Great Tables GT object to avoid pandas dependency."""
14200+
if df_lib is None:
14201+
# Use library detection to select appropriate DataFrame library
14202+
if _is_lib_present("polars"):
14203+
import polars as pl
14204+
14205+
df_lib = pl
14206+
elif _is_lib_present("pandas"):
14207+
import pandas as pd
14208+
14209+
df_lib = pd
14210+
else:
14211+
raise ImportError("Neither Polars nor Pandas is available for formatting")
14212+
14213+
# Create a single-row, single-column DataFrame using the specified library
14214+
df = df_lib.DataFrame({"value": [value]})
14215+
14216+
# Create GT object and format the column
14217+
gt_obj = GT(df).fmt_number(
14218+
columns="value", decimals=decimals, drop_trailing_zeros=drop_trailing_zeros, locale=locale
14219+
)
14220+
14221+
# Extract the formatted value using _get_column_of_values
14222+
formatted_values = _get_column_of_values(gt_obj, column_name="value", context="html")
14223+
14224+
return formatted_values[0] # Return the single formatted value
14225+
14226+
14227+
def _create_thresholds_html(thresholds: Thresholds, locale: str, df_lib=None) -> str:
1415814228
if thresholds == Thresholds():
1415914229
return ""
1416014230

14231+
# Helper functions to format numbers safely
14232+
def _format_number_safe(value: float, decimals: int, drop_trailing_zeros: bool = False) -> str:
14233+
if df_lib is not None and value is not None:
14234+
# Use GT-based formatting to avoid Pandas dependency completely
14235+
return _format_single_float_with_gt_custom(
14236+
value,
14237+
decimals=decimals,
14238+
drop_trailing_zeros=drop_trailing_zeros,
14239+
locale=locale,
14240+
df_lib=df_lib,
14241+
)
14242+
else:
14243+
# Fallback to the original behavior
14244+
return fmt_number(
14245+
value, decimals=decimals, drop_trailing_zeros=drop_trailing_zeros, locale=locale
14246+
)[0]
14247+
14248+
def _format_integer_safe(value: int) -> str:
14249+
if df_lib is not None and value is not None:
14250+
# Use GT-based formatting to avoid Pandas dependency completely
14251+
return _format_single_integer_with_gt(value, locale=locale, df_lib=df_lib)
14252+
else:
14253+
# Fallback to the original behavior
14254+
return fmt_integer(value, locale=locale)[0]
14255+
1416114256
warning = (
14162-
fmt_number(
14163-
thresholds.warning_fraction, decimals=3, drop_trailing_zeros=True, locale=locale
14164-
)[0]
14257+
_format_number_safe(thresholds.warning_fraction, decimals=3, drop_trailing_zeros=True)
1416514258
if thresholds.warning_fraction is not None
1416614259
else (
14167-
fmt_integer(thresholds.warning_count, locale=locale)[0]
14260+
_format_integer_safe(thresholds.warning_count)
1416814261
if thresholds.warning_count is not None
1416914262
else "—"
1417014263
)
1417114264
)
1417214265

1417314266
error = (
14174-
fmt_number(thresholds.error_fraction, decimals=3, drop_trailing_zeros=True, locale=locale)[
14175-
0
14176-
]
14267+
_format_number_safe(thresholds.error_fraction, decimals=3, drop_trailing_zeros=True)
1417714268
if thresholds.error_fraction is not None
1417814269
else (
14179-
fmt_integer(thresholds.error_count, locale=locale)[0]
14270+
_format_integer_safe(thresholds.error_count)
1418014271
if thresholds.error_count is not None
1418114272
else "—"
1418214273
)
1418314274
)
1418414275

1418514276
critical = (
14186-
fmt_number(
14187-
thresholds.critical_fraction, decimals=3, drop_trailing_zeros=True, locale=locale
14188-
)[0]
14277+
_format_number_safe(thresholds.critical_fraction, decimals=3, drop_trailing_zeros=True)
1418914278
if thresholds.critical_fraction is not None
1419014279
else (
14191-
fmt_integer(thresholds.critical_count, locale=locale)[0]
14280+
_format_integer_safe(thresholds.critical_count)
1419214281
if thresholds.critical_count is not None
1419314282
else "—"
1419414283
)

0 commit comments

Comments
 (0)