Instruction:
Can you tell what is the following Python 3 function doing
def _infer_xy_labels_3d(darray, x, y, rgb):
    assert rgb is None or rgb != x
    assert rgb is None or rgb != y
    # Start by detecting and reporting invalid combinations of arguments
    assert darray.ndim == 3
    not_none = [a for a in (x, y, rgb) if a is not None]
    if len(set(not_none)) < len(not_none):
        raise ValueError(
            'Dimension names must be None or unique strings, but imshow was '
            'passed x=%r, y=%r, and rgb=%r.' % (x, y, rgb))
    for label in not_none:
        if label not in darray.dims:
            raise ValueError('%r is not a dimension' % (label,))

    # Then calculate rgb dimension if certain and check validity
    could_be_color = [label for label in darray.dims
                      if darray[label].size in (3, 4) and label not in (x, y)]
    if rgb is None and not could_be_color:
        raise ValueError(
            'A 3-dimensional array was passed to imshow(), but there is no '
            'dimension that could be color.  At least one dimension must be '
            'of size 3 (RGB) or 4 (RGBA), and not given as x or y.')
    if rgb is None and len(could_be_color) == 1:
        rgb = could_be_color[0]
    if rgb is not None and darray[rgb].size not in (3, 4):
        raise ValueError('Cannot interpret dim %r of size %s as RGB or RGBA.'
                         % (rgb, darray[rgb].size))

    # If rgb dimension is still unknown, there must be two or three dimensions
    # in could_be_color.  We therefore warn, and use a heuristic to break ties.
    if rgb is None:
        assert len(could_be_color) in (2, 3)
        rgb = could_be_color[-1]
        warnings.warn(
            'Several dimensions of this array could be colors.  Xarray '
            'will use the last possible dimension (%r) to match '
            'matplotlib.pyplot.imshow.  You can pass names of x, y, '
            'and/or rgb dimensions to override this guess.' % rgb)
    assert rgb is not None

    # Finally, we pick out the red slice and delegate to the 2D version:
    return _infer_xy_labels(darray.isel(**{rgb: 0}), x, y)

Response: Infer x and y labels for showing RGB images.


Instruction:
Can you implement a function in Python 3 that
infers x and y labels for a 2D data array.

Response:
def _infer_xy_labels(darray, x, y, imshow=False, rgb=None):
    """
    Determine x and y labels. For use in _plot2d

    darray must be a 2 dimensional data array, or 3d for imshow only.
    """
    assert x is None or x != y
    if imshow and darray.ndim == 3:
        return _infer_xy_labels_3d(darray, x, y, rgb)

    if x is None and y is None:
        if darray.ndim != 2:
            raise ValueError('DataArray must be 2d')
        y, x = darray.dims
    elif x is None:
        if y not in darray.dims and y not in darray.coords:
            raise ValueError('y must be a dimension name if x is not supplied')
        x = darray.dims[0] if y == darray.dims[1] else darray.dims[1]
    elif y is None:
        if x not in darray.dims and x not in darray.coords:
            raise ValueError('x must be a dimension name if y is not supplied')
        y = darray.dims[0] if x == darray.dims[1] else darray.dims[1]
    elif any(k not in darray.coords and k not in darray.dims for k in (x, y)):
        raise ValueError('x and y must be coordinate variables')
    return x, y


Instruction:
Make a summary of the following Python 3 code
def label_from_attrs(da, extra=''):
    ''' Makes informative labels if variable metadata (attrs) follows
        CF conventions. '''

    if da.attrs.get('long_name'):
        name = da.attrs['long_name']
    elif da.attrs.get('standard_name'):
        name = da.attrs['standard_name']
    elif da.name is not None:
        name = da.name
    else:
        name = ''

    if da.attrs.get('units'):
        units = ' [{}]'.format(da.attrs['units'])
    else:
        units = ''

    return '\n'.join(textwrap.wrap(name + extra + units, 30))

Response:
Makes informative labels if variable metadata ( attrs ) follows
        CF conventions.


Instruction:
Explain what the following Python 3 code does
def _interval_to_bound_points(array):

    array_boundaries = np.array([x.left for x in array])
    array_boundaries = np.concatenate(
        (array_boundaries, np.array([array[-1].right])))

    return array_boundaries

Response: Helper function which returns an array containing the Intervals boundaries.


Instruction:
Can you generate the documentation for the following Python 3 function
def _resolve_intervals_2dplot(val, func_name):
    label_extra = ''
    if _valid_other_type(val, [pd.Interval]):
        if func_name == 'pcolormesh':
            val = _interval_to_bound_points(val)
        else:
            val = _interval_to_mid_points(val)
            label_extra = '_center'

    return val, label_extra

Response: Helper function to resolve the values of a coordinate array containing pd. Interval with their mid - points.


Instruction:
Implement a Python 3 function for
checking if x has a type from types?

Response:
def _valid_other_type(x, types):
    """
    Do all elements of x have a type from types?
    """
    return all(any(isinstance(el, t) for t in types) for el in np.ravel(x))


Instruction:
Can you generate the documentation for the following Python 3 function
def _valid_numpy_subdtype(x, numpy_types):
    # If any of the types given in numpy_types is understood as numpy.generic,
    # all possible x will be considered valid.  This is probably unwanted.
    for t in numpy_types:
        assert not np.issubdtype(np.generic, t)

    return any(np.issubdtype(x.dtype, t) for t in numpy_types)

Response: Check if x is a subdtype of numpy_types.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _ensure_plottable(*args):
    numpy_types = [np.floating, np.integer, np.timedelta64, np.datetime64]
    other_types = [datetime]
    try:
        import cftime
        cftime_datetime = [cftime.datetime]
    except ImportError:
        cftime_datetime = []
    other_types = other_types + cftime_datetime
    for x in args:
        if not (_valid_numpy_subdtype(np.array(x), numpy_types)
                or _valid_other_type(np.array(x), other_types)):
            raise TypeError('Plotting requires coordinates to be numeric '
                            'or dates of type np.datetime64, '
                            'datetime.datetime, cftime.datetime or '
                            'pd.Interval.')
        if (_valid_other_type(np.array(x), cftime_datetime)
                and not nc_time_axis_available):
            raise ImportError('Plotting of arrays of cftime.datetime '
                              'objects or arrays indexed by '
                              'cftime.datetime objects requires the '
                              'optional `nc-time-axis` (v1.2.0 or later) '
                              'package.')

Response: Raise exception if any of the arguments are not plottable.


Instruction:
Write a Python 3 function for
updating axes with provided parameters.

Response:
def _update_axes(ax, xincrease, yincrease,
                 xscale=None, yscale=None,
                 xticks=None, yticks=None,
                 xlim=None, ylim=None):
    """
    Update axes with provided parameters
    """
    if xincrease is None:
        pass
    elif xincrease and ax.xaxis_inverted():
        ax.invert_xaxis()
    elif not xincrease and not ax.xaxis_inverted():
        ax.invert_xaxis()

    if yincrease is None:
        pass
    elif yincrease and ax.yaxis_inverted():
        ax.invert_yaxis()
    elif not yincrease and not ax.yaxis_inverted():
        ax.invert_yaxis()

    # The default xscale, yscale needs to be None.
    # If we set a scale it resets the axes formatters,
    # This means that set_xscale('linear') on a datetime axis
    # will remove the date labels. So only set the scale when explicitly
    # asked to. https://github.com/matplotlib/matplotlib/issues/8740
    if xscale is not None:
        ax.set_xscale(xscale)
    if yscale is not None:
        ax.set_yscale(yscale)

    if xticks is not None:
        ax.set_xticks(xticks)
    if yticks is not None:
        ax.set_yticks(yticks)

    if xlim is not None:
        ax.set_xlim(xlim)
    if ylim is not None:
        ax.set_ylim(ylim)


Instruction:
How would you explain what the following Python 3 function does
def _is_monotonic(coord, axis=0):
    if coord.shape[axis] < 3:
        return True
    else:
        n = coord.shape[axis]
        delta_pos = (coord.take(np.arange(1, n), axis=axis) >=
                     coord.take(np.arange(0, n - 1), axis=axis))
        delta_neg = (coord.take(np.arange(1, n), axis=axis) <=
                     coord.take(np.arange(0, n - 1), axis=axis))
        return np.all(delta_pos) or np.all(delta_neg)

Response: Return True if the given array is monotonic.


Instruction:
Explain what the following Python 3 code does
def _infer_interval_breaks(coord, axis=0, check_monotonic=False):
    coord = np.asarray(coord)

    if check_monotonic and not _is_monotonic(coord, axis=axis):
        raise ValueError("The input coordinate is not sorted in increasing "
                         "order along axis %d. This can lead to unexpected "
                         "results. Consider calling the `sortby` method on "
                         "the input DataArray. To plot data with categorical "
                         "axes, consider using the `heatmap` function from "
                         "the `seaborn` statistical plotting library." % axis)

    deltas = 0.5 * np.diff(coord, axis=axis)
    if deltas.size == 0:
        deltas = np.array(0.0)
    first = np.take(coord, [0], axis=axis) - np.take(deltas, [0], axis=axis)
    last = np.take(coord, [-1], axis=axis) + np.take(deltas, [-1], axis=axis)
    trim_last = tuple(slice(None, -1) if n == axis else slice(None)
                      for n in range(coord.ndim))
    return np.concatenate([first, coord[trim_last] + deltas, last], axis=axis)

Response: Infer the interval breaks of a given coordinate.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _process_cmap_cbar_kwargs(func, kwargs, data):

    cmap = kwargs.pop('cmap', None)
    colors = kwargs.pop('colors', None)

    cbar_kwargs = kwargs.pop('cbar_kwargs', {})
    cbar_kwargs = {} if cbar_kwargs is None else dict(cbar_kwargs)

    levels = kwargs.pop('levels', None)
    if 'contour' in func.__name__ and levels is None:
        levels = 7  # this is the matplotlib default

    # colors is mutually exclusive with cmap
    if cmap and colors:
        raise ValueError("Can't specify both cmap and colors.")

    # colors is only valid when levels is supplied or the plot is of type
    # contour or contourf
    if colors and (('contour' not in func.__name__) and (not levels)):
        raise ValueError("Can only specify colors with contour or levels")

    # we should not be getting a list of colors in cmap anymore
    # is there a better way to do this test?
    if isinstance(cmap, (list, tuple)):
        warnings.warn("Specifying a list of colors in cmap is deprecated. "
                      "Use colors keyword instead.",
                      DeprecationWarning, stacklevel=3)

    cmap_kwargs = {'plot_data': data,
                   'levels': levels,
                   'cmap': colors if colors else cmap,
                   'filled': func.__name__ != 'contour'}

    cmap_args = getfullargspec(_determine_cmap_params).args
    cmap_kwargs.update((a, kwargs[a]) for a in cmap_args if a in kwargs)
    cmap_params = _determine_cmap_params(**cmap_kwargs)

    return cmap_params, cbar_kwargs

