def flatten(data_structure):
    """
    The flatten function takes a nested data structure (list of lists of lists etc) and returns a flattened version of it (list of values) as well as a flatten pattern that stores the nesting information.

    >>> flatten([1,'abc',[0,[1,1,[5]],'def'],9,10,11])
    ([1, 'abc', 0, 1, 1, 5, 'def', 9, 10, 11], '..[.[..[.]].]...')
    """
    data_stream = []
    structure_pattern = []
    stack = [[data_structure,0]]
    while len(stack) > 0:
        target,pos = stack[-1]
        if pos >= len(target):
            stack.pop(-1)
            structure_pattern.append(']')
        else:
            item = target[pos]
            stack[-1][1] += 1
            if isinstance(item,(list,tuple)):
                stack.append([item,0])
                structure_pattern.append('[')
            else:
                data_stream.append(item)
                structure_pattern.append('.')
    structure_pattern.pop(-1) #remove trailing ]
    return data_stream,''.join(structure_pattern)