<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def partition_range(stop, annotations=None):
 """ Partition the range from 0 to `stop` based on annotations. [(0, 15, {0}), (15, 21, {0, 1}), (21, 30, {1}), (30, 32, {0, 1}), (32, 35, {0}), (35, 40, set()), (40, 46, {1}), (46, 50, set())] :arg stop: End point (not included) of the range (similar to the `stop` argument of the built-in :func:`range` function). :type stop: int :arg annotations: For each annotation level, a list of (`start`, `stop`) pairs defining an annotated region. :type annotations: list :return: Partitioning of the range as (`start`, `stop`, `levels`) tuples defining a region with a set of annotation levels. :rtype: list All regions (`start`, `stop`) are defined as in slicing notation, so zero-based and `stop` is not included. The `annotations` argument is a list of annotations. An annotation is a list of regions as (`start`, `stop`) tuples. The level of each annotation is its index in `annotations`. Annotation regions can overlap (overlap within one level is ignored) and do not need to be sorted. """

    annotations = annotations or []

    partitioning = []
    part_start, part_levels = 0, None

    # We loop over the range, only touching positions where levels potentially
    # change.
    for p in sorted(set(itertools.chain([0, stop],
                                        *itertools.chain(*annotations)))):
        if p == stop:
            partitioning.append( (part_start, p, part_levels) )
            break

        # Annotation levels for position p.
        levels = {level for level, regions in enumerate(annotations)
                  if any(x <= p < y for x, y in regions)}

        if p == 0:
            part_levels = levels
            continue

        if levels != part_levels:
            partitioning.append( (part_start, p, part_levels) )
            part_start, part_levels = p, levels

    return partitioning