Response: Process kwargs that need to be parsed from kwargs and return cmap_params cbar_kwargs


Instruction:
How would you implement a function in Python 3 that
plots a DataArray using matplotlib. pyplot.

Response:
def plot(darray, row=None, col=None, col_wrap=None, ax=None, hue=None,
         rtol=0.01, subplot_kws=None, **kwargs):
    """
    Default plot of DataArray using matplotlib.pyplot.

    Calls xarray plotting function based on the dimensions of
    darray.squeeze()

    =============== ===========================
    Dimensions      Plotting function
    --------------- ---------------------------
    1               :py:func:`xarray.plot.line`
    2               :py:func:`xarray.plot.pcolormesh`
    Anything else   :py:func:`xarray.plot.hist`
    =============== ===========================

    Parameters
    ----------
    darray : DataArray
    row : string, optional
        If passed, make row faceted plots on this dimension name
    col : string, optional
        If passed, make column faceted plots on this dimension name
    hue : string, optional
        If passed, make faceted line plots with hue on this dimension name
    col_wrap : integer, optional
        Use together with ``col`` to wrap faceted plots
    ax : matplotlib axes, optional
        If None, uses the current axis. Not applicable when using facets.
    rtol : number, optional
        Relative tolerance used to determine if the indexes
        are uniformly spaced. Usually a small positive number.
    subplot_kws : dict, optional
        Dictionary of keyword arguments for matplotlib subplots. Only applies
        to FacetGrid plotting.
    **kwargs : optional
        Additional keyword arguments to matplotlib

    """
    darray = darray.squeeze()

    plot_dims = set(darray.dims)
    plot_dims.discard(row)
    plot_dims.discard(col)
    plot_dims.discard(hue)

    ndims = len(plot_dims)

    error_msg = ('Only 1d and 2d plots are supported for facets in xarray. '
                 'See the package `Seaborn` for more options.')

    if ndims in [1, 2]:
        if row or col:
            kwargs['row'] = row
            kwargs['col'] = col
            kwargs['col_wrap'] = col_wrap
            kwargs['subplot_kws'] = subplot_kws
        if ndims == 1:
            plotfunc = line
            kwargs['hue'] = hue
        elif ndims == 2:
            if hue:
                plotfunc = line
                kwargs['hue'] = hue
            else:
                plotfunc = pcolormesh
    else:
        if row or col or hue:
            raise ValueError(error_msg)
        plotfunc = hist

    kwargs['ax'] = ax

    return plotfunc(darray, **kwargs)


Instruction:
Implement a function in Python 3 to
function to plot a single line of the given DataArray index against values

Response:
def line(darray, *args, **kwargs):
    """
    Line plot of DataArray index against values

    Wraps :func:`matplotlib:matplotlib.pyplot.plot`

    Parameters
    ----------
    darray : DataArray
        Must be 1 dimensional
    figsize : tuple, optional
        A tuple (width, height) of the figure in inches.
        Mutually exclusive with ``size`` and ``ax``.
    aspect : scalar, optional
        Aspect ratio of plot, so that ``aspect * size`` gives the width in
        inches. Only used if a ``size`` is provided.
    size : scalar, optional
        If provided, create a new figure for the plot with the given size.
        Height (in inches) of each plot. See also: ``aspect``.
    ax : matplotlib axes object, optional
        Axis on which to plot this figure. By default, use the current axis.
        Mutually exclusive with ``size`` and ``figsize``.
    hue : string, optional
        Dimension or coordinate for which you want multiple lines plotted.
        If plotting against a 2D coordinate, ``hue`` must be a dimension.
    x, y : string, optional
        Dimensions or coordinates for x, y axis.
        Only one of these may be specified.
        The other coordinate plots values from the DataArray on which this
        plot method is called.
    xscale, yscale : 'linear', 'symlog', 'log', 'logit', optional
        Specifies scaling for the x- and y-axes respectively
    xticks, yticks : Specify tick locations for x- and y-axes
    xlim, ylim : Specify x- and y-axes limits
    xincrease : None, True, or False, optional
        Should the values on the x axes be increasing from left to right?
        if None, use the default for the matplotlib function.
    yincrease : None, True, or False, optional
        Should the values on the y axes be increasing from top to bottom?
        if None, use the default for the matplotlib function.
    add_legend : boolean, optional
        Add legend with y axis coordinates (2D inputs only).
    *args, **kwargs : optional
        Additional arguments to matplotlib.pyplot.plot

    """

    # Handle facetgrids first
    row = kwargs.pop('row', None)
    col = kwargs.pop('col', None)
    if row or col:
        allargs = locals().copy()
        allargs.update(allargs.pop('kwargs'))
        allargs.pop('darray')
        return _easy_facetgrid(darray, line, kind='line', **allargs)

    ndims = len(darray.dims)
    if ndims > 2:
        raise ValueError('Line plots are for 1- or 2-dimensional DataArrays. '
                         'Passed DataArray has {ndims} '
                         'dimensions'.format(ndims=ndims))

    # Ensures consistency with .plot method
    figsize = kwargs.pop('figsize', None)
    aspect = kwargs.pop('aspect', None)
    size = kwargs.pop('size', None)
    ax = kwargs.pop('ax', None)
    hue = kwargs.pop('hue', None)
    x = kwargs.pop('x', None)
    y = kwargs.pop('y', None)
    xincrease = kwargs.pop('xincrease', None)  # default needs to be None
    yincrease = kwargs.pop('yincrease', None)
    xscale = kwargs.pop('xscale', None)  # default needs to be None
    yscale = kwargs.pop('yscale', None)
    xticks = kwargs.pop('xticks', None)
    yticks = kwargs.pop('yticks', None)
    xlim = kwargs.pop('xlim', None)
    ylim = kwargs.pop('ylim', None)
    add_legend = kwargs.pop('add_legend', True)
    _labels = kwargs.pop('_labels', True)
    if args is ():
        args = kwargs.pop('args', ())

    ax = get_axis(figsize, size, aspect, ax)
    xplt, yplt, hueplt, xlabel, ylabel, huelabel = \
        _infer_line_data(darray, x, y, hue)

    # Remove pd.Intervals if contained in xplt.values.
    if _valid_other_type(xplt.values, [pd.Interval]):
        # Is it a step plot? (see matplotlib.Axes.step)
        if kwargs.get('linestyle', '').startswith('steps-'):
            xplt_val, yplt_val = _interval_to_double_bound_points(xplt.values,
                                                                  yplt.values)
            # Remove steps-* to be sure that matplotlib is not confused
            kwargs['linestyle'] = (kwargs['linestyle']
                                   .replace('steps-pre', '')
                                   .replace('steps-post', '')
                                   .replace('steps-mid', ''))
            if kwargs['linestyle'] == '':
                kwargs.pop('linestyle')
        else:
            xplt_val = _interval_to_mid_points(xplt.values)
            yplt_val = yplt.values
            xlabel += '_center'
    else:
        xplt_val = xplt.values
        yplt_val = yplt.values

    _ensure_plottable(xplt_val, yplt_val)

    primitive = ax.plot(xplt_val, yplt_val, *args, **kwargs)

    if _labels:
        if xlabel is not None:
            ax.set_xlabel(xlabel)

        if ylabel is not None:
            ax.set_ylabel(ylabel)

        ax.set_title(darray._title_for_slice())

    if darray.ndim == 2 and add_legend:
        ax.legend(handles=primitive,
                  labels=list(hueplt.values),
                  title=huelabel)

    # Rotate dates on xlabels
    # Do this without calling autofmt_xdate so that x-axes ticks
    # on other subplots (if any) are not deleted.
    # https://stackoverflow.com/questions/17430105/autofmt-xdate-deletes-x-axis-labels-of-all-subplots
    if np.issubdtype(xplt.dtype, np.datetime64):
        for xlabels in ax.get_xticklabels():
            xlabels.set_rotation(30)
            xlabels.set_ha('right')

    _update_axes(ax, xincrease, yincrease, xscale, yscale,
                 xticks, yticks, xlim, ylim)

    return primitive


Instruction:
Make a summary of the following Python 3 code
def step(darray, *args, **kwargs):
    if ('ls' in kwargs.keys()) and ('linestyle' not in kwargs.keys()):
        kwargs['linestyle'] = kwargs.pop('ls')

    where = kwargs.pop('where', 'pre')

    if where not in ('pre', 'post', 'mid'):
        raise ValueError("'where' argument to step must be "
                         "'pre', 'post' or 'mid'")

    kwargs['linestyle'] = 'steps-' + where + kwargs.get('linestyle', '')

    return line(darray, *args, **kwargs)

Response:
This function is a convenience function for plotting a single step plot of DataArray index against values
Formula


Instruction:
How would you explain what the following Python 3 function does
def hist(darray, figsize=None, size=None, aspect=None, ax=None, **kwargs):
    ax = get_axis(figsize, size, aspect, ax)

    xincrease = kwargs.pop('xincrease', None)  # default needs to be None
    yincrease = kwargs.pop('yincrease', None)
    xscale = kwargs.pop('xscale', None)  # default needs to be None
    yscale = kwargs.pop('yscale', None)
    xticks = kwargs.pop('xticks', None)
    yticks = kwargs.pop('yticks', None)
    xlim = kwargs.pop('xlim', None)
    ylim = kwargs.pop('ylim', None)

    no_nan = np.ravel(darray.values)
    no_nan = no_nan[pd.notnull(no_nan)]

    primitive = ax.hist(no_nan, **kwargs)

    ax.set_title('Histogram')
    ax.set_xlabel(label_from_attrs(darray))

    _update_axes(ax, xincrease, yincrease, xscale, yscale,
                 xticks, yticks, xlim, ylim)

    return primitive

