diff --git a/src/humanize/number.py b/src/humanize/number.py index f57588e..013448e 100644 --- a/src/humanize/number.py +++ b/src/humanize/number.py @@ -35,11 +35,19 @@ def ordinal(value): return "%d%s" % (value, t[value % 10]) -def intcomma(value): +def intcomma(value, ndigits=None): """Converts an integer to a string containing commas every three digits. - For example, 3000 becomes '3,000' and 45000 becomes '45,000'. To maintain - some compatibility with Django's intcomma, this function also accepts - floats.""" + + For example, 3000 becomes "3,000" and 45000 becomes "45,000". To maintain some + compatibility with Django's intcomma, this function also accepts floats. + + Args: + value (int, float, string): Integer or float to convert. + ndigits (int, None): digits of precision for rounding after the decimal point. + + Returns: + str: string containing commas every three digits. + """ try: if isinstance(value, str): float(value.replace(",", "")) @@ -47,7 +55,12 @@ def intcomma(value): float(value) except (TypeError, ValueError): return value - orig = str(value) + + if ndigits: + orig = "{0:.{1}f}".format(value, ndigits) + else: + orig = str(value) + new = re.sub(r"^(-?\d+)(\d{3})", r"\g<1>,\g<2>", orig) if orig == new: return new diff --git a/tests/test_number.py b/tests/test_number.py index cdb0d7c..c7cbc66 100644 --- a/tests/test_number.py +++ b/tests/test_number.py @@ -30,25 +30,36 @@ def test_ordinal(test_input, expected): @pytest.mark.parametrize( - "test_input, expected", + "test_args, expected", [ - (100, "100"), - (1000, "1,000"), - (10123, "10,123"), - (10311, "10,311"), - (1000000, "1,000,000"), - (1234567.25, "1,234,567.25"), - ("100", "100"), - ("1000", "1,000"), - ("10123", "10,123"), - ("10311", "10,311"), - ("1000000", "1,000,000"), - ("1234567.1234567", "1,234,567.1234567"), - (None, None), + ([100], "100"), + ([1000], "1,000"), + ([10123], "10,123"), + ([10311], "10,311"), + ([1000000], "1,000,000"), + ([1234567.25], "1,234,567.25"), + (["100"], "100"), + (["1000"], "1,000"), + (["10123"], "10,123"), + (["10311"], "10,311"), + (["1000000"], "1,000,000"), + (["1234567.1234567"], "1,234,567.1234567"), + ([None], None), + ([14308.40], "14,308.4"), + ([14308.40, None], "14,308.4"), + ([14308.40, 1], "14,308.4"), + ([14308.40, 2], "14,308.40"), + ([14308.40, 3], "14,308.400"), + ([1234.5454545], "1,234.5454545"), + ([1234.5454545, None], "1,234.5454545"), + ([1234.5454545, 1], "1,234.5"), + ([1234.5454545, 2], "1,234.55"), + ([1234.5454545, 3], "1,234.545"), + ([1234.5454545, 10], "1,234.5454545000"), ], ) -def test_intcomma(test_input, expected): - assert humanize.intcomma(test_input) == expected +def test_intcomma(test_args, expected): + assert humanize.intcomma(*test_args) == expected def test_intword_powers():