modified: nfig1.py
[GalaxyCodeBases.git] / python / human-readable.py
blobcf586ae227aa56bc7f8a0fc6caf5cc9c6976cb93
1 #!/usr/bin/env python
3 """
4 Bytes-to-human / human-to-bytes converter.
5 Based on: http://goo.gl/kTQMs
6 Working with Python 2.x and 3.x.
8 Author: Giampaolo Rodola' <g.rodola [AT] gmail [DOT] com>
9 License: MIT
11 http://code.activestate.com/recipes/578019-bytes-to-human-human-to-bytes-converter/
12 """
14 # see: http://goo.gl/kTQMs
15 SYMBOLS = {
16 'customary' : ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'),
17 'customary_ext' : ('byte', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa',
18 'zetta', 'iotta'),
19 'iec' : ('Bi', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'),
20 'iec_ext' : ('byte', 'kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi',
21 'zebi', 'yobi'),
24 def bytes2human(n, format='%(value).1f %(symbol)s', symbols='customary'):
25 """
26 Convert n bytes into a human readable string based on format.
27 symbols can be either "customary", "customary_ext", "iec" or "iec_ext",
28 see: http://goo.gl/kTQMs
30 >>> bytes2human(0)
31 '0.0 B'
32 >>> bytes2human(0.9)
33 '0.0 B'
34 >>> bytes2human(1)
35 '1.0 B'
36 >>> bytes2human(1.9)
37 '1.0 B'
38 >>> bytes2human(1024)
39 '1.0 K'
40 >>> bytes2human(1048576)
41 '1.0 M'
42 >>> bytes2human(1099511627776127398123789121)
43 '909.5 Y'
45 >>> bytes2human(9856, symbols="customary")
46 '9.6 K'
47 >>> bytes2human(9856, symbols="customary_ext")
48 '9.6 kilo'
49 >>> bytes2human(9856, symbols="iec")
50 '9.6 Ki'
51 >>> bytes2human(9856, symbols="iec_ext")
52 '9.6 kibi'
54 >>> bytes2human(10000, "%(value).1f %(symbol)s/sec")
55 '9.8 K/sec'
57 >>> # precision can be adjusted by playing with %f operator
58 >>> bytes2human(10000, format="%(value).5f %(symbol)s")
59 '9.76562 K'
60 """
61 n = int(n)
62 if n < 0:
63 raise ValueError("n < 0")
64 symbols = SYMBOLS[symbols]
65 prefix = {}
66 for i, s in enumerate(symbols[1:]):
67 prefix[s] = 1 << (i+1)*10
68 for symbol in reversed(symbols[1:]):
69 if n >= prefix[symbol]:
70 value = float(n) / prefix[symbol]
71 return format % locals()
72 return format % dict(symbol=symbols[0], value=n)
74 def human2bytes(s):
75 """
76 Attempts to guess the string format based on default symbols
77 set and return the corresponding bytes as an integer.
78 When unable to recognize the format ValueError is raised.
80 >>> human2bytes('0 B')
82 >>> human2bytes('1 K')
83 1024
84 >>> human2bytes('1 M')
85 1048576
86 >>> human2bytes('1 Gi')
87 1073741824
88 >>> human2bytes('1 tera')
89 1099511627776
91 >>> human2bytes('0.5kilo')
92 512
93 >>> human2bytes('0.1 byte')
95 >>> human2bytes('1 k') # k is an alias for K
96 1024
97 >>> human2bytes('12 foo')
98 Traceback (most recent call last):
99 ...
100 ValueError: can't interpret '12 foo'
102 init = s
103 num = ""
104 while s and s[0:1].isdigit() or s[0:1] == '.':
105 num += s[0]
106 s = s[1:]
107 num = float(num)
108 letter = s.strip()
109 for name, sset in SYMBOLS.items():
110 if letter in sset:
111 break
112 else:
113 if letter == 'k':
114 # treat 'k' as an alias for 'K' as per: http://goo.gl/kTQMs
115 sset = SYMBOLS['customary']
116 letter = letter.upper()
117 else:
118 raise ValueError("can't interpret %r" % init)
119 prefix = {sset[0]:1}
120 for i, s in enumerate(sset[1:]):
121 prefix[s] = 1 << (i+1)*10
122 return int(num * prefix[letter])
125 if __name__ == "__main__":
126 #import doctest
127 #doctest.testmod()
128 import sys
129 print(bytes2human(sys.argv[1]))
130 print(human2bytes(sys.argv[2]))