0303699ebd5cf957a1b3753e65a6272569364d81
[hooke.git] / hooke / ui / gui / prettyformat.py
1 # Copyright (C) 2009-2010 Rolf Schmidt <rschmidt@alcor.concordia.ca>
2 #                         W. Trevor King <wking@drexel.edu>
3 #
4 # This file is part of Hooke.
5 #
6 # Hooke is free software: you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation, either
9 # version 3 of the License, or (at your option) any later version.
10 #
11 # Hooke is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with Hooke.  If not, see
18 # <http://www.gnu.org/licenses/>.
19
20 """Format values with nice prefixes.
21 History:
22
23 * 2009 07 16:
24
25   * added negative number support
26   * added decimal-formatted output
27 """
28 __version__ = "1.0.1"
29
30 import math
31 from numpy import isnan
32
33 def pretty_format(fValue, sUnit='', iDecimals=-1, iMultiplier=1, bLeadingSpaces=False):
34     if fValue != 0:
35         iLeadingSpaces = 0
36         if bLeadingSpaces:
37             iLeadingSpaces = 5
38         if iMultiplier == 1:
39             iMultiplier=get_multiplier(fValue)
40         sUnitString = ''
41         if sUnit != '':
42             sUnitString = ' ' + get_prefix(iMultiplier) + sUnit
43         if iDecimals >= 0:
44             formatString = '% ' + repr(iLeadingSpaces + iDecimals) + '.' + repr(iDecimals) + 'f'
45             return formatString % (fValue / iMultiplier) + sUnitString
46         else:
47             return str(fValue / iMultiplier) + sUnitString
48     else:
49         return '0'
50     return str(fValue / iMultiplier) + ' ' + get_prefix(fValue / iMultiplier) + sUnit
51
52 def get_multiplier(fValue):
53     return pow(10, get_power(fValue))
54
55 def get_power(fValue):
56     if fValue != 0 and not isnan(fValue):
57         #get the log10 from fValue (make sure the value is not negative)
58         dHelp = math.floor(math.log10(math.fabs(fValue)))
59         #reduce the log10 to a multiple of 3 and return it
60         return dHelp-(dHelp % 3)
61     else:
62         return 0
63
64 def get_prefix(fValue):
65     #set up a dictionary to find the prefix
66     prefix = {
67         24: lambda: 'Y',
68         21: lambda: 'Z',
69         18: lambda: 'E',
70         15: lambda: 'P',
71         12: lambda: 'T',
72         9: lambda: 'G',
73         6: lambda: 'M',
74         3: lambda: 'k',
75         0: lambda: '',
76         -3: lambda: 'm',
77         -6: lambda: u'\u00B5',
78         -9: lambda: 'n',
79         -12: lambda: 'p',
80         -15: lambda: 'f',
81         -18: lambda: 'a',
82         -21: lambda: 'z',
83         -24: lambda: 'y',
84     }
85     if fValue != 0 and not isnan(fValue):
86         #get the log10 from fValue
87         dHelp = math.floor(math.log10(math.fabs(fValue)))
88     else:
89         dHelp = 0
90     #reduce the log10 to a multiple of 3 and create the return string
91     return prefix.get(dHelp - (dHelp % 3))()
92
93 '''
94 dTestValue=-2.4115665714484597e-008
95 print 'Value: '+str(dTestValue)+')'
96 print 'pretty_format example (value, unit)'
97 print pretty_format(dTestValue, 'N')
98 print'-----------------------'
99 print 'pretty_format example (value, unit, decimals)'
100 print pretty_format(dTestValue, 'N', 3)
101 print'-----------------------'
102 print 'pretty_format example (value, unit, decimals, multiplier)'
103 print pretty_format(dTestValue, 'N', 5, 0.000001)
104 print'-----------------------'
105 print 'pretty_format example (value, unit, decimals, multiplier, leading spaces)'
106 print pretty_format(0.0166276297705, 'N', 3, 0.001, True)
107 print pretty_format(0.00750520813323, 'N', 3, 0.001, True)
108 print pretty_format(0.0136453282825, 'N', 3, 0.001, True)
109 '''
110 '''
111 #example use autoFormatValue
112 dTestValue=0.00000000567
113 print 'autoFormatValue example ('+str(dTestValue)+')'
114 print autoFormatValue(dTestValue, 'N')
115 #outputs 5.67 nN
116 '''
117 '''
118 #example use of decimalFormatValue(fValue, iDecimals, sUnit):
119 dTestValue=-2.4115665714484597e-008
120 iDecimals=3
121 print 'decimalFormatValue example ('+str(dTestValue)+')'
122 print decimalFormatValue(dTestValue, iDecimals, 'N')
123 #outputs -24.116 nN
124 #change iDecimals to see the effect
125 '''
126 '''
127 #example use formatValue
128 dTestValue=0.000000000567
129 print 'formatValue example ('+str(dTestValue)+')'
130 #find the (common) multiplier
131 iMultiplier=get_multiplier(dTestValue)
132 #use the multiplier and a unit to format the value
133 print formatValue(dTestValue, iMultiplier, 'N')
134 #outputs 567.0 pN
135 '''
136 '''
137 #to output a scale:
138 #choose any value on the axis and find the multiplier and prefix for it
139 #use those to format the rest of the scale
140 #as values can span several orders of magnitude, you have to decide what units to use
141
142 #tuple of values:
143 scaleValues=0.000000000985, 0.000000001000, 0.000000001015
144 #use this element (change to 1 or 2 to see the effect on the scale and label)
145 iIndex=0
146 #get the multiplier from the value at iIndex
147 iMultiplier=get_multiplier(scaleValues[iIndex])
148 print '\nScale example'
149 iDecimals=3
150 #print the scale
151 for aValue in scaleValues: print decimalFormat(aValue/iMultiplier, iDecimals),
152 #print the scale label using the value at iIndex
153 print '\n'+get_prefix(scaleValues[iIndex])+'N'
154 '''