<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def stretch_histogram(img, dark_clip_percentile=None, bright_clip_percentile=None, dark_clip_value=None, bright_clip_value=None, ignore_zero=True):
 """Stretch img histogram. 2 possible modes: by percentile (pass dark/bright_clip_percentile), or by value (pass dark/bright_clip_value) :param dark_clip_percentile: percent of pixels that will be saturated to min_value :param bright_clip_percentile: percent of pixels that will be saturated to max_value :param dark_clip_value: all values below this will be saturated to min_value :param bright_clip_value: all values above this will be saturated to max_value :param ignore_zero: if true, pixels with value 0 are ignored in stretch calculation :returns image (same shape as 'img') """

    # verify stretching method is specified:
    if (dark_clip_percentile is not None and dark_clip_value is not None) or \
            (bright_clip_percentile is not None and bright_clip_value is not None):
        raise KeyError('Provided parameters for both by-percentile and by-value stretch, need only one of those.')

    # the default stretching:
    if dark_clip_percentile is None and dark_clip_value is None:
        dark_clip_percentile = 0.001
    if bright_clip_percentile is None and bright_clip_value is None:
        bright_clip_percentile = 0.001

    if dark_clip_percentile is not None:
        dark_clip_value = np.percentile(img[img != 0] if ignore_zero else img, 100 * dark_clip_percentile)
    if bright_clip_percentile is not None:
        bright_clip_value = np.percentile(img[img != 0] if ignore_zero else img, 100 * (1 - bright_clip_percentile))

    dst_min = np.iinfo(img.dtype).min
    dst_max = np.iinfo(img.dtype).max

    if bright_clip_value == dark_clip_value:
        raise HistogramStretchingError
    gain = (dst_max - dst_min) / (bright_clip_value - dark_clip_value)
    offset = -gain * dark_clip_value + dst_min

    stretched = np.empty_like(img, dtype=img.dtype)
    if len(img.shape) == 2:
        stretched[:, :] = np.clip(gain * img[:, :].astype(np.float32) + offset, dst_min, dst_max).astype(img.dtype)
    else:
        for band in range(img.shape[0]):
            stretched[band, :, :] = np.clip(gain * img[band, :, :].astype(np.float32) + offset,
                                            dst_min, dst_max).astype(img.dtype)
    return stretched