Skip to content

Commit

Permalink
Add natural_list (#110)
Browse files Browse the repository at this point in the history
Co-authored-by: Akshay Raj Gollahalli <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <[email protected]>
  • Loading branch information
4 people authored Oct 5, 2024
1 parent 19b43d3 commit d7f5dc5
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 6 deletions.
8 changes: 2 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,8 @@ dmypy.json
# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Jetbrains IDEs
.idea/

# hatch-vcs
src/*/_version.py
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Welcome to the humanize API reference.
- [Time](time.md)
- [Filesize](filesize.md)
- [I18n](i18n.md)
- [Lists](lists.md)

{%
include-markdown "../README.md"
Expand Down
3 changes: 3 additions & 0 deletions docs/lists.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Lists

::: humanize.lists
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ nav:
- Time: time.md
- Filesize: filesize.md
- Internationalisation: i18n.md
- Lists: lists.md

plugins:
- search
Expand Down
2 changes: 2 additions & 0 deletions src/humanize/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from humanize.filesize import naturalsize
from humanize.i18n import activate, deactivate, decimal_separator, thousands_separator
from humanize.lists import natural_list
from humanize.number import (
apnumber,
clamp,
Expand Down Expand Up @@ -38,6 +39,7 @@
"naturaldate",
"naturalday",
"naturaldelta",
"natural_list",
"naturalsize",
"naturaltime",
"ordinal",
Expand Down
34 changes: 34 additions & 0 deletions src/humanize/lists.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Lists related humanization."""

from __future__ import annotations

from typing import Any

__all__ = ["natural_list"]


def natural_list(items: list[Any]) -> str:
"""Natural list.
Convert a list of items into a human-readable string with commas and 'and'.
Examples:
>>> natural_list(["one", "two", "three"])
'one, two and three'
>>> natural_list(["one", "two"])
'one and two'
>>> natural_list(["one"])
'one'
Args:
items (list): An iterable of items.
Returns:
str: A string with commas and 'and' in the right places.
"""
if len(items) == 1:
return str(items[0])
elif len(items) == 2:
return f"{str(items[0])} and {str(items[1])}"
else:
return ", ".join(str(item) for item in items[:-1]) + f" and {str(items[-1])}"
23 changes: 23 additions & 0 deletions tests/test_lists.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from __future__ import annotations

import pytest

import humanize


@pytest.mark.parametrize(
"test_args, expected",
[
([["1", "2", "3"]], "1, 2 and 3"),
([["one", "two", "three"]], "one, two and three"),
([["one", "two"]], "one and two"),
([["one"]], "one"),
([[""]], ""),
([[1, 2, 3]], "1, 2 and 3"),
([[1, "two"]], "1 and two"),
],
)
def test_natural_list(
test_args: list[str] | list[int] | list[str | int], expected: str
) -> None:
assert humanize.natural_list(*test_args) == expected

0 comments on commit d7f5dc5

Please sign in to comment.