Instruction:
Can you generate a brief explanation for the following Python 3 code
def _as_array_or_item(data):
    data = np.asarray(data)
    if data.ndim == 0:
        if data.dtype.kind == 'M':
            data = np.datetime64(data, 'ns')
        elif data.dtype.kind == 'm':
            data = np.timedelta64(data, 'ns')
    return data

Response: Return the given values as a numpy array or as an individual item if the given values are 0d datetime64 or timedelta64 array.


Instruction:
Write a Python 3 script to
create broadcast compatible variables with the same dimensions.

Response:
def _broadcast_compat_variables(*variables):
    """Create broadcast compatible variables, with the same dimensions.

    Unlike the result of broadcast_variables(), some variables may have
    dimensions of size 1 instead of the the size of the broadcast dimension.
    """
    dims = tuple(_unified_dims(variables))
    return tuple(var.set_dims(dims) if var.dims != dims else var
                 for var in variables)


Instruction:
Can you create a Python 3 function that
gives any number of variables return variables with matching dimensions and broadcast data.

Response:
def broadcast_variables(*variables):
    """Given any number of variables, return variables with matching dimensions
    and broadcast data.

    The data on the returned variables will be a view of the data on the
    corresponding original arrays, but dimensions will be reordered and
    inserted so that both broadcast arrays have the same dimensions. The new
    dimensions are sorted in order of appearance in the first variable's
    dimensions followed by the second variable's dimensions.
    """
    dims_map = _unified_dims(variables)
    dims_tuple = tuple(dims_map)
    return tuple(var.set_dims(dims_map) if var.dims != dims_tuple else var
                 for var in variables)


Instruction:
Can you generate the documentation for the following Python 3 function
def concat(variables, dim='concat_dim', positions=None, shortcut=False):
    variables = list(variables)
    if all(isinstance(v, IndexVariable) for v in variables):
        return IndexVariable.concat(variables, dim, positions, shortcut)
    else:
        return Variable.concat(variables, dim, positions, shortcut)

Response: Concatenate a list of Variable objects along a new or existing dimension.


Instruction:
Can you tell what is the following Python 3 function doing
def assert_unique_multiindex_level_names(variables):
    level_names = defaultdict(list)
    all_level_names = set()
    for var_name, var in variables.items():
        if isinstance(var._data, PandasIndexAdapter):
            idx_level_names = var.to_index_variable().level_names
            if idx_level_names is not None:
                for n in idx_level_names:
                    level_names[n].append('%r (%s)' % (n, var_name))
            if idx_level_names:
                all_level_names.update(idx_level_names)

    for k, v in level_names.items():
        if k in variables:
            v.append('(%s)' % k)

    duplicate_names = [v for v in level_names.values() if len(v) > 1]
    if duplicate_names:
        conflict_str = '\n'.join([', '.join(v) for v in duplicate_names])
        raise ValueError('conflicting MultiIndex level name(s):\n%s'
                         % conflict_str)
    # Check confliction between level names and dimensions GH:2299
    for k, v in variables.items():
        for d in v.dims:
            if d in all_level_names:
                raise ValueError('conflicting level / dimension names. {} '
                                 'already exists as a level name.'.format(d))

Response: Check for uniqueness of MultiIndex level names in all given variables.


Instruction:
Can you tell what is the following Python 3 function doing
def to_base_variable(self):
        return Variable(self.dims, self._data, self._attrs,
                        encoding=self._encoding, fastpath=True)

Response: Return this variable as a base xarray. Variable


Instruction:
Make a summary of the following Python 3 code
def to_index_variable(self):
        return IndexVariable(self.dims, self._data, self._attrs,
                             encoding=self._encoding, fastpath=True)

Response: Return this variable as an xarray. IndexVariable


Instruction:
Explain what the following Python 3 code does
def to_dict(self, data=True):
        item = {'dims': self.dims,
                'attrs': decode_numpy_dict_values(self.attrs)}
        if data:
            item['data'] = ensure_us_time_resolution(self.values).tolist()
        else:
            item.update({'dtype': str(self.dtype), 'shape': self.shape})
        return item

Response: Returns a dictionary representation of the object.


Instruction:
Can you tell what is the following Python 3 function doing
def _broadcast_indexes(self, key):
        key = self._item_key_to_tuple(key)  # key is a tuple
        # key is a tuple of full size
        key = indexing.expanded_indexer(key, self.ndim)
        # Convert a scalar Variable to an integer
        key = tuple(
            k.data.item() if isinstance(k, Variable) and k.ndim == 0 else k
            for k in key)
        # Convert a 0d-array to an integer
        key = tuple(
            k.item() if isinstance(k, np.ndarray) and k.ndim == 0 else k
            for k in key)

        if all(isinstance(k, BASIC_INDEXING_TYPES) for k in key):
            return self._broadcast_indexes_basic(key)

        self._validate_indexers(key)
        # Detect it can be mapped as an outer indexer
        # If all key is unlabeled, or
        # key can be mapped as an OuterIndexer.
        if all(not isinstance(k, Variable) for k in key):
            return self._broadcast_indexes_outer(key)

        # If all key is 1-dimensional and there are no duplicate labels,
        # key can be mapped as an OuterIndexer.
        dims = []
        for k, d in zip(key, self.dims):
            if isinstance(k, Variable):
                if len(k.dims) > 1:
                    return self._broadcast_indexes_vectorized(key)
                dims.append(k.dims[0])
            elif not isinstance(k, integer_types):
                dims.append(d)
        if len(set(dims)) == len(dims):
            return self._broadcast_indexes_outer(key)

        return self._broadcast_indexes_vectorized(key)

Response: This method is used to broadcast the indexes of the items in the item.


Instruction:
Implement a function in Python 3 to
make sanity checks for the indexes.

Response:
def _validate_indexers(self, key):
        """ Make sanity checks """
        for dim, k in zip(self.dims, key):
            if isinstance(k, BASIC_INDEXING_TYPES):
                pass
            else:
                if not isinstance(k, Variable):
                    k = np.asarray(k)
                    if k.ndim > 1:
                        raise IndexError(
                            "Unlabeled multi-dimensional array cannot be "
                            "used for indexing: {}".format(k))
                if k.dtype.kind == 'b':
                    if self.shape[self.get_axis_num(dim)] != len(k):
                        raise IndexError(
                            "Boolean array size {0:d} is used to index array "
                            "with shape {1:s}.".format(len(k),
                                                       str(self.shape)))
                    if k.ndim > 1:
                        raise IndexError("{}-dimensional boolean indexing is "
                                         "not supported. ".format(k.ndim))
                    if getattr(k, 'dims', (dim, )) != (dim, ):
                        raise IndexError(
                            "Boolean indexer should be unlabeled or on the "
                            "same dimension to the indexed array. Indexer is "
                            "on {0:s} but the target dimension is "
                            "{1:s}.".format(str(k.dims), dim))


Instruction:
Can you generate the documentation for the following Python 3 function
def _finalize_indexing_result(self, dims, data):
        return type(self)(dims, data, self._attrs, self._encoding,
                          fastpath=True)

Response: Used by IndexVariable to return IndexVariable objects when possible.


Instruction:
Write a Python 3 function for
indexing this Variable with - 1 remapped to fill_value.

Response:
def _getitem_with_mask(self, key, fill_value=dtypes.NA):
        """Index this Variable with -1 remapped to fill_value."""
        # TODO(shoyer): expose this method in public API somewhere (isel?) and
        # use it for reindex.
        # TODO(shoyer): add a sanity check that all other integers are
        # non-negative
        # TODO(shoyer): add an optimization, remapping -1 to an adjacent value
        # that is actually indexed rather than mapping it to the last value
        # along each axis.

        if fill_value is dtypes.NA:
            fill_value = dtypes.get_fill_value(self.dtype)

        dims, indexer, new_order = self._broadcast_indexes(key)

        if self.size:
            if isinstance(self._data, dask_array_type):
                # dask's indexing is faster this way; also vindex does not
                # support negative indices yet:
                # https://github.com/dask/dask/pull/2967
                actual_indexer = indexing.posify_mask_indexer(indexer)
            else:
                actual_indexer = indexer

            data = as_indexable(self._data)[actual_indexer]
            chunks_hint = getattr(data, 'chunks', None)
            mask = indexing.create_mask(indexer, self.shape, chunks_hint)
            data = duck_array_ops.where(mask, fill_value, data)
        else:
            # array cannot be indexed along dimensions of size 0, so just
            # build the mask directly instead.
            mask = indexing.create_mask(indexer, self.shape)
            data = np.broadcast_to(fill_value, getattr(mask, 'shape', ()))

        if new_order:
            data = np.moveaxis(data, range(len(new_order)), new_order)
        return self._finalize_indexing_result(dims, data)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def copy(self, deep=True, data=None):
        if data is None:
            data = self._data

            if isinstance(data, indexing.MemoryCachedArray):
                # don't share caching between copies
                data = indexing.MemoryCachedArray(data.array)

            if deep:
                if isinstance(data, dask_array_type):
                    data = data.copy()
                elif not isinstance(data, PandasIndexAdapter):
                    # pandas.Index is immutable
                    data = np.array(data)
        else:
            data = as_compatible_data(data)
            if self.shape != data.shape:
                raise ValueError("Data shape {} must match shape of object {}"
                                 .format(data.shape, self.shape))

        # note:
        # dims is already an immutable tuple
        # attributes and encoding will be copied when the new Array is created
        return type(self)(self.dims, data, self._attrs, self._encoding,
                          fastpath=True)

Response: Returns a copy of this object.


Instruction:
Given the following Python 3 function, write the documentation
def chunk(self, chunks=None, name=None, lock=False):
        import dask.array as da

        if utils.is_dict_like(chunks):
            chunks = dict((self.get_axis_num(dim), chunk)
                          for dim, chunk in chunks.items())

        if chunks is None:
            chunks = self.chunks or self.shape

        data = self._data
        if isinstance(data, da.Array):
            data = data.rechunk(chunks)
        else:
            if utils.is_dict_like(chunks):
                chunks = tuple(chunks.get(n, s)
                               for n, s in enumerate(self.shape))
            # da.from_array works by using lazily indexing with a tuple of
            # slices. Using OuterIndexer is a pragmatic choice: dask does not
            # yet handle different indexing types in an explicit way:
            # https://github.com/dask/dask/issues/2883
            data = indexing.ImplicitToExplicitIndexingAdapter(
                data, indexing.OuterIndexer)
            data = da.from_array(data, chunks, name=name, lock=lock)

        return type(self)(self.dims, data, self._attrs, self._encoding,
                          fastpath=True)

