Skip to content

Commit

Permalink
Update __data_size__.py
Browse files Browse the repository at this point in the history
Looks like you were re-implementing the ceiling function (math.ceil) in a couple places. Made some cosmetic changes that pep8 recommends. I haven't actually tried to run the code, a few tests would be nice.
  • Loading branch information
B Martsberger committed Mar 16, 2015
1 parent 4d8e687 commit d9b11d9
Showing 1 changed file with 38 additions and 46 deletions.
84 changes: 38 additions & 46 deletions datasize/__data_size__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
def __bits_to_bytes__(b, **kwargs):
if 'word_length' in kwargs:
word_length = kwargs['word_length']
else:
word_length = 8
B = round(b/word_length)
if b % word_length > 0:
B += 1
from math import ceil

def __bits_to_bytes__(b, word_length=8):
B = ceil(b/word_length)
return int(B)

class data_size(int):
class DataSize(int):
'''Integer subclass that handles units appropriate for data allocation.
Adapts popular string representations of data sizes to integer values
supporting arithmetic and alternate string representations.
Expand All @@ -26,8 +22,8 @@ class data_size(int):
Arithmetic methods inherit directly from int, and return int. This
keeps this class smaller, and avoids unecessary constructor overhead.
'''
word_length = 8 #defaults to octet = byte for conversion to/from bits
bit_suffix, byte_suffix = 'b','B'
word_length = 8 # defaults to octet = byte for conversion to/from bits
bit_suffix, byte_suffix = 'b', 'B'
metric_prefixes = {
# metric/decimal unit prefixes
'k' : 1000,
Expand All @@ -54,45 +50,43 @@ class data_size(int):
unit_prefixes = metric_prefixes.copy()
unit_prefixes.update(IEC_prefixes)
# also make a map from unit denominations to prefix
prefix_units = dict(zip( tuple(unit_prefixes.values()),tuple(unit_prefixes.keys())) )
prefix_units = dict(zip( tuple(unit_prefixes.values()), tuple(unit_prefixes.keys())) )
nonstandard_units = dict(zip((m for m in IEC_prefixes.values()),(k[0] for k in IEC_prefixes.keys())))
def __init__(self,spec,**kwargs):

def __init__(self, spec, word_length=8):
'''Usage:
min_heap = data_size('768Mib')
max_heap = data_size('2G')
min_heap = DataSize('768Mib')
max_heap = DataSize('2G')
max_heap - min_heap = high_memory_warning_limit
sys_mem = data_size('16GiB')
disk_sz = data_size('650GB')
baud = data_size('25Mb')
sys_mem = DataSize('16GiB')
disk_sz = DataSize('650GB')
baud = DataSize('25Mb')
Optional keyword argument 'word_length' can be used
to specify some other bits per byte than the default of 8.
'''
if 'word_length' in kwargs:
self.word_length = int(kwargs['word_length'])
def __new__(subclass,spec, **kwargs):
'''Because data_size is a subclass of int, we must override __new__()
self.word_length = int(word_length)

def __new__(subclass, spec, **kwargs):
'''Because DataSize is a subclass of int, we must override __new__()
to implement a string decoder that can provide an immutable integer value
for instances.
'''
if 'word_length' in kwargs:
word_length = int(kwargs['word_length'])
else:
word_length = data_size.word_length
word_length = int(kwargs.get('word_length', DataSize.word_length))
unit = 'bytes'
multiple = 1
try:
raw = spec[:]
if raw[-1] == data_size.bit_suffix:
if raw[-1] == DataSize.bit_suffix:
unit = 'bits'
raw = raw.rstrip(data_size.bit_suffix).rstrip(data_size.byte_suffix)
units = [unit for unit in data_size.unit_prefixes.keys()]
raw = raw.rstrip(DataSize.bit_suffix).rstrip(DataSize.byte_suffix)
units = DataSize.unit_prefixes.keys()
units.sort(reverse=True)
for prefix in units:
offset = len(prefix)
if raw[-offset:] == prefix:
raw = raw[:-offset]
multiple = data_size.unit_prefixes[prefix]
multiple = DataSize.unit_prefixes[prefix]
break
except TypeError:
raw = spec
Expand All @@ -105,10 +99,9 @@ def __new__(subclass,spec, **kwargs):
bits = raw_number * word_length * multiple
value = raw_number * multiple
if type(value) == type(float(0)):
if not value.is_integer():
value = round(value + 0.5)
value = int(value)
return int.__new__(subclass,value)
value = int(ceil(value))
return int.__new__(subclass, value)

def __format__(self, code):
'''formats as a decimal number, but recognizes data units as type format codes.
Precision is ignored for integer multiples of the unit specified in the format code.
Expand All @@ -130,18 +123,17 @@ def __format__(self, code):
prefix = ''
denomination = 1
multiple = 1
auto_modes = ('a','A')
auto_modes = ('a', 'A')
prefix_units = self.prefix_units
if not code or code[-1] == 'a':
fmt_mode = 'a'
elif code[-1] == 'A':
fmt_mode = 'A'
base_unit = ''
else:
if code[-1] == 'A':
fmt_mode = 'A'
base_unit = ''
else:
fmt_mode = None
fmt_mode = None

if fmt_mode in auto_modes: # automatically choose a denomination/unit
if fmt_mode in auto_modes: # automatically choose a denomination/unit
if fmt_mode == 'A':
prefix_units = self.nonstandard_units
code = code.rstrip(''.join(auto_modes))
Expand All @@ -153,9 +145,9 @@ def __format__(self, code):
denomination = quantity
break
else:
if code[-1] in ('b','B'):
if code[-1] in ('b', 'B'):
base_unit = code[-1]
code = code[:-1] #eat the base unit
code = code[:-1] # eat the base unit
if base_unit == 'b':
multiple = self.word_length

Expand All @@ -171,10 +163,10 @@ def __format__(self, code):
base_unit = 'B'
value = float(self * multiple)/float(denomination)

if value.is_integer(): # emit integers if we can do it cleanly
if value.is_integer(): # emit integers if we can do it cleanly
code += 'd'
cast = lambda x:int(x)
code = code.split('.',1)[0] # if there is precision in the code, strip it`
cast = lambda x: int(x)
code = code.split('.', 1)[0] # if there is precision in the code, strip it`
else:
code += 'f'
cast = lambda x: x
Expand Down

0 comments on commit d9b11d9

Please sign in to comment.