/ examples / udecimal_moneyfmt.py
udecimal_moneyfmt.py
 1  # SPDX-FileCopyrightText: © 2004 Python Software Foundation. <https://www.python.org/psf/>
 2  #
 3  # SPDX-License-Identifier: Python-2.0
 4  # All rights reserved.
 5  
 6  # pylint: disable=redefined-builtin,too-many-arguments,too-many-locals
 7  
 8  from jepler_udecimal import Decimal
 9  
10  
11  def moneyfmt(value, places=2, curr="", sep=",", dp=".", pos="", neg="-", trailneg=""):
12      """Convert Decimal to a money formatted string.
13  
14      places:  required number of places after the decimal point
15      curr:    optional currency symbol before the sign (may be blank)
16      sep:     optional grouping separator (comma, period, space, or blank)
17      dp:      decimal point indicator (comma or period)
18               only specify as blank when places is zero
19      pos:     optional sign for positive numbers: '+', space or blank
20      neg:     optional sign for negative numbers: '-', '(', space or blank
21      trailneg:optional trailing minus indicator:  '-', ')', space or blank
22  
23      >>> d = Decimal('-1234567.8901')
24      >>> moneyfmt(d, curr='$')
25      '-$1,234,567.89'
26      >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
27      '1.234.568-'
28      >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
29      '($1,234,567.89)'
30      >>> moneyfmt(Decimal(123456789), sep=' ')
31      '123 456 789.00'
32      >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
33      '<0.02>'
34  
35      """
36      q = Decimal(10) ** -places  # 2 places --> '0.01'
37      sign, digits, _ = value.quantize(q).as_tuple()
38      result = []
39      digits = list(map(str, digits))
40      build, next = result.append, digits.pop
41      if sign:
42          build(trailneg)
43      for i in range(places):
44          build(next() if digits else "0")
45      if places:
46          build(dp)
47      if not digits:
48          build("0")
49      i = 0
50      while digits:
51          build(next())
52          i += 1
53          if i == 3 and digits:
54              i = 0
55              build(sep)
56      build(curr)
57      build(neg if sign else pos)
58      return "".join(reversed(result))
59  
60  
61  if __name__ == "__main__":
62      d = Decimal("-1234567.8901")
63      print(moneyfmt(d, curr="$"))
64      print(moneyfmt(d, places=0, sep=".", dp="", neg="", trailneg="-"))
65      print(moneyfmt(d, curr="$", neg="(", trailneg=")"))
66      print(moneyfmt(Decimal(123456789), sep=" "))
67      print(moneyfmt(Decimal("-0.02"), neg="<", trailneg=">"))