blob: e73badf3d5224b47119ae50b72b045dad267ca9c [file] [log] [blame]
Amin Hassanif94b6432018-01-26 17:39:47 -08001#
2# Copyright (C) 2013 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
Gilad Arnold553b0ec2013-01-26 01:00:39 -080016
17"""Various formatting functions."""
18
Andrew Lassalle165843c2019-11-05 13:30:34 -080019from __future__ import division
20
Gilad Arnold553b0ec2013-01-26 01:00:39 -080021
22def NumToPercent(num, total, min_precision=1, max_precision=5):
23 """Returns the percentage (string) of |num| out of |total|.
24
25 If the percentage includes a fraction, it will be computed down to the least
26 precision that yields a non-zero and ranging between |min_precision| and
27 |max_precision|. Values are always rounded down. All arithmetic operations
28 are integer built-ins. Examples (using default precision):
29
30 (1, 1) => 100%
31 (3, 10) => 30%
32 (3, 9) => 33.3%
33 (3, 900) => 0.3%
34 (3, 9000000) => 0.00003%
35 (3, 900000000) => 0%
36 (5, 2) => 250%
37
38 Args:
39 num: the value of the part
40 total: the value of the whole
41 min_precision: minimum precision for fractional percentage
42 max_precision: maximum precision for fractional percentage
43 Returns:
Gilad Arnold6a3a3872013-10-04 18:18:45 -070044 Percentage string, or None if percent cannot be computed (i.e. total is
45 zero).
Gilad Arnold553b0ec2013-01-26 01:00:39 -080046
47 """
Gilad Arnold6a3a3872013-10-04 18:18:45 -070048 if total == 0:
49 return None
50
Gilad Arnold553b0ec2013-01-26 01:00:39 -080051 percent = 0
52 precision = min(min_precision, max_precision)
53 factor = 10 ** precision
54 while precision <= max_precision:
Andrew Lassalle165843c2019-11-05 13:30:34 -080055 percent = num * 100 * factor // total
Gilad Arnold553b0ec2013-01-26 01:00:39 -080056 if percent:
57 break
58 factor *= 10
59 precision += 1
60
61 whole, frac = divmod(percent, factor)
62 while frac and not frac % 10:
63 frac /= 10
64 precision -= 1
65
66 return '%d%s%%' % (whole, '.%0*d' % (precision, frac) if frac else '')
67
68
69def BytesToHumanReadable(size, precision=1, decimal=False):
70 """Returns a human readable representation of a given |size|.
71
72 The returned string includes unit notations in either binary (KiB, MiB, etc)
73 or decimal (kB, MB, etc), based on the value of |decimal|. The chosen unit is
74 the largest that yields a whole (or mixed) number. It may contain up to
75 |precision| fractional digits. Values are always rounded down. Largest unit
76 is an exabyte. All arithmetic operations are integer built-ins. Examples
77 (using default precision and binary units):
78
79 4096 => 4 KiB
80 5000 => 4.8 KiB
81 500000 => 488.2 KiB
82 5000000 => 4.7 MiB
83
84 Args:
85 size: the size in bytes
86 precision: the number of digits past the decimal point
87 decimal: whether to compute/present decimal or binary units
88 Returns:
89 Readable size string, or None if no conversion is applicable (i.e. size is
90 less than the smallest unit).
91
92 """
93 constants = (
94 (('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'), 1024),
95 (('kB', 'MB', 'GB', 'TB', 'PB', 'EB'), 1000)
96 )
97 suffixes, base = constants[decimal]
98 exp, magnitude = 0, 1
99 while exp < len(suffixes):
100 next_magnitude = magnitude * base
101 if size < next_magnitude:
102 break
103 exp += 1
104 magnitude = next_magnitude
105
106 if exp != 0:
Andrew Lassalle165843c2019-11-05 13:30:34 -0800107 whole = size // magnitude
108 frac = (size % magnitude) * (10 ** precision) // magnitude
Gilad Arnold553b0ec2013-01-26 01:00:39 -0800109 while frac and not frac % 10:
110 frac /= 10
111 return '%d%s %s' % (whole, '.%d' % frac if frac else '', suffixes[exp - 1])