author | rptlab |
Tue, 30 Apr 2013 14:28:14 +0100 | |
branch | py33 |
changeset 3723 | 99aa837b6703 |
parent 3721 | 0c93dd8ff567 |
child 4252 | fe660f227cac |
permissions | -rw-r--r-- |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
1 |
#!/bin/env python |
3617 | 2 |
#Copyright ReportLab Europe Ltd. 2000-2012 |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
3 |
#see license.txt for license details |
2332 | 4 |
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/lib/formatters.py |
2864
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
5 |
__all__=('Formatter','DecimalFormatter') |
2332 | 6 |
__version__=''' $Id$ ''' |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
7 |
__doc__=""" |
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
8 |
These help format numbers and dates in a user friendly way. |
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
9 |
Used by the graphics framework. |
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
10 |
""" |
2864
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
11 |
import string, sys, os, re |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
12 |
|
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
13 |
class Formatter: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
14 |
"Base formatter - simply applies python format strings" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
15 |
def __init__(self, pattern): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
16 |
self.pattern = pattern |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
17 |
def format(self, obj): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
18 |
return self.pattern % obj |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
19 |
def __repr__(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
20 |
return "%s('%s')" % (self.__class__.__name__, self.pattern) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
21 |
def __call__(self, x): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
22 |
return self.format(x) |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
23 |
|
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
24 |
|
2864
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
25 |
_ld_re=re.compile(r'^\d*\.') |
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
26 |
_tz_re=re.compile('0+$') |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
27 |
class DecimalFormatter(Formatter): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
28 |
"""lets you specify how to build a decimal. |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
29 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
30 |
A future NumberFormatter class will take Microsoft-style patterns |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
31 |
instead - "$#,##0.00" is WAY easier than this.""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
32 |
def __init__(self, places=2, decimalSep='.', thousandSep=None, prefix=None, suffix=None): |
2864
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
33 |
if places=='auto': |
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
34 |
self.calcPlaces = self._calcPlaces |
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
35 |
else: |
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
36 |
self.places = places |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
37 |
self.dot = decimalSep |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
38 |
self.comma = thousandSep |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
39 |
self.prefix = prefix |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
40 |
self.suffix = suffix |
1330
9b212b5065f6
Formatter objects added, and used for chart label formatting
andy_robinson
parents:
diff
changeset
|
41 |
|
2864
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
42 |
def _calcPlaces(self,V): |
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
43 |
'''called with the full set of values to be formatted so we can calculate places''' |
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
44 |
self.places = max([len(_tz_re.sub('',_ld_re.sub('',str(v)))) for v in V]) |
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
45 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
46 |
def format(self, num): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
47 |
# positivize the numbers |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
48 |
sign=num<0 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
49 |
if sign: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
50 |
num = -num |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
51 |
places, sep = self.places, self.dot |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
52 |
strip = places<=0 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
53 |
if places and strip: places = -places |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
54 |
strInt = ('%.' + str(places) + 'f') % num |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
55 |
if places: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
56 |
strInt, strFrac = strInt.split('.') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
57 |
strFrac = sep + strFrac |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
58 |
if strip: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
59 |
while strFrac and strFrac[-1] in ['0',sep]: strFrac = strFrac[:-1] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
60 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
61 |
strFrac = '' |
1546 | 62 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
63 |
if self.comma is not None: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
64 |
strNew = '' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
65 |
while strInt: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
66 |
left, right = strInt[0:-3], strInt[-3:] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
67 |
if left == '': |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
68 |
#strNew = self.comma + right + strNew |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
69 |
strNew = right + strNew |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
70 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
71 |
strNew = self.comma + right + strNew |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
72 |
strInt = left |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
73 |
strInt = strNew |
1548 | 74 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
75 |
strBody = strInt + strFrac |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
76 |
if sign: strBody = '-' + strBody |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
77 |
if self.prefix: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
78 |
strBody = self.prefix + strBody |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
79 |
if self.suffix: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
80 |
strBody = strBody + self.suffix |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
81 |
return strBody |
1683 | 82 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
83 |
def __repr__(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
84 |
return "%s(places=%d, decimalSep=%s, thousandSep=%s, prefix=%s, suffix=%s)" % ( |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
85 |
self.__class__.__name__, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
86 |
self.places, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
87 |
repr(self.dot), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
88 |
repr(self.comma), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
89 |
repr(self.prefix), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
90 |
repr(self.suffix) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
91 |
) |
1548 | 92 |
|
93 |
if __name__=='__main__': |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
94 |
def t(n, s, places=2, decimalSep='.', thousandSep=None, prefix=None, suffix=None): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
95 |
f=DecimalFormatter(places,decimalSep,thousandSep,prefix,suffix) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
96 |
r = f(n) |
3721 | 97 |
print("places=%2d dot=%-4s comma=%-4s prefix=%-4s suffix=%-4s result=%10s %s" %(f.places, f.dot, f.comma, f.prefix, f.suffix,r, r==s and 'OK' or 'BAD')) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
98 |
t(1000.9,'1,000.9',1,thousandSep=',') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
99 |
t(1000.95,'1,001.0',1,thousandSep=',') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
100 |
t(1000.95,'1,001',-1,thousandSep=',') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
101 |
t(1000.9,'1,001',0,thousandSep=',') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
102 |
t(1000.9,'1000.9',1) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
103 |
t(1000.95,'1001.0',1) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
104 |
t(1000.95,'1001',-1) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
105 |
t(1000.9,'1001',0) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
106 |
t(1000.1,'1000.1',1) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
107 |
t(1000.55,'1000.6',1) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1548
diff
changeset
|
108 |
t(1000.449,'1000.4',-1) |
2864
1e9a05cb3383
reportlab: add places='auto' capability to DecimalFormatter
rgbecker
parents:
2332
diff
changeset
|
109 |
t(1000.45,'1000',0) |