예제 #1
0
class Transformer:

    FIRST_INDEX = "FIRST_INDEX"
    SEQUENCE = "SEQUENCE"
    NO_SEQUENCE = "NO_SEQUENCE"
    SEQUENCE_BREAK = "SEQUENCE_BREAK"
    BUFFERING_SEQUENCE_BREAK = "BUFFERING_SEQUENCE_BREAK"

    def __init__(self):
        self.state = Transformer.FIRST_INDEX
        self.transitions = [
            [Transformer.FIRST_INDEX, self.number_exists, self.return_number_as_is, Transformer.SEQUENCE], 
            [Transformer.FIRST_INDEX, self.number_not_exists, self.return_number_as_is, Transformer.NO_SEQUENCE], 
            [Transformer.SEQUENCE, self.number_exists, self.return_number_as_is, Transformer.SEQUENCE], 
            [Transformer.SEQUENCE, self.number_not_exists, self.return_nothing, Transformer.SEQUENCE_BREAK], 
            [Transformer.SEQUENCE_BREAK, self.number_exists, self.return_number_as_is, Transformer.BUFFERING_SEQUENCE_BREAK], #Brain F**k
            [Transformer.SEQUENCE_BREAK, self.number_not_exists, self.return_nothing, Transformer.SEQUENCE_BREAK], 
            [Transformer.BUFFERING_SEQUENCE_BREAK, all_conditions(self.number_exists, self.is_buffer_not_filled), self.return_number_as_is, Transformer.BUFFERING_SEQUENCE_BREAK], 
            [Transformer.BUFFERING_SEQUENCE_BREAK, all_conditions(self.number_exists, self.is_buffer_filled), self.interpolate_numbers, Transformer.SEQUENCE], 
            [Transformer.BUFFERING_SEQUENCE_BREAK, self.number_not_exists, self.return_buffered_numbers_as_is, Transformer.NO_SEQUENCE],
            [Transformer.NO_SEQUENCE, self.number_exists, self.return_number_as_is, Transformer.SEQUENCE], 
            [Transformer.NO_SEQUENCE, self.number_not_exists, self.return_number_as_is, Transformer.NO_SEQUENCE]
        ]
        self.buffer = RingBuffer(length = BUFFER_FILLED_SIZE * 2 + SEQUENCE_BREAK_MAX_SIZE)

    def number_exists(self, index, number):
        return number is not None

    def number_not_exists(self, index, number):
        return not self.number_exists(index, number)

    def return_number_as_is(self, index, number):
        self.buffer.add_item((index, number))
        return [(index, number)]

    def return_nothing(self, index, number):
        self.buffer.add_item((index, number))
        return []

    def interpolate_numbers(self, index, number):
        groups = self.buffer.last_item_groups(3, grouper = none_number_grouper)
        extraction = sum(groups, [])
        e = filter(lambda p: p[1] is not None, extraction)
        t = map(lambda p: p[0], e)
        n = map(lambda p: p[1], e)
        f = interpolate.interp1d(t, n)

        d = []
        for j, _ in groups[1]:
            d.append((j, f(j)))
    
        self.buffer.add_item((index, number))
        return d + [(index, number)]

    def is_buffer_filled(self, index, number):
        group = self.buffer.last_item_group(grouper = none_number_grouper)
        print "group = %s" % group
        return len(group) >= BUFFER_FILLED_SIZE

    def is_buffer_not_filled(self, index, number):
        return not self.is_buffer_filled(index, number)

    def return_buffered_numbers_as_is(self, index, number):
        self.buffer.add_item((index, number))
        groups = self.buffer.last_item_groups(2, grouper = none_number_grouper)
        print " =========> group = %s" % groups
        return groups[1]

    def is_sequence_break_too_long(self, index, number):
        sequence_break = self.buffer.last_item_group(grouper = none_number_grouper)
        return len(sequence_break) > SEQUENCE_BREAK_MAX_SIZE    
    
    def is_sequence_break_short_enough(self, index, number):
        return not self.is_sequence_break_too_long(index, number)

    def transform(self, index, number):
        print "transform(%s, %s)" % (index, number)
        for transition in self.transitions:
            if transition[STATE] == self.state:
                print "self.state = %s" % self.state
                if transition[CONDITION](index, number):
                    print " ---> %s success" % transition[CONDITION].__name__
                    pairs = transition[ACTION](index, number)
                    next_state = transition[NEXT_STATE]
                    self.state = next_state
                    return pairs
                else:
                    print " ---> %s failed" % transition[CONDITION].__name__

        raise Exception("Unable to continue")