# If you wish to beliave to documentation, than I'd say that Ellipsis is used
# for multidimensional slices. Lets on the first place figure out how they appear
# and where could you expect to see them and how would you see them.
# glot.io does not support numpy, so just as comment:
# >>> import numpy as np
# >>> x = np.array([[[1],[2],[3]], [[4],[5],[6]]])
# >>> x[...,0]
# array([[1, 2, 3],
# [4, 5, 6]])
# So what exaclty will we got into function?
from args_viewer import ArgsViewer
av = ArgsViewer()
print av[...]
print av[:, "string", 1:0:4, 4, ..., 4 + 1j]
# So actually we can throw there what ever we want... Since now my slicing
# experience will never be the same. But going ahead I've found interesting
# elements which is:
# 1. slice(None, None, None)
# 2. slice(1, 0, 4)
# 3. Ellipsis
# The last one is well known for us and we've looking for him. It's an instance
# of EllipsisType. So before starting holly war with our mind and figureout what
# whose two first are, lets answer the question: "What does mean Ellipsis here
# for us?".
#
# Right. Totally right, my friend. Ellipsis means exactly that, what we would
# express on his place in the code! So we're empowered to give it any meaning
# we wish.
from matrix import Matrix
m = Matrix([
[
[i * 100 + j * 10 + k for k in range(0, 6)]
for j in range(0, 6)
]
for i in range(0, 6)
])
print "\nExperiment with Matrix:\n"
# Now lets access to first element
print m[0, 0, 0], "\n"
# And for internal slice
print m[0, 1:3, 0], "\n"
# And finaly use Ellipsis
print m[..., 1:3]
class ArgsViewer(object):
"""It does nothing special except just return us
first argument of item getter"""
def __getitem__(self, parameters):
return parameters
import types
class Matrix(object):
def __init__(self, seed):
self.rows = []
self.dimensions = self.__extract(seed)
# We're not checking:
# 1. That elements could be sets, tuples or other iterable;
# 2. Have same dimension
def __extract(self, seed):
if not isinstance(seed, types.ListType) or len(seed) is 0:
raise ValueError("Seed can not be not a list type or empty")
if all(isinstance(x, types.ListType) for x in seed):
self.rows = map(Matrix, seed)
return 1 + self.rows[0].dimensions
else:
self.rows = seed
return 1
# We're not doing quite a lot of things here... Very simpel logic.
# I'm not craving excellence here, just example to understand.
def __getitem__(self, parameters):
# No slice parameters - return all content
if len(parameters) is 0:
return self.rows
# First parameter is Ellipsis
if len(parameters) > 0 and parameters[0] is Ellipsis:
# Skip as many dimensions till whose left will fit with parameters
if self.dimensions + 1 > len(parameters):
return [x[parameters] for x in self.rows]
# Time when Ellipsis done its job is finally arrived
else:
parameters = parameters[1:]
current, parameters = parameters[0], parameters[1:]
# Handle slice
if isinstance(current, types.SliceType):
return [
x if len(parameters) is 0 else x[parameters]
for x in self.rows[current.start:current.stop:current.step]
]
# Handle index
if isinstance(current, types.IntType):
return self.rows[current] if len(parameters) is 0 else self.rows[current][parameters]