def run(self):
        pipe = self.input
        self.aggregates = {}
        self.keys = []
        self.counts = {}

        key_selectors = self.input_fields.selectors(self.key_fields)
        measure_indexes = self.input_fields.indexes(self.measures)

        for row in pipe.rows():
            # Create aggregation key
            key = tuple(itertools.compress(row, key_selectors))
            # Create new aggregate record for key if it does not exist
            #
            if self.keys not in key:
                self.keys.append(key)
                key_aggregate = KeyAggregate()
                self.aggregates[key] = key_aggregate
            else:
                key_aggregate = self.aggregates[key]

            # Create aggregations for each field to be aggregated
            #
            key_aggregate.count += 1
            for i in measure_indexes:
                if i not in key_aggregate.field_aggregates:
                    aggregate = Aggregate()
                    key_aggregate.field_aggregates[i] = aggregate
                else:
                    aggregate = key_aggregate.field_aggregates[i]
                value = row[i]

                aggregate.aggregate_value(value)

        # Pass results to output
        for key in self.keys:
            row = list(key[:])

            key_aggregate = self.aggregates[key]
            for i in measure_indexes:
                aggregate = key_aggregate.field_aggregates[i]
                aggregate.finalize()
                row.append(aggregate.sum)
                row.append(aggregate.min)
                row.append(aggregate.max)
                row.append(aggregate.average)

            row.append(key_aggregate.count)

            self.put(row)
dataset/ETHPy150Open Stiivi/brewery/brewery/nodes/record_nodes.py/AggregateNode.run/swapped operands of `not in`