Response: Plots a histogram of the given DataArray.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _plot2d(plotfunc):
    commondoc = """
    Parameters
    ----------
    darray : DataArray
        Must be 2 dimensional, unless creating faceted plots
    x : string, optional
        Coordinate for x axis. If None use darray.dims[1]
    y : string, optional
        Coordinate for y axis. If None use darray.dims[0]
    figsize : tuple, optional
        A tuple (width, height) of the figure in inches.
        Mutually exclusive with ``size`` and ``ax``.
    aspect : scalar, optional
        Aspect ratio of plot, so that ``aspect * size`` gives the width in
        inches. Only used if a ``size`` is provided.
    size : scalar, optional
        If provided, create a new figure for the plot with the given size.
        Height (in inches) of each plot. See also: ``aspect``.
    ax : matplotlib axes object, optional
        Axis on which to plot this figure. By default, use the current axis.
        Mutually exclusive with ``size`` and ``figsize``.
    row : string, optional
        If passed, make row faceted plots on this dimension name
    col : string, optional
        If passed, make column faceted plots on this dimension name
    col_wrap : integer, optional
        Use together with ``col`` to wrap faceted plots
    xscale, yscale : 'linear', 'symlog', 'log', 'logit', optional
        Specifies scaling for the x- and y-axes respectively
    xticks, yticks : Specify tick locations for x- and y-axes
    xlim, ylim : Specify x- and y-axes limits
    xincrease : None, True, or False, optional
        Should the values on the x axes be increasing from left to right?
        if None, use the default for the matplotlib function.
    yincrease : None, True, or False, optional
        Should the values on the y axes be increasing from top to bottom?
        if None, use the default for the matplotlib function.
    add_colorbar : Boolean, optional
        Adds colorbar to axis
    add_labels : Boolean, optional
        Use xarray metadata to label axes
    norm : ``matplotlib.colors.Normalize`` instance, optional
        If the ``norm`` has vmin or vmax specified, the corresponding kwarg
        must be None.
    vmin, vmax : floats, optional
        Values to anchor the colormap, otherwise they are inferred from the
        data and other keyword arguments. When a diverging dataset is inferred,
        setting one of these values will fix the other by symmetry around
        ``center``. Setting both values prevents use of a diverging colormap.
        If discrete levels are provided as an explicit list, both of these
        values are ignored.
    cmap : matplotlib colormap name or object, optional
        The mapping from data values to color space. If not provided, this
        will be either be ``viridis`` (if the function infers a sequential
        dataset) or ``RdBu_r`` (if the function infers a diverging dataset).
        When `Seaborn` is installed, ``cmap`` may also be a `seaborn`
        color palette. If ``cmap`` is seaborn color palette and the plot type
        is not ``contour`` or ``contourf``, ``levels`` must also be specified.
    colors : discrete colors to plot, optional
        A single color or a list of colors. If the plot type is not ``contour``
        or ``contourf``, the ``levels`` argument is required.
    center : float, optional
        The value at which to center the colormap. Passing this value implies
        use of a diverging colormap. Setting it to ``False`` prevents use of a
        diverging colormap.
    robust : bool, optional
        If True and ``vmin`` or ``vmax`` are absent, the colormap range is
        computed with 2nd and 98th percentiles instead of the extreme values.
    extend : {'neither', 'both', 'min', 'max'}, optional
        How to draw arrows extending the colorbar beyond its limits. If not
        provided, extend is inferred from vmin, vmax and the data limits.
    levels : int or list-like object, optional
        Split the colormap (cmap) into discrete color intervals. If an integer
        is provided, "nice" levels are chosen based on the data range: this can
        imply that the final number of levels is not exactly the expected one.
        Setting ``vmin`` and/or ``vmax`` with ``levels=N`` is equivalent to
        setting ``levels=np.linspace(vmin, vmax, N)``.
    infer_intervals : bool, optional
        Only applies to pcolormesh. If True, the coordinate intervals are
        passed to pcolormesh. If False, the original coordinates are used
        (this can be useful for certain map projections). The default is to
        always infer intervals, unless the mesh is irregular and plotted on
        a map projection.
    subplot_kws : dict, optional
        Dictionary of keyword arguments for matplotlib subplots. Only applies
        to FacetGrid plotting.
    cbar_ax : matplotlib Axes, optional
        Axes in which to draw the colorbar.
    cbar_kwargs : dict, optional
        Dictionary of keyword arguments to pass to the colorbar.
    **kwargs : optional
        Additional arguments to wrapped matplotlib function

    Returns
    -------
    artist :
        The same type of primitive artist that the wrapped matplotlib
        function returns
    """

    # Build on the original docstring
    plotfunc.__doc__ = '%s\n%s' % (plotfunc.__doc__, commondoc)

    @functools.wraps(plotfunc)
    def newplotfunc(darray, x=None, y=None, figsize=None, size=None,
                    aspect=None, ax=None, row=None, col=None,
                    col_wrap=None, xincrease=True, yincrease=True,
                    add_colorbar=None, add_labels=True, vmin=None, vmax=None,
                    cmap=None, center=None, robust=False, extend=None,
                    levels=None, infer_intervals=None, colors=None,
                    subplot_kws=None, cbar_ax=None, cbar_kwargs=None,
                    xscale=None, yscale=None, xticks=None, yticks=None,
                    xlim=None, ylim=None, norm=None, **kwargs):
        # All 2d plots in xarray share this function signature.
        # Method signature below should be consistent.

        # Decide on a default for the colorbar before facetgrids
        if add_colorbar is None:
            add_colorbar = plotfunc.__name__ != 'contour'
        imshow_rgb = (
            plotfunc.__name__ == 'imshow' and
            darray.ndim == (3 + (row is not None) + (col is not None)))
        if imshow_rgb:
            # Don't add a colorbar when showing an image with explicit colors
            add_colorbar = False
            # Matplotlib does not support normalising RGB data, so do it here.
            # See eg. https://github.com/matplotlib/matplotlib/pull/10220
            if robust or vmax is not None or vmin is not None:
                darray = _rescale_imshow_rgb(darray, vmin, vmax, robust)
                vmin, vmax, robust = None, None, False

        # Handle facetgrids first
        if row or col:
            allargs = locals().copy()
            allargs.pop('imshow_rgb')
            allargs.update(allargs.pop('kwargs'))
            allargs.pop('darray')
            # Need the decorated plotting function
            allargs['plotfunc'] = globals()[plotfunc.__name__]
            return _easy_facetgrid(darray, kind='dataarray', **allargs)

        plt = import_matplotlib_pyplot()

        rgb = kwargs.pop('rgb', None)
        if rgb is not None and plotfunc.__name__ != 'imshow':
            raise ValueError('The "rgb" keyword is only valid for imshow()')
        elif rgb is not None and not imshow_rgb:
            raise ValueError('The "rgb" keyword is only valid for imshow()'
                             'with a three-dimensional array (per facet)')

        xlab, ylab = _infer_xy_labels(
            darray=darray, x=x, y=y, imshow=imshow_rgb, rgb=rgb)

        # better to pass the ndarrays directly to plotting functions
        xval = darray[xlab].values
        yval = darray[ylab].values

        # check if we need to broadcast one dimension
        if xval.ndim < yval.ndim:
            xval = np.broadcast_to(xval, yval.shape)

        if yval.ndim < xval.ndim:
            yval = np.broadcast_to(yval, xval.shape)

        # May need to transpose for correct x, y labels
        # xlab may be the name of a coord, we have to check for dim names
        if imshow_rgb:
            # For RGB[A] images, matplotlib requires the color dimension
            # to be last.  In Xarray the order should be unimportant, so
            # we transpose to (y, x, color) to make this work.
            yx_dims = (ylab, xlab)
            dims = yx_dims + tuple(d for d in darray.dims if d not in yx_dims)
            if dims != darray.dims:
                darray = darray.transpose(*dims)
        elif darray[xlab].dims[-1] == darray.dims[0]:
            darray = darray.transpose()

        # Pass the data as a masked ndarray too
        zval = darray.to_masked_array(copy=False)

        # Replace pd.Intervals if contained in xval or yval.
        xplt, xlab_extra = _resolve_intervals_2dplot(xval, plotfunc.__name__)
        yplt, ylab_extra = _resolve_intervals_2dplot(yval, plotfunc.__name__)

        _ensure_plottable(xplt, yplt)

        cmap_params, cbar_kwargs = _process_cmap_cbar_kwargs(
            plotfunc, locals(), zval.data)

        if 'contour' in plotfunc.__name__:
            # extend is a keyword argument only for contour and contourf, but
            # passing it to the colorbar is sufficient for imshow and
            # pcolormesh
            kwargs['extend'] = cmap_params['extend']
            kwargs['levels'] = cmap_params['levels']
            # if colors == a single color, matplotlib draws dashed negative
            # contours. we lose this feature if we pass cmap and not colors
            if isinstance(colors, str):
                cmap_params['cmap'] = None
                kwargs['colors'] = colors

        if 'pcolormesh' == plotfunc.__name__:
            kwargs['infer_intervals'] = infer_intervals

        if 'imshow' == plotfunc.__name__ and isinstance(aspect, str):
            # forbid usage of mpl strings
            raise ValueError("plt.imshow's `aspect` kwarg is not available "
                             "in xarray")

        ax = get_axis(figsize, size, aspect, ax)
        primitive = plotfunc(xplt, yplt, zval, ax=ax, cmap=cmap_params['cmap'],
                             vmin=cmap_params['vmin'],
                             vmax=cmap_params['vmax'],
                             norm=cmap_params['norm'],
                             **kwargs)

        # Label the plot with metadata
        if add_labels:
            ax.set_xlabel(label_from_attrs(darray[xlab], xlab_extra))
            ax.set_ylabel(label_from_attrs(darray[ylab], ylab_extra))
            ax.set_title(darray._title_for_slice())

        if add_colorbar:
            if add_labels and 'label' not in cbar_kwargs:
                cbar_kwargs['label'] = label_from_attrs(darray)
            cbar = _add_colorbar(primitive, ax, cbar_ax, cbar_kwargs,
                                 cmap_params)

        elif (cbar_ax is not None or cbar_kwargs):
            # inform the user about keywords which aren't used
            raise ValueError("cbar_ax and cbar_kwargs can't be used with "
                             "add_colorbar=False.")

        # origin kwarg overrides yincrease
        if 'origin' in kwargs:
            yincrease = None

        _update_axes(ax, xincrease, yincrease, xscale, yscale,
                     xticks, yticks, xlim, ylim)

        # Rotate dates on xlabels
        # Do this without calling autofmt_xdate so that x-axes ticks
        # on other subplots (if any) are not deleted.
        # https://stackoverflow.com/questions/17430105/autofmt-xdate-deletes-x-axis-labels-of-all-subplots
        if np.issubdtype(xplt.dtype, np.datetime64):
            for xlabels in ax.get_xticklabels():
                xlabels.set_rotation(30)
                xlabels.set_ha('right')

        return primitive

    # For use as DataArray.plot.plotmethod
    @functools.wraps(newplotfunc)
    def plotmethod(_PlotMethods_obj, x=None, y=None, figsize=None, size=None,
                   aspect=None, ax=None, row=None, col=None, col_wrap=None,
                   xincrease=True, yincrease=True, add_colorbar=None,
                   add_labels=True, vmin=None, vmax=None, cmap=None,
                   colors=None, center=None, robust=False, extend=None,
                   levels=None, infer_intervals=None, subplot_kws=None,
                   cbar_ax=None, cbar_kwargs=None,
                   xscale=None, yscale=None, xticks=None, yticks=None,
                   xlim=None, ylim=None, norm=None, **kwargs):
        """
        The method should have the same signature as the function.

        This just makes the method work on Plotmethods objects,
        and passes all the other arguments straight through.
        """
        allargs = locals()
        allargs['darray'] = _PlotMethods_obj._da
        allargs.update(kwargs)
        for arg in ['_PlotMethods_obj', 'newplotfunc', 'kwargs']:
            del allargs[arg]
        return newplotfunc(**allargs)

    # Add to class _PlotMethods
    setattr(_PlotMethods, plotmethod.__name__, plotmethod)

    return newplotfunc