Response: Coerce this array s data into a dask array with the given chunks.


Instruction:
Can you write a function in Python 3 where it
returns a new array indexed along the specified dimension.

Response:
def isel(self, indexers=None, drop=False, **indexers_kwargs):
        """Return a new array indexed along the specified dimension(s).

        Parameters
        ----------
        **indexers : {dim: indexer, ...}
            Keyword arguments with names matching dimensions and values given
            by integers, slice objects or arrays.

        Returns
        -------
        obj : Array object
            A new Array with the selected data and dimensions. In general,
            the new variable's data will be a view of this variable's data,
            unless numpy fancy indexing was triggered by using an array
            indexer, in which case the data will be a copy.
        """
        indexers = either_dict_or_kwargs(indexers, indexers_kwargs, 'isel')

        invalid = [k for k in indexers if k not in self.dims]
        if invalid:
            raise ValueError("dimensions %r do not exist" % invalid)

        key = [slice(None)] * self.ndim
        for i, dim in enumerate(self.dims):
            if dim in indexers:
                key[i] = indexers[dim]
        return self[tuple(key)]


Instruction:
Write a Python 3 function for
returning a new object with squeezed data.

Response:
def squeeze(self, dim=None):
        """Return a new object with squeezed data.

        Parameters
        ----------
        dim : None or str or tuple of str, optional
            Selects a subset of the length one dimensions. If a dimension is
            selected with length greater than one, an error is raised. If
            None, all length one dimensions are squeezed.

        Returns
        -------
        squeezed : same type as caller
            This object, but with with all or a subset of the dimensions of
            length 1 removed.

        See Also
        --------
        numpy.squeeze
        """
        dims = common.get_squeeze_dims(self, dim)
        return self.isel({d: 0 for d in dims})


Instruction:
Implement a Python 3 function for
returning a new Variable with shifted data.

Response:
def shift(self, shifts=None, fill_value=dtypes.NA, **shifts_kwargs):
        """
        Return a new Variable with shifted data.

        Parameters
        ----------
        shifts : mapping of the form {dim: offset}
            Integer offset to shift along each of the given dimensions.
            Positive offsets shift to the right; negative offsets shift to the
            left.
        fill_value: scalar, optional
            Value to use for newly missing values
        **shifts_kwargs:
            The keyword arguments form of ``shifts``.
            One of shifts or shifts_kwarg must be provided.

        Returns
        -------
        shifted : Variable
            Variable with the same dimensions and attributes but shifted data.
        """
        shifts = either_dict_or_kwargs(shifts, shifts_kwargs, 'shift')
        result = self
        for dim, count in shifts.items():
            result = result._shift_one_dim(dim, count, fill_value=fill_value)
        return result


Instruction:
How would you code a function in Python 3 to
return a new Variable with paddings padded to the edges of each dimension.

Response:
def pad_with_fill_value(self, pad_widths=None, fill_value=dtypes.NA,
                            **pad_widths_kwargs):
        """
        Return a new Variable with paddings.

        Parameters
        ----------
        pad_width: Mapping of the form {dim: (before, after)}
            Number of values padded to the edges of each dimension.
        **pad_widths_kwargs:
            Keyword argument for pad_widths
        """
        pad_widths = either_dict_or_kwargs(pad_widths, pad_widths_kwargs,
                                           'pad')

        if fill_value is dtypes.NA:
            dtype, fill_value = dtypes.maybe_promote(self.dtype)
        else:
            dtype = self.dtype

        if isinstance(self.data, dask_array_type):
            array = self.data

            # Dask does not yet support pad. We manually implement it.
            # https://github.com/dask/dask/issues/1926
            for d, pad in pad_widths.items():
                axis = self.get_axis_num(d)
                before_shape = list(array.shape)
                before_shape[axis] = pad[0]
                before_chunks = list(array.chunks)
                before_chunks[axis] = (pad[0], )
                after_shape = list(array.shape)
                after_shape[axis] = pad[1]
                after_chunks = list(array.chunks)
                after_chunks[axis] = (pad[1], )

                arrays = []
                if pad[0] > 0:
                    arrays.append(da.full(before_shape, fill_value,
                                          dtype=dtype, chunks=before_chunks))
                arrays.append(array)
                if pad[1] > 0:
                    arrays.append(da.full(after_shape, fill_value,
                                          dtype=dtype, chunks=after_chunks))
                if len(arrays) > 1:
                    array = da.concatenate(arrays, axis=axis)
        else:
            pads = [(0, 0) if d not in pad_widths else pad_widths[d]
                    for d in self.dims]
            array = np.pad(self.data.astype(dtype, copy=False), pads,
                           mode='constant', constant_values=fill_value)
        return type(self)(self.dims, array)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def roll(self, shifts=None, **shifts_kwargs):
        shifts = either_dict_or_kwargs(shifts, shifts_kwargs, 'roll')

        result = self
        for dim, count in shifts.items():
            result = result._roll_one_dim(dim, count)
        return result

Response: Return a new Variable with rolld data.


Instruction:
How would you explain what the following Python 3 function does
def transpose(self, *dims) -> 'Variable':
        if len(dims) == 0:
            dims = self.dims[::-1]
        axes = self.get_axis_num(dims)
        if len(dims) < 2:  # no need to transpose if only one dimension
            return self.copy(deep=False)

        data = as_indexable(self._data).transpose(axes)
        return type(self)(dims, data, self._attrs, self._encoding,
                          fastpath=True)

Response: Return a new Variable object with transposed dimensions.


Instruction:
How would you code a function in Python 3 to
return a new Variable with given set of dimensions.

Response:
def set_dims(self, dims, shape=None):
        """Return a new variable with given set of dimensions.
        This method might be used to attach new dimension(s) to variable.

        When possible, this operation does not copy this variable's data.

        Parameters
        ----------
        dims : str or sequence of str or dict
            Dimensions to include on the new variable. If a dict, values are
            used to provide the sizes of new dimensions; otherwise, new
            dimensions are inserted with length 1.

        Returns
        -------
        Variable
        """
        if isinstance(dims, str):
            dims = [dims]

        if shape is None and utils.is_dict_like(dims):
            shape = dims.values()

        missing_dims = set(self.dims) - set(dims)
        if missing_dims:
            raise ValueError('new dimensions %r must be a superset of '
                             'existing dimensions %r' % (dims, self.dims))

        self_dims = set(self.dims)
        expanded_dims = tuple(
            d for d in dims if d not in self_dims) + self.dims

        if self.dims == expanded_dims:
            # don't use broadcast_to unless necessary so the result remains
            # writeable if possible
            expanded_data = self.data
        elif shape is not None:
            dims_map = dict(zip(dims, shape))
            tmp_shape = tuple(dims_map[d] for d in expanded_dims)
            expanded_data = duck_array_ops.broadcast_to(self.data, tmp_shape)
        else:
            expanded_data = self.data[
                (None,) * (len(expanded_dims) - self.ndim)]

        expanded_var = Variable(expanded_dims, expanded_data, self._attrs,
                                self._encoding, fastpath=True)
        return expanded_var.transpose(*dims)


Instruction:
How would you implement a function in Python 3 that
stacks any number of existing dimensions into a single new dimension.

Response:
def stack(self, dimensions=None, **dimensions_kwargs):
        """
        Stack any number of existing dimensions into a single new dimension.

        New dimensions will be added at the end, and the order of the data
        along each new dimension will be in contiguous (C) order.

        Parameters
        ----------
        dimensions : Mapping of form new_name=(dim1, dim2, ...)
            Names of new dimensions, and the existing dimensions that they
            replace.
        **dimensions_kwargs:
            The keyword arguments form of ``dimensions``.
            One of dimensions or dimensions_kwargs must be provided.

        Returns
        -------
        stacked : Variable
            Variable with the same attributes but stacked data.

        See also
        --------
        Variable.unstack
        """
        dimensions = either_dict_or_kwargs(dimensions, dimensions_kwargs,
                                           'stack')
        result = self
        for new_dim, dims in dimensions.items():
            result = result._stack_once(dims, new_dim)
        return result


Instruction:
Write a Python 3 function for
reducing this array by applying func along some dimension.

