Skip to content

Instantly share code, notes, and snippets.

@acdimalev
Last active January 15, 2022 21:05
Show Gist options
  • Save acdimalev/069ad5c043a47852989331d75e4b0fcc to your computer and use it in GitHub Desktop.
Save acdimalev/069ad5c043a47852989331d75e4b0fcc to your computer and use it in GitHub Desktop.
def bits(measurement, unit):
'''Jinja filter to convert measurement from one unit to another.
Example:
{{ '1GiB' | bits('MiB') }}
-> 1024
'''
return first(convertTo(unit)(decode(measurement)))
conv = {
'b': 1,
'B': 8,
'Kib': 1024,
'KiB': 8 * 1024,
'Mib': 1024 ** 2,
'MiB': 8 * 1024 ** 2,
'Gib': 1024 ** 3,
'GiB': 8 * 1024 ** 3,
'Kb': 1000,
'KB': 8 * 1000,
'Mb': 1000 ** 2,
'MB': 8 * 1000 ** 2,
'Gb': 1000 ** 3,
'GB': 8 * 1000 ** 3,
}
# splitAt: int -> str -> (str, str)
# split string into two at given index
splitAt = lambda i: lambda s: (s[:i], s[i:])
# firstNonNumericIndex: str -> int
# find index of first non-numeric character in a string
firstNonNumericIndex = lambda s: map(str.isdigit, s).index(False)
# decode: str -> (int, str)
# split a measurement (e.g. "1MiB") into magnitude and unit
# ! FIXME: `int("")` is an error
decode = lambda s: (lambda m, u: (int(m), u))(*splitAt(firstNonNumericIndex(s))(s))
# convertTo: str -> (int, str) -> (int, str)
# convert measurement from one unit to another
# ! FIXME: invalid units throws an exception
convertTo = lambda u_f: lambda x: (lambda m, u_0: (int(m * conv[u_0] / conv[u_f]), u_f))(*x)
# encode: (int, str) -> str
# encode measurement (e.g. "1MiB") from magnitude and unit
encode = lambda x: (lambda m, u: str(m) + u)(*x)
# first: (x, _) -> x
# return first element of a tuple
first = lambda x: (lambda x, _: x)(*x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment