Home | History | Annotate | Download | only in update_payload
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """Various formatting functions."""
      6 
      7 
      8 def NumToPercent(num, total, min_precision=1, max_precision=5):
      9   """Returns the percentage (string) of |num| out of |total|.
     10 
     11   If the percentage includes a fraction, it will be computed down to the least
     12   precision that yields a non-zero and ranging between |min_precision| and
     13   |max_precision|. Values are always rounded down. All arithmetic operations
     14   are integer built-ins. Examples (using default precision):
     15 
     16     (1, 1) => 100%
     17     (3, 10) => 30%
     18     (3, 9) => 33.3%
     19     (3, 900) => 0.3%
     20     (3, 9000000) => 0.00003%
     21     (3, 900000000) => 0%
     22     (5, 2) => 250%
     23 
     24   Args:
     25     num: the value of the part
     26     total: the value of the whole
     27     min_precision: minimum precision for fractional percentage
     28     max_precision: maximum precision for fractional percentage
     29   Returns:
     30     Percentage string, or None if percent cannot be computed (i.e. total is
     31     zero).
     32 
     33   """
     34   if total == 0:
     35     return None
     36 
     37   percent = 0
     38   precision = min(min_precision, max_precision)
     39   factor = 10 ** precision
     40   while precision <= max_precision:
     41     percent = num * 100 * factor / total
     42     if percent:
     43       break
     44     factor *= 10
     45     precision += 1
     46 
     47   whole, frac = divmod(percent, factor)
     48   while frac and not frac % 10:
     49     frac /= 10
     50     precision -= 1
     51 
     52   return '%d%s%%' % (whole, '.%0*d' % (precision, frac) if frac else '')
     53 
     54 
     55 def BytesToHumanReadable(size, precision=1, decimal=False):
     56   """Returns a human readable representation of a given |size|.
     57 
     58   The returned string includes unit notations in either binary (KiB, MiB, etc)
     59   or decimal (kB, MB, etc), based on the value of |decimal|. The chosen unit is
     60   the largest that yields a whole (or mixed) number. It may contain up to
     61   |precision| fractional digits. Values are always rounded down. Largest unit
     62   is an exabyte. All arithmetic operations are integer built-ins. Examples
     63   (using default precision and binary units):
     64 
     65     4096 => 4 KiB
     66     5000 => 4.8 KiB
     67     500000 => 488.2 KiB
     68     5000000 => 4.7 MiB
     69 
     70   Args:
     71     size: the size in bytes
     72     precision: the number of digits past the decimal point
     73     decimal: whether to compute/present decimal or binary units
     74   Returns:
     75     Readable size string, or None if no conversion is applicable (i.e. size is
     76     less than the smallest unit).
     77 
     78   """
     79   constants = (
     80       (('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'), 1024),
     81       (('kB', 'MB', 'GB', 'TB', 'PB', 'EB'), 1000)
     82   )
     83   suffixes, base = constants[decimal]
     84   exp, magnitude = 0, 1
     85   while exp < len(suffixes):
     86     next_magnitude = magnitude * base
     87     if size < next_magnitude:
     88       break
     89     exp += 1
     90     magnitude = next_magnitude
     91 
     92   if exp != 0:
     93     whole = size / magnitude
     94     frac = (size % magnitude) * (10 ** precision) / magnitude
     95     while frac and not frac % 10:
     96       frac /= 10
     97     return '%d%s %s' % (whole, '.%d' % frac if frac else '', suffixes[exp - 1])
     98