Response:
def reduce(self, func, dim=None, axis=None,
               keep_attrs=None, allow_lazy=False, **kwargs):
        """Reduce this array by applying `func` along some dimension(s).

        Parameters
        ----------
        func : function
            Function which can be called in the form
            `func(x, axis=axis, **kwargs)` to return the result of reducing an
            np.ndarray over an integer valued axis.
        dim : str or sequence of str, optional
            Dimension(s) over which to apply `func`.
        axis : int or sequence of int, optional
            Axis(es) over which to apply `func`. Only one of the 'dim'
            and 'axis' arguments can be supplied. If neither are supplied, then
            the reduction is calculated over the flattened array (by calling
            `func(x)` without an axis argument).
        keep_attrs : bool, optional
            If True, the variable's attributes (`attrs`) will be copied from
            the original object to the new one.  If False (default), the new
            object will be returned without attributes.
        **kwargs : dict
            Additional keyword arguments passed on to `func`.

        Returns
        -------
        reduced : Array
            Array with summarized data and the indicated dimension(s)
            removed.
        """
        if dim is common.ALL_DIMS:
            dim = None
        if dim is not None and axis is not None:
            raise ValueError("cannot supply both 'axis' and 'dim' arguments")

        if dim is not None:
            axis = self.get_axis_num(dim)
        input_data = self.data if allow_lazy else self.values
        if axis is not None:
            data = func(input_data, axis=axis, **kwargs)
        else:
            data = func(input_data, **kwargs)

        if getattr(data, 'shape', ()) == self.shape:
            dims = self.dims
        else:
            removed_axes = (range(self.ndim) if axis is None
                            else np.atleast_1d(axis) % self.ndim)
            dims = [adim for n, adim in enumerate(self.dims)
                    if n not in removed_axes]

        if keep_attrs is None:
            keep_attrs = _get_keep_attrs(default=False)
        attrs = self._attrs if keep_attrs else None

        return Variable(dims, data, attrs=attrs)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def concat(cls, variables, dim='concat_dim', positions=None,
               shortcut=False):
        """Concatenate variables along a new or existing dimension.

        Parameters
        ----------
        variables : iterable of Array
            Arrays to stack together. Each variable is expected to have
            matching dimensions and shape except for along the stacked
            dimension.
        dim : str or DataArray, optional
            Name of the dimension to stack along. This can either be a new
            dimension name, in which case it is added along axis=0, or an
            existing dimension name, in which case the location of the
            dimension is unchanged. Where to insert the new dimension is
            determined by the first variable.
        positions : None or list of integer arrays, optional
            List of integer arrays which specifies the integer positions to
            which to assign each dataset along the concatenated dimension.
            If not supplied, objects are concatenated in the provided order.
        shortcut : bool, optional
            This option is used internally to speed-up groupby operations.
            If `shortcut` is True, some checks of internal consistency between
            arrays to concatenate are skipped.

        Returns
        -------
        stacked : Variable
            Concatenated Variable formed by stacking all the supplied variables
            along the given dimension.
        """
        if not isinstance(dim, str):
            dim, = dim.dims

        # can't do this lazily: we need to loop through variables at least
        # twice
        variables = list(variables)
        first_var = variables[0]

        arrays = [v.data for v in variables]

        if dim in first_var.dims:
            axis = first_var.get_axis_num(dim)
            dims = first_var.dims
            data = duck_array_ops.concatenate(arrays, axis=axis)
            if positions is not None:
                # TODO: deprecate this option -- we don't need it for groupby
                # any more.
                indices = nputils.inverse_permutation(
                    np.concatenate(positions))
                data = duck_array_ops.take(data, indices, axis=axis)
        else:
            axis = 0
            dims = (dim,) + first_var.dims
            data = duck_array_ops.stack(arrays, axis=axis)

        attrs = OrderedDict(first_var.attrs)
        encoding = OrderedDict(first_var.encoding)
        if not shortcut:
            for var in variables:
                if var.dims != first_var.dims:
                    raise ValueError('inconsistent dimensions')
                utils.remove_incompatible_items(attrs, var.attrs)

        return cls(dims, data, attrs, encoding)

Response: Concatenate a list of ArrayLogEntry objects along a new or existing dimension.


Instruction:
Create a Python 3 function to
true if two Variables have the same dimensions and values ; otherwise False.

Response:
def equals(self, other, equiv=duck_array_ops.array_equiv):
        """True if two Variables have the same dimensions and values;
        otherwise False.

        Variables can still be equal (like pandas objects) if they have NaN
        values in the same locations.

        This method is necessary because `v1 == v2` for Variables
        does element-wise comparisons (like numpy.ndarrays).
        """
        other = getattr(other, 'variable', other)
        try:
            return (self.dims == other.dims and
                    (self._data is other._data or
                     equiv(self.data, other.data)))
        except (TypeError, AttributeError):
            return False


Instruction:
How would you explain what the following Python 3 function does
def broadcast_equals(self, other, equiv=duck_array_ops.array_equiv):
        try:
            self, other = broadcast_variables(self, other)
        except (ValueError, AttributeError):
            return False
        return self.equals(other, equiv=equiv)

Response: True if two Variables have the values after being broadcast against each other.


Instruction:
Can you write a function in Python 3 where it
likes equals but also checks attributes.

Response:
def identical(self, other):
        """Like equals, but also checks attributes.
        """
        try:
            return (utils.dict_equiv(self.attrs, other.attrs) and
                    self.equals(other))
        except (TypeError, AttributeError):
            return False


Instruction:
Implement a function in Python 3 to
compute the qth quantile of the data along the specified dimension.

Response:
def quantile(self, q, dim=None, interpolation='linear'):
        """Compute the qth quantile of the data along the specified dimension.

        Returns the qth quantiles(s) of the array elements.

        Parameters
        ----------
        q : float in range of [0,1] (or sequence of floats)
            Quantile to compute, which must be between 0 and 1
            inclusive.
        dim : str or sequence of str, optional
            Dimension(s) over which to apply quantile.
        interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}
            This optional parameter specifies the interpolation method to
            use when the desired quantile lies between two data points
            ``i < j``:
                * linear: ``i + (j - i) * fraction``, where ``fraction`` is
                  the fractional part of the index surrounded by ``i`` and
                  ``j``.
                * lower: ``i``.
                * higher: ``j``.
                * nearest: ``i`` or ``j``, whichever is nearest.
                * midpoint: ``(i + j) / 2``.

        Returns
        -------
        quantiles : Variable
            If `q` is a single quantile, then the result
            is a scalar. If multiple percentiles are given, first axis of
            the result corresponds to the quantile and a quantile dimension
            is added to the return array. The other dimensions are the
             dimensions that remain after the reduction of the array.

        See Also
        --------
        numpy.nanpercentile, pandas.Series.quantile, Dataset.quantile,
        DataArray.quantile
        """
        if isinstance(self.data, dask_array_type):
            raise TypeError("quantile does not work for arrays stored as dask "
                            "arrays. Load the data via .compute() or .load() "
                            "prior to calling this method.")

        q = np.asarray(q, dtype=np.float64)

        new_dims = list(self.dims)
        if dim is not None:
            axis = self.get_axis_num(dim)
            if utils.is_scalar(dim):
                new_dims.remove(dim)
            else:
                for d in dim:
                    new_dims.remove(d)
        else:
            axis = None
            new_dims = []

        # only add the quantile dimension if q is array like
        if q.ndim != 0:
            new_dims = ['quantile'] + new_dims

        qs = np.nanpercentile(self.data, q * 100., axis=axis,
                              interpolation=interpolation)
        return Variable(new_dims, qs)


Instruction:
How would you explain what the following Python 3 function does
def rank(self, dim, pct=False):
        import bottleneck as bn

        if isinstance(self.data, dask_array_type):
            raise TypeError("rank does not work for arrays stored as dask "
                            "arrays. Load the data via .compute() or .load() "
                            "prior to calling this method.")

        axis = self.get_axis_num(dim)
        func = bn.nanrankdata if self.dtype.kind == 'f' else bn.rankdata
        ranked = func(self.data, axis=axis)
        if pct:
            count = np.sum(~np.isnan(self.data), axis=axis, keepdims=True)
            ranked /= count
        return Variable(self.dims, ranked)

Response:
Ranks the data.

        Equal values are assigned a rank that is the average of the ranks that
        would have been otherwise assigned to all of the values within that
        set.  Ranks begin at 1, not 0. If `pct`, computes percentage ranks.

        NaNs in the input array are returned as NaNs.

        The `bottleneck` library is required.

        Parameters
        ----------
        dim : str
            Dimension over which to compute rank.
        pct : bool, optional
            If True, compute percentage ranks, otherwise compute integer ranks.

        Returns
        -------
        ranked : Variable

        See Also
        --------
        Dataset.rank, DataArray.rank


Instruction:
How would you explain what the following Python 3 function does
def rolling_window(self, dim, window, window_dim, center=False,
                       fill_value=dtypes.NA):
        """
        Make a rolling_window along dim and add a new_dim to the last place.

        Parameters
        ----------
        dim: str
            Dimension over which to compute rolling_window
        window: int
            Window size of the rolling
        window_dim: str
            New name of the window dimension.
        center: boolean. default False.
            If True, pad fill_value for both ends. Otherwise, pad in the head
            of the axis.
        fill_value:
            value to be filled.

        Returns
        -------
        Variable that is a view of the original array with a added dimension of
        size w.
        The return dim: self.dims + (window_dim, )
        The return shape: self.shape + (window, )

        Examples
        --------
        >>> v=Variable(('a', 'b'), np.arange(8).reshape((2,4)))
        >>> v.rolling_window(x, 'b', 3, 'window_dim')
        <xarray.Variable (a: 2, b: 4, window_dim: 3)>
        array([[[nan, nan, 0], [nan, 0, 1], [0, 1, 2], [1, 2, 3]],
               [[nan, nan, 4], [nan, 4, 5], [4, 5, 6], [5, 6, 7]]])

        >>> v.rolling_window(x, 'b', 3, 'window_dim', center=True)
        <xarray.Variable (a: 2, b: 4, window_dim: 3)>
        array([[[nan, 0, 1], [0, 1, 2], [1, 2, 3], [2, 3, nan]],
               [[nan, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, nan]]])
        """
        if fill_value is dtypes.NA:  # np.nan is passed
            dtype, fill_value = dtypes.maybe_promote(self.dtype)
            array = self.astype(dtype, copy=False).data
        else:
            dtype = self.dtype
            array = self.data

        new_dims = self.dims + (window_dim, )
        return Variable(new_dims, duck_array_ops.rolling_window(
            array, axis=self.get_axis_num(dim), window=window,
            center=center, fill_value=fill_value))

Response: This function creates a rolling_window of the array along dim and adds a new_dim to the last place.


Instruction:
Can you tell what is the following Python 3 function doing
def coarsen(self, windows, func, boundary='exact', side='left'):
        windows = {k: v for k, v in windows.items() if k in self.dims}
        if not windows:
            return self.copy()

        reshaped, axes = self._coarsen_reshape(windows, boundary, side)
        if isinstance(func, str):
            name = func
            func = getattr(duck_array_ops, name, None)
            if func is None:
                raise NameError('{} is not a valid method.'.format(name))
        return type(self)(self.dims, func(reshaped, axis=axes), self._attrs)

Response: Return a new array with coarsened data.


Instruction:
Can you implement a function in Python 3 that
constructs a reshaped array for corsen .

