Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/textform/fold.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ def readrow(self):
# Buffer empty, so pivot next row
row = super().readrow()

# Rebuild the buffer because the rows we return are not ours.
self._buffer = [{self.tag: tag} for tag in self.tags]

# Update the folds
for g, group in enumerate(self._groups):
output = self.outputs[g+1]
Expand Down
5 changes: 3 additions & 2 deletions src/textform/iterate.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Iterate(Transform):
def __init__(self, source, input, tags, strings, layout='csv', **config):
super().__init__('iterate', input, (tags, strings,), source)

self._validateOutputs()
self._validateOutputs(self.inputs)

self.function = bind_iterate(self.name, layout, strings, **config)
self._buffer = []
Expand All @@ -54,12 +54,13 @@ def readrow(self):
if self._position < len(self._buffer):
return self._unbuffer()

# Buffer empty, so expand the next row
# Buffer flushed, so expand the next row
row = self.source.readrow()
ragged = self.function(row[self.input])
del row[self.input]

# Update the buffer
self._buffer = []
for tag in ragged:
buffered = dict(zip(self.outputs, (str(tag), str(ragged[tag]),)))
buffered.update(row)
Expand Down
29 changes: 25 additions & 4 deletions src/textform/unfold.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def __init__(self, source, inputs, outputs):

self.fixed = [f for f in filter(lambda input: input not in self.inputs, self.source.fieldnames)]

# Ragged group buffer
self._ragged = None

def _schema(self):
schema = super()._schema()

Expand Down Expand Up @@ -46,10 +49,28 @@ def readrow(self):
# and emitting a row whenever it is complete
row = None
for g in range(len(self._groups[0])):
folded = super().readrow()

if row is None: row = {fixed: folded[fixed] for fixed in self.fixed}
row.update({self._groups[f][g]: folded[self.folds[f]] for f in range(len(self.folds))})
folded = self._ragged
self._ragged = None
if not folded:
try:
folded = super().readrow()
except StopIteration:
if row: break
raise

if row is None:
row = {output: None for output in self.outputs}
row.update({fixed: folded[fixed] for fixed in self.fixed})

elif not all([folded[fixed] == row[fixed] for fixed in self.fixed]):
self._ragged = {output: None for output in self.outputs}
self._ragged.update(folded)
break

try:
row.update({self._groups[f][g]: folded[self.folds[f]] for f in range(len(self.folds))})
except:
raise

self._updateSchemaTypes(row, self.outputs)

Expand Down
9 changes: 9 additions & 0 deletions tests/test_fold.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,12 @@ def test_voila_6(self):
self.assertEqual(5 + actual // len(unfolded), row['#BLENDs'], actual)
actual += 1
self.assertEqual((len(csv) - 1) * len(unfolded), actual)

def test_drop_tags(self):
s = None
s = txf.Sequence(s, 'Fold 1')
s = txf.Sequence(s, 'Fold 2')
s = txf.Limit(s, 4)
s = txf.Fold(s, ('Fold 1', 'Fold 2',), ('Tags', 'Group',))
s = txf.Drop(s, 'Tags')
s.pump()