Login

Template filter for formatting negative numbers

Author:
pkshiu
Posted:
April 16, 2009
Language:
Python
Version:
1.0
Score:
1 (after 1 ratings)

I have a need to conditionally format a negative number, a hedgefund's daily price change, Excel style. i.e. show a negative number as a parenthesized number instead of a negative sign. Here is a filter that will do that and more, solving a more general case. See the doctest for examples.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""
    A filter to format negative number.

    Sometimes one want to display negative number differently then
    just using a negative sign.

    Call with optional argument, specify one or more of:
    negativeformat:"negative_prefix,negative_suffix,normal_prefix,normal_suffix"

    If value is negative, the value's negatve sign will be removed,
    and then wrapped between negative_prefix and negative_suffix.

    If value is positive, the value is simply
    wrapped between negative_prefix and negative_suffix.

    See doctests below for examples:


    # replace negative sign with parenthsis
    >>> print negativeformat('100')
    100

    >>> print negativeformat('-100')
    (100)

    >>> print negativeformat('0')
    0


    # replace negative sign with parenthsis, and prepend dollar sign
    >>> print negativeformat('100',arg='($,),$')
    $100

    >>> print negativeformat('-100',arg='($,),$')
    ($100)

    # replace negative sign with parenthsis, and append percentage sign
    >>> print negativeformat('100',arg='(,%),,%')
    100%

    >>> print negativeformat('-100',arg='(,%),,%')
    (100%)

    # silly example, we just want to prepend a dollar sign.
    >>> print negativeformat('100',arg='$,,$')
    $100

    >>> print negativeformat('-100',arg='$-,,$')
    $-100

"""
from django import template
from django.template.defaultfilters import stringfilter

register = template.Library()

@register.filter
@stringfilter
def negativeformat(value, arg='(,)'):
    """
    A filter to format negative number.
    """
    # process arg: prefix and suffix for negative case, prefix and suffix for positive case.
    # All can be optional.
    args = arg.split(',')

    prefix = suffix = ''
    neg_prefix = neg_suffix = ''

    # fill args out to four, with default values
    extras = ['' for i in range(4-len(args))]
    args.extend(extras)

    neg_prefix, neg_suffix ,prefix, suffix = args

    if len(value) == 0:
        return value
    if value[0] == '-':
        return '%s%s%s' % (neg_prefix, value[1:], neg_suffix)
    else:
        return '%s%s%s' % (prefix, value, suffix)


if __name__ == '__main__':
    import doctest
    doctest.testmod()

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 8 months, 3 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 9 months ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 3 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 4 months ago
  5. Help text hyperlinks by sa2812 1 year, 5 months ago

Comments

showell (on April 17, 2009):

One suggestion to make this a little easier to visually parse would be to have underscore as the placeholder:

formats = '()$,+$' neg, pos = format.split(',') negpre, negsuf = neg.split('') pospre, possuf = pos.split('')

#

pkshiu (on May 5, 2009):

Interesting idea. It does look better. Thanks showell. I'll leave it up to the user to use it in either way. I was using perhaps a pseudo standard way to specify mulitple args using the comma separator.

#

Please login first before commenting.