summaryrefslogtreecommitdiff
path: root/humanify
blob: 32454fc18becfd0011e9355d1a8914d3ca94cd2c (plain)
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
87
88
89
90
#!/usr/bin/python
# Copyright 2011  Lars Wirzenius
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import cliapp
import sys


class Humanify(cliapp.Application):

    iso_prefixes = [
        (1000**8, 'Y'),
        (1000**7, 'Z'),
        (1000**6, 'E'),
        (1000**5, 'P'),
        (1000**4, 'T'),
        (1000**3, 'G'),
        (1000**2, 'M'),
        (1000, 'k'),
        (1, ''),
    ]
    iec_prefixes = [
        (1024**8, 'Yi'),
        (1024**7, 'Zi'),
        (1024**6, 'Ei'),
        (1024**5, 'Pi'),
        (1024**4, 'Ti'),
        (1024**3, 'Gi'),
        (1024**2, 'MI'),
        (1024, 'Ki'),
        (1, ''),
    ]

    def add_settings(self):
        self.settings.boolean(['binary', 'iec'], 
                              'use 10-based, not 2-based prefixes '
                                '(ISO vs IEC)')
        self.settings.boolean(['bits'],  'inputs give numbers of bits')

    def process_args(self, args):
        self.units = self.determine_units()

        if args:
            for arg in args:
                self.humanify(arg)
        else:
            for line in sys.stdin:
                self.humanify(float(line.strip()))

    def determine_units(self):
        if self.settings['binary']:
            prefixes = self.iec_prefixes
        else:
            prefixes = self.iso_prefixes
        if self.settings['bits']:
            suffix = 'b'
        else:
            suffix = 'B'
        return [(factor, prefix + suffix) for factor, prefix in prefixes]

    def humanify(self, arg):
        self.output.write('%s\n' % self._humanify(float(arg), self.units))
        
    def _humanify(self, value, units):
        assert units
        if value >= units[0][0]:
            return '%.0f %s' % (round(float(value) / units[0][0]), 
                                 units[0][1])
        for factor, unit in units:
            size = float(value) / float(factor)
            if 1 <= size < 1000:
                return '%.0f %s' % (round(size), unit)
        return '%.0f %s' % (round(float(value) / units[-1][0]), units[-1][1])


if __name__ == '__main__':
    Humanify().run()