Response:
def _coarsen_reshape(self, windows, boundary, side):
        """
        Construct a reshaped-array for corsen
        """
        if not utils.is_dict_like(boundary):
            boundary = {d: boundary for d in windows.keys()}

        if not utils.is_dict_like(side):
            side = {d: side for d in windows.keys()}

        # remove unrelated dimensions
        boundary = {k: v for k, v in boundary.items() if k in windows}
        side = {k: v for k, v in side.items() if k in windows}

        for d, window in windows.items():
            if window <= 0:
                raise ValueError('window must be > 0. Given {}'.format(window))

        variable = self
        for d, window in windows.items():
            # trim or pad the object
            size = variable.shape[self._get_axis_num(d)]
            n = int(size / window)
            if boundary[d] == 'exact':
                if n * window != size:
                    raise ValueError(
                        'Could not coarsen a dimension of size {} with '
                        'window {}'.format(size, window))
            elif boundary[d] == 'trim':
                if side[d] == 'left':
                    variable = variable.isel({d: slice(0, window * n)})
                else:
                    excess = size - window * n
                    variable = variable.isel({d: slice(excess, None)})
            elif boundary[d] == 'pad':  # pad
                pad = window * n - size
                if pad < 0:
                    pad += window
                if side[d] == 'left':
                    pad_widths = {d: (0, pad)}
                else:
                    pad_widths = {d: (pad, 0)}
                variable = variable.pad_with_fill_value(pad_widths)
            else:
                raise TypeError(
                    "{} is invalid for boundary. Valid option is 'exact', "
                    "'trim' and 'pad'".format(boundary[d]))

        shape = []
        axes = []
        axis_count = 0
        for i, d in enumerate(variable.dims):
            if d in windows:
                size = variable.shape[i]
                shape.append(int(size / windows[d]))
                shape.append(windows[d])
                axis_count += 1
                axes.append(i + axis_count)
            else:
                shape.append(variable.shape[i])

        return variable.data.reshape(shape), tuple(axes)


Instruction:
Explain what the following Python 3 code does
def _to_numeric(self, offset=None, datetime_unit=None, dtype=float):
        numeric_array = duck_array_ops.datetime_to_numeric(
            self.data, offset, datetime_unit, dtype)
        return type(self)(self.dims, numeric_array, self._attrs)

Response: Convert the object to numeric.


Instruction:
Write a Python 3 function that can
specialize version of Variable. concat for IndexVariable objects.

Response:
def concat(cls, variables, dim='concat_dim', positions=None,
               shortcut=False):
        """Specialized version of Variable.concat for IndexVariable objects.

        This exists because we want to avoid converting Index objects to NumPy
        arrays, if possible.
        """
        if not isinstance(dim, str):
            dim, = dim.dims

        variables = list(variables)
        first_var = variables[0]

        if any(not isinstance(v, cls) for v in variables):
            raise TypeError('IndexVariable.concat requires that all input '
                            'variables be IndexVariable objects')

        indexes = [v._data.array for v in variables]

        if not indexes:
            data = []
        else:
            data = indexes[0].append(indexes[1:])

            if positions is not None:
                indices = nputils.inverse_permutation(
                    np.concatenate(positions))
                data = data.take(indices)

        attrs = OrderedDict(first_var.attrs)
        if not shortcut:
            for var in variables:
                if var.dims != first_var.dims:
                    raise ValueError('inconsistent dimensions')
                utils.remove_incompatible_items(attrs, var.attrs)

        return cls(first_var.dims, data, attrs)


Instruction:
Can you write a function in Python 3 where it
returns a copy of this VariableReservedEntry object.

Response:
def copy(self, deep=True, data=None):
        """Returns a copy of this object.

        `deep` is ignored since data is stored in the form of
        pandas.Index, which is already immutable. Dimensions, attributes
        and encodings are always copied.

        Use `data` to create a new object with the same structure as
        original but entirely new data.

        Parameters
        ----------
        deep : bool, optional
            Deep is always ignored.
        data : array_like, optional
            Data to use in the new object. Must have same shape as original.

        Returns
        -------
        object : Variable
            New object with dimensions, attributes, encodings, and optionally
            data copied from original.
        """
        if data is None:
            data = self._data
        else:
            data = as_compatible_data(data)
            if self.shape != data.shape:
                raise ValueError("Data shape {} must match shape of object {}"
                                 .format(data.shape, self.shape))
        return type(self)(self.dims, data, self._attrs,
                          self._encoding, fastpath=True)


Instruction:
Can you write a function in Python 3 where it
converts this variable to a pandas. Index.

Response:
def to_index(self):
        """Convert this variable to a pandas.Index"""
        # n.b. creating a new pandas.Index from an old pandas.Index is
        # basically free as pandas.Index objects are immutable
        assert self.ndim == 1
        index = self._data.array
        if isinstance(index, pd.MultiIndex):
            # set default names for multi-index unnamed levels so that
            # we can safely rename dimension / coordinate later
            valid_level_names = [name or '{}_level_{}'.format(self.dims[0], i)
                                 for i, name in enumerate(index.names)]
            index = index.set_names(valid_level_names)
        else:
            index = index.set_names(self.name)
        return index


Instruction:
Can you generate the documentation for the following Python 3 function
def level_names(self):
        index = self.to_index()
        if isinstance(index, pd.MultiIndex):
            return index.names
        else:
            return None

Response:
Return the level names of this IndexVariable or None if this IndexVariable has no
        MultiIndex.


Instruction:
Make a summary of the following Python 3 code
def get_level_variable(self, level):
        if self.level_names is None:
            raise ValueError("IndexVariable %r has no MultiIndex" % self.name)
        index = self.to_index()
        return type(self)(self.dims, index.get_level_values(level))

Response: Return a new IndexVariable from a given MultiIndex level.


Instruction:
Can you tell what is the following Python 3 function doing
def _parsed_string_to_bounds(date_type, resolution, parsed):
    if resolution == 'year':
        return (date_type(parsed.year, 1, 1),
                date_type(parsed.year + 1, 1, 1) - timedelta(microseconds=1))
    elif resolution == 'month':
        if parsed.month == 12:
            end = date_type(parsed.year + 1, 1, 1) - timedelta(microseconds=1)
        else:
            end = (date_type(parsed.year, parsed.month + 1, 1) -
                   timedelta(microseconds=1))
        return date_type(parsed.year, parsed.month, 1), end
    elif resolution == 'day':
        start = date_type(parsed.year, parsed.month, parsed.day)
        return start, start + timedelta(days=1, microseconds=-1)
    elif resolution == 'hour':
        start = date_type(parsed.year, parsed.month, parsed.day, parsed.hour)
        return start, start + timedelta(hours=1, microseconds=-1)
    elif resolution == 'minute':
        start = date_type(parsed.year, parsed.month, parsed.day, parsed.hour,
                          parsed.minute)
        return start, start + timedelta(minutes=1, microseconds=-1)
    elif resolution == 'second':
        start = date_type(parsed.year, parsed.month, parsed.day, parsed.hour,
                          parsed.minute, parsed.second)
        return start, start + timedelta(seconds=1, microseconds=-1)
    else:
        raise KeyError

Response:
Generalization of pandas. tseries. index. DatetimeIndex. _parsed_string_to_bounds
    for use with non - standard calendars and cftime. datetime
    objects.


Instruction:
Can you tell what is the following Python 3 function doing
def get_date_field(datetimes, field):
    return np.array([getattr(date, field) for date in datetimes])

Response: Adapted from pandas. tslib. get_date_field


Instruction:
How would you code a function in Python 3 to
return a property that can be used to access the given field.

Response:
def _field_accessor(name, docstring=None, min_cftime_version='0.0'):
    """Adapted from pandas.tseries.index._field_accessor"""

    def f(self, min_cftime_version=min_cftime_version):
        import cftime

        version = cftime.__version__

        if LooseVersion(version) >= LooseVersion(min_cftime_version):
            return get_date_field(self._data, name)
        else:
            raise ImportError('The {!r} accessor requires a minimum '
                              'version of cftime of {}. Found an '
                              'installed version of {}.'.format(
                                  name, min_cftime_version, version))

    f.__name__ = name
    f.__doc__ = docstring
    return property(f)


Instruction:
How would you code a function in Python 3 to
create a numpy array from an array of strings.

Response:
def _parse_array_of_cftime_strings(strings, date_type):
    """Create a numpy array from an array of strings.

    For use in generating dates from strings for use with interp.  Assumes the
    array is either 0-dimensional or 1-dimensional.

    Parameters
    ----------
    strings : array of strings
        Strings to convert to dates
    date_type : cftime.datetime type
        Calendar type to use for dates

    Returns
    -------
    np.array
    """
    return np.array([_parse_iso8601_without_reso(date_type, s)
                     for s in strings.ravel()]).reshape(strings.shape)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _partial_date_slice(self, resolution, parsed):
        start, end = _parsed_string_to_bounds(self.date_type, resolution,
                                              parsed)

        times = self._data

        if self.is_monotonic:
            if (len(times) and ((start < times[0] and end < times[0]) or
                                (start > times[-1] and end > times[-1]))):
                # we are out of range
                raise KeyError

            # a monotonic (sorted) series can be sliced
            left = times.searchsorted(start, side='left')
            right = times.searchsorted(end, side='right')
            return slice(left, right)

        lhs_mask = times >= start
        rhs_mask = times <= end
        return np.flatnonzero(lhs_mask & rhs_mask)

Response: Adapted from pandas. tseries. index. DatetimeIndex. _partial_date_slice


Instruction:
Can you write a function in Python 3 where it
adapts from pandas. tseries. index. DatetimeIndex. _get_string_slice

Response:
def _get_string_slice(self, key):
        """Adapted from pandas.tseries.index.DatetimeIndex._get_string_slice"""
        parsed, resolution = _parse_iso8601_with_reso(self.date_type, key)
        try:
            loc = self._partial_date_slice(resolution, parsed)
        except KeyError:
            raise KeyError(key)
        return loc


Instruction:
Here you have a function in Python 3, explain what it does
def get_loc(self, key, method=None, tolerance=None):
        if isinstance(key, str):
            return self._get_string_slice(key)
        else:
            return pd.Index.get_loc(self, key, method=method,
                                    tolerance=tolerance)

Response: Adapted from pandas. tseries. index. DatetimeIndex. get_loc


Instruction:
How would you code a function in Python 3 to
adapt from pandas. tseries. index. DatetimeIndex. _maybe_cast_slice_bound

Response:
def _maybe_cast_slice_bound(self, label, side, kind):
        """Adapted from
        pandas.tseries.index.DatetimeIndex._maybe_cast_slice_bound"""
        if isinstance(label, str):
            parsed, resolution = _parse_iso8601_with_reso(self.date_type,
                                                          label)
            start, end = _parsed_string_to_bounds(self.date_type, resolution,
                                                  parsed)
            if self.is_monotonic_decreasing and len(self) > 1:
                return end if side == 'left' else start
            return start if side == 'left' else end
        else:
            return label


Instruction:
How would you explain what the following Python 3 function does
def get_value(self, series, key):
        if np.asarray(key).dtype == np.dtype(bool):
            return series.iloc[key]
        elif isinstance(key, slice):
            return series.iloc[self.slice_indexer(
                key.start, key.stop, key.step)]
        else:
            return series.iloc[self.get_loc(key)]

