# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Various formatting functions.""" def NumToPercent(num, total, min_precision=1, max_precision=5): """Returns the percentage (string) of |num| out of |total|. If the percentage includes a fraction, it will be computed down to the least precision that yields a non-zero and ranging between |min_precision| and |max_precision|. Values are always rounded down. All arithmetic operations are integer built-ins. Examples (using default precision): (1, 1) => 100% (3, 10) => 30% (3, 9) => 33.3% (3, 900) => 0.3% (3, 9000000) => 0.00003% (3, 900000000) => 0% (5, 2) => 250% Args: num: the value of the part total: the value of the whole min_precision: minimum precision for fractional percentage max_precision: maximum precision for fractional percentage Returns: Percentage string, or None if percent cannot be computed (i.e. total is zero). """ if total == 0: return None percent = 0 precision = min(min_precision, max_precision) factor = 10 ** precision while precision <= max_precision: percent = num * 100 * factor / total if percent: break factor *= 10 precision += 1 whole, frac = divmod(percent, factor) while frac and not frac % 10: frac /= 10 precision -= 1 return '%d%s%%' % (whole, '.%0*d' % (precision, frac) if frac else '') def BytesToHumanReadable(size, precision=1, decimal=False): """Returns a human readable representation of a given |size|. The returned string includes unit notations in either binary (KiB, MiB, etc) or decimal (kB, MB, etc), based on the value of |decimal|. The chosen unit is the largest that yields a whole (or mixed) number. It may contain up to |precision| fractional digits. Values are always rounded down. Largest unit is an exabyte. All arithmetic operations are integer built-ins. Examples (using default precision and binary units): 4096 => 4 KiB 5000 => 4.8 KiB 500000 => 488.2 KiB 5000000 => 4.7 MiB Args: size: the size in bytes precision: the number of digits past the decimal point decimal: whether to compute/present decimal or binary units Returns: Readable size string, or None if no conversion is applicable (i.e. size is less than the smallest unit). """ constants = ( (('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'), 1024), (('kB', 'MB', 'GB', 'TB', 'PB', 'EB'), 1000) ) suffixes, base = constants[decimal] exp, magnitude = 0, 1 while exp < len(suffixes): next_magnitude = magnitude * base if size < next_magnitude: break exp += 1 magnitude = next_magnitude if exp != 0: whole = size / magnitude frac = (size % magnitude) * (10 ** precision) / magnitude while frac and not frac % 10: frac /= 10 return '%d%s %s' % (whole, '.%d' % frac if frac else '', suffixes[exp - 1])