<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def high_low(data, channels=None, high=None, low=None, full_output=False):
 """ Gate out high and low values across all specified channels. Gate out events in `data` with values in the specified channels which are larger than or equal to `high` or less than or equal to `low`. Parameters data : FCSData or numpy array NxD flow cytometry data where N is the number of events and D is the number of parameters (aka channels). channels : int, str, list of int, list of str, optional Channels on which to perform gating. If None, use all channels. high, low : int, float, optional High and low threshold values. If None, `high` and `low` will be taken from ``data.range`` if available, otherwise ``np.inf`` and ``-np.inf`` will be used. full_output : bool, optional Flag specifying to return additional outputs. If true, the outputs are given as a namedtuple. Returns ------- gated_data : FCSData or numpy array Gated flow cytometry data of the same format as `data`. mask : numpy array of bool, only if ``full_output==True`` Boolean gate mask used to gate data such that ``gated_data = data[mask]``. """

    # Extract channels in which to gate
    if channels is None:
        data_ch = data
    else:
        data_ch = data[:,channels]
        if data_ch.ndim == 1:
            data_ch = data_ch.reshape((-1,1))

    # Default values for high and low
    if high is None:
        if hasattr(data_ch, 'range'):
            high = [np.Inf if di is None else di[1] for di in data_ch.range()]
            high = np.array(high)
        else:
            high = np.Inf
    if low is None:
        if hasattr(data_ch, 'range'):
            low = [-np.Inf if di is None else di[0] for di in data_ch.range()]
            low = np.array(low)
        else:
            low = -np.Inf

    # Gate
    mask = np.all((data_ch < high) & (data_ch > low), axis = 1)
    gated_data = data[mask]

    if full_output:
        HighLowGateOutput = collections.namedtuple(
            'HighLowGateOutput',
            ['gated_data', 'mask'])
        return HighLowGateOutput(gated_data=gated_data, mask=mask)
    else:
        return gated_data