4. Instances¶
4.1. Instance Attributes¶
bitmath objects have several instance attributes:
-
BitMathInstance.
base
¶ The mathematical base of the unit of the instance (this will be 2 or 10)
>>> b = bitmath.Byte(1337) >>> print b.base 2
-
BitMathInstance.
binary
¶ The Python binary representation of the instance’s value (in bits)
>>> b = bitmath.Byte(1337) >>> print b.binary 0b10100111001000
-
BitMathInstance.
bin
¶ This is an alias for
binary
-
BitMathInstance.
bits
¶ The number of bits in the object
>>> b = bitmath.Byte(1337) >>> print b.bits 10696.0
-
BitMathInstance.
bytes
¶ The number of bytes in the object
>>> b = bitmath.Byte(1337) >>> print b.bytes 1337
-
BitMathInstance.
power
¶ The mathematical power the
base
of the unit of the instance is raised to>>> b = bitmath.Byte(1337) >>> print b.power 0
-
BitMathInstance.
system
¶ The system of units used to measure this instance (
NIST
orSI
)>>> b = bitmath.Byte(1337) >>> print b.system NIST
-
BitMathInstance.
value
¶ The value of the instance in prefix units1
>>> b = bitmath.Byte(1337) >>> print b.value 1337.0
-
BitMathInstance.
unit
¶ The string representation of this prefix unit (such as
MiB
orkb
)>>> b = bitmath.Byte(1337) >>> print b.unit Byte
-
BitMathInstance.
unit_plural
¶ The pluralized string representation of this prefix unit.
>>> b = bitmath.Byte(1337) >>> print b.unit_plural Bytes
-
BitMathInstance.
unit_singular
¶ The singular string representation of this prefix unit (such as
MiB
orkb
)>>> b = bitmath.Byte(1337) >>> print b.unit_singular Byte
Notes:
- Given an instance
k
, wherek = KiB(1.3)
, thenk.value
is 1.3
The following is an example of how to access some of these attributes and what you can expect their printed representation to look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> dvd_capacity = GB(4.7)
>>> print "Capacity in bits: %s\nbytes: %s\n" % \
(dvd_capacity.bits, dvd_capacity.bytes)
Capacity in bits: 37600000000.0
bytes: 4700000000.0
>>> dvd_capacity.value
4.7
>>> dvd_capacity.bin
'0b100011000001001000100111100000000000'
>>> dvd_capacity.binary
'0b100011000001001000100111100000000000'
|
4.2. Instance Methods¶
bitmath objects come with a few basic methods: to_THING()
,
format()
, and best_prefix()
.
4.2.1. to_THING()¶
Like the available classes, there are 24
to_THING()
methods available. THING
is any of the bitmath
classes. You can even to_THING()
an instance into itself again:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | >>> from bitmath import *
>>> one_mib = MiB(1)
>>> one_mib_in_kb = one_mib.to_kb()
>>> one_mib == one_mib_in_kb
True
>>> another_mib = one_mib.to_MiB()
>>> print one_mib, one_mib_in_kb, another_mib
1.0 MiB 8388.608 kb 1.0 MiB
>>> six_TB = TB(6)
>>> six_TB_in_bits = six_TB.to_Bit()
>>> print six_TB, six_TB_in_bits
6.0 TB 4.8e+13 Bit
>>> six_TB == six_TB_in_bits
True
|
4.2.2. best_prefix()¶
-
best_prefix
([system=None])¶ Return an equivalent instance which uses the best human-readable prefix-unit to represent it.
Parameters: system (int) – one of bitmath.NIST
orbitmath.SI
Returns: An equivalent bitmath
instanceReturn type: bitmath
Raises: ValueError – if an invalid unit system is given for system
The best_prefix()
method returns the result of converting a
bitmath instance into an equivalent instance using a prefix unit that
better represents the original value. Another way to think of this is
automatic discovery of the most sane, or human readable, unit to
represent a given size. This functionality is especially important in
the domain of interactive applications which need to report file sizes
or transfer rates to users.
As an analog, consider you have 923,874,434¢ in your bank account. You
probably wouldn’t want to read your bank statement and find your
balance in pennies. Most likely, your bank statement would read a
balance of $9,238,744.34. In this example, the input prefix is the
cent: ¢
. The best prefix for this is the dollar: $
.
Let’s, for example, say we are reporting a transfer rate in an
interactive application. It’s important to present this information in
an easily consumable format. The library we’re using to calculate the
rate of transfer reports the rate in bytes per second from a
tx_rate()
function.
We’ll use this example twice. In the first occurrence, we will print out the transfer rate in a more easily digestible format than pure bytes/second. In the second occurrence we’ll take it a step further, and use the format method to make the output even easier to read.
>>> for _rate in tx_rate():
... print "Rate: %s/second" % Bit(_rate)
... time.sleep(1)
Rate: 100.0 Bit/sec
Rate: 24000.0 Bit/sec
Rate: 1024.0 Bit/sec
Rate: 60151.0 Bit/sec
Rate: 33.0 Bit/sec
Rate: 9999.0 Bit/sec
Rate: 9238742.0 Bit/sec
Rate: 2.09895849555e+13 Bit/sec
Rate: 934098021.0 Bit/sec
Rate: 934894.0 Bit/sec
And now using a custom formatting definition:
>>> for _rate in tx_rate():
... print Bit(_rate).best_prefix().format("Rate: {value:.3f} {unit}/sec")
... time.sleep(1)
Rate: 12.500 Byte/sec
Rate: 2.930 KiB/sec
Rate: 128.000 Byte/sec
Rate: 7.343 KiB/sec
Rate: 4.125 Byte/sec
Rate: 1.221 KiB/sec
Rate: 1.101 MiB/sec
Rate: 2.386 TiB/sec
Rate: 111.353 MiB/sec
Rate: 114.123 KiB/sec
4.2.3. format()¶
-
BitMathInstance.
format
(fmt_spec)¶ Return a custom-formatted string to represent this instance.
Parameters: fmt_spec (str) – A valid formatting mini-language string Returns: The custom formatted representation Return type: string
bitmath instances come with a verbose built-in string representation:
>>> leet_bits = Bit(1337)
>>> print leet_bits
1337.0 Bit
However, for instances which aren’t whole numbers (as in MiB(1/3.0)
== 0.333333333333 MiB
, etc), their representation can be undesirable.
The format()
method gives you complete control over the
instance’s representation. All of the instances attributes are available to use when choosing a
representation.
The following sections describe some common use cases of the
format()
method as well as provide a brief tutorial of the greater Python formatting
meta-language.
4.2.3.1. Setting Decimal Precision¶
By default, bitmath instances will print to a fairly long precision for values which are not whole multiples of their prefix unit. In most use cases, simply printing out the first 2 or 3 digits of precision is acceptable.
The following examples will show us how to print out a bitmath instance in a more human readable way, by limiting the decimal precision to 2 digits.
First, for reference, the default formatting:
>>> ugly_number = MB(50).to_MiB() / 8.0
>>> print ugly_number
5.96046447754 MiB
Now, let’s use the format()
method to limit that to two
digits of precision:
>>> print ugly_number.format("{value:.2f}{unit}")
5.96 MiB
By changing the 2 character, you increase or decrease the
precision. Set it to 0 ({value:.0f}
) and you have what
effectively looks like an integer.
4.2.3.2. Format All the Instance Attributes¶
The following example prints out every instance attribute. Take note of how an attribute may be referenced multiple times.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | >>> longer_format = """Formatting attributes for %s
...: This instances prefix unit is {unit}, which is a {system} type unit
...: The unit value is {value}
...: This value can be truncated to just 1 digit of precision: {value:.1f}
...: In binary this looks like: {binary}
...: The prefix unit is derived from a base of {base}
...: Which is raised to the power {power}
...: There are {bytes} bytes in this instance
...: The instance is {bits} bits large
...: bytes/bits without trailing decimals: {bytes:.0f}/{bits:.0f}""" % str(ugly_number)
>>> print ugly_number.format(longer_format)
Formatting attributes for 5.96046447754 MiB
This instances prefix unit is MiB, which is a NIST type unit
The unit value is 5.96046447754
This value can be truncated to just 1 digit of precision: 6.0
In binary this looks like: 0b10111110101111000010000000
The prefix unit is derived from a base of 2
Which is raised to the power 20
There are 6250000.0 bytes in this instance
The instance is 50000000.0 bits large
bytes/bits without trailing decimals: 6250000/50000000
|
Note
On line 4 we print with 1 digit of precision, on line 16 we see the value has been rounded to 6.0
4.3. Instance Properties¶
4.3.1. THING Properties¶
Like the available classes, there are 24
THING
properties available. THING
is any of the bitmath
classes. Under the covers these properties call to_THING
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> from bitmath import *
>>> one_mib = MiB(1)
>>> one_mib == one_mib.kb
True
>>> print one_mib, one_mib.kb, one_mib.MiB
1.0 MiB 8388.608 kb 1.0 MiB
>>> six_TB = TB(6)
>>> print six_TB, six_TB.Bit
6.0 TB 4.8e+13 Bit
>>> six_TB == six_TB.Bit
True
|
4.4. The Formatting Mini-Language¶
That is all you begin printing numbers with custom precision. If you want to learn a little bit more about using the formatting mini-language, read on.
You may be asking yourself where these {value:.2f}
and {unit}
strings came from. These are part of the Format Specification
Mini-Language
which is part of the Python standard library. To be explicitly clear
about what’s going on here, let’s break the first specifier
({value:.2f}
) down into it’s component parts:
{value:.2f}
| |||
| |||\---- The "f" says to format this as a floating point type
| ||\----- The 2 indicates we want 2 digits of precision (default is 6)
| |\------ The '.' character must precede the precision specifier for floats
| \------- The : separates the attribute name from the formatting specification
\---------- The name of the attribute to print
The second specifier ({unit}
) says to format the unit
attribute as a string (string is the default type when no type is
given).
See also
- Python String Format Cookbook
- Marcus Kazmierczak’s excellent introduction to string formatting