<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def all_but_blocks(names, data, newline="\n", remove_empty_next=True, remove_comments=True):
 """ Multiline string from a list of strings data, removing every block with any of the given names, as well as their delimiters. Removes the empty lines after BLOCK_END when ``remove_empty_next`` is True. Returns a joined string with the given newline, or a line generator if it's None. If desired, this function use ``commentless`` internally to remove the remaining comments. """

    @allow_implicit_stop
    def remove_blocks(name, iterable):
        start, end = BLOCK_START % name, BLOCK_END % name
        it = iter(iterable)
        while True:
            line = next(it)
            while line != start:
                yield line
                line = next(it)
            it = tail(itertools.dropwhile(not_eq(end), it))
            if remove_empty_next:
                it = itertools.dropwhile(lambda el: not el.strip(), it)
    if isinstance(names, str):
        names = [names]
    processors = [functools.partial(remove_blocks, name) for name in names]
    if remove_comments:
        processors.append(commentless)
    gen = functools.reduce(lambda result, func: func(result),
                           processors, data)
    return gen if newline is None else newline.join(gen)