Repository: pola-rs/polars
File: py-polars/src/polars/expr/expr.py (Python)

Code before:
        shape: (4, 1)
        ┌─────┐
        │ a   │
        │ --- │
        │ f64 │
        ╞═════╡
        │ 1.0 │
        │ 1.0 │
        │ 1.0 │
        │ 2.0 │
        └─────┘
        """
        return wrap_expr(self._pyexpr.ceil())

    def round(self, decimals: int = 0, mode: RoundMode = "half_to_even") -> Expr:
        """
        Round underlying floating point data by `decimals` digits.

        Parameters
        ----------
        decimals
            Number of decimals to round by.
        mode : {'half_to_even', 'half_away_from_zero', 'to_zero'}
            The rounding strategy used for tiebreaks of values at the midpoint; the
            choice of mode only affects values that are exactly halfway between two
            rounded candidates.

            * *half_to_even* (default)
                Round midpoints to the nearest **even** number. For example, when
                rounding to 0 decimals: 0.5 rounds to 0, 1.5 rounds to 2, 2.5 rounds
                to 2. When rounding to 1 decimal: 0.25 rounds to 0.2, 0.35 rounds to
                0.4. Also known as "banker's rounding"; this is the default because
                it tends to minimise cumulative rounding bias.
            * *half_away_from_zero*
                Round midpoints **away from zero**. For example, when rounding to
                0 decimals: 0.5 rounds to 1, -0.5 rounds to -1, 2.5 rounds to 3. When
                rounding to 1 decimal: 0.25 rounds to 0.3, -0.35 rounds to -0.4.
                Also known as "commercial rounding".
            * *to_zero*
                Always round (truncate) **towards zero**, discarding the fractional
                part beyond the given number of decimals. For example, when rounding
                to 0 decimals: 0.9 rounds to 0, -0.9 rounds to 0. When rounding to 1
                decimal: 1.29 rounds to 1.2, -1.29 rounds to -1.2. This is entirely
                equivalent to the :meth:`truncate` method.

        Notes
        -----
        Rounding modes only differ in how they handle ties at the "midpoint", which is
        the value that falls exactly halfway between two rounded candidates. When
        rounding to 0 decimals the midpoint is 0.5, when rounding to 1 decimal it is
        0.05, when rounding to 2 decimals it is 0.005, and so on. Values that are not

Review comment (suggestion):
I'm not happy with the phrasing in this section, it is misleading now we have `to_zero`. May I suggest the following:

> The rounding strategy used. If the rounding strategy starts with `half_` all values are rounded to the nearest whole value, with the rounding strategy only used for breaking ties when a value is exactly between two whole values. Other rounding strategies specify explicitly which whole value is chosen and always apply, not just for tiebreaks.

Code after:
        shape: (4, 1)
        ┌─────┐
        │ a   │
        │ --- │
        │ f64 │
        ╞═════╡
        │ 1.0 │
        │ 1.0 │
        │ 1.0 │
        │ 2.0 │
        └─────┘
        """
        return wrap_expr(self._pyexpr.ceil())

    def round(self, decimals: int = 0, mode: RoundMode = "half_to_even") -> Expr:
        """
        Round underlying floating point data by `decimals` digits.

        Parameters
        ----------
        decimals
            Number of decimals to round by.
        mode : {'half_to_even', 'half_away_from_zero', 'to_zero'}
            The rounding strategy used. A "rounded value" is a value with at most
            `decimals` decimal places (e.g. integers when ``decimals=0``, multiples
            of 0.1 when ``decimals=1``, 0.01 when ``decimals=2``, and so on).

            Strategies that start with ``half_`` round all values to the *nearest*
            rounded value, only using the strategy to break ties when a value falls
            exactly between two rounded values (e.g. 0.5 when ``decimals=0``, 0.05
            when ``decimals=1``). Other rounding strategies specify explicitly
            which rounded value is chosen and always apply (not just for tiebreaks).

            * *half_to_even* (default)
                Round to the nearest value; break ties by choosing the nearest
                **even** value. For example, 0.5 rounds to 0, 1.5 rounds to 2,
                2.5 rounds to 2. Also known as "banker's rounding"; this is the
                default because it tends to minimise cumulative rounding bias.
            * *half_away_from_zero*
                Round to the nearest value; break ties by rounding **away from
                zero**. For example, 0.5 rounds to 1, -0.5 rounds to -1, 2.5
                rounds to 3. Also known as "commercial rounding".
            * *to_zero*
                Always round (truncate) **towards zero**, discarding the fractional
                part beyond `decimals`. For example, 0.9 rounds to 0, -0.9 rounds
                to 0, 1.29 rounds to 1.2 (with ``decimals=1``). Equivalent to the
                :meth:`truncate` method.

        See Also
        --------
        ceil : Round up to the nearest integer.