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