Skip to content

Round numbers

round_numbers

Round-numbers strategy — reduce float precision.

RoundNumbersStrategy

Bases: SmeltStrategy

Recursively round floats to precision decimal places.

Source code in packages/axm-smelt/src/axm_smelt/strategies/round_numbers.py
Python
class RoundNumbersStrategy(SmeltStrategy):
    """Recursively round floats to *precision* decimal places."""

    def __init__(self, precision: int = 2) -> None:
        self._precision = precision

    @property
    def name(self) -> str:
        """Strategy identifier used in the registry."""
        return "round_numbers"

    @property
    def category(self) -> str:
        """Strategy category (``cosmetic``)."""
        return "cosmetic"

    def _round_text(self, text: str) -> str:
        """Round float literals found in plain text (e.g. tabular output)."""
        return _round_in_str(text, self._precision)

    def apply(self, ctx: SmeltContext) -> SmeltContext:
        """Round float values to the configured precision.

        Uses ``ctx.parsed`` for the JSON path and falls back to
        regex-based rounding on plain text (e.g. post-tabular output).
        Propagates the rounded object as ``parsed`` on the returned
        context.
        """
        parsed = ctx.parsed
        if parsed is not None:
            rounded = _round_walk(parsed, self._precision)
            result = json.dumps(rounded, separators=(",", ":"), ensure_ascii=False)
            return SmeltContext(text=result, format=ctx.format, parsed=rounded)

        text = ctx.text
        stripped = text.strip()
        if not stripped:
            return ctx

        if stripped[0] in ("{", "["):
            try:
                data = json.loads(stripped)
                rounded = _round_walk(data, self._precision)
                result = json.dumps(rounded, separators=(",", ":"), ensure_ascii=False)
                return SmeltContext(text=result, format=ctx.format, parsed=rounded)
            except (json.JSONDecodeError, ValueError):
                pass

        # Fallback: round floats in plain text (post-tabular output, etc.)
        result = self._round_text(text)
        if result != text:
            return SmeltContext(text=result, format=ctx.format, parsed=None)
        return ctx
category property

Strategy category (cosmetic).

name property

Strategy identifier used in the registry.

apply(ctx)

Round float values to the configured precision.

Uses ctx.parsed for the JSON path and falls back to regex-based rounding on plain text (e.g. post-tabular output). Propagates the rounded object as parsed on the returned context.

Source code in packages/axm-smelt/src/axm_smelt/strategies/round_numbers.py
Python
def apply(self, ctx: SmeltContext) -> SmeltContext:
    """Round float values to the configured precision.

    Uses ``ctx.parsed`` for the JSON path and falls back to
    regex-based rounding on plain text (e.g. post-tabular output).
    Propagates the rounded object as ``parsed`` on the returned
    context.
    """
    parsed = ctx.parsed
    if parsed is not None:
        rounded = _round_walk(parsed, self._precision)
        result = json.dumps(rounded, separators=(",", ":"), ensure_ascii=False)
        return SmeltContext(text=result, format=ctx.format, parsed=rounded)

    text = ctx.text
    stripped = text.strip()
    if not stripped:
        return ctx

    if stripped[0] in ("{", "["):
        try:
            data = json.loads(stripped)
            rounded = _round_walk(data, self._precision)
            result = json.dumps(rounded, separators=(",", ":"), ensure_ascii=False)
            return SmeltContext(text=result, format=ctx.format, parsed=rounded)
        except (json.JSONDecodeError, ValueError):
            pass

    # Fallback: round floats in plain text (post-tabular output, etc.)
    result = self._round_text(text)
    if result != text:
        return SmeltContext(text=result, format=ctx.format, parsed=None)
    return ctx