Skip to content

prose

champalimaud.prose

Phrases built from a table, to quote it in a sentence.

A list joined with commas and "and", and the smallest and largest value of a column with their labels.

and_list(items)

Join items as a phrase.

Parameters:

Name Type Description Default
items sequence of str

The items, in order.

required

Returns:

Type Description
str

"a", "a and b", or "a, b, and c".

Examples:

>>> and_list(["A", "B", "C"])
'A, B, and C'
Source code in champalimaud/prose.py
def and_list(items: Sequence[str]) -> str:
    """Join items as a phrase.

    Parameters
    ----------
    items : sequence of str
        The items, in order.

    Returns
    -------
    str
        ``"a"``, ``"a and b"``, or ``"a, b, and c"``.

    Examples
    --------
    >>> and_list(["A", "B", "C"])
    'A, B, and C'
    """
    if len(items) <= 2:
        return " and ".join(items)
    return ", ".join(items[:-1]) + ", and " + items[-1]

span_of(table, column, *, by='type', fmt='')

Quote the smallest and largest value of a column, with labels.

Parameters:

Name Type Description Default
table DataFrame

Has column and by.

required
column str

Column whose smallest and largest value are quoted.

required
by str

Column that labels each row.

"type"
fmt str

Format spec of the values, such as ".0%".

""

Returns:

Type Description
str

For example "8% (A) to 13% (B)".

See Also

value_list : Every row, not only the ends.

Examples:

>>> import polars as pl
>>> table = pl.DataFrame(
...     {
...         "type": ["A", "B", "C"],
...         "share": [0.08, 0.13, 0.11],
...     }
... )
>>> span_of(table, "share", fmt=".0%")
'8% (A) to 13% (B)'
Source code in champalimaud/prose.py
def span_of(
    table: pl.DataFrame, column: str, *, by: str = "type", fmt: str = ""
) -> str:
    """Quote the smallest and largest value of a column, with labels.

    Parameters
    ----------
    table : polars.DataFrame
        Has `column` and `by`.
    column : str
        Column whose smallest and largest value are quoted.
    by : str, default "type"
        Column that labels each row.
    fmt : str, default ""
        Format spec of the values, such as ``".0%"``.

    Returns
    -------
    str
        For example ``"8% (A) to 13% (B)"``.

    See Also
    --------
    value_list : Every row, not only the ends.

    Examples
    --------
    >>> import polars as pl
    >>> table = pl.DataFrame(
    ...     {
    ...         "type": ["A", "B", "C"],
    ...         "share": [0.08, 0.13, 0.11],
    ...     }
    ... )
    >>> span_of(table, "share", fmt=".0%")
    '8% (A) to 13% (B)'
    """
    ordered = table.sort(column)
    low = ordered.row(0, named=True)
    high = ordered.row(-1, named=True)
    return (
        f"{low[column]:{fmt}} ({low[by]}) to {high[column]:{fmt}} ({high[by]})"
    )

value_list(table, column, *, by='type', fmt='', template='{label} {value}')

Quote the rows of a table as a phrase, one value per row.

Parameters:

Name Type Description Default
table DataFrame

Has column and by.

required
column str

Column whose value is quoted for each row.

required
by str

Column that labels each row.

"type"
fmt str

Format spec of the values.

""
template str

Text for one row, filled with label and value.

"{label} {value}"

Returns:

Type Description
str

The rows in order, joined as and_list does, such as "A 8%, B 13%, and C 11%".

See Also

span_of : Only the smallest and the largest.

Examples:

>>> import polars as pl
>>> table = pl.DataFrame(
...     {
...         "type": ["A", "B", "C"],
...         "share": [0.08, 0.13, 0.11],
...     }
... )
>>> value_list(table, "share", fmt=".0%")
'A 8%, B 13%, and C 11%'
Source code in champalimaud/prose.py
def value_list(
    table: pl.DataFrame,
    column: str,
    *,
    by: str = "type",
    fmt: str = "",
    template: str = "{label} {value}",
) -> str:
    """Quote the rows of a table as a phrase, one value per row.

    Parameters
    ----------
    table : polars.DataFrame
        Has `column` and `by`.
    column : str
        Column whose value is quoted for each row.
    by : str, default "type"
        Column that labels each row.
    fmt : str, default ""
        Format spec of the values.
    template : str, default "{label} {value}"
        Text for one row, filled with ``label`` and ``value``.

    Returns
    -------
    str
        The rows in order, joined as `and_list` does, such as
        ``"A 8%, B 13%, and C 11%"``.

    See Also
    --------
    span_of : Only the smallest and the largest.

    Examples
    --------
    >>> import polars as pl
    >>> table = pl.DataFrame(
    ...     {
    ...         "type": ["A", "B", "C"],
    ...         "share": [0.08, 0.13, 0.11],
    ...     }
    ... )
    >>> value_list(table, "share", fmt=".0%")
    'A 8%, B 13%, and C 11%'
    """
    return and_list(
        [
            template.format(label=row[by], value=f"{row[column]:{fmt}}")
            for row in table.iter_rows(named=True)
        ]
    )