mbhall88/MemoryUnits
Python objects for dealing with metric units and memory, file, and genome sizes ๐พ
MemoryUnits
Python objects for dealing with metric units and memory, file, and genome sizes.
Table of Contents
Install
This library is intended to be "header-only". That is, just copy and paste the code (and
test) into your project.
No need to pip install anything.
The only dependency is pytest if you include the test code in your project. The actual
library code requires no dependencies outside the Python standard library.
Usage
Working with memory and file sizes becomes a little more elegant.
There are two main classes in this library: Unit and Memory
Unit
Unit is the class used for scaling your memory value. The units are the same as
metric units and go from Kilo up to Zetta (with Bytes as the base).
They can be constructed in two different ways, or you can directly use one as the class
is just an Enum.
from memory_units import Unit
# use directly
unit = Unit.KILO
# construct from a variety of strings
suffixes = ["MB", "M", "m", "mb", "Mb"]
for s in suffixes:
unit = Unit.from_suffix(s)
assert unit == Unit.MEGA
# construct from a power order
power = 3
unit = Unit.from_power(power)
assert unit == Unit.GIGA
# get the suffix and power easily
assert unit.suffix == "GB"
assert unit.power == 3Memory
This is the main attraction.
You can construct a Memory object in a couple of ways.
from memory_units import Unit, Memory, InvalidMemoryString
# default construction specifying the value and unit
mem = Memory(20, Unit.TERA)
# empty initialisation is one byte
mem = Memory()
assert mem.bytes() == 1
# or you can construct one from a string
mem = Memory.from_str("12KB")
# the string can be formatted in many ways
strings = ["500MB", "500.0MB", "500M", "500mb", "500 mB"]
expected = Memory(500, Unit.MEGA)
for s in strings:
actual = Memory.from_str(s)
assert actual == expected
# if you try to initialise from a bad string, you will get an `InvalidMemoryString` exception.
s = "60LB"
try:
mem = Memory.from_str(s)
except InvalidMemoryString as err:
print(err)
# 60LB is an invalid memory string.In the above examples, you might have noticed that we used the equality operator (==)
to compare two Memory objects. The equality operator actually works by comparing the
number of bytes, rather than the value and unit. So, if I want to see if two memory
variables are the same, but they have different units - no problem!
from memory_units import Unit, Memory
mem1 = Memory(500, Unit.MEGA)
mem2 = Memory(0.5, Unit.GIGA)
assert mem1 == mem2Converting between different units is a pretty common need. Let's say we want to convert
2,500 kilobytes into megabytes.
from memory_units import Unit, Memory
mem = Memory(2_500, Unit.KILO)
desired_units = Unit.MEGA
actual = mem.to(desired_units)
expected = Memory(2.5, desired_units)
assert actual == expectedOr we just want plain ol' bytes.
from memory_units import Unit, Memory
mem = Memory(40, Unit.GIGA)
actual = mem.bytes()
expected = 40_000_000_000
assert actual == expectedHmmm, but we want our resulting bytes to be in binary multiples, i.e. 1024 instead of
1000.
from memory_units import Unit, Memory
mem = Memory(40, Unit.KILO)
actual = mem.bytes(decimal_multiples=False)
expected = 40_960
assert actual == expectedWant a pretty printed version of your memory?
from memory_units import Unit, Memory
mem = Memory(50, Unit.KILO)
actual = str(mem)
expected = "50KB"
assert actual == expectedYou also have access to some basic properties on the Memory object.
from memory_units import Unit, Memory
mem = Memory(5.6, Unit.EXA)
assert mem.power == 6
assert mem.suffix == "EB"
assert mem.value == 5.6Bioinformatics bonus
Lastly, if you work in bioinformatics (as I do), you might find your code will look a
little more relevant if you just rename the Memory class.
from memory_units import Unit, Memory as GenomeSize
size = GenomeSize(4.4, Unit.GIGA)
actual_bases = size.bytes()
expected_bases = 4_400_000_000
assert actual_bases == expected_basesContributing
I am very happy to receive pull requests!
Set up
pip install --pre -r dev-requirements.txtTests
Ensure tests pass before pushing anything. Also, make sure you have not reduced the
code coverage.
pytest
# or with coverage
pytest --cov=./Linting
Please ensure there are no errors.
flake8 .Formatting
Please make sure the code is formatted with black before pushing it.
black .