<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def extract_patches(images, patch_shape, samples_per_image=40, seed=0, cycle=True):
 """ Takes a set of images and yields randomly chosen patches of specified size. Parameters images : iterable The images have to be iterable, and each element must be a Numpy array with at least two spatial 2 dimensions as the first and second axis. patch_shape : tuple, length 2 The spatial shape of the patches that should be extracted. If the images have further dimensions beyond the spatial, the patches will copy these too. samples_per_image : int Samples to extract before moving on to the next image. seed : int Seed with which to select the patches. cycle : bool If True, then the function will produce patches indefinitely, by going back to the first image when all are done. If False, the iteration will stop when there are no more images. Returns ------- patch_generator This function returns a generator that will produce patches. Examples -------- Now, let us say we want to exact patches from the these, where each patch has at least some activity. (25, 5, 5) """

    rs = np.random.RandomState(seed)
    for Xi in itr.cycle(images):
        # How many patches could we extract?
        w, h = [Xi.shape[i]-patch_shape[i] for i in range(2)]

        assert w > 0 and h > 0

        # Maybe shuffle an iterator of the indices?
        indices = np.asarray(list(itr.product(range(w), range(h))))
        rs.shuffle(indices)
        for x, y in indices[:samples_per_image]:
            yield Xi[x:x+patch_shape[0], y:y+patch_shape[1]]