Python objects for dealing with metric units and memory, file, and genome sizes.
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.
Working with memory and file sizes becomes a little more elegant.
There are two main classes in this library: Unit
and Memory
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 == 3
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 == mem2
Converting 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 == expected
Or 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 == expected
Hmmm, 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 == expected
Want 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 == expected
You 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.6
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_bases
I am very happy to receive pull requests!
pip install --pre -r dev-requirements.txt
Ensure tests pass before pushing anything. Also, make sure you have not reduced the code coverage.
pytest
# or with coverage
pytest --cov=./
Please ensure there are no errors.
flake8 .
Please make sure the code is formatted with black
before pushing it.
black .