Response: Adapted from pandas. tseries. index. DatetimeIndex. get_value


Instruction:
Create a Python 3 function to
shift the CFTimeIndex a multiple of the given frequency.

Response:
def shift(self, n, freq):
        """Shift the CFTimeIndex a multiple of the given frequency.

        See the documentation for :py:func:`~xarray.cftime_range` for a
        complete listing of valid frequency strings.

        Parameters
        ----------
        n : int
            Periods to shift by
        freq : str or datetime.timedelta
            A frequency string or datetime.timedelta object to shift by

        Returns
        -------
        CFTimeIndex

        See also
        --------
        pandas.DatetimeIndex.shift

        Examples
        --------
        >>> index = xr.cftime_range('2000', periods=1, freq='M')
        >>> index
        CFTimeIndex([2000-01-31 00:00:00], dtype='object')
        >>> index.shift(1, 'M')
        CFTimeIndex([2000-02-29 00:00:00], dtype='object')
        """
        from .cftime_offsets import to_offset

        if not isinstance(n, int):
            raise TypeError("'n' must be an int, got {}.".format(n))
        if isinstance(freq, timedelta):
            return self + n * freq
        elif isinstance(freq, str):
            return self + n * to_offset(freq)
        else:
            raise TypeError(
                "'freq' must be of type "
                "str or datetime.timedelta, got {}.".format(freq))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def to_datetimeindex(self, unsafe=False):
        nptimes = cftime_to_nptime(self)
        calendar = infer_calendar_name(self)
        if calendar not in _STANDARD_CALENDARS and not unsafe:
            warnings.warn(
                'Converting a CFTimeIndex with dates from a non-standard '
                'calendar, {!r}, to a pandas.DatetimeIndex, which uses dates '
                'from the standard calendar.  This may lead to subtle errors '
                'in operations that depend on the length of time between '
                'dates.'.format(calendar), RuntimeWarning, stacklevel=2)
        return pd.DatetimeIndex(nptimes)

Response: Convert this index to a pandas. DatetimeIndex.


Instruction:
Create a Python 3 function for
creating a function that dispatches to dask for dask array inputs.

Response:
def _dask_or_eager_func(name, eager_module=np, dask_module=dask_array,
                        list_of_args=False, array_args=slice(1),
                        requires_dask=None):
    """Create a function that dispatches to dask for dask array inputs."""
    if dask_module is not None:
        def f(*args, **kwargs):
            if list_of_args:
                dispatch_args = args[0]
            else:
                dispatch_args = args[array_args]
            if any(isinstance(a, dask_array.Array) for a in dispatch_args):
                try:
                    wrapped = getattr(dask_module, name)
                except AttributeError as e:
                    raise AttributeError("%s: requires dask >=%s" %
                                         (e, requires_dask))
            else:
                wrapped = getattr(eager_module, name)
            return wrapped(*args, **kwargs)
    else:
        def f(*args, **kwargs):
            return getattr(eager_module, name)(*args, **kwargs)
    return f


Instruction:
Can you generate a brief explanation for the following Python 3 code
def as_shared_dtype(scalars_or_arrays):
    arrays = [asarray(x) for x in scalars_or_arrays]
    # Pass arrays directly instead of dtypes to result_type so scalars
    # get handled properly.
    # Note that result_type() safely gets the dtype from dask arrays without
    # evaluating them.
    out_type = dtypes.result_type(*arrays)
    return [x.astype(out_type, copy=False) for x in arrays]

Response: Cast a list of scalars to a shared dtype using xarray s type promotion rules.


Instruction:
Given the following Python 3 function, write the documentation
def allclose_or_equiv(arr1, arr2, rtol=1e-5, atol=1e-8):
    arr1, arr2 = as_like_arrays(arr1, arr2)
    if arr1.shape != arr2.shape:
        return False
    return bool(
        isclose(arr1, arr2, rtol=rtol, atol=atol, equal_nan=True).all())

Response: Like np. allclose but also allows values to be NaN in both arrays


Instruction:
Can you tell what is the following Python 3 function doing
def array_equiv(arr1, arr2):
    arr1, arr2 = as_like_arrays(arr1, arr2)
    if arr1.shape != arr2.shape:
        return False

    with warnings.catch_warnings():
        warnings.filterwarnings('ignore', "In the future, 'NAT == x'")

        flag_array = (arr1 == arr2)
        flag_array |= (isnull(arr1) & isnull(arr2))

        return bool(flag_array.all())

Response: Like np. array_equal but also allows values to be NaN in both arrays


Instruction:
Create a Python 3 function for
counting the number of non - NA in this array along the given axis or axes.

Response:
def count(data, axis=None):
    """Count the number of non-NA in this array along the given axis or axes
    """
    return np.sum(np.logical_not(isnull(data)), axis=axis)


Instruction:
Can you generate the documentation for the following Python 3 function
def datetime_to_numeric(array, offset=None, datetime_unit=None, dtype=float):
    # TODO: make this function dask-compatible?
    if offset is None:
        offset = array.min()
    array = array - offset

    if not hasattr(array, 'dtype'):  # scalar is converted to 0d-array
        array = np.array(array)

    if array.dtype.kind in 'O':
        # possibly convert object array containing datetime.timedelta
        array = np.asarray(pd.Series(array.ravel())).reshape(array.shape)

    if datetime_unit:
        array = array / np.timedelta64(1, datetime_unit)

    # convert np.NaT to np.nan
    if array.dtype.kind in 'mM':
        return np.where(isnull(array), np.nan, array.astype(dtype))
    return array.astype(dtype)

Response: Convert an array containing datetime - like data to an array of floats.


Instruction:
Can you implement a function in Python 3 that
returns the first non - NA elements in this array along the given axis

Response:
def first(values, axis, skipna=None):
    """Return the first non-NA elements in this array along the given axis
    """
    if (skipna or skipna is None) and values.dtype.kind not in 'iSU':
        # only bother for dtypes that can hold NaN
        _fail_on_dask_array_input_skipna(values)
        return nanfirst(values, axis)
    return take(values, 0, axis=axis)


Instruction:
Here you have a function in Python 3, explain what it does
def last(values, axis, skipna=None):
    if (skipna or skipna is None) and values.dtype.kind not in 'iSU':
        # only bother for dtypes that can hold NaN
        _fail_on_dask_array_input_skipna(values)
        return nanlast(values, axis)
    return take(values, -1, axis=axis)

Response: Return the last non - NA elements in this array along the given axis


Instruction:
Can you tell what is the following Python 3 function doing
def rolling_window(array, axis, window, center, fill_value):
    if isinstance(array, dask_array_type):
        return dask_array_ops.rolling_window(
            array, axis, window, center, fill_value)
    else:  # np.ndarray
        return nputils.rolling_window(
            array, axis, window, center, fill_value)

Response: Make an ndarray with a rolling window of axis - th dimension.


Instruction:
How would you explain what the following Python 3 function does
def concat(objs, dim=None, data_vars='all', coords='different',
           compat='equals', positions=None, indexers=None, mode=None,
           concat_over=None):
    """Concatenate xarray objects along a new or existing dimension.

    Parameters
    ----------
    objs : sequence of Dataset and DataArray objects
        xarray objects to concatenate together. Each object is expected to
        consist of variables and coordinates with matching shapes except for
        along the concatenated dimension.
    dim : str or DataArray or pandas.Index
        Name of the dimension to concatenate along. This can either be a new
        dimension name, in which case it is added along axis=0, or an existing
        dimension name, in which case the location of the dimension is
        unchanged. If dimension is provided as a DataArray or Index, its name
        is used as the dimension to concatenate along and the values are added
        as a coordinate.
    data_vars : {'minimal', 'different', 'all' or list of str}, optional
        These data variables will be concatenated together:
          * 'minimal': Only data variables in which the dimension already
            appears are included.
          * 'different': Data variables which are not equal (ignoring
            attributes) across all datasets are also concatenated (as well as
            all for which dimension already appears). Beware: this option may
            load the data payload of data variables into memory if they are not
            already loaded.
          * 'all': All data variables will be concatenated.
          * list of str: The listed data variables will be concatenated, in
            addition to the 'minimal' data variables.
        If objects are DataArrays, data_vars must be 'all'.
    coords : {'minimal', 'different', 'all' or list of str}, optional
        These coordinate variables will be concatenated together:
          * 'minimal': Only coordinates in which the dimension already appears
            are included.
          * 'different': Coordinates which are not equal (ignoring attributes)
            across all datasets are also concatenated (as well as all for which
            dimension already appears). Beware: this option may load the data
            payload of coordinate variables into memory if they are not already
            loaded.
          * 'all': All coordinate variables will be concatenated, except
            those corresponding to other dimensions.
          * list of str: The listed coordinate variables will be concatenated,
            in addition the 'minimal' coordinates.
    compat : {'equals', 'identical'}, optional
        String indicating how to compare non-concatenated variables and
        dataset global attributes for potential conflicts. 'equals' means
        that all variable values and dimensions must be the same;
        'identical' means that variable attributes and global attributes
        must also be equal.
    positions : None or list of integer arrays, optional
        List of integer arrays which specifies the integer positions to which
        to assign each dataset along the concatenated dimension. If not
        supplied, objects are concatenated in the provided order.
    indexers, mode, concat_over : deprecated

    Returns
    -------
    concatenated : type of objs

    See also
    --------
    merge
    auto_combine
    """
    # TODO: add join and ignore_index arguments copied from pandas.concat
    # TODO: support concatenating scalar coordinates even if the concatenated
    # dimension already exists
    from .dataset import Dataset
    from .dataarray import DataArray

    try:
        first_obj, objs = utils.peek_at(objs)
    except StopIteration:
        raise ValueError('must supply at least one object to concatenate')

    if dim is None:
        warnings.warn('the `dim` argument to `concat` will be required '
                      'in a future version of xarray; for now, setting it to '
                      "the old default of 'concat_dim'",
                      FutureWarning, stacklevel=2)
        dim = 'concat_dims'

    if indexers is not None:  # pragma: nocover
        warnings.warn('indexers has been renamed to positions; the alias '
                      'will be removed in a future version of xarray',
                      FutureWarning, stacklevel=2)
        positions = indexers

    if mode is not None:
        raise ValueError('`mode` is no longer a valid argument to '
                         'xarray.concat; it has been split into the '
                         '`data_vars` and `coords` arguments')
    if concat_over is not None:
        raise ValueError('`concat_over` is no longer a valid argument to '
                         'xarray.concat; it has been split into the '
                         '`data_vars` and `coords` arguments')

    if isinstance(first_obj, DataArray):
        f = _dataarray_concat
    elif isinstance(first_obj, Dataset):
        f = _dataset_concat
    else:
        raise TypeError('can only concatenate xarray Dataset and DataArray '
                        'objects, got %s' % type(first_obj))
    return f(objs, dim, data_vars, coords, compat, positions)

