gc3libs.quantity — gc3pie development (SVN $Revision$) documentation

### Navigation

- index
- modules |
- next |
- previous |
- gc3pie development (SVN $Revision$) documentation »
- Programmer Documentation »
- GC3Libs programming API »

# gc3libs.quantity

Manipulation of quantities with units attached with automated conversion among compatible units.

For details and the discussion leading up to this, see: <http://code.google.com/p/gc3pie/issues/detail?id=47>

class `gc3libs.quantity.` `Duration`

  Represent the duration of a time lapse.

  Construction of a duration can be done by parsing a string specification; several formats are accepted:

  - A duration is an aggregate of days, hours, minutes and seconds:

        >>> l3 = Duration('1day 4hours 9minutes 16seconds')
        >>> l3.amount(Duration.s) # convert to seconds
        101356

  - Any of the terms can be omitted (in which case it defaults to zero):

        >>> l4 = Duration('1day 4hours 16seconds')
        >>> l4 == l3 - Duration('9 minutes')
        True

  - The unit names can be singular or plural, and any amount of space can be added between the time unit name and the associated amount:

        >>> l5 = Duration('3 hour 42 minute')
        >>> l6 = Duration('3 hours 42 minutes')
        >>> l7 = Duration('3hours 42minutes')
        >>> l5 == l6 == l7
        True

  - Unit names can also be abbreviated using just the leading letter:

        >>> l8 = Duration('3h 42m')
        >>> l9 = Duration('3h42m')
        >>> l8 == l9
        True

  - The abbreviated formats HH:MM:SS and DD:HH:MM:SS are also accepted:

        >>> # 1 hour + 1 minute + 1 second
        >>> l1 = Duration('01:01:01')
        >>> l1 == Duration('3661 s')
        True

        >>> # 1 day, 2 hours, 3 minutes, 4 seconds
        >>> l2 = Duration('01:02:03:04')
        >>> l2.amount(Duration.s)
        93784

    However, the formats HH:MM and MM:SS are rejected as ambiguous:

        >>> # is this hours:minutes or minutes:seconds ?
        >>> l0 = Duration('01:02')
        Traceback (most recent call last):
          ...
        ValueError: Duration '01:02' is ambiguous: use '1m 2s' for 1 minutes and 2 seconds, or '1h 2m' for 1 hours and 2 minutes.

  - Finally, you can specify a duration like any other quantity, as an integral amount of a given time unit:

        >>> l1 = Duration('1 day')
        >>> l2 = Duration('86400 s')
        >>> l1 == l2
        True

  A new quantity can also be defined as a multiple of an existing one:

      >>> an_hour = Duration('1 hour')
      >>> a_day = 24 * an_hour
      >>> a_day.amount(Duration.h)
      24

  The quantities `Duration.hours`, `Duration.minutes` and `Duration.seconds` (and their single-letter abbreviations `h`, `m`, `s`) are pre-defined with their obvious meaning.

  Also module-level aliases `hours`, `minutes` and `seconds` (and the one-letter forms) are available:

      >>> a_day1 = 24*hours
      >>> a_day2 = 1440*minutes
      >>> a_day3 = 86400*seconds

  This allows for yet another way of constructing duration objects, i.e., by passing the amount and the unit separately to the constructor:

      >>> a_day4 = Duration(24, hours)

  Two durations are equal if they indicate the exact same amount in seconds:

      >>> a_day1 == a_day2
      True
      >>> a_day1.amount(s)
      86400
      >>> a_day2.amount(s)
      86400

      >>> a_day == an_hour
      False
      >>> a_day.amount(minutes)
      1440
      >>> an_hour.amount(minutes)
      60

  Basic arithmetic is possible with durations:

      >>> two_hours = an_hour + an_hour
      >>> two_hours == 2*an_hour
      True

      >>> one_hour = two_hours - an_hour
      >>> one_hour.amount(seconds)
      3600

  It is also possible to add duration quantities defined with different units; the result is naturally expressed in the smaller unit of the two:

      >>> one_hour_and_half = an_hour + 30*minutes
      >>> one_hour_and_half
      Duration(90, unit=m)

  Note that the two unit class and numeric amount are accessible through the unit and `amount()` attributes:

      >>> one_hour_and_half.unit
      Duration(1, unit=m)
      >>> one_hour_and_half.amount()
      90

  The `amount()` method accepts an optional specification of an alternate unit to express the amount into:

      >>> one_hour_and_half.amount(Duration.hours)
      1

  An optional conv argument is available to specify a numerical domain for conversion, in case the default integer arithmetic is not precise enough:

      >>> one_hour_and_half.amount(Duration.hours, conv=float)
      1.5

  The `to_str()` method allows representing a duration as a string, and provides choice of the output format and unit. The format string should contain exactly two `%`-specifiers: the first one is used to format the numerical amount, and the second one to format the measurement unit name.

  By default, the unit used originally for defining the quantity is used:

      >>> an_hour.to_str('%d [%s]')
      '1 [hour]'

  This can be overridden by specifying an optional second argument unit:

      >>> an_hour.to_str('%d [%s]', unit=Duration.m)
      '60 [m]'

  A third optional argument conv can set the numerical type to be used for conversion computations:

      >>> an_hour.to_str('%.1f [%s]', unit=Duration.m, conv=float)
      '60.0 [m]'

  The default numerical type is int, which in particular implies that you get a null amount if the requested unit is larger than the quantity:

      >>> an_hour.to_str('%d [%s]', unit=Duration.days)
      '0 [days]'

  Conversion to string uses the unit originally used for defining the quantity and the `%g%s` format:

      >>> str(an_hour)
      '1hour'

  `to_timedelta`(duration)

    Convert a duration into a Python datetime.timedelta object.

    This is useful to operate on Python’s datetime.time and datetime.date objects, which can be added or subtracted to datetime.timedelta.

