| Amin Hassani | f94b643 | 2018-01-26 17:39:47 -0800 | [diff] [blame] | 1 | # |
| 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 Arnold | 553b0ec | 2013-01-26 01:00:39 -0800 | [diff] [blame] | 16 | |
| 17 | """Various formatting functions.""" |
| 18 | |
| Andrew Lassalle | 165843c | 2019-11-05 13:30:34 -0800 | [diff] [blame] | 19 | from __future__ import division |
| 20 | |
| Gilad Arnold | 553b0ec | 2013-01-26 01:00:39 -0800 | [diff] [blame] | 21 | |
| 22 | def 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 Arnold | 6a3a387 | 2013-10-04 18:18:45 -0700 | [diff] [blame] | 44 | Percentage string, or None if percent cannot be computed (i.e. total is |
| 45 | zero). |
| Gilad Arnold | 553b0ec | 2013-01-26 01:00:39 -0800 | [diff] [blame] | 46 | |
| 47 | """ |
| Gilad Arnold | 6a3a387 | 2013-10-04 18:18:45 -0700 | [diff] [blame] | 48 | if total == 0: |
| 49 | return None |
| 50 | |
| Gilad Arnold | 553b0ec | 2013-01-26 01:00:39 -0800 | [diff] [blame] | 51 | percent = 0 |
| 52 | precision = min(min_precision, max_precision) |
| 53 | factor = 10 ** precision |
| 54 | while precision <= max_precision: |
| Andrew Lassalle | 165843c | 2019-11-05 13:30:34 -0800 | [diff] [blame] | 55 | percent = num * 100 * factor // total |
| Gilad Arnold | 553b0ec | 2013-01-26 01:00:39 -0800 | [diff] [blame] | 56 | 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 | |
| 69 | def 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 Lassalle | 165843c | 2019-11-05 13:30:34 -0800 | [diff] [blame] | 107 | whole = size // magnitude |
| 108 | frac = (size % magnitude) * (10 ** precision) // magnitude |
| Gilad Arnold | 553b0ec | 2013-01-26 01:00:39 -0800 | [diff] [blame] | 109 | while frac and not frac % 10: |
| 110 | frac /= 10 |
| 111 | return '%d%s %s' % (whole, '.%d' % frac if frac else '', suffixes[exp - 1]) |