Response: Concatenate two or more xarray objects along a new or existing dimension.


Instruction:
Can you write a function in Python 3 where it
calculates the name and 1d coordinate variable for concatenating along the new dimension.

Response:
def _calc_concat_dim_coord(dim):
    """
    Infer the dimension name and 1d coordinate variable (if appropriate)
    for concatenating along the new dimension.
    """
    from .dataarray import DataArray

    if isinstance(dim, str):
        coord = None
    elif not isinstance(dim, (DataArray, Variable)):
        dim_name = getattr(dim, 'name', None)
        if dim_name is None:
            dim_name = 'concat_dim'
        coord = IndexVariable(dim_name, dim)
        dim = dim_name
    elif not isinstance(dim, DataArray):
        coord = as_variable(dim).to_index_variable()
        dim, = coord.dims
    else:
        coord = dim
        dim, = coord.dims
    return dim, coord


Instruction:
Given the following Python 3 function, write the documentation
def _calc_concat_over(datasets, dim, data_vars, coords):
    # Return values
    concat_over = set()
    equals = {}

    if dim in datasets[0]:
        concat_over.add(dim)
    for ds in datasets:
        concat_over.update(k for k, v in ds.variables.items()
                           if dim in v.dims)

    def process_subset_opt(opt, subset):
        if isinstance(opt, str):
            if opt == 'different':
                # all nonindexes that are not the same in each dataset
                for k in getattr(datasets[0], subset):
                    if k not in concat_over:
                        # Compare the variable of all datasets vs. the one
                        # of the first dataset. Perform the minimum amount of
                        # loads in order to avoid multiple loads from disk
                        # while keeping the RAM footprint low.
                        v_lhs = datasets[0].variables[k].load()
                        # We'll need to know later on if variables are equal.
                        computed = []
                        for ds_rhs in datasets[1:]:
                            v_rhs = ds_rhs.variables[k].compute()
                            computed.append(v_rhs)
                            if not v_lhs.equals(v_rhs):
                                concat_over.add(k)
                                equals[k] = False
                                # computed variables are not to be re-computed
                                # again in the future
                                for ds, v in zip(datasets[1:], computed):
                                    ds.variables[k].data = v.data
                                break
                        else:
                            equals[k] = True

            elif opt == 'all':
                concat_over.update(set(getattr(datasets[0], subset)) -
                                   set(datasets[0].dims))
            elif opt == 'minimal':
                pass
            else:
                raise ValueError("unexpected value for %s: %s" % (subset, opt))
        else:
            invalid_vars = [k for k in opt
                            if k not in getattr(datasets[0], subset)]
            if invalid_vars:
                if subset == 'coords':
                    raise ValueError(
                        'some variables in coords are not coordinates on '
                        'the first dataset: %s' % (invalid_vars,))
                else:
                    raise ValueError(
                        'some variables in data_vars are not data variables '
                        'on the first dataset: %s' % (invalid_vars,))
            concat_over.update(opt)

    process_subset_opt(data_vars, 'data_vars')
    process_subset_opt(coords, 'coords')
    return concat_over, equals

Response: Calculates which dataset variables need to be concatenated in the result.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _dataset_concat(datasets, dim, data_vars, coords, compat, positions):
    from .dataset import Dataset

    if compat not in ['equals', 'identical']:
        raise ValueError("compat=%r invalid: must be 'equals' "
                         "or 'identical'" % compat)

    dim, coord = _calc_concat_dim_coord(dim)
    # Make sure we're working on a copy (we'll be loading variables)
    datasets = [ds.copy() for ds in datasets]
    datasets = align(*datasets, join='outer', copy=False, exclude=[dim])

    concat_over, equals = _calc_concat_over(datasets, dim, data_vars, coords)

    def insert_result_variable(k, v):
        assert isinstance(v, Variable)
        if k in datasets[0].coords:
            result_coord_names.add(k)
        result_vars[k] = v

    # create the new dataset and add constant variables
    result_vars = OrderedDict()
    result_coord_names = set(datasets[0].coords)
    result_attrs = datasets[0].attrs
    result_encoding = datasets[0].encoding

    for k, v in datasets[0].variables.items():
        if k not in concat_over:
            insert_result_variable(k, v)

    # check that global attributes and non-concatenated variables are fixed
    # across all datasets
    for ds in datasets[1:]:
        if (compat == 'identical' and
                not utils.dict_equiv(ds.attrs, result_attrs)):
            raise ValueError('dataset global attributes not equal')
        for k, v in ds.variables.items():
            if k not in result_vars and k not in concat_over:
                raise ValueError('encountered unexpected variable %r' % k)
            elif (k in result_coord_names) != (k in ds.coords):
                raise ValueError('%r is a coordinate in some datasets but not '
                                 'others' % k)
            elif k in result_vars and k != dim:
                # Don't use Variable.identical as it internally invokes
                # Variable.equals, and we may already know the answer
                if compat == 'identical' and not utils.dict_equiv(
                        v.attrs, result_vars[k].attrs):
                    raise ValueError(
                        'variable %s not identical across datasets' % k)

                # Proceed with equals()
                try:
                    # May be populated when using the "different" method
                    is_equal = equals[k]
                except KeyError:
                    result_vars[k].load()
                    is_equal = v.equals(result_vars[k])
                if not is_equal:
                    raise ValueError(
                        'variable %s not equal across datasets' % k)

    # we've already verified everything is consistent; now, calculate
    # shared dimension sizes so we can expand the necessary variables
    dim_lengths = [ds.dims.get(dim, 1) for ds in datasets]
    non_concat_dims = {}
    for ds in datasets:
        non_concat_dims.update(ds.dims)
    non_concat_dims.pop(dim, None)

    def ensure_common_dims(vars):
        # ensure each variable with the given name shares the same
        # dimensions and the same shape for all of them except along the
        # concat dimension
        common_dims = tuple(pd.unique([d for v in vars for d in v.dims]))
        if dim not in common_dims:
            common_dims = (dim,) + common_dims
        for var, dim_len in zip(vars, dim_lengths):
            if var.dims != common_dims:
                common_shape = tuple(non_concat_dims.get(d, dim_len)
                                     for d in common_dims)
                var = var.set_dims(common_dims, common_shape)
            yield var

    # stack up each variable to fill-out the dataset (in order)
    for k in datasets[0].variables:
        if k in concat_over:
            vars = ensure_common_dims([ds.variables[k] for ds in datasets])
            combined = concat_vars(vars, dim, positions)
            insert_result_variable(k, combined)

    result = Dataset(result_vars, attrs=result_attrs)
    result = result.set_coords(result_coord_names)
    result.encoding = result_encoding

    if coord is not None:
        # add concat dimension last to ensure that its in the final Dataset
        result[coord.name] = coord

    return result

Response: Concatenate a sequence of datasets along a new or existing dimension.


Instruction:
Given the following Python 3 function, write the documentation
def _infer_tile_ids_from_nested_list(entry, current_pos):

    if isinstance(entry, list):
        for i, item in enumerate(entry):
            for result in _infer_tile_ids_from_nested_list(item,
                                                           current_pos + (i,)):
                yield result
    else:
        yield current_pos, entry

Response: A generator function that yields tuples containing the tile IDs of each object in the nested list.


Instruction:
Given the following Python 3 function, write the documentation
def _combine_nd(combined_ids, concat_dims, data_vars='all',
                coords='different', compat='no_conflicts'):
    """
    Concatenates and merges an N-dimensional structure of datasets.

    No checks are performed on the consistency of the datasets, concat_dims or
    tile_IDs, because it is assumed that this has already been done.

    Parameters
    ----------
    combined_ids : Dict[Tuple[int, ...]], xarray.Dataset]
        Structure containing all datasets to be concatenated with "tile_IDs" as
        keys, which specify position within the desired final combined result.
    concat_dims : sequence of str
        The dimensions along which the datasets should be concatenated. Must be
        in order, and the length must match

    Returns
    -------
    combined_ds : xarray.Dataset
    """

    # Perform N-D dimensional concatenation
    # Each iteration of this loop reduces the length of the tile_ids tuples
    # by one. It always combines along the first dimension, removing the first
    # element of the tuple
    for concat_dim in concat_dims:
        combined_ids = _auto_combine_all_along_first_dim(combined_ids,
                                                         dim=concat_dim,
                                                         data_vars=data_vars,
                                                         coords=coords,
                                                         compat=compat)
    combined_ds = list(combined_ids.values())[0]
    return combined_ds

Response: Concatenates a set of datasets into a single N - dimensional structure.


Instruction:
Can you tell what is the following Python 3 function doing
def _auto_combine(datasets, concat_dims, compat, data_vars, coords,
                  infer_order_from_coords, ids):
    """
    Calls logic to decide concatenation order before concatenating.
    """

    # Arrange datasets for concatenation
    if infer_order_from_coords:
        raise NotImplementedError
        # TODO Use coordinates to determine tile_ID for each dataset in N-D
        # Ignore how they were ordered previously
        # Should look like:
        # combined_ids, concat_dims = _infer_tile_ids_from_coords(datasets,
        # concat_dims)
    else:
        # Use information from the shape of the user input
        if not ids:
            # Determine tile_IDs by structure of input in N-D
            # (i.e. ordering in list-of-lists)
            combined_ids, concat_dims = _infer_concat_order_from_positions(
                datasets, concat_dims)
        else:
            # Already sorted so just use the ids already passed
            combined_ids = OrderedDict(zip(ids, datasets))

    # Check that the inferred shape is combinable
    _check_shape_tile_ids(combined_ids)

    # Repeatedly concatenate then merge along each dimension
    combined = _combine_nd(combined_ids, concat_dims, compat=compat,
                           data_vars=data_vars, coords=coords)
    return combined