Response: Decorator for common 2d plotting logic


Instruction:
Write a Python 3 script for
plotting a 2D array of pixels on a matplotlib axes.

Response:
def imshow(x, y, z, ax, **kwargs):
    """
    Image plot of 2d DataArray using matplotlib.pyplot

    Wraps :func:`matplotlib:matplotlib.pyplot.imshow`

    While other plot methods require the DataArray to be strictly
    two-dimensional, ``imshow`` also accepts a 3D array where some
    dimension can be interpreted as RGB or RGBA color channels and
    allows this dimension to be specified via the kwarg ``rgb=``.

    Unlike matplotlib, Xarray can apply ``vmin`` and ``vmax`` to RGB or RGBA
    data, by applying a single scaling factor and offset to all bands.
    Passing  ``robust=True`` infers ``vmin`` and ``vmax``
    :ref:`in the usual way <robust-plotting>`.

    .. note::
        This function needs uniformly spaced coordinates to
        properly label the axes. Call DataArray.plot() to check.

    The pixels are centered on the coordinates values. Ie, if the coordinate
    value is 3.2 then the pixels for those coordinates will be centered on 3.2.
    """

    if x.ndim != 1 or y.ndim != 1:
        raise ValueError('imshow requires 1D coordinates, try using '
                         'pcolormesh or contour(f)')

    # Centering the pixels- Assumes uniform spacing
    try:
        xstep = (x[1] - x[0]) / 2.0
    except IndexError:
        # Arbitrary default value, similar to matplotlib behaviour
        xstep = .1
    try:
        ystep = (y[1] - y[0]) / 2.0
    except IndexError:
        ystep = .1
    left, right = x[0] - xstep, x[-1] + xstep
    bottom, top = y[-1] + ystep, y[0] - ystep

    defaults = {'origin': 'upper',
                'interpolation': 'nearest'}

    if not hasattr(ax, 'projection'):
        # not for cartopy geoaxes
        defaults['aspect'] = 'auto'

    # Allow user to override these defaults
    defaults.update(kwargs)

    if defaults['origin'] == 'upper':
        defaults['extent'] = [left, right, bottom, top]
    else:
        defaults['extent'] = [left, right, top, bottom]

    if z.ndim == 3:
        # matplotlib imshow uses black for missing data, but Xarray makes
        # missing data transparent.  We therefore add an alpha channel if
        # there isn't one, and set it to transparent where data is masked.
        if z.shape[-1] == 3:
            alpha = np.ma.ones(z.shape[:2] + (1,), dtype=z.dtype)
            if np.issubdtype(z.dtype, np.integer):
                alpha *= 255
            z = np.ma.concatenate((z, alpha), axis=2)
        else:
            z = z.copy()
        z[np.any(z.mask, axis=-1), -1] = 0

    primitive = ax.imshow(z, **defaults)

    return primitive


Instruction:
Explain what the following Python 3 code does
def contour(x, y, z, ax, **kwargs):
    primitive = ax.contour(x, y, z, **kwargs)
    return primitive

Response: Contour plot of 2d DataArray


Instruction:
Here you have a function in Python 3, explain what it does
def contourf(x, y, z, ax, **kwargs):
    primitive = ax.contourf(x, y, z, **kwargs)
    return primitive

Response: Wrapper around matplotlib. pyplot. contourf


Instruction:
Explain what the following Python 3 code does
def pcolormesh(x, y, z, ax, infer_intervals=None, **kwargs):

    # decide on a default for infer_intervals (GH781)
    x = np.asarray(x)
    if infer_intervals is None:
        if hasattr(ax, 'projection'):
            if len(x.shape) == 1:
                infer_intervals = True
            else:
                infer_intervals = False
        else:
            infer_intervals = True

    if (infer_intervals and
            ((np.shape(x)[0] == np.shape(z)[1]) or
             ((x.ndim > 1) and (np.shape(x)[1] == np.shape(z)[1])))):
        if len(x.shape) == 1:
            x = _infer_interval_breaks(x, check_monotonic=True)
        else:
            # we have to infer the intervals on both axes
            x = _infer_interval_breaks(x, axis=1)
            x = _infer_interval_breaks(x, axis=0)

    if (infer_intervals and
            (np.shape(y)[0] == np.shape(z)[0])):
        if len(y.shape) == 1:
            y = _infer_interval_breaks(y, check_monotonic=True)
        else:
            # we have to infer the intervals on both axes
            y = _infer_interval_breaks(y, axis=1)
            y = _infer_interval_breaks(y, axis=0)

    primitive = ax.pcolormesh(x, y, z, **kwargs)

    # by default, pcolormesh picks "round" values for bounds
    # this results in ugly looking plots with lots of surrounding whitespace
    if not hasattr(ax, 'projection') and x.ndim == 1 and y.ndim == 1:
        # not a cartopy geoaxis
        ax.set_xlim(x[0], x[-1])
        ax.set_ylim(y[0], y[-1])

    return primitive

Response: A wrapper around matplotlib. pyplot. pcolormesh that takes a 2d array x y z and returns a 2d array x y z.


Instruction:
How would you explain what the following Python 3 function does
def _get_scheduler(get=None, collection=None):
    try:
        # dask 0.18.1 and later
        from dask.base import get_scheduler
        actual_get = get_scheduler(get, collection)
    except ImportError:
        try:
            from dask.utils import effective_get
            actual_get = effective_get(get, collection)
        except ImportError:
            return None

    try:
        from dask.distributed import Client
        if isinstance(actual_get.__self__, Client):
            return 'distributed'
    except (ImportError, AttributeError):
        try:
            import dask.multiprocessing
            if actual_get == dask.multiprocessing.get:
                return 'multiprocessing'
            else:
                return 'threaded'
        except ImportError:
            return 'threaded'

Response: Determine the dask scheduler that is being used.


Instruction:
Here you have a function in Python 3, explain what it does
def acquire(lock, blocking=True):
    if blocking:
        # no arguments needed
        return lock.acquire()
    elif DistributedLock is not None and isinstance(lock, DistributedLock):
        # distributed.Lock doesn't support the blocking argument yet:
        # https://github.com/dask/distributed/pull/2412
        return lock.acquire(timeout=0)
    else:
        # "blocking" keyword argument not supported for:
        # - threading.Lock on Python 2.
        # - dask.SerializableLock with dask v1.0.0 or earlier.
        # - multiprocessing.Lock calls the argument "block" instead.
        return lock.acquire(blocking)

Response: Acquire a lock possibly in a non - blocking fashion.


Instruction:
Write a Python 3 script for
combining a sequence of locks into a single lock.

Response:
def combine_locks(locks):
    """Combine a sequence of locks into a single lock."""
    all_locks = []
    for lock in locks:
        if isinstance(lock, CombinedLock):
            all_locks.extend(lock.locks)
        elif lock is not None:
            all_locks.append(lock)

    num_locks = len(all_locks)
    if num_locks > 1:
        return CombinedLock(all_locks)
    elif num_locks == 1:
        return all_locks[0]
    else:
        return DummyLock()


Instruction:
Can you create a Python 3 function that
gets a list of dimensions to squeeze out.

Response:
def get_squeeze_dims(xarray_obj,
                     dim: Union[Hashable, Iterable[Hashable], None] = None,
                     axis: Union[int, Iterable[int], None] = None
                     ) -> List[Hashable]:
    """Get a list of dimensions to squeeze out.
    """
    if dim is not None and axis is not None:
        raise ValueError('cannot use both parameters `axis` and `dim`')
    if dim is None and axis is None:
        return [d for d, s in xarray_obj.sizes.items() if s == 1]

    if isinstance(dim, Iterable) and not isinstance(dim, str):
        dim = list(dim)
    elif dim is not None:
        dim = [dim]
    else:
        assert axis is not None
        if isinstance(axis, int):
            axis = [axis]
        axis = list(axis)
        if any(not isinstance(a, int) for a in axis):
            raise TypeError(
                'parameter `axis` must be int or iterable of int.')
        alldims = list(xarray_obj.sizes.keys())
        dim = [alldims[a] for a in axis]

    if any(xarray_obj.sizes[k] > 1 for k in dim):
        raise ValueError('cannot select a dimension to squeeze out '
                         'which has length greater than one')
    return dim


Instruction:
Can you tell what is the following Python 3 function doing
def full_like(other, fill_value, dtype: Union[str, np.dtype, None] = None):
    from .dataarray import DataArray
    from .dataset import Dataset
    from .variable import Variable

    if isinstance(other, Dataset):
        data_vars = OrderedDict(
            (k, _full_like_variable(v, fill_value, dtype))
            for k, v in other.data_vars.items())
        return Dataset(data_vars, coords=other.coords, attrs=other.attrs)
    elif isinstance(other, DataArray):
        return DataArray(
            _full_like_variable(other.variable, fill_value, dtype),
            dims=other.dims, coords=other.coords, attrs=other.attrs,
            name=other.name)
    elif isinstance(other, Variable):
        return _full_like_variable(other, fill_value, dtype)
    else:
        raise TypeError("Expected DataArray, Dataset, or Variable")

Response: Return a new object with the same shape and type as a given object.


Instruction:
Write a Python 3 function that can
check if a dtype is a subclass of the numpy datetime types

Response:
def is_np_datetime_like(dtype: Union[str, np.dtype]) -> bool:
    """Check if a dtype is a subclass of the numpy datetime types
    """
    return (np.issubdtype(dtype, np.datetime64) or
            np.issubdtype(dtype, np.timedelta64))


Instruction:
How would you explain what the following Python 3 function does
def _contains_cftime_datetimes(array) -> bool:
    try:
        from cftime import datetime as cftime_datetime
    except ImportError:
        return False
    else:
        if array.dtype == np.dtype('O') and array.size > 0:
            sample = array.ravel()[0]
            if isinstance(sample, dask_array_type):
                sample = sample.compute()
                if isinstance(sample, np.ndarray):
                    sample = sample.item()
            return isinstance(sample, cftime_datetime)
        else:
            return False

Response:
Check if an array contains cftime. datetime objects
Invitements


