caellion-python-commons: caellion/pycommons/stringutil/formatters.py Source File

caellion-python-commons

formatters.py
Go to the documentation of this file.
1 """!
2 This module provides various string formatters
3 """
4
5 import math
6
7
8 class InvalidDurationException(Exception):
9 """!
10 This exception is raised whenever provided duration is zero or negative.
11 """
12
13 pass
14
15
16 class NumberFormatting:
17 """!
18 This class provides various number formats
19 """
20
21 def formatSI(v, dec=0):
22 """!
23 Formats number as an SI-prefixed decimal
24
25 @param v Number to be formatted
26 @param dec Number of decimal places
27
28 @returns formatted string
29 """
30 sign = ""
31 if v < 0:
32 sign = "-"
33 v = abs(v)
34 suffix = ""
35 SI_suffix = "kMGTPEZY"
36
37 if v >= 1000:
38 value_mag = math.log10(v)
39
40 suffix_index = min(len(SI_suffix) - 1,
41 max(0, math.floor(value_mag / 3) - 1))
42
43 value = v / pow(10, (suffix_index + 1) * 3)
44 suffix = SI_suffix[suffix_index]
45 else:
46 value = v
47
48 return sign + ("{:." + str(dec) + "f}").format(value) + suffix
49
50 def formatBinarySI(v, dec=0):
51 """!
52 Formats number as an SI-prefixed decimal, using binary unit prefixes (ki, Mi, etc.)
53
54 @param v Number to be formatted
55 @param dec Number of decimal places
56
57 @returns formatted string
58 """
59 sign = ""
60 if v < 0:
61 sign = "-"
62 v = abs(v)
63 suffix = ""
64 SI_suffix = "kMGTPEZY"
65
66 if v >= 1024:
67 value_mag = math.log(v, 2)
68
69 suffix_index = min(len(SI_suffix) - 1,
70 max(0, math.floor(value_mag / 10) - 1))
71
72 value = v / pow(2, (suffix_index + 1) * 10)
73 suffix = SI_suffix[suffix_index] + "i"
74 else:
75 value = v
76
77 return sign + ("{:." + str(dec) + "f}").format(value) + suffix
78
79 # for formatting less than one (0.X) with suffixes like milli
80 def formatSISubValue(v, dec=0):
81 """!
82 Formats less-than-one numbers to an SI-prefixed decimal (using prefixes like m, μ)
83
84 @param v Number to be formatted
85 @param dec Number of decimal places
86
87 @returns formatted string
88 """
89 sign = ""
90 if v < 0:
91 sign = "-"
92 v = abs(v)
93 SI_suffix = "mμnpfazy"
94 max_log = (len(SI_suffix)) * 3
95
96 if v >= 1 / pow(10, max_log):
97 value_mag = -1 * math.log10(v)
98 suffix_index = math.ceil(value_mag / 3) - 1
99 value = v * pow(10, (suffix_index + 1) * 3)
100 suffix = SI_suffix[suffix_index]
101 elif v > 0:
102 value = 0
103 suffix = "y"
104 else:
105 value = 0
106 suffix = ""
107
108 return sign + ("{:." + str(dec) + "f}").format(value) + suffix
109
110 # for formatting less than one (0.X) with suffixes like milli, binary
111 def formatSIBinarySubValue(v, dec=0): # pragma: no mutate
112 """!
113 Formats fractional number to SI-prefixed decimal using binary unit prefixes
114
115 @warning This is not supported
116 """
117 return "BinSubValueError"
118
119 # router for formatting all values
120 def formatSIFullRange(v, dec):
121 """!
122 Formats number using full range (will format numbers below 1 with subvalue variant) using SI decimal unit prefixes
123
124 @param v Number to be formatted
125 @param dec Number of decimal places
126
127 @returns formatted string
128 """
129 if v > -1 and v < 1:
130 return NumberFormatting.formatSISubValue(v, dec)
131 else:
132 return NumberFormatting.formatSI(v, dec)
133
134 def formatUnitsPerIntervalDynamic(units, seconds, unit):
135 """!
136 Generates an expression like "1.0kg/year"
137
138 @param units amount of units that have happened over measurement interval
139 @param seconds measurement interval, expressed in seconds
140 @param unit name of unit (kg in example above)
141
142 @returns formatted string, expression like "1.0kg/year"
143 """
144 if units < 0:
145 return "-" + NumberFormatting.formatUnitsPerIntervalDynamic(abs(units), seconds, unit)
146
147 if seconds <= 0:
148 raise InvalidDurationException(
149 str("{:s} is not a valid, positive duration").format(str(seconds)))
150
151 units_per_second = units / seconds
152 units_per_millisecond = units_per_second / 1000.0
153 units_per_microsecond = units_per_second / 1000000.0
154 units_per_millennium = units_per_second * 1000.0 * 365.0 * 86400.0
155 units_per_century = units_per_second * 100.0 * 365.0 * 86400.0
156 units_per_year = units_per_second * 365.0 * 86400.0
157 units_per_week = units_per_second * 7.0 * 86400.0
158 units_per_day = units_per_second * 86400.0
159 units_per_hour = units_per_second * 3600.0
160 units_per_minute = units_per_second * 60.0
161
162 if units_per_century < 1.0:
163 return str("{:.2f}{:s}/{:s}").format(units_per_millennium, unit, "millennium")
164 elif units_per_year < 1.0:
165 return str("{:.2f}{:s}/{:s}").format(units_per_century, unit, "century")
166 elif units_per_week < 1.0:
167 return str("{:.2f}{:s}/{:s}").format(units_per_year, unit, "year")
168 elif units_per_day < 1.0:
169 return str("{:.2f}{:s}/{:s}").format(units_per_week, unit, "week")
170 elif units_per_hour < 1.0:
171 return str("{:.2f}{:s}/{:s}").format(units_per_day, unit, "day")
172 elif units_per_minute < 1.0:
173 return str("{:.2f}{:s}/{:s}").format(units_per_hour, unit, "hour")
174 elif units_per_second < 1.0:
175 return str("{:.2f}{:s}/{:s}").format(units_per_minute, unit, "minute")
176 elif units_per_millisecond < 1.0:
177 return str("{:.2f}{:s}/{:s}").format(units_per_second, unit, "second")
178 elif units_per_microsecond < 1.0:
179 return str("{:.2f}{:s}/{:s}").format(units_per_millisecond, unit, "millisecond")
180 else:
181 return str("{:.2f}{:s}/{:s}").format(units_per_microsecond, unit, "microsecond")
caellion.pycommons.stringutil.formatters.InvalidDurationException
This exception is raised whenever provided duration is zero or negative.
Definition: formatters.py:8
caellion.pycommons.stringutil.formatters.NumberFormatting
This class provides various number formats.
Definition: formatters.py:16
caellion.pycommons.stringutil.formatters.NumberFormatting.formatSISubValue
def formatSISubValue(v, dec=0)
Formats less-than-one numbers to an SI-prefixed decimal (using prefixes like m, μ)
Definition: formatters.py:80
caellion.pycommons.stringutil.formatters.NumberFormatting.formatUnitsPerIntervalDynamic
def formatUnitsPerIntervalDynamic(units, seconds, unit)
Generates an expression like "1.0kg/year".
Definition: formatters.py:134
caellion.pycommons.stringutil.formatters.NumberFormatting.formatSIFullRange
def formatSIFullRange(v, dec)
Formats number using full range (will format numbers below 1 with subvalue variant) using SI decimal ...
Definition: formatters.py:120
caellion.pycommons.stringutil.formatters.NumberFormatting.formatSIBinarySubValue
def formatSIBinarySubValue(v, dec=0)
Formats fractional number to SI-prefixed decimal using binary unit prefixes.
Definition: formatters.py:111
caellion.pycommons.stringutil.formatters.NumberFormatting.formatBinarySI
def formatBinarySI(v, dec=0)
Formats number as an SI-prefixed decimal, using binary unit prefixes (ki, Mi, etc....
Definition: formatters.py:50
caellion.pycommons.stringutil.formatters.NumberFormatting.formatSI
def formatSI(v, dec=0)
Formats number as an SI-prefixed decimal.
Definition: formatters.py:21