For a directory with a magic '%' file, we generate a result set
for each item in the directory, and then do a product to generate
- a result list with all combinations (A Product).
+ a result list with all combinations (A Product). If the file
+ contains an integer, it is used as the divisor for a random
+ subset.
For a directory with a magic '$' file, or for a directory whose name
ends in '$', we generate a list of all items that we will randomly
def _get_matrix(path, subset=None):
- mat = None
- first = None
- matlimit = None
- if subset:
- (index, outof) = subset
- mat = _build_matrix(path, mincyclicity=outof)
- first = (mat.size() // outof) * index
- if index == outof or index == outof - 1:
- matlimit = mat.size()
- else:
- matlimit = (mat.size() // outof) * (index + 1)
+ (which, divisions) = (0,1) if subset is None else subset
+ if divisions > 1:
+ mat = _build_matrix(path, mincyclicity=divisions)
+ mat = matrix.Subset(mat, divisions, which=which)
else:
- first = 0
mat = _build_matrix(path)
- matlimit = mat.size()
- return mat, first, matlimit
+ return mat, 0, mat.size()
def _build_matrix(path, mincyclicity=0, item=''):
elif '%' in files:
# convolve items
files.remove('%')
+ with open(os.path.join(path, '%')) as f:
+ divisions = f.read()
+ if len(divisions) == 0:
+ divisions = 1
+ else:
+ divisions = int(divisions)
+ assert divisions > 0
submats = []
for fn in sorted(files):
submat = _build_matrix(
os.path.join(path, fn),
- mincyclicity=0,
- item=fn)
+ 0,
+ fn)
if submat is not None:
submats.append(submat)
mat = matrix.Product(item, submats)
- if mat and mat.cyclicity() < mincyclicity:
+ minc = mincyclicity * divisions
+ if mat and mat.cyclicity() < minc:
mat = matrix.Cycle(
- (mincyclicity + mat.cyclicity() - 1) // mat.cyclicity(), mat
+ (minc + mat.cyclicity() - 1) // mat.cyclicity(), mat
)
+ if divisions > 1:
+ mat = matrix.Subset(mat, divisions)
return mat
else:
# list items
def tostr(self, depth):
return '\t'*depth + "Cycle({num}):\n".format(num=self.num) + self.mat.tostr(depth + 1)
+# Logically, inverse of Cycle
+class Subset(Matrix):
+ """
+ Run a matrix subset.
+ """
+ def __init__(self, mat, divisions, which=None):
+ self.mat = mat
+ self.divisions = divisions
+ if which is None:
+ self.which = random.randint(0, divisions-1)
+ else:
+ assert which < divisions
+ self.which = which
+
+ def size(self):
+ return self.mat.size() // self.divisions
+
+ def index(self, i):
+ i += self.which * self.size()
+ assert i < self.mat.size()
+ return self.mat.index(i)
+
+ def minscanlen(self):
+ return self.mat.minscanlen()
+
+ def tostr(self, depth):
+ return '\t'*depth + "Subset({num}, {index}):\n".format(num=self.num, index=self.index) + self.mat.tostr(depth + 1)
+
+
class Base(Matrix):
"""
Just a single item.