<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def jitter(x, factor=1, amount=None, random_state=None):
 """ Add a small amount of noise to values in an array_like Parameters x : array_like Values to apply a jitter factor : float Multiplicative value to used in automatically determining the `amount`. If the `amount` is given then the `factor` has no effect. amount : float This defines the range ([-amount, amount]) of the jitter to apply to the values. If `0` then ``amount = factor * z/50``. If `None` then ``amount = factor * d/5``, where d is about the smallest difference between `x` values and `z` is the range of the `x` values. random_state : int or ~numpy.random.RandomState, optional Seed or Random number generator to use. If ``None``, then numpy global generator :class:`numpy.random` is used. References: - Chambers, J. M., Cleveland, W. S., Kleiner, B. and Tukey, P.A. (1983) *Graphical Methods for Data Analysis*. Wadsworth; figures 2.8, 4.22, 5.4. """

    if len(x) == 0:
        return x

    if random_state is None:
        random_state = np.random
    elif isinstance(random_state, int):
        random_state = np.random.RandomState(random_state)

    x = np.asarray(x)

    try:
        z = np.ptp(x[np.isfinite(x)])
    except IndexError:
        z = 0

    if z == 0:
        z = np.abs(np.min(x))
    if z == 0:
        z = 1

    if amount is None:
        _x = np.round(x, 3-np.int(np.floor(np.log10(z)))).astype(np.int)
        xx = np.unique(np.sort(_x))
        d = np.diff(xx)
        if len(d):
            d = d.min()
        elif xx != 0:
            d = xx/10.
        else:
            d = z/10
        amount = factor/5. * abs(d)
    elif amount == 0:
        amount = factor * (z / 50.)

    return x + random_state.uniform(-amount, amount, len(x))