Response: Combines the datasets into a single N - D tree.


Instruction:
Can you generate the documentation for the following Python 3 function
def auto_combine(datasets, concat_dim=_CONCAT_DIM_DEFAULT,
                 compat='no_conflicts', data_vars='all', coords='different'):
    """Attempt to auto-magically combine the given datasets into one.
    This method attempts to combine a list of datasets into a single entity by
    inspecting metadata and using a combination of concat and merge.
    It does not concatenate along more than one dimension or sort data under
    any circumstances. It does align coordinates, but different variables on
    datasets can cause it to fail under some scenarios. In complex cases, you
    may need to clean up your data and use ``concat``/``merge`` explicitly.
    ``auto_combine`` works well if you have N years of data and M data
    variables, and each combination of a distinct time period and set of data
    variables is saved its own dataset.

    Parameters
    ----------
    datasets : sequence of xarray.Dataset
        Dataset objects to merge.
    concat_dim : str or DataArray or Index, optional
        Dimension along which to concatenate variables, as used by
        :py:func:`xarray.concat`. You only need to provide this argument if
        the dimension along which you want to concatenate is not a dimension
        in the original datasets, e.g., if you want to stack a collection of
        2D arrays along a third dimension.
        By default, xarray attempts to infer this argument by examining
        component files. Set ``concat_dim=None`` explicitly to disable
        concatenation.
    compat : {'identical', 'equals', 'broadcast_equals', 'no_conflicts'}, optional
        String indicating how to compare variables of the same name for
        potential conflicts:

        - 'broadcast_equals': all values must be equal when variables are
          broadcast against each other to ensure common dimensions.
        - 'equals': all values and dimensions must be the same.
        - 'identical': all values, dimensions and attributes must be the
          same.
        - 'no_conflicts': only values which are not null in both datasets
          must be equal. The returned dataset then contains the combination
          of all non-null values.
    data_vars : {'minimal', 'different', 'all' or list of str}, optional
        Details are in the documentation of concat
    coords : {'minimal', 'different', 'all' or list of str}, optional
        Details are in the documentation of conca

    Returns
    -------
    combined : xarray.Dataset

    See also
    --------
    concat
    Dataset.merge
    """  # noqa

    # Coerce 1D input into ND to maintain backwards-compatible API until API
    # for N-D combine decided
    # (see https://github.com/pydata/xarray/pull/2553/#issuecomment-445892746)
    if concat_dim is None or concat_dim == _CONCAT_DIM_DEFAULT:
        concat_dims = concat_dim
    elif not isinstance(concat_dim, list):
        concat_dims = [concat_dim]
    else:
        concat_dims = concat_dim
    infer_order_from_coords = False

    # The IDs argument tells _auto_combine that the datasets are not yet sorted
    return _auto_combine(datasets, concat_dims=concat_dims, compat=compat,
                         data_vars=data_vars, coords=coords,
                         infer_order_from_coords=infer_order_from_coords,
                         ids=False)

Response: This method attempts to auto - magically combine the given datasets into one.


Instruction:
Given the following Python 3 function, write the documentation
def get_date_type(calendar):
    try:
        import cftime
    except ImportError:
        raise ImportError(
            'cftime is required for dates with non-standard calendars')
    else:
        calendars = {
            'noleap': cftime.DatetimeNoLeap,
            '360_day': cftime.Datetime360Day,
            '365_day': cftime.DatetimeNoLeap,
            '366_day': cftime.DatetimeAllLeap,
            'gregorian': cftime.DatetimeGregorian,
            'proleptic_gregorian': cftime.DatetimeProlepticGregorian,
            'julian': cftime.DatetimeJulian,
            'all_leap': cftime.DatetimeAllLeap,
            'standard': cftime.DatetimeGregorian
        }
        return calendars[calendar]

Response: Return the cftime date type for a given calendar name.


Instruction:
Implement a Python 3 function for
returning the day in the month that satisfies a BaseCFTimeOffset s onOffset policy.

Response:
def _get_day_of_month(other, day_option):
    """Find the day in `other`'s month that satisfies a BaseCFTimeOffset's
    onOffset policy, as described by the `day_option` argument.

    Parameters
    ----------
    other : cftime.datetime
    day_option : 'start', 'end'
        'start': returns 1
        'end': returns last day of the month

    Returns
    -------
    day_of_month : int

    """

    if day_option == 'start':
        return 1
    elif day_option == 'end':
        days_in_month = _days_in_month(other)
        return days_in_month
    elif day_option is None:
        # Note: unlike `_shift_month`, _get_day_of_month does not
        # allow day_option = None
        raise NotImplementedError
    else:
        raise ValueError(day_option)


Instruction:
Make a summary of the following Python 3 code
def _days_in_month(date):
    if date.month == 12:
        reference = type(date)(date.year + 1, 1, 1)
    else:
        reference = type(date)(date.year, date.month + 1, 1)
    return (reference - timedelta(days=1)).day

Response: The number of days in the month of the given date


Instruction:
Here you have a function in Python 3, explain what it does
def _adjust_n_months(other_day, n, reference_day):
    if n > 0 and other_day < reference_day:
        n = n - 1
    elif n <= 0 and other_day > reference_day:
        n = n + 1
    return n

Response:
Adjust the number of times a monthly offset is applied based
    on the day of a given date.


Instruction:
Can you implement a function in Python 3 that
adjusts the number of times an annual offset is applied based on another date and the reference day provided

Response:
def _adjust_n_years(other, n, month, reference_day):
    """Adjust the number of times an annual offset is applied based on
    another date, and the reference day provided"""
    if n > 0:
        if other.month < month or (other.month == month and
                                   other.day < reference_day):
            n -= 1
    else:
        if other.month > month or (other.month == month and
                                   other.day > reference_day):
            n += 1
    return n


Instruction:
Can you generate the documentation for the following Python 3 function
def _shift_month(date, months, day_option='start'):
    delta_year = (date.month + months) // 12
    month = (date.month + months) % 12

    if month == 0:
        month = 12
        delta_year = delta_year - 1
    year = date.year + delta_year

    if day_option == 'start':
        day = 1
    elif day_option == 'end':
        reference = type(date)(year, month, 1)
        day = _days_in_month(reference)
    else:
        raise ValueError(day_option)
    # dayofwk=-1 is required to update the dayofwk and dayofyr attributes of
    # the returned date object in versions of cftime between 1.0.2 and
    # 1.0.3.4.  It can be removed for versions of cftime greater than
    # 1.0.3.4.
    return date.replace(year=year, month=month, day=day, dayofwk=-1)

Response: Shift the date to a given number of months away.


Instruction:
How would you explain what the following Python 3 function does
def roll_qtrday(other, n, month, day_option, modby=3):

    months_since = other.month % modby - month % modby

    if n > 0:
        if months_since < 0 or (
                months_since == 0 and
                other.day < _get_day_of_month(other, day_option)):
            # pretend to roll back if on same month but
            # before compare_day
            n -= 1
    else:
        if months_since > 0 or (
                months_since == 0 and
                other.day > _get_day_of_month(other, day_option)):
            # make sure to roll forward, so negate
            n += 1
    return n

Response: Roll the number of periods to a given day in a given month.


Instruction:
Can you tell what is the following Python 3 function doing
def to_offset(freq):
    if isinstance(freq, BaseCFTimeOffset):
        return freq
    else:
        try:
            freq_data = re.match(_PATTERN, freq).groupdict()
        except AttributeError:
            raise ValueError('Invalid frequency string provided')

    freq = freq_data['freq']
    multiples = freq_data['multiple']
    if multiples is None:
        multiples = 1
    else:
        multiples = int(multiples)

    return _FREQUENCIES[freq](n=multiples)

Response: Convert a frequency string to the appropriate subclass of BaseCFTimeOffset.


Instruction:
Create a Python 3 function for
generating an equally - spaced sequence of cftime. datetime objects between start and end.

Response:
def _generate_linear_range(start, end, periods):
    """Generate an equally-spaced sequence of cftime.datetime objects between
    and including two dates (whose length equals the number of periods)."""
    import cftime

    total_seconds = (end - start).total_seconds()
    values = np.linspace(0., total_seconds, periods, endpoint=True)
    units = 'seconds since {}'.format(format_cftime_datetime(start))
    calendar = start.calendar
    return cftime.num2date(values, units=units, calendar=calendar,
                           only_use_cftime_datetimes=True)


Instruction:
Can you generate the documentation for the following Python 3 function
def _generate_range(start, end, periods, offset):
    if start:
        start = offset.rollforward(start)

    if end:
        end = offset.rollback(end)

    if periods is None and end < start:
        end = None
        periods = 0

    if end is None:
        end = start + (periods - 1) * offset

    if start is None:
        start = end - (periods - 1) * offset

    current = start
    if offset.n >= 0:
        while current <= end:
            yield current

            next_date = current + offset
            if next_date <= current:
                raise ValueError('Offset {offset} did not increment date'
                                 .format(offset=offset))
            current = next_date
    else:
        while current >= end:
            yield current

            next_date = current + offset
            if next_date >= current:
                raise ValueError('Offset {offset} did not decrement date'
                                 .format(offset=offset))
            current = next_date

Response: Generate a regular range of cftime. datetime objects with a specific time offset.


Instruction:
Can you write a function in Python 3 where it
returns a fixed frequency CFTimeIndex for the given start and end dates.

