vesicellular/rectangulararray.py

60 lines
1.5 KiB
Python

# v1
# Written by nortti
# Under Unlicense
from functools import reduce
import operator
class RankError(Exception):
None
class RectangularArray:
def __init__(self, sizes, *, default = None, initial = None):
if isinstance(sizes, int):
self.sizes = (sizes,)
else:
self.sizes = tuple(sizes)
self.rank = len(self.sizes)
combined_size = reduce(operator.mul, self.sizes)
if initial is None:
self.array = [default] * combined_size
else:
if len(initial) != combined_size:
raise ValueError('Initial array of wrong size passed (expected %i, got %i)' % (combined_size, len(initial)))
def __get_location_from_indices(self, indices):
if isinstance(indices, int):
indices = (indices,)
else:
indices = tuple(indices)
if len(indices) != self.rank:
raise RankError('Rank mismatch accessing array (expected %i, got %i)' % (self.rank, len(indices)))
location = 0
for dimension in range(self.rank):
index = indices[dimension]
size = self.sizes[dimension]
if index >= size:
raise IndexError('Index Out of Range (is %i, max %i)' % (index, self.sizes[dimension] - 1))
location *= size
location += index
return location
def __getitem__(self, indices):
location = self.__get_location_from_indices(indices)
return self.array[location]
def __setitem__(self, indices, value):
location = self.__get_location_from_indices(indices)
self.array[location] = value
def __repr__(self):
return 'RectangularArray(%s, initial = %s)' % (repr(self.sizes), repr(self.array))