<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def block_perm_and_perms_within_blocks(permutation, block_structure):
 """Decompose a permutation into a block permutation and into permutations acting within each block. :param permutation: The overall permutation to be factored. :type permutation: tuple :param block_structure: The channel dimensions of the blocks :type block_structure: tuple :return: ``(block_permutation, permutations_within_blocks)`` Where ``block_permutations`` is an image tuple for a permutation of the block indices and ``permutations_within_blocks`` is a list of image tuples for the permutations of the channels within each block :rtype: tuple """

    nblocks = len(block_structure)

    offsets = [sum(block_structure[:k]) for k in range(nblocks)]
    images = [permutation[offset: offset + length] for (offset, length) in zip(offsets, block_structure)]

    images_mins = list(map(min, images))


    key_block_perm_inv = lambda block_index: images_mins[block_index]

    block_perm_inv = tuple(sorted(range(nblocks), key = key_block_perm_inv))
    # print(images_mins)
    # print(permutation, block_structure, "-->", block_perm, invert_permutation(block_perm))
    block_perm = invert_permutation(block_perm_inv)

    assert images_mins[block_perm_inv[0]] == min(images_mins)
    assert images_mins[block_perm_inv[-1]] == max(images_mins)

    # block_perm = tuple(invert_permutation(block_perm_inv))

    perms_within_blocks = []
    for (offset, length, image) in zip(offsets, block_structure, images):
        block_key = lambda elt_index: image[elt_index]
        within_inv = sorted(range(length), key = block_key)
        within = invert_permutation(tuple(within_inv))
        assert permutation[within_inv[0] + offset] == min(image)
        assert permutation[within_inv[-1] + offset] == max(image)
        perms_within_blocks.append(within)

    return block_perm, perms_within_blocks