Response:
def cftime_range(start=None, end=None, periods=None, freq='D',
                 normalize=False, name=None, closed=None,
                 calendar='standard'):
    """Return a fixed frequency CFTimeIndex.

    Parameters
    ----------
    start : str or cftime.datetime, optional
        Left bound for generating dates.
    end : str or cftime.datetime, optional
        Right bound for generating dates.
    periods : integer, optional
        Number of periods to generate.
    freq : str, default 'D', BaseCFTimeOffset, or None
       Frequency strings can have multiples, e.g. '5H'.
    normalize : bool, default False
        Normalize start/end dates to midnight before generating date range.
    name : str, default None
        Name of the resulting index
    closed : {None, 'left', 'right'}, optional
        Make the interval closed with respect to the given frequency to the
        'left', 'right', or both sides (None, the default).
    calendar : str
        Calendar type for the datetimes (default 'standard').

    Returns
    -------
    CFTimeIndex

    Notes
    -----

    This function is an analog of ``pandas.date_range`` for use in generating
    sequences of ``cftime.datetime`` objects.  It supports most of the
    features of ``pandas.date_range`` (e.g. specifying how the index is
    ``closed`` on either side, or whether or not to ``normalize`` the start and
    end bounds); however, there are some notable exceptions:

    - You cannot specify a ``tz`` (time zone) argument.
    - Start or end dates specified as partial-datetime strings must use the
      `ISO-8601 format <https://en.wikipedia.org/wiki/ISO_8601>`_.
    - It supports many, but not all, frequencies supported by
      ``pandas.date_range``.  For example it does not currently support any of
      the business-related, semi-monthly, or sub-second frequencies.
    - Compound sub-monthly frequencies are not supported, e.g. '1H1min', as
      these can easily be written in terms of the finest common resolution,
      e.g. '61min'.

    Valid simple frequency strings for use with ``cftime``-calendars include
    any multiples of the following.

    +--------+--------------------------+
    | Alias  | Description              |
    +========+==========================+
    | A, Y   | Year-end frequency       |
    +--------+--------------------------+
    | AS, YS | Year-start frequency     |
    +--------+--------------------------+
    | Q      | Quarter-end frequency    |
    +--------+--------------------------+
    | QS     | Quarter-start frequency  |
    +--------+--------------------------+
    | M      | Month-end frequency      |
    +--------+--------------------------+
    | MS     | Month-start frequency    |
    +--------+--------------------------+
    | D      | Day frequency            |
    +--------+--------------------------+
    | H      | Hour frequency           |
    +--------+--------------------------+
    | T, min | Minute frequency         |
    +--------+--------------------------+
    | S      | Second frequency         |
    +--------+--------------------------+

    Any multiples of the following anchored offsets are also supported.

    +----------+--------------------------------------------------------------------+
    | Alias    | Description                                                        |
    +==========+====================================================================+
    | A(S)-JAN | Annual frequency, anchored at the end (or beginning) of January    |
    +----------+--------------------------------------------------------------------+
    | A(S)-FEB | Annual frequency, anchored at the end (or beginning) of February   |
    +----------+--------------------------------------------------------------------+
    | A(S)-MAR | Annual frequency, anchored at the end (or beginning) of March      |
    +----------+--------------------------------------------------------------------+
    | A(S)-APR | Annual frequency, anchored at the end (or beginning) of April      |
    +----------+--------------------------------------------------------------------+
    | A(S)-MAY | Annual frequency, anchored at the end (or beginning) of May        |
    +----------+--------------------------------------------------------------------+
    | A(S)-JUN | Annual frequency, anchored at the end (or beginning) of June       |
    +----------+--------------------------------------------------------------------+
    | A(S)-JUL | Annual frequency, anchored at the end (or beginning) of July       |
    +----------+--------------------------------------------------------------------+
    | A(S)-AUG | Annual frequency, anchored at the end (or beginning) of August     |
    +----------+--------------------------------------------------------------------+
    | A(S)-SEP | Annual frequency, anchored at the end (or beginning) of September  |
    +----------+--------------------------------------------------------------------+
    | A(S)-OCT | Annual frequency, anchored at the end (or beginning) of October    |
    +----------+--------------------------------------------------------------------+
    | A(S)-NOV | Annual frequency, anchored at the end (or beginning) of November   |
    +----------+--------------------------------------------------------------------+
    | A(S)-DEC | Annual frequency, anchored at the end (or beginning) of December   |
    +----------+--------------------------------------------------------------------+
    | Q(S)-JAN | Quarter frequency, anchored at the end (or beginning) of January   |
    +----------+--------------------------------------------------------------------+
    | Q(S)-FEB | Quarter frequency, anchored at the end (or beginning) of February  |
    +----------+--------------------------------------------------------------------+
    | Q(S)-MAR | Quarter frequency, anchored at the end (or beginning) of March     |
    +----------+--------------------------------------------------------------------+
    | Q(S)-APR | Quarter frequency, anchored at the end (or beginning) of April     |
    +----------+--------------------------------------------------------------------+
    | Q(S)-MAY | Quarter frequency, anchored at the end (or beginning) of May       |
    +----------+--------------------------------------------------------------------+
    | Q(S)-JUN | Quarter frequency, anchored at the end (or beginning) of June      |
    +----------+--------------------------------------------------------------------+
    | Q(S)-JUL | Quarter frequency, anchored at the end (or beginning) of July      |
    +----------+--------------------------------------------------------------------+
    | Q(S)-AUG | Quarter frequency, anchored at the end (or beginning) of August    |
    +----------+--------------------------------------------------------------------+
    | Q(S)-SEP | Quarter frequency, anchored at the end (or beginning) of September |
    +----------+--------------------------------------------------------------------+
    | Q(S)-OCT | Quarter frequency, anchored at the end (or beginning) of October   |
    +----------+--------------------------------------------------------------------+
    | Q(S)-NOV | Quarter frequency, anchored at the end (or beginning) of November  |
    +----------+--------------------------------------------------------------------+
    | Q(S)-DEC | Quarter frequency, anchored at the end (or beginning) of December  |
    +----------+--------------------------------------------------------------------+

    Finally, the following calendar aliases are supported.

    +--------------------------------+---------------------------------------+
    | Alias                          | Date type                             |
    +================================+=======================================+
    | standard, gregorian            | ``cftime.DatetimeGregorian``          |
    +--------------------------------+---------------------------------------+
    | proleptic_gregorian            | ``cftime.DatetimeProlepticGregorian`` |
    +--------------------------------+---------------------------------------+
    | noleap, 365_day                | ``cftime.DatetimeNoLeap``             |
    +--------------------------------+---------------------------------------+
    | all_leap, 366_day              | ``cftime.DatetimeAllLeap``            |
    +--------------------------------+---------------------------------------+
    | 360_day                        | ``cftime.Datetime360Day``             |
    +--------------------------------+---------------------------------------+
    | julian                         | ``cftime.DatetimeJulian``             |
    +--------------------------------+---------------------------------------+

    Examples
    --------

    This function returns a ``CFTimeIndex``, populated with ``cftime.datetime``
    objects associated with the specified calendar type, e.g.

    >>> xr.cftime_range(start='2000', periods=6, freq='2MS', calendar='noleap')
    CFTimeIndex([2000-01-01 00:00:00, 2000-03-01 00:00:00, 2000-05-01 00:00:00,
                 2000-07-01 00:00:00, 2000-09-01 00:00:00, 2000-11-01 00:00:00],
                dtype='object')

    As in the standard pandas function, three of the ``start``, ``end``,
    ``periods``, or ``freq`` arguments must be specified at a given time, with
    the other set to ``None``.  See the `pandas documentation
    <https://pandas.pydata.org/pandas-docs/stable/generated/pandas.date_range.html#pandas.date_range>`_
    for more examples of the behavior of ``date_range`` with each of the
    parameters.

    See Also
    --------
    pandas.date_range
    """  # noqa: E501
    # Adapted from pandas.core.indexes.datetimes._generate_range.
    if _count_not_none(start, end, periods, freq) != 3:
        raise ValueError(
            "Of the arguments 'start', 'end', 'periods', and 'freq', three "
            "must be specified at a time.")

    if start is not None:
        start = to_cftime_datetime(start, calendar)
        start = _maybe_normalize_date(start, normalize)
    if end is not None:
        end = to_cftime_datetime(end, calendar)
        end = _maybe_normalize_date(end, normalize)

    if freq is None:
        dates = _generate_linear_range(start, end, periods)
    else:
        offset = to_offset(freq)
        dates = np.array(list(_generate_range(start, end, periods, offset)))

    left_closed = False
    right_closed = False

    if closed is None:
        left_closed = True
        right_closed = True
    elif closed == 'left':
        left_closed = True
    elif closed == 'right':
        right_closed = True
    else:
        raise ValueError("Closed must be either 'left', 'right' or None")

    if (not left_closed and len(dates) and
            start is not None and dates[0] == start):
        dates = dates[1:]
    if (not right_closed and len(dates) and
            end is not None and dates[-1] == end):
        dates = dates[:-1]

    return CFTimeIndex(dates, name=name)


Instruction:
How would you code a function in Python 3 to
check if the given date is in the set of possible dates created using a length - one version of this offset class.

Response:
def onOffset(self, date):
        """Check if the given date is in the set of possible dates created
        using a length-one version of this offset class."""
        mod_month = (date.month - self.month) % 3
        return mod_month == 0 and date.day == self._get_offset_day(date)


Instruction:
Can you write a function in Python 3 where it
rolls date forward to nearest start of quarter

Response:
def rollforward(self, date):
        """Roll date forward to nearest start of quarter"""
        if self.onOffset(date):
            return date
        else:
            return date + QuarterBegin(month=self.month)


Instruction:
Can you tell what is the following Python 3 function doing
def rollback(self, date):
        if self.onOffset(date):
            return date
        else:
            return date - QuarterBegin(month=self.month)

Response: Roll date backward to nearest start of quarter


Instruction:
Can you generate the documentation for the following Python 3 function
def rollforward(self, date):
        if self.onOffset(date):
            return date
        else:
            return date + QuarterEnd(month=self.month)

Response: Roll date forward to nearest end of quarter


Instruction:
How would you code a function in Python 3 to
roll date backward to nearest end of quarter

Response:
def rollback(self, date):
        """Roll date backward to nearest end of quarter"""
        if self.onOffset(date):
            return date
        else:
            return date - QuarterEnd(month=self.month)


Instruction:
Given the following Python 3 function, write the documentation
def rollforward(self, date):
        if self.onOffset(date):
            return date
        else:
            return date + YearBegin(month=self.month)

Response: Roll date forward to nearest start of year


Instruction:
Make a summary of the following Python 3 code
def rollback(self, date):
        if self.onOffset(date):
            return date
        else:
            return date - YearBegin(month=self.month)

Response: Roll date backward to nearest start of year


Instruction:
Write a Python 3 script to
check if the given date is in the set of possible dates created using a length - one version of this offset class.

Response:
def onOffset(self, date):
        """Check if the given date is in the set of possible dates created
        using a length-one version of this offset class."""
        return date.day == _days_in_month(date) and date.month == self.month


Instruction:
Create a Python 3 function for
rolling date forward to nearest end of year

Response:
def rollforward(self, date):
        """Roll date forward to nearest end of year"""
        if self.onOffset(date):
            return date
        else:
            return date + YearEnd(month=self.month)