Package: bitmath
bitmathbitmathsimplifies many
facets of interacting with file sizes in various units. Originally
focusing on file size unit conversion, functionality now includes:Converting betweenSIandNISTprefix units (kBtoGiB)Converting between units of the same type (SI to SI, or NIST to NIST)Automatic human-readable prefix selection (like inhurry.filesize)Basic arithmetic operations (subtracting 42KiB from 50GiB)Rich comparison operations (1024 Bytes == 1KiB)bitwise operations (<<,>>,&,|,^)Reading a device’s storage capacity (Linux/OS X support only)argparseintegration as a custom typeprogressbarintegration as a better file transfer speed widgetString parsingSortingIn addition to the conversion and math operations,bitmathprovides
human readable representations of values which are suitable for use in
interactive shells as well as larger scripts and applications. The
format produced for these representations is customizable via the
functionality included in stdlibsstring.format.In discussion we will refer to the NIST units primarily. I.e., instead
of “megabyte” we will refer to “mebibyte”. The former is10^3 = 1,000,000bytes, whereas the second is2^20 = 1,048,576bytes. When you see file sizes or transfer rates in your web browser,
most of the time what you’re really seeing are the base-2 sizes/rates.Don’t Forget!The source for bitmathis available on GitHub.And did we mention there’s almost 200 unittests?Check them out for
yourself.InstallationThe easiest way to install bitmath is viadnf(oryum) if
you’re on a Fedora/RHEL based distribution. bitmath is available in
the main Fedora repositories, as well as theEPEL6andEPEL7repositories. There are now dual python2.x and python3.x releases
available.Python 2.x:$sudodnfinstallpython2-bitmathPython 3.x:$sudodnfinstallpython3-bitmathNoteUpgrading: If you have the oldpython-bitmathpackage
installed presently, you could also runsudo dnf updatepython-bitmathinsteadPyPi:You could also install bitmath fromPyPiif you like:$sudopipinstallbitmathNotepipinstalls need pip >= 1.1. To workaround this,download
bitmath, from
PyPi and thenpip installbitmath-x.y.z.tar.gz. Seeissue #57for more information.PPA:Ubuntu Xenial, Wily, Vivid, Trusty, and Precise users can install
bitmath from thelaunchpad PPA:$sudoadd-apt-repositoryppa:tbielawa/bitmath$sudoapt-getupdate$sudoapt-getinstallpython-bitmathSource:Or, if you want to install from source:$sudopython./setup.pyinstallIf you want the bitmath manpage installed as well:$sudomakeinstallDocumentationThe main documentation lives athttp://bitmath.readthedocs.org/en/latest/.Topics include:ThebitmathModuleUtility FunctionsContext ManagersModule VariablesargparseintegrationprogressbarintegrationThebitmathcommand-line ToolClassesInitializingAvailable ClassesClass MethodsInstancesInstance AttributesInstance MethodsInstance PropertiesThe Formatting Mini-LanguageGetting StartedTables of Supported OperationsBasic MathUnit ConversionRich ComparisonSortingReal Life ExamplesDownload SpeedsCalculating how many files fit on a devicePrinting Human-Readable File Sizes in PythonCalculating Linux BDP and TCP Window ScalingContributing to bitmathAppendicesRules for MathOn UnitsWho uses BitmathRelated ProjectsNEWSCopyrightExamplesArithmetic>>>importbitmath>>>log_size=bitmath.kB(137.4)>>>log_zipped_size=bitmath.Byte(987)>>>print"Compression saved%sspace"%(log_size-log_zipped_size)Compressionsaved136.413kBspace>>>thumb_drive=bitmath.GiB(12)>>>song_size=bitmath.MiB(5)>>>songs_per_drive=thumb_drive/song_size>>>printsongs_per_drive2457.6Convert UnitsFile size unit conversion:>>>frombitmathimport*>>>dvd_size=GiB(4.7)>>>print"DVD Size in MiB:%s"%dvd_size.to_MiB()DVDSizeinMiB:4812.8MiBSelect a human-readable unit>>>small_number=kB(100)>>>ugly_number=small_number.to_TiB()>>>printugly_number9.09494701773e-08TiB>>>printugly_number.best_prefix()97.65625KiBRich Comparison>>>cd_size=MiB(700)>>>cd_size>dvd_sizeFalse>>>cd_size<dvd_sizeTrue>>>MiB(1)==KiB(1024)True>>>MiB(1)<=KiB(1024)TrueSorting>>>sizes=[KiB(7337.0),KiB(1441.0),KiB(2126.0),KiB(2178.0),KiB(2326.0),KiB(4003.0),KiB(48.0),KiB(1770.0),KiB(7892.0),KiB(4190.0)]>>>printsorted(sizes)[KiB(48.0),KiB(1441.0),KiB(1770.0),KiB(2126.0),KiB(2178.0),KiB(2326.0),KiB(4003.0),KiB(4190.0),KiB(7337.0),KiB(7892.0)]Custom FormattingUse of the custom formatting systemAll of the available instance propertiesExample:>>>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)>>>printugly_number.format(longer_format)Formattingattributesfor5.96046447754MiBThisinstancesprefixunitisMiB,whichisaNISTtypeunitTheunitvalueis5.96046447754Thisvaluecanbetruncatedtojust1digitofprecision:6.0Inbinarythislookslike:0b10111110101111000010000000Theprefixunitisderivedfromabaseof2Whichisraisedtothepower20Thereare6250000.0bytesinthisinstanceTheinstanceis50000000.0bitslargebytes/bitswithouttrailingdecimals:6250000/50000000Utility Functionsbitmath.getsize()>>>printbitmath.getsize('python-bitmath.spec')3.7060546875KiBbitmath.parse_string()Parse a string with standard units:>>>importbitmath>>>a_dvd=bitmath.parse_string("4.7 GiB")>>>printtype(a_dvd)<class'bitmath.GiB'>>>>printa_dvd4.7GiBbitmath.parse_string_unsafe()Parse a string with ambiguous units:>>>importbitmath>>>a_gig=bitmath.parse_string_unsafe("1gb")>>>printtype(a_gig)<class'bitmath.GB'>>>>a_gig==bitmath.GB(1)True>>>bitmath.parse_string_unsafe('1gb')==bitmath.parse_string_unsafe('1g')Truebitmath.query_device_capacity()>>>importbitmath>>>withopen('/dev/sda')asfp:...root_disk=bitmath.query_device_capacity(fp)...printroot_disk.best_prefix()...238.474937439GiBbitmath.listdir()>>>foriinbitmath.listdir('./tests/',followlinks=True,relpath=True,bestprefix=True):...printi...('tests/test_file_size.py',KiB(9.2900390625))('tests/test_basic_math.py',KiB(7.1767578125))('tests/__init__.py',KiB(1.974609375))('tests/test_bitwise_operations.py',KiB(2.6376953125))('tests/test_context_manager.py',KiB(3.7744140625))('tests/test_representation.py',KiB(5.2568359375))('tests/test_properties.py',KiB(2.03125))('tests/test_instantiating.py',KiB(3.4580078125))('tests/test_future_math.py',KiB(2.2001953125))('tests/test_best_prefix_BASE.py',KiB(2.1044921875))('tests/test_rich_comparison.py',KiB(3.9423828125))('tests/test_best_prefix_NIST.py',KiB(5.431640625))('tests/test_unique_testcase_names.sh',Byte(311.0))('tests/.coverage',KiB(3.1708984375))('tests/test_best_prefix_SI.py',KiB(5.34375))('tests/test_to_built_in_conversion.py',KiB(1.798828125))('tests/test_to_Type_conversion.py',KiB(8.0185546875))('tests/test_sorting.py',KiB(4.2197265625))('tests/listdir_symlinks/10_byte_file_link',Byte(10.0))('tests/listdir_symlinks/depth1/depth2/10_byte_file',Byte(10.0))('tests/listdir_nosymlinks/depth1/depth2/10_byte_file',Byte(10.0))('tests/listdir_nosymlinks/depth1/depth2/1024_byte_file',KiB(1.0))('tests/file_sizes/kbytes.test',KiB(1.0))('tests/file_sizes/bytes.test',Byte(38.0))('tests/listdir/10_byte_file',Byte(10.0))Formatting>>>withbitmath.format(fmt_str="[{value:.3f}@{unit}]"):...foriinbitmath.listdir('./tests/',followlinks=True,relpath=True,bestprefix=True):...printi[1]...[9.290@KiB][7.177@KiB][1.975@KiB][2.638@KiB][3.774@KiB][5.257@KiB][2.031@KiB][3.458@KiB][2.200@KiB][2.104@KiB][3.942@KiB][5.432@KiB][311.000@Byte][3.171@KiB][5.344@KiB][1.799@KiB][8.019@KiB][4.220@KiB][10.000@Byte][10.000@Byte][10.000@Byte][1.000@KiB][1.000@KiB][38.000@Byte][10.000@Byte]argparseIntegrationExample script usingbitmath.integrations.BitmathTypeas an
argparser argument type:importargparseimportbitmathparser=argparse.ArgumentParser(description="Arg parser with a bitmath type argument")parser.add_argument('--block-size',type=bitmath.integrations.BitmathType,required=True)results=parser.parse_args()print"Parsed in:{PARSED}; Which looks like{TOKIB}as a Kibibit".format(PARSED=results.block_size,TOKIB=results.block_size.Kib)If ran as a script the results would be similar to this:$python./bmargparse.py--block-size100MiBParsedin:100.0MiB;Whichlookslike819200.0KibasaKibibitprogressbarIntegrationUsebitmath.integrations.BitmathFileTransferSpeedas aprogressbarfile transfer speed widget to monitor download speeds:importrequestsimportprogressbarimportbitmathimportbitmath.integrationsFETCH='https://www.kernel.org/pub/linux/kernel/v3.0/patch-3.16.gz'widgets=['Bitmath Progress Bar Demo: ',' ',progressbar.Bar(marker=progressbar.RotatingMarker()),' ',bitmath.integrations.BitmathFileTransferSpeed()]r=requests.get(FETCH,stream=True)size=bitmath.Byte(int(r.headers['Content-Length']))pbar=progressbar.ProgressBar(widgets=widgets,maxval=int(size),term_width=80).start()chunk_size=2048withopen('/dev/null','wb')asfd:forchunkinr.iter_content(chunk_size):fd.write(chunk)if(pbar.currval+chunk_size)<pbar.maxval:pbar.update(pbar.currval+chunk_size)pbar.finish()If ran as a script the results would be similar to this:$python./smalldl.pyBitmathProgressBarDemo:|||||||||||||||||||||||||||||||||||||||||1.58MiB/s