Instruction:
Here you have a function in Python 3, explain what it does
def get_axis_num(self, dim: Union[Hashable, Iterable[Hashable]]
                     ) -> Union[int, Tuple[int, ...]]:
        """Return axis number(s) corresponding to dimension(s) in this array.

        Parameters
        ----------
        dim : str or iterable of str
            Dimension name(s) for which to lookup axes.

        Returns
        -------
        int or tuple of int
            Axis number or numbers corresponding to the given dimensions.
        """
        if isinstance(dim, Iterable) and not isinstance(dim, str):
            return tuple(self._get_axis_num(d) for d in dim)
        else:
            return self._get_axis_num(dim)

Response: Returns the axis number or tuple corresponding to the given dimension.


Instruction:
Make a summary of the following Python 3 code
def sizes(self: Any) -> Mapping[Hashable, int]:
        return Frozen(OrderedDict(zip(self.dims, self.shape)))

Response: Ordered mapping from dimension names to lengths.


Instruction:
Can you create a Python 3 function that
provides method for the key - autocompletions in IPython.

Response:
def _ipython_key_completions_(self) -> List[str]:
        """Provide method for the key-autocompletions in IPython.
        See http://ipython.readthedocs.io/en/stable/config/integrating.html#tab-completion
        For the details.
        """  # noqa
        item_lists = [item
                      for sublist in self._item_sources
                      for item in sublist
                      if isinstance(item, str)]
        return list(set(item_lists))


Instruction:
Write a Python 3 script to
return a new object with squeezed data.

