File: instances.rst

package info (click to toggle)
python-bitmath 1.3.3.1-4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 736 kB
  • sloc: python: 2,056; makefile: 324; sh: 20
file content (449 lines) | stat: -rw-r--r-- 12,138 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
Instances
#########

.. _instance_attributes:

.. contents::
   :depth: 3
   :local:


.. _instances_attributes:

Instance Attributes
*******************

bitmath objects have several instance attributes:

.. py:attribute:: BitMathInstance.base

   The mathematical base of the unit of the instance (this will be **2** or **10**)

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.base
      2

.. py:attribute:: BitMathInstance.binary

   The `Python binary representation
   <https://docs.python.org/2/library/functions.html#bin>`_ of the
   instance's value (in bits)

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.binary
      0b10100111001000

.. py:attribute:: BitMathInstance.bin

   This is an alias for ``binary``

.. py:attribute:: BitMathInstance.bits

   The number of bits in the object

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.bits
      10696.0

.. py:attribute:: BitMathInstance.bytes

   The number of bytes in the object

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.bytes
      1337

.. py:attribute:: BitMathInstance.power

   The mathematical power the ``base`` of the unit of the instance is raised to

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.power
      0

.. py:attribute:: BitMathInstance.system

   The system of units used to measure this instance (``NIST`` or ``SI``)

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.system
      NIST

.. py:attribute:: BitMathInstance.value

   The value of the instance in *prefix* units\ :sup:`1`

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.value
      1337.0

.. py:attribute:: BitMathInstance.unit

   The string representation of this prefix unit (such as ``MiB`` or ``kb``)

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.unit
      Byte

.. py:attribute:: BitMathInstance.unit_plural

   The pluralized string representation of this prefix unit.

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.unit_plural
      Bytes

.. py:attribute:: BitMathInstance.unit_singular

   The singular string representation of this prefix unit (such as
   ``MiB`` or ``kb``)

   .. code-block:: python

      >>> b = bitmath.Byte(1337)
      >>> print b.unit_singular
      Byte


**Notes:**

1. Given an instance ``k``, where ``k = KiB(1.3)``, then ``k.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:

.. code-block:: python
   :linenos:

   >>> 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'



Instance Methods
****************

bitmath objects come with a few basic methods: :py:meth:`to_THING`,
:py:meth:`format`, and :py:meth:`best_prefix`.


.. _instances_to_thing:

to_THING()
==========

Like the :ref:`available classes <classes_available>`, there are 24
``to_THING()`` methods available. ``THING`` is any of the bitmath
classes. You can even ``to_THING()`` an instance into itself again:


.. code-block:: python
   :linenos:
   :emphasize-lines: 3,7,12

   >>> 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


.. _instances_best_prefix:

best_prefix()
=============

.. py:method:: best_prefix([system=None])

   Return an equivalent instance which uses the best human-readable
   prefix-unit to represent it.

   :param int system: one of :py:const:`bitmath.NIST` or :py:const:`bitmath.SI`
   :return: An equivalent :py:class:`bitmath` instance
   :rtype: :py:class:`bitmath`
   :raises ValueError: if an invalid unit system is given for ``system``


The :py:meth:`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
:py:func:`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 :ref:`format <instances_format>` method to make the output
even easier to read.

.. code-block:: python


   >>> 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:

.. code-block:: python

   >>> 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



.. _instances_format:

format()
========

.. py:method:: BitMathInstance.format(fmt_spec)

   Return a custom-formatted string to represent this instance.

   :param str fmt_spec: A valid formatting mini-language string
   :return: The custom formatted representation
   :rtype: ``string``


bitmath instances come with a verbose built-in string representation:

.. code-block:: python

   >>> 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 :py:meth:`format` method gives you complete control over the
instance's representation. All of the :ref:`instances attributes
<instance_attributes>` are available to use when choosing a
representation.

The following sections describe some common use cases of the
:py:meth:`format` method as well as provide a :ref:`brief tutorial
<instances_mini_language>` of the greater Python formatting
meta-language.


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:

.. code-block:: python

   >>> ugly_number = MB(50).to_MiB() / 8.0
   >>> print ugly_number
   5.96046447754 MiB

Now, let's use the :py:meth:`format` method to limit that to two
digits of precision:

.. code-block:: python

   >>> 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.


Format All the Instance Attributes
----------------------------------

The following example prints out every instance attribute. Take note
of how an attribute may be referenced multiple times.

.. code-block:: python
   :linenos:
   :emphasize-lines: 4,16

   >>> 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**

.. _instances_properties:

Instance Properties
*******************

THING Properties
================

Like the :ref:`available classes <classes_available>`, there are 24
``THING`` properties available. ``THING`` is any of the bitmath
classes. Under the covers these properties call ``to_THING``.


.. code-block:: python
   :linenos:
   :emphasize-lines: 3,6,10

   >>> 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




.. _instances_mini_language:

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
<https://docs.python.org/2/library/string.html#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).

.. seealso::

   `Python String Format Cookbook <https://mkaz.blog/code/python-string-format-cookbook/>`_
      `Marcus Kazmierczak’s <https://mkaz.com/>`_ *excellent* introduction to string formatting