class `gc3libs.quantity.` `Memory`

  Represent an amount of RAM.

  Construction of a memory quantity can be done by parsing a string specification (amount followed by unit):

      >>> byte = Memory('1 B')
      >>> kilobyte = Memory('1 kB')

  A new quantity can also be defined as a multiple of an existing one:

      >>> a_thousand_kB = 1000*kilobyte

  The base-10 units (up to TB, Terabytes) and base-2 (up to TiB, TiBiBytes) are available as attributes of the Memory class. This allows for a third way of constructing quantity objects, i.e., by passing the amount and the unit separately to the constructor:

      >>> a_megabyte = Memory(1, Memory.MB)
      >>> a_mibibyte = Memory(1, Memory.MiB)

      >>> a_gigabyte = 1*Memory.GB
      >>> a_gibibyte = 1*Memory.GiB

      >>> two_terabytes = 2*Memory.TB
      >>> two_tibibytes = 2*Memory.TiB

  Two memory quantities are equal if they indicate the exact same amount in bytes:

      >>> kilobyte == 1000*byte
      True
      >>> a_megabyte == a_mibibyte
      False
      >>> a_megabyte < a_mibibyte
      True
      >>> a_megabyte > a_gigabyte
      False

  Basic arithmetic is possible with memory quantities:

      >>> two_bytes = byte + byte
      >>> two_bytes == 2*byte
      True
      >>> half_gigabyte = a_gigabyte / 2
      >>> half_gigabyte
      Memory(476.837, unit=MiB)

  The ratio of two memory quantities is correctly computed as a pure (floating-point) number:

      >>> a_gigabyte / a_megabyte
      1000.0

  It is also possible to add memory quantities defined with different units; the result is naturally expressed in the smaller unit of the two:

      >>> one_gigabyte_and_half = 1*Memory.GB + 500*Memory.MB
      >>> one_gigabyte_and_half
      Memory(1500, unit=MB)

  Note that the two unit class and numeric amount are accessible through the unit and `amount()` attributes:

      >>> one_gigabyte_and_half.unit
      Memory(1, unit=MB)
      >>> one_gigabyte_and_half.amount()
      1500

  The `amount()` method accepts an optional specification of an alternate unit to express the amount into:

      >>> one_gigabyte_and_half.amount(Memory.GB)
      1

  An optional conv argument is available to specify a numerical domain for conversion, in case the default integer arithmetic is not precise enough:

      >>> one_gigabyte_and_half.amount(Memory.GB, conv=float)
      1.5

  The `to_str()` method allows representing a quantity as a string, and provides choice of the output format and unit. The format string should contain exactly two `%`-specifiers: the first one is used to format the numerical amount, and the second one to format the measurement unit name.

  By default, the unit used originally for defining the quantity is used:

      >>> a_megabyte.to_str('%d [%s]')
      '1 [MB]'

  This can be overridden by specifying an optional second argument unit:

      >>> a_megabyte.to_str('%d [%s]', unit=Memory.kB)
      '1000 [kB]'

  A third optional argument conv can set the numerical type to be used for conversion computations:

      >>> a_megabyte.to_str('%g%s', unit=Memory.GB, conv=float)
      '0.001GB'

  The default numerical type is int, which in particular implies that you get a null amount if the requested unit is larger than the quantity:

      >>> a_megabyte.to_str('%g%s', unit=Memory.GB, conv=int)
      '0GB'

  Conversion to string uses the unit originally used for defining the quantity and the `%g%s` format:

      >>> str(a_megabyte)
      '1MB'

class `gc3libs.quantity.` `Quantity`(base_unit_name, **other_units)

  Metaclass for creating quantity classes.

  This factory creates subclasses of `_Quantity` and bootstraps the base unit.

  The name of the base unit is given as argument to the metaclass instance:

      >>> class Memory1(object):
      ...   __metaclass__ = Quantity('B')
      ...
      >>> B = Memory1('1 B')
      >>> print (2*B)
      2B

  Optional keyword arguments create additional units; the argument key gives the unit name, and its value gives the ratio of the new unit to the base unit. For example:

      >>> class Memory2(object):
      ...   __metaclass__ = Quantity('B', kB=1000, MB=1000*1000)
      ...
      >>> a_thousand_kB = Memory2('1000kB')
      >>> MB = Memory2('1   MB')
      >>> a_thousand_kB == MB
      True

  Note that the units (base and additional) are also available as class attributes for easier referencing in Python code:

      >>> a_thousand_kB == Memory2.MB
      True

### Navigation

- index
- modules |
- next |
- previous |
- gc3pie development (SVN $Revision$) documentation »
- Programmer Documentation »
- GC3Libs programming API »