Response:
def squeeze(self, dim: Union[Hashable, Iterable[Hashable], None] = None,
                drop: bool = False,
                axis: Union[int, Iterable[int], None] = None):
        """Return a new object with squeezed data.

        Parameters
        ----------
        dim : None or Hashable or iterable of Hashable, 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.
        drop : bool, optional
            If ``drop=True``, drop squeezed coordinates instead of making them
            scalar.
        axis : None or int or iterable of int, optional
            Like dim, but positional.

        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 = get_squeeze_dims(self, dim, axis)
        return self.isel(drop=drop, **{d: 0 for d in dims})


Instruction:
How would you explain what the following Python 3 function does
def get_index(self, key: Hashable) -> pd.Index:
        if key not in self.dims:
            raise KeyError(key)

        try:
            return self.indexes[key]
        except KeyError:
            # need to ensure dtype=int64 in case range is empty on Python 2
            return pd.Index(range(self.sizes[key]), name=key, dtype=np.int64)

Response: Get an index for a dimension with fall - back to a default RangeIndex


Instruction:
Can you implement a function in Python 3 that
assigns new coordinates to the current object.

Response:
def assign_coords(self, **kwargs):
        """Assign new coordinates to this object.

        Returns a new object with all the original data in addition to the new
        coordinates.

        Parameters
        ----------
        kwargs : keyword, value pairs
            keywords are the variables names. If the values are callable, they
            are computed on this object and assigned to new coordinate
            variables. If the values are not callable, (e.g. a DataArray,
            scalar, or array), they are simply assigned.

        Returns
        -------
        assigned : same type as caller
            A new object with the new coordinates in addition to the existing
            data.

        Examples
        --------

        Convert longitude coordinates from 0-359 to -180-179:

        >>> da = xr.DataArray(np.random.rand(4),
        ...                   coords=[np.array([358, 359, 0, 1])],
        ...                   dims='lon')
        >>> da
        <xarray.DataArray (lon: 4)>
        array([0.28298 , 0.667347, 0.657938, 0.177683])
        Coordinates:
          * lon      (lon) int64 358 359 0 1
        >>> da.assign_coords(lon=(((da.lon + 180) % 360) - 180))
        <xarray.DataArray (lon: 4)>
        array([0.28298 , 0.667347, 0.657938, 0.177683])
        Coordinates:
          * lon      (lon) int64 -2 -1 0 1

        Notes
        -----
        Since ``kwargs`` is a dictionary, the order of your arguments may not
        be preserved, and so the order of the new variables is not well
        defined. Assigning multiple variables within the same ``assign_coords``
        is possible, but you cannot reference other variables created within
        the same ``assign_coords`` call.

        See also
        --------
        Dataset.assign
        Dataset.swap_dims
        """
        data = self.copy(deep=False)
        results = self._calc_assign_results(kwargs)
        data.coords.update(results)
        return data


Instruction:
Implement a function in Python 3 to
assign new attrs to this object.

Response:
def assign_attrs(self, *args, **kwargs):
        """Assign new attrs to this object.

        Returns a new object equivalent to self.attrs.update(*args, **kwargs).

        Parameters
        ----------
        args : positional arguments passed into ``attrs.update``.
        kwargs : keyword arguments passed into ``attrs.update``.

        Returns
        -------
        assigned : same type as caller
            A new object with the new attrs in addition to the existing data.

        See also
        --------
        Dataset.assign
        """
        out = self.copy(deep=False)
        out.attrs.update(*args, **kwargs)
        return out


Instruction:
How would you code a function in Python 3 to
apply func(self, *args, **kwargs) This method replicates the pandas method of the same name. Parameters ---------- func : function function to apply to this xarray object (Dataset/DataArray). ``args``, and ``kwargs`` are passed into ``func``. Alternatively a ``(callable, data_keyword)`` tuple where ``data_keyword`` is a string indicating the keyword of ``callable`` that expects the xarray object. args : positional arguments passed into ``func``. kwargs : a dictionary of keyword arguments passed into ``func``. Returns ------- object : the return type of ``func``. Notes ----- Use ``.pipe`` when chaining together functions that expect xarray or pandas objects, e.g., instead of writing >>> f(g(h(ds), arg1=a), arg2=b, arg3=c) You can write >>> (ds.pipe(h) ... .pipe(g, arg1=a) ... .pipe(f, arg2=b, arg3=c) ... ) If you have a function that takes the data as (say) the second argument, pass a tuple indicating which keyword expects the data. For example, suppose ``f`` takes its data as ``arg2``: >>> (ds.pipe(h) ... .pipe(g, arg1=a) ... .pipe((f, 'arg2'), arg1=a, arg3=c) ... ) See Also -------- pandas.DataFrame.pipe

Response:
def pipe(self, func: Union[Callable[..., T], Tuple[Callable[..., T], str]],
             *args, **kwargs) -> T:
        """
        Apply func(self, *args, **kwargs)

        This method replicates the pandas method of the same name.

        Parameters
        ----------
        func : function
            function to apply to this xarray object (Dataset/DataArray).
            ``args``, and ``kwargs`` are passed into ``func``.
            Alternatively a ``(callable, data_keyword)`` tuple where
            ``data_keyword`` is a string indicating the keyword of
            ``callable`` that expects the xarray object.
        args : positional arguments passed into ``func``.
        kwargs : a dictionary of keyword arguments passed into ``func``.

        Returns
        -------
        object : the return type of ``func``.

        Notes
        -----

        Use ``.pipe`` when chaining together functions that expect
        xarray or pandas objects, e.g., instead of writing

        >>> f(g(h(ds), arg1=a), arg2=b, arg3=c)

        You can write

        >>> (ds.pipe(h)
        ...    .pipe(g, arg1=a)
        ...    .pipe(f, arg2=b, arg3=c)
        ... )

        If you have a function that takes the data as (say) the second
        argument, pass a tuple indicating which keyword expects the
        data. For example, suppose ``f`` takes its data as ``arg2``:

        >>> (ds.pipe(h)
        ...    .pipe(g, arg1=a)
        ...    .pipe((f, 'arg2'), arg1=a, arg3=c)
        ...  )

        See Also
        --------
        pandas.DataFrame.pipe
        """
        if isinstance(func, tuple):
            func, target = func
            if target in kwargs:
                raise ValueError('%s is both the pipe target and a keyword '
                                 'argument' % target)
            kwargs[target] = self
            return func(*args, **kwargs)
        else:
            return func(self, *args, **kwargs)


Instruction:
How would you explain what the following Python 3 function does
def groupby(self, group, squeeze: bool = True):
        return self._groupby_cls(self, group, squeeze=squeeze)

Response:
Returns a GroupBy object for performing grouped operations on the a
            array.


Instruction:
Explain what the following Python 3 code does
def groupby_bins(self, group, bins, right: bool = True, labels=None,
                     precision: int = 3, include_lowest: bool = False,
                     squeeze: bool = True):
        """Returns a GroupBy object for performing grouped operations.

        Rather than using all unique values of `group`, the values are discretized
        first by applying `pandas.cut` [1]_ to `group`.

        Parameters
        ----------
        group : str, DataArray or IndexVariable
            Array whose binned values should be used to group this array. If a
            string, must be the name of a variable contained in this dataset.
        bins : int or array of scalars
            If bins is an int, it defines the number of equal-width bins in the
            range of x. However, in this case, the range of x is extended by .1%
            on each side to include the min or max values of x. If bins is a
            sequence it defines the bin edges allowing for non-uniform bin
            width. No extension of the range of x is done in this case.
        right : boolean, optional
            Indicates whether the bins include the rightmost edge or not. If
            right == True (the default), then the bins [1,2,3,4] indicate
            (1,2], (2,3], (3,4].
        labels : array or boolean, default None
            Used as labels for the resulting bins. Must be of the same length as
            the resulting bins. If False, string bin labels are assigned by
            `pandas.cut`.
        precision : int
            The precision at which to store and display the bins labels.
        include_lowest : bool
            Whether the first interval should be left-inclusive or not.
        squeeze : boolean, optional
            If "group" is a dimension of any arrays in this dataset, `squeeze`
            controls whether the subarrays have a dimension of length 1 along
            that dimension or if the dimension is squeezed out.

        Returns
        -------
        grouped : GroupBy
            A `GroupBy` object patterned after `pandas.GroupBy` that can be
            iterated over in the form of `(unique_value, grouped_array)` pairs.
            The name of the group has the added suffix `_bins` in order to
            distinguish it from the original variable.

        References
        ----------
        .. [1] http://pandas.pydata.org/pandas-docs/stable/generated/pandas.cut.html
        """  # noqa
        return self._groupby_cls(self, group, squeeze=squeeze, bins=bins,
                                 cut_kwargs={'right': right, 'labels': labels,
                                             'precision': precision,
                                             'include_lowest': include_lowest})

Response: Returns a GroupBy object for performing grouped operations on the avec of unique values of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the avec of the values.


Instruction:
Can you implement a function in Python 3 that
creates a rolling window object for the given date and time.

Response:
def rolling(self, dim: Optional[Mapping[Hashable, int]] = None,
                min_periods: Optional[int] = None, center: bool = False,
                **dim_kwargs: int):
        """
        Rolling window object.

        Parameters
        ----------
        dim: dict, optional
            Mapping from the dimension name to create the rolling iterator
            along (e.g. `time`) to its moving window size.
        min_periods : int, default None
            Minimum number of observations in window required to have a value
            (otherwise result is NA). The default, None, is equivalent to
            setting min_periods equal to the size of the window.
        center : boolean, default False
            Set the labels at the center of the window.
        **dim_kwargs : optional
            The keyword arguments form of ``dim``.
            One of dim or dim_kwargs must be provided.

        Returns
        -------
        Rolling object (core.rolling.DataArrayRolling for DataArray,
        core.rolling.DatasetRolling for Dataset.)

        Examples
        --------
        Create rolling seasonal average of monthly data e.g. DJF, JFM, ..., SON:

        >>> da = xr.DataArray(np.linspace(0, 11, num=12),
        ...                   coords=[pd.date_range('15/12/1999',
        ...                           periods=12, freq=pd.DateOffset(months=1))],
        ...                   dims='time')
        >>> da
        <xarray.DataArray (time: 12)>
        array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7., 8.,   9.,  10.,  11.])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-15 2000-01-15 2000-02-15 ...
        >>> da.rolling(time=3, center=True).mean()
        <xarray.DataArray (time: 12)>
        array([nan,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., nan])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-15 2000-01-15 2000-02-15 ...

        Remove the NaNs using ``dropna()``:

        >>> da.rolling(time=3, center=True).mean().dropna('time')
        <xarray.DataArray (time: 10)>
        array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
        Coordinates:
          * time     (time) datetime64[ns] 2000-01-15 2000-02-15 2000-03-15 ...

        See Also
        --------
        core.rolling.DataArrayRolling
        core.rolling.DatasetRolling
        """  # noqa
        dim = either_dict_or_kwargs(dim, dim_kwargs, 'rolling')
        return self._rolling_cls(self, dim, min_periods=min_periods,
                                 center=center)


Instruction:
Explain what the following Python 3 code does
def coarsen(self, dim: Optional[Mapping[Hashable, int]] = None,
                boundary: str = 'exact',
                side: Union[str, Mapping[Hashable, str]] = 'left',
                coord_func: str = 'mean',
                **dim_kwargs: int):
        """
        Coarsen object.

        Parameters
        ----------
        dim: dict, optional
            Mapping from the dimension name to the window size.
            dim : str
                Name of the dimension to create the rolling iterator
                along (e.g., `time`).
            window : int
                Size of the moving window.
        boundary : 'exact' | 'trim' | 'pad'
            If 'exact', a ValueError will be raised if dimension size is not a
            multiple of the window size. If 'trim', the excess entries are
            dropped. If 'pad', NA will be padded.
        side : 'left' or 'right' or mapping from dimension to 'left' or 'right'
        coord_func: function (name) that is applied to the coordintes,
            or a mapping from coordinate name to function (name).

        Returns
        -------
        Coarsen object (core.rolling.DataArrayCoarsen for DataArray,
        core.rolling.DatasetCoarsen for Dataset.)

        Examples
        --------
        Coarsen the long time series by averaging over every four days.

        >>> da = xr.DataArray(np.linspace(0, 364, num=364),
        ...                   dims='time',
        ...                   coords={'time': pd.date_range(
        ...                       '15/12/1999', periods=364)})
        >>> da
        <xarray.DataArray (time: 364)>
        array([  0.      ,   1.002755,   2.00551 , ..., 361.99449 , 362.997245,
               364.      ])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-15 1999-12-16 ... 2000-12-12
        >>>
        >>> da.coarsen(time=3, boundary='trim').mean()
        <xarray.DataArray (time: 121)>
        array([  1.002755,   4.011019,   7.019284,  ...,  358.986226,
               361.99449 ])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-16 1999-12-19 ... 2000-12-10
        >>>

        See Also
        --------
        core.rolling.DataArrayCoarsen
        core.rolling.DatasetCoarsen
        """
        dim = either_dict_or_kwargs(dim, dim_kwargs, 'coarsen')
        return self._coarsen_cls(
            self, dim, boundary=boundary, side=side,
            coord_func=coord_func)

Response: Returns a new object that coarsen the long time series.


Instruction:
How would you implement a function in Python 3 that
returns a Resample object for performing downsampling and upsampling operations.

Response:
def resample(self, indexer: Optional[Mapping[Hashable, str]] = None,
                 skipna=None, closed: Optional[str] = None,
                 label: Optional[str] = None,
                 base: int = 0, keep_attrs: Optional[bool] = None,
                 loffset=None,
                 **indexer_kwargs: str):
        """Returns a Resample object for performing resampling operations.

        Handles both downsampling and upsampling. If any intervals contain no
        values from the original object, they will be given the value ``NaN``.

        Parameters
        ----------
        indexer : {dim: freq}, optional
            Mapping from the dimension name to resample frequency.
        skipna : bool, optional
            Whether to skip missing values when aggregating in downsampling.
        closed : 'left' or 'right', optional
            Side of each interval to treat as closed.
        label : 'left or 'right', optional
            Side of each interval to use for labeling.
        base : int, optional
            For frequencies that evenly subdivide 1 day, the "origin" of the
            aggregated intervals. For example, for '24H' frequency, base could
            range from 0 through 23.
        loffset : timedelta or str, optional
            Offset used to adjust the resampled time labels. Some pandas date
            offset strings are supported.
        keep_attrs : bool, optional
            If True, the object'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.
        **indexer_kwargs : {dim: freq}
            The keyword arguments form of ``indexer``.
            One of indexer or indexer_kwargs must be provided.

        Returns
        -------
        resampled : same type as caller
            This object resampled.

        Examples
        --------
        Downsample monthly time-series data to seasonal data:

        >>> da = xr.DataArray(np.linspace(0, 11, num=12),
        ...                   coords=[pd.date_range('15/12/1999',
        ...                           periods=12, freq=pd.DateOffset(months=1))],
        ...                   dims='time')
        >>> da
        <xarray.DataArray (time: 12)>
        array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7., 8.,   9.,  10.,  11.])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-15 2000-01-15 2000-02-15 ...
        >>> da.resample(time="QS-DEC").mean()
        <xarray.DataArray (time: 4)>
        array([ 1.,  4.,  7., 10.])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-01 2000-03-01 2000-06-01 2000-09-01

        Upsample monthly time-series data to daily data:

        >>> da.resample(time='1D').interpolate('linear')
        <xarray.DataArray (time: 337)>
        array([ 0.      ,  0.032258,  0.064516, ..., 10.935484, 10.967742, 11.      ])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-15 1999-12-16 1999-12-17 ...

        Limit scope of upsampling method
        >>> da.resample(time='1D').nearest(tolerance='1D')
        <xarray.DataArray (time: 337)>
        array([ 0.,  0., nan, ..., nan, 11., 11.])
        Coordinates:
          * time     (time) datetime64[ns] 1999-12-15 1999-12-16 ... 2000-11-15

        References
        ----------

        .. [1] http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
        """  # noqa
        # TODO support non-string indexer after removing the old API.

        from .dataarray import DataArray
        from .resample import RESAMPLE_DIM
        from ..coding.cftimeindex import CFTimeIndex

        if keep_attrs is None:
            keep_attrs = _get_keep_attrs(default=False)

        # note: the second argument (now 'skipna') use to be 'dim'
        if ((skipna is not None and not isinstance(skipna, bool))
                or ('how' in indexer_kwargs and 'how' not in self.dims)
                or ('dim' in indexer_kwargs and 'dim' not in self.dims)):
            raise TypeError(
                'resample() no longer supports the `how` or '
                '`dim` arguments. Instead call methods on resample '
                "objects, e.g., data.resample(time='1D').mean()")

        indexer = either_dict_or_kwargs(indexer, indexer_kwargs, 'resample')
        if len(indexer) != 1:
            raise ValueError(
                "Resampling only supported along single dimensions."
            )
        dim, freq = next(iter(indexer.items()))

        dim_name = dim
        dim_coord = self[dim]

        if isinstance(self.indexes[dim_name], CFTimeIndex):
            from .resample_cftime import CFTimeGrouper
            grouper = CFTimeGrouper(freq, closed, label, base, loffset)
        else:
            # TODO: to_offset() call required for pandas==0.19.2
            grouper = pd.Grouper(freq=freq, closed=closed, label=label,
                                 base=base,
                                 loffset=pd.tseries.frequencies.to_offset(
                                     loffset))
        group = DataArray(dim_coord, coords=dim_coord.coords,
                          dims=dim_coord.dims, name=RESAMPLE_DIM)
        resampler = self._resample_cls(self, group=group, dim=dim_name,
                                       grouper=grouper,
                                       resample_dim=RESAMPLE_DIM)

        return resampler


Instruction:
How would you explain what the following Python 3 function does
def where(self, cond, other=dtypes.NA, drop: bool = False):
        from .alignment import align
        from .dataarray import DataArray
        from .dataset import Dataset

        if drop:
            if other is not dtypes.NA:
                raise ValueError('cannot set `other` if drop=True')

            if not isinstance(cond, (Dataset, DataArray)):
                raise TypeError("cond argument is %r but must be a %r or %r" %
                                (cond, Dataset, DataArray))

            # align so we can use integer indexing
            self, cond = align(self, cond)

            # get cond with the minimal size needed for the Dataset
            if isinstance(cond, Dataset):
                clipcond = cond.to_array().any('variable')
            else:
                clipcond = cond

            # clip the data corresponding to coordinate dims that are not used
            nonzeros = zip(clipcond.dims, np.nonzero(clipcond.values))
            indexers = {k: np.unique(v) for k, v in nonzeros}

            self = self.isel(**indexers)
            cond = cond.isel(**indexers)

        return ops.where_method(self, cond, other)

Response: Filter elements from this object according to a condition.


Instruction:
Can you write a function in Python 3 where it
closes any files linked to this object.

Response:
def close(self: Any) -> None:
        """Close any files linked to this object
        """
        if self._file_obj is not None:
            self._file_obj.close()
        self._file_obj = None


Instruction:
Make a summary of the following Python 3 code
def isin(self, test_elements):
        from .computation import apply_ufunc
        from .dataset import Dataset
        from .dataarray import DataArray
        from .variable import Variable

        if isinstance(test_elements, Dataset):
            raise TypeError(
                'isin() argument must be convertible to an array: {}'
                .format(test_elements))
        elif isinstance(test_elements, (Variable, DataArray)):
            # need to explicitly pull out data to support dask arrays as the
            # second argument
            test_elements = test_elements.data

        return apply_ufunc(
            duck_array_ops.isin,
            self,
            kwargs=dict(test_elements=test_elements),
            dask='allowed',
        )

Response: Tests each value in the array for whether it is in test elements.


Instruction:
Implement a Python 3 function for
comparing two docker versions

Response:
def compare_version(v1, v2):
    """Compare docker versions

    >>> v1 = '1.9'
    >>> v2 = '1.10'
    >>> compare_version(v1, v2)
    1
    >>> compare_version(v2, v1)
    -1
    >>> compare_version(v2, v2)
    0
    """
    s1 = StrictVersion(v1)
    s2 = StrictVersion(v2)
    if s1 == s2:
        return 0
    elif s1 > s2:
        return -1
    else:
        return 1


Instruction:
Here you have a function in Python 3, explain what it does
def datetime_to_timestamp(dt):
    delta = dt - datetime.utcfromtimestamp(0)
    return delta.seconds + delta.days * 24 * 3600

Response: Convert a UTC datetime to a Unix timestamp


Instruction:
Create a Python 3 function for
reading a line - separated environment file.

Response:
def parse_env_file(env_file):
    """
    Reads a line-separated environment file.
    The format of each line should be "key=value".
    """
    environment = {}

    with open(env_file, 'r') as f:
        for line in f:

            if line[0] == '#':
                continue

            line = line.strip()
            if not line:
                continue

            parse_line = line.split('=', 1)
            if len(parse_line) == 2:
                k, v = parse_line
                environment[k] = v
            else:
                raise errors.DockerException(
                    'Invalid line in environment file {0}:\n{1}'.format(
                        env_file, line))

    return environment


Instruction:
How would you implement a function in Python 3 that
configures a plugin. Args: name (string): The name of the plugin. The ``:latest`` tag is optional, and is the default if omitted. options (dict): A key-value mapping of options Returns: ``True`` if successful

Response:
def configure_plugin(self, name, options):
        """
            Configure a plugin.

            Args:
                name (string): The name of the plugin. The ``:latest`` tag is
                    optional, and is the default if omitted.
                options (dict): A key-value mapping of options

            Returns:
                ``True`` if successful
        """
        url = self._url('/plugins/{0}/set', name)
        data = options
        if isinstance(data, dict):
            data = ['{0}={1}'.format(k, v) for k, v in six.iteritems(data)]
        res = self._post_json(url, data=data)
        self._raise_for_status(res)
        return True


Instruction:
Write a Python 3 script for
creating a new plugin.

Response:
def create_plugin(self, name, plugin_data_dir, gzip=False):
        """
            Create a new plugin.

            Args:
                name (string): The name of the plugin. The ``:latest`` tag is
                    optional, and is the default if omitted.
                plugin_data_dir (string): Path to the plugin data directory.
                    Plugin data directory must contain the ``config.json``
                    manifest file and the ``rootfs`` directory.
                gzip (bool): Compress the context using gzip. Default: False

            Returns:
                ``True`` if successful
        """
        url = self._url('/plugins/create')

        with utils.create_archive(
            root=plugin_data_dir, gzip=gzip,
            files=set(utils.build.walk(plugin_data_dir, []))
        ) as archv:
            res = self._post(url, params={'name': name}, data=archv)
        self._raise_for_status(res)
        return True


Instruction:
Can you generate a brief explanation for the following Python 3 code
def disable_plugin(self, name):
        url = self._url('/plugins/{0}/disable', name)
        res = self._post(url)
        self._raise_for_status(res)
        return True

Response: Disable an installed plugin.


Instruction:
Can you create a Python 3 function that
enables an installed plugin.

Response:
def enable_plugin(self, name, timeout=0):
        """
            Enable an installed plugin.

            Args:
                name (string): The name of the plugin. The ``:latest`` tag is
                    optional, and is the default if omitted.
                timeout (int): Operation timeout (in seconds). Default: 0

            Returns:
                ``True`` if successful
        """
        url = self._url('/plugins/{0}/enable', name)
        params = {'timeout': timeout}
        res = self._post(url, params=params)
        self._raise_for_status(res)
        return True


Instruction:
Given the following Python 3 function, write the documentation
def inspect_plugin(self, name):
        url = self._url('/plugins/{0}/json', name)
        return self._result(self._get(url), True)

Response:
Retrieve plugin metadata.

            Args:
                name (string): The name of the plugin. The ``:latest`` tag is
                    optional, and is the default if omitted.

            Returns:
                A dict containing plugin info


Instruction:
Given the following Python 3 function, write the documentation
def plugins(self):
        url = self._url('/plugins')
        return self._result(self._get(url), True)

Response: Retrieve a list of installed plugins.


Instruction:
Create a Python 3 function to
retrieve list of privileges granted to a remote plugin.

Response:
def plugin_privileges(self, name):
        """
            Retrieve list of privileges to be granted to a plugin.

            Args:
                name (string): Name of the remote plugin to examine. The
                    ``:latest`` tag is optional, and is the default if omitted.

            Returns:
                A list of dictionaries representing the plugin's
                permissions

        """
        params = {
            'remote': name,
        }

        headers = {}
        registry, repo_name = auth.resolve_repository_name(name)
        header = auth.get_config_header(self, registry)
        if header:
            headers['X-Registry-Auth'] = header

        url = self._url('/plugins/privileges')
        return self._result(
            self._get(url, params=params, headers=headers), True
        )


Instruction:
Create a Python 3 function for
pushing a new plugin to the registry.

Response:
def push_plugin(self, name):
        """
            Push a plugin to the registry.

            Args:
                name (string): Name of the plugin to upload. The ``:latest``
                    tag is optional, and is the default if omitted.

            Returns:
                ``True`` if successful
        """
        url = self._url('/plugins/{0}/pull', name)

        headers = {}
        registry, repo_name = auth.resolve_repository_name(name)
        header = auth.get_config_header(self, registry)
        if header:
            headers['X-Registry-Auth'] = header
        res = self._post(url, headers=headers)
        self._raise_for_status(res)
        return self._stream_helper(res, decode=True)


Instruction:
Implement a function in Python 3 to
remove an installed plugin.

Response:
def remove_plugin(self, name, force=False):
        """
            Remove an installed plugin.

            Args:
                name (string): Name of the plugin to remove. The ``:latest``
                    tag is optional, and is the default if omitted.
                force (bool): Disable the plugin before removing. This may
                    result in issues if the plugin is in use by a container.

            Returns:
                ``True`` if successful
        """
        url = self._url('/plugins/{0}', name)
        res = self._delete(url, params={'force': force})
        self._raise_for_status(res)
        return True


Instruction:
How would you explain what the following Python 3 function does
def upgrade_plugin(self, name, remote, privileges):

        url = self._url('/plugins/{0}/upgrade', name)
        params = {
            'remote': remote,
        }

        headers = {}
        registry, repo_name = auth.resolve_repository_name(remote)
        header = auth.get_config_header(self, registry)
        if header:
            headers['X-Registry-Auth'] = header
        response = self._post_json(
            url, params=params, headers=headers, data=privileges,
            stream=True
        )
        self._raise_for_status(response)
        return self._stream_helper(response, decode=True)

Response: Upgrade an installed plugin.


Instruction:
Given the following Python 3 function, write the documentation
def from_env(cls, **kwargs):
        timeout = kwargs.pop('timeout', DEFAULT_TIMEOUT_SECONDS)
        version = kwargs.pop('version', None)
        return cls(
            timeout=timeout, version=version, **kwargs_from_env(**kwargs)
        )

Response: Returns a new instance of the class from environment variables.


Instruction:
Can you generate the documentation for the following Python 3 function
def close(self):

        if not self._response.raw.closed:
            # find the underlying socket object
            # based on api.client._get_raw_response_socket

            sock_fp = self._response.raw._fp.fp

            if hasattr(sock_fp, 'raw'):
                sock_raw = sock_fp.raw

                if hasattr(sock_raw, 'sock'):
                    sock = sock_raw.sock

                elif hasattr(sock_raw, '_sock'):
                    sock = sock_raw._sock

            elif hasattr(sock_fp, 'channel'):
                # We're working with a paramiko (SSH) channel, which doesn't
                # support cancelable streams with the current implementation
                raise DockerException(
                    'Cancellable streams not supported for the SSH protocol'
                )
            else:
                sock = sock_fp._sock

            if hasattr(urllib3.contrib, 'pyopenssl') and isinstance(
                    sock, urllib3.contrib.pyopenssl.WrappedSocket):
                sock = sock.socket

            sock.shutdown(socket.SHUT_RDWR)
            sock.close()

Response: Closes the event streaming.


Instruction:
How would you code a function in Python 3 to
read at most n bytes from socket returning a tuple of the n - byte integers.

Response:
def read(socket, n=4096):
    """
    Reads at most n bytes from socket
    """

    recoverable_errors = (errno.EINTR, errno.EDEADLK, errno.EWOULDBLOCK)

    if six.PY3 and not isinstance(socket, NpipeSocket):
        select.select([socket], [], [])

    try:
        if hasattr(socket, 'recv'):
            return socket.recv(n)
        if six.PY3 and isinstance(socket, getattr(pysocket, 'SocketIO')):
            return socket.read(n)
        return os.read(socket.fileno(), n)
    except EnvironmentError as e:
        if e.errno not in recoverable_errors:
            raise


Instruction:
Can you implement a function in Python 3 that
reads exactly n bytes from socket returning a binary string.

Response:
def read_exactly(socket, n):
    """
    Reads exactly n bytes from socket
    Raises SocketError if there isn't enough data
    """
    data = six.binary_type()
    while len(data) < n:
        next_data = read(socket, n - len(data))
        if not next_data:
            raise SocketError("Unexpected EOF")
        data += next_data
    return data


Instruction:
Can you generate the documentation for the following Python 3 function
def next_frame_header(socket):
    try:
        data = read_exactly(socket, 8)
    except SocketError:
        return (-1, -1)

    stream, actual = struct.unpack('>BxxxL', data)
    return (stream, actual)

Response: Reads the next frame of data from the socket and returns the stream and size of the next frame.


Instruction:
How would you explain what the following Python 3 function does
def frames_iter(socket, tty):
    if tty:
        return ((STDOUT, frame) for frame in frames_iter_tty(socket))
    else:
        return frames_iter_no_tty(socket)

Response: Return an iterator of frames read from socket.


Instruction:
Here you have a function in Python 3, explain what it does
def frames_iter_no_tty(socket):
    while True:
        (stream, n) = next_frame_header(socket)
        if n < 0:
            break
        while n > 0:
            result = read(socket, n)
            if result is None:
                continue
            data_length = len(result)
            if data_length == 0:
                # We have reached EOF
                return
            n -= data_length
            yield (stream, result)

Response:
Returns a generator of data read from the socket when tty setting is
    is not enabled.


Instruction:
Implement a Python 3 function for
iterating through frames read from the socket and return the result. Args: demux (bool): If False, stdout and stderr are multiplexed, and the result is the concatenation of all the frames. If True, the streams are demultiplexed, and the result is a 2-tuple where each item is the concatenation of frames belonging to the same stream.

Response:
def consume_socket_output(frames, demux=False):
    """
    Iterate through frames read from the socket and return the result.

    Args:

        demux (bool):
            If False, stdout and stderr are multiplexed, and the result is the
            concatenation of all the frames. If True, the streams are
            demultiplexed, and the result is a 2-tuple where each item is the
            concatenation of frames belonging to the same stream.
    """
    if demux is False:
        # If the streams are multiplexed, the generator returns strings, that
        # we just need to concatenate.
        return six.binary_type().join(frames)

    # If the streams are demultiplexed, the generator yields tuples
    # (stdout, stderr)
    out = [None, None]
    for frame in frames:
        # It is guaranteed that for each frame, one and only one stream
        # is not None.
        assert frame != (None, None)
        if frame[0] is not None:
            if out[0] is None:
                out[0] = frame[0]
            else:
                out[0] += frame[0]
        else:
            if out[1] is None:
                out[1] = frame[1]
            else:
                out[1] += frame[1]
    return tuple(out)


Instruction:
Write a Python 3 function for
building a new instance of a new node.

Response:
def build(self, path=None, tag=None, quiet=False, fileobj=None,
              nocache=False, rm=False, timeout=None,
              custom_context=False, encoding=None, pull=False,
              forcerm=False, dockerfile=None, container_limits=None,
              decode=False, buildargs=None, gzip=False, shmsize=None,
              labels=None, cache_from=None, target=None, network_mode=None,
              squash=None, extra_hosts=None, platform=None, isolation=None,
              use_config_proxy=False):
        """
        Similar to the ``docker build`` command. Either ``path`` or ``fileobj``
        needs to be set. ``path`` can be a local path (to a directory
        containing a Dockerfile) or a remote URL. ``fileobj`` must be a
        readable file-like object to a Dockerfile.

        If you have a tar file for the Docker build context (including a
        Dockerfile) already, pass a readable file-like object to ``fileobj``
        and also pass ``custom_context=True``. If the stream is compressed
        also, set ``encoding`` to the correct value (e.g ``gzip``).

        Example:
            >>> from io import BytesIO
            >>> from docker import APIClient
            >>> dockerfile = '''
            ... # Shared Volume
            ... FROM busybox:buildroot-2014.02
            ... VOLUME /data
            ... CMD ["/bin/sh"]
            ... '''
            >>> f = BytesIO(dockerfile.encode('utf-8'))
            >>> cli = APIClient(base_url='tcp://127.0.0.1:2375')
            >>> response = [line for line in cli.build(
            ...     fileobj=f, rm=True, tag='yourname/volume'
            ... )]
            >>> response
            ['{"stream":" ---\\u003e a9eb17255234\\n"}',
             '{"stream":"Step 1 : VOLUME /data\\n"}',
             '{"stream":" ---\\u003e Running in abdc1e6896c6\\n"}',
             '{"stream":" ---\\u003e 713bca62012e\\n"}',
             '{"stream":"Removing intermediate container abdc1e6896c6\\n"}',
             '{"stream":"Step 2 : CMD [\\"/bin/sh\\"]\\n"}',
             '{"stream":" ---\\u003e Running in dba30f2a1a7e\\n"}',
             '{"stream":" ---\\u003e 032b8b2855fc\\n"}',
             '{"stream":"Removing intermediate container dba30f2a1a7e\\n"}',
             '{"stream":"Successfully built 032b8b2855fc\\n"}']

        Args:
            path (str): Path to the directory containing the Dockerfile
            fileobj: A file object to use as the Dockerfile. (Or a file-like
                object)
            tag (str): A tag to add to the final image
            quiet (bool): Whether to return the status
            nocache (bool): Don't use the cache when set to ``True``
            rm (bool): Remove intermediate containers. The ``docker build``
                command now defaults to ``--rm=true``, but we have kept the old
                default of `False` to preserve backward compatibility
            timeout (int): HTTP timeout
            custom_context (bool): Optional if using ``fileobj``
            encoding (str): The encoding for a stream. Set to ``gzip`` for
                compressing
            pull (bool): Downloads any updates to the FROM image in Dockerfiles
            forcerm (bool): Always remove intermediate containers, even after
                unsuccessful builds
            dockerfile (str): path within the build context to the Dockerfile
            buildargs (dict): A dictionary of build arguments
            container_limits (dict): A dictionary of limits applied to each
                container created by the build process. Valid keys:

                - memory (int): set memory limit for build
                - memswap (int): Total memory (memory + swap), -1 to disable
                    swap
                - cpushares (int): CPU shares (relative weight)
                - cpusetcpus (str): CPUs in which to allow execution, e.g.,
                    ``"0-3"``, ``"0,1"``
            decode (bool): If set to ``True``, the returned stream will be
                decoded into dicts on the fly. Default ``False``
            shmsize (int): Size of `/dev/shm` in bytes. The size must be
                greater than 0. If omitted the system uses 64MB
            labels (dict): A dictionary of labels to set on the image
            cache_from (:py:class:`list`): A list of images used for build
                cache resolution
            target (str): Name of the build-stage to build in a multi-stage
                Dockerfile
            network_mode (str): networking mode for the run commands during
                build
            squash (bool): Squash the resulting images layers into a
                single layer.
            extra_hosts (dict): Extra hosts to add to /etc/hosts in building
                containers, as a mapping of hostname to IP address.
            platform (str): Platform in the format ``os[/arch[/variant]]``
            isolation (str): Isolation technology used during build.
                Default: `None`.
            use_config_proxy (bool): If ``True``, and if the docker client
                configuration file (``~/.docker/config.json`` by default)
                contains a proxy configuration, the corresponding environment
                variables will be set in the container being built.

        Returns:
            A generator for the build output.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
            ``TypeError``
                If neither ``path`` nor ``fileobj`` is specified.
        """
        remote = context = None
        headers = {}
        container_limits = container_limits or {}
        buildargs = buildargs or {}
        if path is None and fileobj is None:
            raise TypeError("Either path or fileobj needs to be provided.")
        if gzip and encoding is not None:
            raise errors.DockerException(
                'Can not use custom encoding if gzip is enabled'
            )

        for key in container_limits.keys():
            if key not in constants.CONTAINER_LIMITS_KEYS:
                raise errors.DockerException(
                    'Invalid container_limits key {0}'.format(key)
                )

        if custom_context:
            if not fileobj:
                raise TypeError("You must specify fileobj with custom_context")
            context = fileobj
        elif fileobj is not None:
            context = utils.mkbuildcontext(fileobj)
        elif path.startswith(('http://', 'https://',
                              'git://', 'github.com/', 'git@')):
            remote = path
        elif not os.path.isdir(path):
            raise TypeError("You must specify a directory to build in path")
        else:
            dockerignore = os.path.join(path, '.dockerignore')
            exclude = None
            if os.path.exists(dockerignore):
                with open(dockerignore, 'r') as f:
                    exclude = list(filter(
                        lambda x: x != '' and x[0] != '#',
                        [l.strip() for l in f.read().splitlines()]
                    ))
            dockerfile = process_dockerfile(dockerfile, path)
            context = utils.tar(
                path, exclude=exclude, dockerfile=dockerfile, gzip=gzip
            )
            encoding = 'gzip' if gzip else encoding

        u = self._url('/build')
        params = {
            't': tag,
            'remote': remote,
            'q': quiet,
            'nocache': nocache,
            'rm': rm,
            'forcerm': forcerm,
            'pull': pull,
            'dockerfile': dockerfile,
        }
        params.update(container_limits)

        if use_config_proxy:
            proxy_args = self._proxy_configs.get_environment()
            for k, v in proxy_args.items():
                buildargs.setdefault(k, v)
        if buildargs:
            params.update({'buildargs': json.dumps(buildargs)})

        if shmsize:
            if utils.version_gte(self._version, '1.22'):
                params.update({'shmsize': shmsize})
            else:
                raise errors.InvalidVersion(
                    'shmsize was only introduced in API version 1.22'
                )

        if labels:
            if utils.version_gte(self._version, '1.23'):
                params.update({'labels': json.dumps(labels)})
            else:
                raise errors.InvalidVersion(
                    'labels was only introduced in API version 1.23'
                )

        if cache_from:
            if utils.version_gte(self._version, '1.25'):
                params.update({'cachefrom': json.dumps(cache_from)})
            else:
                raise errors.InvalidVersion(
                    'cache_from was only introduced in API version 1.25'
                )

        if target:
            if utils.version_gte(self._version, '1.29'):
                params.update({'target': target})
            else:
                raise errors.InvalidVersion(
                    'target was only introduced in API version 1.29'
                )

        if network_mode:
            if utils.version_gte(self._version, '1.25'):
                params.update({'networkmode': network_mode})
            else:
                raise errors.InvalidVersion(
                    'network_mode was only introduced in API version 1.25'
                )

        if squash:
            if utils.version_gte(self._version, '1.25'):
                params.update({'squash': squash})
            else:
                raise errors.InvalidVersion(
                    'squash was only introduced in API version 1.25'
                )

        if extra_hosts is not None:
            if utils.version_lt(self._version, '1.27'):
                raise errors.InvalidVersion(
                    'extra_hosts was only introduced in API version 1.27'
                )

            if isinstance(extra_hosts, dict):
                extra_hosts = utils.format_extra_hosts(extra_hosts)
            params.update({'extrahosts': extra_hosts})

        if platform is not None:
            if utils.version_lt(self._version, '1.32'):
                raise errors.InvalidVersion(
                    'platform was only introduced in API version 1.32'
                )
            params['platform'] = platform

        if isolation is not None:
            if utils.version_lt(self._version, '1.24'):
                raise errors.InvalidVersion(
                    'isolation was only introduced in API version 1.24'
                )
            params['isolation'] = isolation

        if context is not None:
            headers = {'Content-Type': 'application/tar'}
            if encoding:
                headers['Content-Encoding'] = encoding

        self._set_auth_headers(headers)

        response = self._post(
            u,
            data=context,
            params=params,
            headers=headers,
            stream=True,
            timeout=timeout,
        )

        if context is not None and not custom_context:
            context.close()

        return self._stream_helper(response, decode=decode)


Instruction:
Can you write a function in Python 3 where it
deletes the builder cache

Response:
def prune_builds(self):
        """
        Delete the builder cache

        Returns:
            (dict): A dictionary containing information about the operation's
                    result. The ``SpaceReclaimed`` key indicates the amount of
                    bytes of disk space reclaimed.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        """
        url = self._url("/build/prune")
        return self._result(self._post(url), True)


Instruction:
Explain what the following Python 3 code does
def create_swarm_spec(self, *args, **kwargs):
        ext_ca = kwargs.pop('external_ca', None)
        if ext_ca:
            kwargs['external_cas'] = [ext_ca]
        return types.SwarmSpec(self._version, *args, **kwargs)

Response: Creates a SwarmSpec instance that can be used as the swarm_spec argument.