Instruction:
Can you tell what is the following Python 3 function doing
def eq(a, b):
    if a is b:
        return True
    if a is None or b is None:
        return True if a is None and b is None else False

    try:
        e = a == b
    except ValueError:
        return False
    except AttributeError:
        return False
    except Exception:
        print("a:", str(type(a)), str(a))
        print("b:", str(type(b)), str(b))
        raise
    t = type(e)
    if t is bool:
        return e
    elif t is bool_:
        return bool(e)
    elif isinstance(e, ndarray):
        try:
            # disaster: if a is empty and b is not, then e.all() is True
            if a.shape != b.shape:
                return False
        except Exception:
            return False
        if (hasattr(e, 'implements') and e.implements('MetaArray')):
            return e.asarray().all()
        else:
            return e.all()
    else:
        raise Exception("== operator returned type %s" % str(type(e)))

Response: Guaranteed equality function for the two objects a and b.


Instruction:
Here you have a function in Python 3, explain what it does
def zoom(self, factor, center=None):
        assert len(center) in (2, 3, 4)
        # Get scale factor, take scale ratio into account
        if np.isscalar(factor):
            scale = [factor, factor]
        else:
            if len(factor) != 2:
                raise TypeError("factor must be scalar or length-2 sequence.")
            scale = list(factor)
        if self.aspect is not None:
            scale[0] = scale[1]

        # Init some variables
        center = center if (center is not None) else self.center
        # Make a new object (copy), so that allocation will
        # trigger view_changed:
        rect = Rect(self.rect)
        # Get space from given center to edges
        left_space = center[0] - rect.left
        right_space = rect.right - center[0]
        bottom_space = center[1] - rect.bottom
        top_space = rect.top - center[1]
        # Scale these spaces
        rect.left = center[0] - left_space * scale[0]
        rect.right = center[0] + right_space * scale[0]
        rect.bottom = center[1] - bottom_space * scale[1]
        rect.top = center[1] + top_space * scale[1]
        self.rect = rect

Response: Zooms the current state of the object at the given center.


Instruction:
Given the following Python 3 function, write the documentation
def pan(self, *pan):
        if len(pan) == 1:
            pan = pan[0]
        self.rect = self.rect + pan

Response:
Pan the view.

        Parameters
        ----------
        *pan : length-2 sequence
            The distance to pan the view, in the coordinate system of the
            scene.


Instruction:
Implement a function in Python 3 to
handle a mouse event and updates the transform accordingly.

Response:
def viewbox_mouse_event(self, event):
        """
        The SubScene received a mouse event; update transform
        accordingly.

        Parameters
        ----------
        event : instance of Event
            The event.
        """
        if event.handled or not self.interactive:
            return

        # Scrolling
        BaseCamera.viewbox_mouse_event(self, event)

        if event.type == 'mouse_wheel':
            center = self._scene_transform.imap(event.pos)
            self.zoom((1 + self.zoom_factor) ** (-event.delta[1] * 30), center)
            event.handled = True

        elif event.type == 'mouse_move':
            if event.press_event is None:
                return

            modifiers = event.mouse_event.modifiers
            p1 = event.mouse_event.press_event.pos
            p2 = event.mouse_event.pos

            if 1 in event.buttons and not modifiers:
                # Translate
                p1 = np.array(event.last_event.pos)[:2]
                p2 = np.array(event.pos)[:2]
                p1s = self._transform.imap(p1)
                p2s = self._transform.imap(p2)
                self.pan(p1s-p2s)
                event.handled = True
            elif 2 in event.buttons and not modifiers:
                # Zoom
                p1c = np.array(event.last_event.pos)[:2]
                p2c = np.array(event.pos)[:2]
                scale = ((1 + self.zoom_factor) **
                         ((p1c-p2c) * np.array([1, -1])))
                center = self._transform.imap(event.press_event.pos[:2])
                self.zoom(scale, center)
                event.handled = True
            else:
                event.handled = False
        elif event.type == 'mouse_press':
            # accept the event if it is button 1 or 2.
            # This is required in order to receive future events
            event.handled = event.button in [1, 2]
        else:
            event.handled = False


Instruction:
Write a Python 3 script to
set the data for the current object.

Response:
def set_data(self, vol, clim=None):
        """ Set the volume data.

        Parameters
        ----------
        vol : ndarray
            The 3D volume.
        clim : tuple | None
            Colormap limits to use. None will use the min and max values.
        """
        # Check volume
        if not isinstance(vol, np.ndarray):
            raise ValueError('Volume visual needs a numpy array.')
        if not ((vol.ndim == 3) or (vol.ndim == 4 and vol.shape[-1] <= 4)):
            raise ValueError('Volume visual needs a 3D image.')

        # Handle clim
        if clim is not None:
            clim = np.array(clim, float)
            if not (clim.ndim == 1 and clim.size == 2):
                raise ValueError('clim must be a 2-element array-like')
            self._clim = tuple(clim)
        if self._clim is None:
            self._clim = vol.min(), vol.max()

        # Apply clim
        vol = np.array(vol, dtype='float32', copy=False)
        if self._clim[1] == self._clim[0]:
            if self._clim[0] != 0.:
                vol *= 1.0 / self._clim[0]
        else:
            vol -= self._clim[0]
            vol /= self._clim[1] - self._clim[0]

        # Apply to texture
        self._tex.set_data(vol)  # will be efficient if vol is same shape
        self.shared_program['u_shape'] = (vol.shape[2], vol.shape[1],
                                          vol.shape[0])

        shape = vol.shape[:3]
        if self._vol_shape != shape:
            self._vol_shape = shape
            self._need_vertex_update = True
        self._vol_shape = shape

        # Get some stats
        self._kb_for_texture = np.prod(self._vol_shape) / 1024


Instruction:
Can you create a Python 3 function that
creates and set the vertex data for the current entry in the internal buffer.

Response:
def _create_vertex_data(self):
        """ Create and set positions and texture coords from the given shape

        We have six faces with 1 quad (2 triangles) each, resulting in
        6*2*3 = 36 vertices in total.
        """
        shape = self._vol_shape

        # Get corner coordinates. The -0.5 offset is to center
        # pixels/voxels. This works correctly for anisotropic data.
        x0, x1 = -0.5, shape[2] - 0.5
        y0, y1 = -0.5, shape[1] - 0.5
        z0, z1 = -0.5, shape[0] - 0.5

        pos = np.array([
            [x0, y0, z0],
            [x1, y0, z0],
            [x0, y1, z0],
            [x1, y1, z0],
            [x0, y0, z1],
            [x1, y0, z1],
            [x0, y1, z1],
            [x1, y1, z1],
        ], dtype=np.float32)

        """
          6-------7
         /|      /|
        4-------5 |
        | |     | |
        | 2-----|-3
        |/      |/
        0-------1
        """

        # Order is chosen such that normals face outward; front faces will be
        # culled.
        indices = np.array([2, 6, 0, 4, 5, 6, 7, 2, 3, 0, 1, 5, 3, 7],
                           dtype=np.uint32)

        # Apply
        self._vertices.set_data(pos)
        self._index_buffer.set_data(indices)


Instruction:
Write a Python 3 function that can
set the data for the current object.

Response:
def set_data(self, pos=None, color=None):
        """Set the data

        Parameters
        ----------
        pos : list, tuple or numpy array
            Bounds of the region along the axis. len(pos) must be >=2.
        color : list, tuple, or array
            The color to use when drawing the line. It must have a shape of
            (1, 4) for a single color region or (len(pos), 4) for a multicolor
            region.
        """
        new_pos = self._pos
        new_color = self._color

        if pos is not None:
            num_elements = len(pos)
            pos = np.array(pos, dtype=np.float32)
            if pos.ndim != 1:
                raise ValueError('Expected 1D array')
            vertex = np.empty((num_elements * 2, 2), dtype=np.float32)
            if self._is_vertical:
                vertex[:, 0] = np.repeat(pos, 2)
                vertex[:, 1] = np.tile([-1, 1], num_elements)
            else:
                vertex[:, 1] = np.repeat(pos, 2)
                vertex[:, 0] = np.tile([1, -1], num_elements)
            new_pos = vertex
            self._changed['pos'] = True

        if color is not None:
            color = np.array(color, dtype=np.float32)
            num_elements = new_pos.shape[0] / 2
            if color.ndim == 2:
                if color.shape[0] != num_elements:
                    raise ValueError('Expected a color for each pos')
                if color.shape[1] != 4:
                    raise ValueError('Each color must be a RGBA array')
                color = np.repeat(color, 2, axis=0).astype(np.float32)
            elif color.ndim == 1:
                if color.shape[0] != 4:
                    raise ValueError('Each color must be a RGBA array')
                color = np.repeat([color], new_pos.shape[0], axis=0)
                color = color.astype(np.float32)
            else:
                raise ValueError('Expected a numpy array of shape '
                                 '(%d, 4) or (1, 4)' % num_elements)
            new_color = color
            self._changed['color'] = True

        # Ensure pos and color have the same size
        if new_pos.shape[0] != new_color.shape[0]:
            raise ValueError('pos and color does must have the same size')

        self._color = new_color
        self._pos = new_pos


Instruction:
Write a Python 3 function that can
merge overlapping intervals. This method is called only once in the constructor.

Response:
def _merge_intervals(self, min_depth):
        """
        Merge overlapping intervals.

        This method is called only once in the constructor.
        """
        def add_interval(ret, start, stop):
            if min_depth is not None:
                shift = 2 * (29 - min_depth)
                mask = (int(1) << shift) - 1

                if stop - start < mask:
                    ret.append((start, stop))
                else:
                    ofs = start & mask
                    st = start
                    if ofs > 0:
                        st = (start - ofs) + (mask + 1)
                        ret.append((start, st))

                    while st + mask + 1 < stop:
                        ret.append((st, st + mask + 1))
                        st = st + mask + 1

                    ret.append((st, stop))
            else:
                ret.append((start, stop))

        ret = []
        start = stop = None
        # Use numpy sort method
        self._intervals.sort(axis=0)
        for itv in self._intervals:
            if start is None:
                start, stop = itv
                continue

            # gap between intervals
            if itv[0] > stop:
                add_interval(ret, start, stop)
                start, stop = itv
            else:
                # merge intervals
                if itv[1] > stop:
                    stop = itv[1]

        if start is not None and stop is not None:
            add_interval(ret, start, stop)

        self._intervals = np.asarray(ret)


Instruction:
Given the following Python 3 function, write the documentation
def union(self, another_is):
        result = IntervalSet()
        if another_is.empty():
            result._intervals = self._intervals
        elif self.empty():
            result._intervals = another_is._intervals
        else:
            # res has no overlapping intervals
            result._intervals = IntervalSet.merge(self._intervals,
                                                  another_is._intervals,
                                                  lambda in_a, in_b: in_a or in_b)
        return result

Response: Return the union between self and another_is.


Instruction:
Implement a Python 3 function for
converting an IntervalSet using the NESTED numbering scheme to an IntervalSet containing UNIQ numbers for HEALPix cells.

Response:
def to_nuniq_interval_set(cls, nested_is):
        """
        Convert an IntervalSet using the NESTED numbering scheme to an IntervalSet containing UNIQ numbers for HEALPix
        cells.

        Parameters
        ----------
        nested_is : `IntervalSet`
            IntervalSet object storing HEALPix cells as [ipix*4^(29-order), (ipix+1)*4^(29-order)[ intervals.

        Returns
        -------
        interval : `IntervalSet`
            IntervalSet object storing HEALPix cells as [ipix + 4*4^(order), ipix+1 + 4*4^(order)[ intervals.
        """
        r2 = nested_is.copy()
        res = []

        if r2.empty():
            return IntervalSet()

        order = 0
        while not r2.empty():
            shift = int(2 * (IntervalSet.HPY_MAX_ORDER - order))
            ofs = (int(1) << shift) - 1
            ofs2 = int(1) << (2 * order + 2)

            r4 = []
            for iv in r2._intervals:
                a = (int(iv[0]) + ofs) >> shift
                b = int(iv[1]) >> shift

                c = a << shift
                d = b << shift
                if d > c:
                    r4.append((c, d))
                    res.append((a + ofs2, b + ofs2))

            if len(r4) > 0:
                r4_is = IntervalSet(np.asarray(r4))
                r2 = r2.difference(r4_is)

            order += 1

        return IntervalSet(np.asarray(res))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def from_nuniq_interval_set(cls, nuniq_is):
        nested_is = IntervalSet()
        # Appending a list is faster than appending a numpy array
        # For these algorithms we append a list and create the interval set from the finished list
        rtmp = []
        last_order = 0
        intervals = nuniq_is._intervals
        diff_order = IntervalSet.HPY_MAX_ORDER
        shift_order = 2 * diff_order
        for interval in intervals:
            for j in range(interval[0], interval[1]):
                order, i_pix = uniq2orderipix(j)

                if order != last_order:
                    nested_is = nested_is.union(IntervalSet(np.asarray(rtmp)))
                    rtmp = []
                    last_order = order
                    diff_order = IntervalSet.HPY_MAX_ORDER - order
                    shift_order = 2 * diff_order

                rtmp.append((i_pix << shift_order, (i_pix + 1) << shift_order))

        nested_is = nested_is.union(IntervalSet(np.asarray(rtmp)))
        return nested_is

Response: Convert an IntervalSet containing NUNIQ intervals to an IntervalSet representing HEALPix entries representing HEALPix cells following the NESTED numbering scheme.


Instruction:
How would you implement a function in Python 3 that
merges two lists of intervals according to the boolean function op and return the result of the operation op between the two lists of intervals a_intervals and b_intervals.

Response:
def merge(a_intervals, b_intervals, op):
        """
        Merge two lists of intervals according to the boolean function op

        ``a_intervals`` and ``b_intervals`` need to be sorted and consistent (no overlapping intervals).
        This operation keeps the resulting interval set consistent.

        Parameters
        ----------
        a_intervals : `~numpy.ndarray`
            A sorted merged list of intervals represented as a N x 2 numpy array
        b_intervals : `~numpy.ndarray`
            A sorted merged list of intervals represented as a N x 2 numpy array
        op : `function`
            Lambda function taking two params and returning the result of the operation between
            these two params.
            Exemple : lambda in_a, in_b: in_a and in_b describes the intersection of ``a_intervals`` and
            ``b_intervals`` whereas lambda in_a, in_b: in_a or in_b describes the union of ``a_intervals`` and
            ``b_intervals``.

        Returns
        -------
        array : `numpy.ndarray`
            a N x 2 numpy containing intervals resulting from the op between ``a_intervals`` and ``b_intervals``.
        """
        a_endpoints = a_intervals.flatten().tolist()
        b_endpoints = b_intervals.flatten().tolist()

        sentinel = max(a_endpoints[-1], b_endpoints[-1]) + 1

        a_endpoints += [sentinel]
        b_endpoints += [sentinel]

        a_index = 0
        b_index = 0

        res = []

        scan = min(a_endpoints[0], b_endpoints[0])
        while scan < sentinel:
            in_a = not ((scan < a_endpoints[a_index]) ^ (a_index % 2))
            in_b = not ((scan < b_endpoints[b_index]) ^ (b_index % 2))
            in_res = op(in_a, in_b)

            if in_res ^ (len(res) % 2):
                res += [scan]
            if scan == a_endpoints[a_index]:
                a_index += 1
            if scan == b_endpoints[b_index]:
                b_index += 1

            scan = min(a_endpoints[a_index], b_endpoints[b_index])

        return np.asarray(res).reshape((-1, 2))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def delete(self):
        # We only allow the object from being deleted once, otherwise
        # we might be deleting another GPU object that got our gl-id
        # after our GPU object was deleted. Also note that e.g.
        # DataBufferView does not have the _glir attribute.
        if hasattr(self, '_glir'):
            # Send our final command into the queue
            self._glir.command('DELETE', self._id)
            # Tell master glir queue that this queue is no longer being used
            self._glir._deletable = True
            # Detach the queue
            del self._glir

Response: Delete the object from the GPU memory.


Instruction:
Can you implement a function in Python 3 that
sets the data of the object.

Response:
def set_data(self, image):
        """Set the data

        Parameters
        ----------
        image : array-like
            The image data.
        """
        data = np.asarray(image)
        if self._data is None or self._data.shape != data.shape:
            self._need_vertex_update = True
        self._data = data
        self._need_texture_upload = True


Instruction:
How would you code a function in Python 3 to
rebuild the _data_lookup_fn using different interpolations within the shader

Response:
def _build_interpolation(self):
        """Rebuild the _data_lookup_fn using different interpolations within
        the shader
        """
        interpolation = self._interpolation
        self._data_lookup_fn = self._interpolation_fun[interpolation]
        self.shared_program.frag['get_data'] = self._data_lookup_fn

        # only 'bilinear' uses 'linear' texture interpolation
        if interpolation == 'bilinear':
            texture_interpolation = 'linear'
        else:
            # 'nearest' (and also 'bilinear') doesn't use spatial_filters.frag
            # so u_kernel and shape setting is skipped
            texture_interpolation = 'nearest'
            if interpolation != 'nearest':
                self.shared_program['u_kernel'] = self._kerneltex
                self._data_lookup_fn['shape'] = self._data.shape[:2][::-1]

        if self._texture.interpolation != texture_interpolation:
            self._texture.interpolation = texture_interpolation

        self._data_lookup_fn['texture'] = self._texture

        self._need_interpolation_update = False


Instruction:
How would you implement a function in Python 3 that
rebuilds the vertex buffers used for rendering the image when using the subdivide method.

Response:
def _build_vertex_data(self):
        """Rebuild the vertex buffers used for rendering the image when using
        the subdivide method.
        """
        grid = self._grid
        w = 1.0 / grid[1]
        h = 1.0 / grid[0]

        quad = np.array([[0, 0, 0], [w, 0, 0], [w, h, 0],
                         [0, 0, 0], [w, h, 0], [0, h, 0]],
                        dtype=np.float32)
        quads = np.empty((grid[1], grid[0], 6, 3), dtype=np.float32)
        quads[:] = quad

        mgrid = np.mgrid[0.:grid[1], 0.:grid[0]].transpose(1, 2, 0)
        mgrid = mgrid[:, :, np.newaxis, :]
        mgrid[..., 0] *= w
        mgrid[..., 1] *= h

        quads[..., :2] += mgrid
        tex_coords = quads.reshape(grid[1]*grid[0]*6, 3)
        tex_coords = np.ascontiguousarray(tex_coords[:, :2])
        vertices = tex_coords * self.size

        self._subdiv_position.set_data(vertices.astype('float32'))
        self._subdiv_texcoord.set_data(tex_coords.astype('float32'))


Instruction:
Write a Python 3 function that can
update the method used for view.

Response:
def _update_method(self, view):
        """Decide which method to use for *view* and configure it accordingly.
        """
        method = self._method
        if method == 'auto':
            if view.transforms.get_transform().Linear:
                method = 'subdivide'
            else:
                method = 'impostor'
        view._method_used = method

        if method == 'subdivide':
            view.view_program['method'] = 0
            view.view_program['a_position'] = self._subdiv_position
            view.view_program['a_texcoord'] = self._subdiv_texcoord
        elif method == 'impostor':
            view.view_program['method'] = 1
            view.view_program['a_position'] = self._impostor_coords
            view.view_program['a_texcoord'] = self._impostor_coords
        else:
            raise ValueError("Unknown image draw method '%s'" % method)

        self.shared_program['image_size'] = self.size
        view._need_method_update = False
        self._prepare_transforms(view)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def append(self, P, closed=False, itemsize=None, **kwargs):

        itemsize = itemsize or len(P)
        itemcount = len(P) / itemsize

        P = P.reshape(itemcount, itemsize, 3)
        if closed:
            V = np.empty((itemcount, itemsize + 3), dtype=self.vtype)
            # Apply default values on vertices
            for name in self.vtype.names:
                if name not in ['collection_index', 'prev', 'curr', 'next']:
                    V[name][1:-2] = kwargs.get(name, self._defaults[name])
            V['prev'][:, 2:-1] = P
            V['prev'][:, 1] = V['prev'][:, -2]
            V['curr'][:, 1:-2] = P
            V['curr'][:, -2] = V['curr'][:, 1]
            V['next'][:, 0:-3] = P
            V['next'][:, -3] = V['next'][:, 0]
            V['next'][:, -2] = V['next'][:, 1]
        else:
            V = np.empty((itemcount, itemsize + 2), dtype=self.vtype)
            # Apply default values on vertices
            for name in self.vtype.names:
                if name not in ['collection_index', 'prev', 'curr', 'next']:
                    V[name][1:-1] = kwargs.get(name, self._defaults[name])
            V['prev'][:, 2:] = P
            V['prev'][:, 1] = V['prev'][:, 2]
            V['curr'][:, 1:-1] = P
            V['next'][:, :-2] = P
            V['next'][:, -2] = V['next'][:, -3]

        V[:, 0] = V[:, 1]
        V[:, -1] = V[:, -2]
        V = V.ravel()
        V = np.repeat(V, 2, axis=0)
        V['id'] = np.tile([1, -1], len(V) / 2)
        if closed:
            V = V.reshape(itemcount, 2 * (itemsize + 3))
        else:
            V = V.reshape(itemcount, 2 * (itemsize + 2))
        V["id"][:, :2] = 2, -2
        V["id"][:, -2:] = 2, -2
        V = V.ravel()

        # Uniforms
        if self.utype:
            U = np.zeros(itemcount, dtype=self.utype)
            for name in self.utype.names:
                if name not in ["__unused__"]:
                    U[name] = kwargs.get(name, self._defaults[name])
        else:
            U = None

        Collection.append(self, vertices=V, uniforms=U,
                          itemsize=2 * (itemsize + 2 + closed))

Response: Append a new set of vertices to the collection.


Instruction:
Implement a Python 3 function for
giving a path P return the baked vertices as they should be copied in

Response:
def bake(self, P, key='curr', closed=False, itemsize=None):
        """
        Given a path P, return the baked vertices as they should be copied in
        the collection if the path has already been appended.

        Example:
        --------

        paths.append(P)
        P *= 2
        paths['prev'][0] = bake(P,'prev')
        paths['curr'][0] = bake(P,'curr')
        paths['next'][0] = bake(P,'next')
        """

        itemsize = itemsize or len(P)
        itemcount = len(P) / itemsize  # noqa
        n = itemsize

        if closed:
            I = np.arange(n + 3)
            if key == 'prev':
                I -= 2
                I[0], I[1], I[-1] = n - 1, n - 1, n - 1
            elif key == 'next':
                I[0], I[-3], I[-2], I[-1] = 1, 0, 1, 1
            else:
                I -= 1
                I[0], I[-1], I[n + 1] = 0, 0, 0
        else:
            I = np.arange(n + 2)
            if key == 'prev':
                I -= 2
                I[0], I[1], I[-1] = 0, 0, n - 2
            elif key == 'next':
                I[0], I[-1], I[-2] = 1, n - 1, n - 1
            else:
                I -= 1
                I[0], I[-1] = 0, n - 1
        I = np.repeat(I, 2)
        return P[I]


Instruction:
How would you implement a function in Python 3 that
draws the current context.

Response:
def draw(self, mode="triangle_strip"):
        """ Draw collection """

        gl.glDepthMask(gl.GL_FALSE)
        Collection.draw(self, mode)
        gl.glDepthMask(gl.GL_TRUE)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _stop_timers(canvas):
    for attr in dir(canvas):
        try:
            attr_obj = getattr(canvas, attr)
        except NotImplementedError:
            # This try/except is needed because canvas.position raises
            # an error (it is not implemented in this backend).
            attr_obj = None
        if isinstance(attr_obj, Timer):
            attr_obj.stop()

Response: Stop all timers in a canvas.


Instruction:
Can you implement a function in Python 3 that
prints stack trace from last call that didn t originate from here

Response:
def _last_stack_str():
    """Print stack trace from call that didn't originate from here"""
    stack = extract_stack()
    for s in stack[::-1]:
        if op.join('vispy', 'gloo', 'buffer.py') not in __file__:
            break
    return format_list([s])[0]


Instruction:
Here you have a function in Python 3, explain what it does
def set_subdata(self, data, offset=0, copy=False):
        data = np.array(data, copy=copy)
        nbytes = data.nbytes

        if offset < 0:
            raise ValueError("Offset must be positive")
        elif (offset + nbytes) > self._nbytes:
            raise ValueError("Data does not fit into buffer")

        # If the whole buffer is to be written, we clear any pending data
        # (because they will be overwritten anyway)
        if nbytes == self._nbytes and offset == 0:
            self._glir.command('SIZE', self._id, nbytes)
        self._glir.command('DATA', self._id, offset, data)

Response: Set a sub - region of the buffer.


Instruction:
Make a summary of the following Python 3 code
def set_data(self, data, copy=False):
        data = np.array(data, copy=copy)
        nbytes = data.nbytes

        if nbytes != self._nbytes:
            self.resize_bytes(nbytes)
        else:
            # Use SIZE to discard any previous data setting
            self._glir.command('SIZE', self._id, nbytes)

        if nbytes:  # Only set data if there *is* data
            self._glir.command('DATA', self._id, 0, data)

Response: Set the data in the buffer.


Instruction:
How would you explain what the following Python 3 function does
def resize_bytes(self, size):
        self._nbytes = size
        self._glir.command('SIZE', self._id, size)
        # Invalidate any view on this buffer
        for view in self._views:
            if view() is not None:
                view()._valid = False
        self._views = []

Response: Resize this buffer to a new size in bytes.


Instruction:
Make a summary of the following Python 3 code
def set_subdata(self, data, offset=0, copy=False, **kwargs):
        data = self._prepare_data(data, **kwargs)
        offset = offset * self.itemsize
        Buffer.set_subdata(self, data=data, offset=offset, copy=copy)

Response: Set a sub - region of the buffer.


Instruction:
Can you tell what is the following Python 3 function doing
def set_data(self, data, copy=False, **kwargs):
        data = self._prepare_data(data, **kwargs)
        self._dtype = data.dtype
        self._stride = data.strides[-1]
        self._itemsize = self._dtype.itemsize
        Buffer.set_data(self, data=data, copy=copy)

Response: Set data for the current object.


Instruction:
How would you explain what the following Python 3 function does
def glsl_type(self):
        if self.dtype is None:
            return None
        dtshape = self.dtype[0].shape
        n = dtshape[0] if dtshape else 1
        if n > 1:
            dtype = 'vec%d' % n
        else:
            dtype = 'float' if 'f' in self.dtype[0].base.kind else 'int'
        return 'attribute', dtype

Response: GLSL declaration string required for a variable to hold this data.


Instruction:
Write a Python 3 function for
compiling all code and return a dict where the keys are determined by the keyword arguments passed to __init__.

Response:
def compile(self, pretty=True):
        """ Compile all code and return a dict {name: code} where the keys
        are determined by the keyword arguments passed to __init__().

        Parameters
        ----------
        pretty : bool
            If True, use a slower method to mangle object names. This produces
            GLSL that is more readable.
            If False, then the output is mostly unreadable GLSL, but is about
            10x faster to compile.

        """
        # Authoritative mapping of {obj: name}
        self._object_names = {}

        #
        # 1. collect list of dependencies for each shader
        #

        # maps {shader_name: [deps]}
        self._shader_deps = {}

        for shader_name, shader in self.shaders.items():
            this_shader_deps = []
            self._shader_deps[shader_name] = this_shader_deps
            dep_set = set()

            for dep in shader.dependencies(sort=True):
                # visit each object no more than once per shader
                if dep.name is None or dep in dep_set:
                    continue
                this_shader_deps.append(dep)
                dep_set.add(dep)

        #
        # 2. Assign names to all objects.
        #
        if pretty:
            self._rename_objects_pretty()
        else:
            self._rename_objects_fast()

        #
        # 3. Now we have a complete namespace; concatenate all definitions
        # together in topological order.
        #
        compiled = {}
        obj_names = self._object_names

        for shader_name, shader in self.shaders.items():
            code = []
            for dep in self._shader_deps[shader_name]:
                dep_code = dep.definition(obj_names)
                if dep_code is not None:
                    # strip out version pragma if present;
                    regex = r'#version (\d+)'
                    m = re.search(regex, dep_code)
                    if m is not None:
                        # check requested version
                        if m.group(1) != '120':
                            raise RuntimeError("Currently only GLSL #version "
                                               "120 is supported.")
                        dep_code = re.sub(regex, '', dep_code)
                    code.append(dep_code)

            compiled[shader_name] = '\n'.join(code)

        self.code = compiled
        return compiled


Instruction:
How would you explain what the following Python 3 function does
def _rename_objects_fast(self):
        for shader_name, deps in self._shader_deps.items():
            for dep in deps:
                name = dep.name
                if name != 'main':
                    ext = '_%x' % id(dep)
                    name = name[:32-len(ext)] + ext
                self._object_names[dep] = name

Response:
Rename all objects quickly to guaranteed - unique names using the
        id


Instruction:
Can you create a Python 3 function that
renames all objects like name_1 to avoid conflicts. Objects are only renamed if necessary.

Response:
def _rename_objects_pretty(self):
        """ Rename all objects like "name_1" to avoid conflicts. Objects are
        only renamed if necessary.

        This method produces more readable GLSL, but is rather slow.
        """
        #
        # 1. For each object, add its static names to the global namespace
        #    and make a list of the shaders used by the object.
        #

        # {name: obj} mapping for finding unique names
        # initialize with reserved keywords.
        self._global_ns = dict([(kwd, None) for kwd in gloo.util.KEYWORDS])
        # functions are local per-shader
        self._shader_ns = dict([(shader, {}) for shader in self.shaders])

        # for each object, keep a list of shaders the object appears in
        obj_shaders = {}

        for shader_name, deps in self._shader_deps.items():
            for dep in deps:
                # Add static names to namespace
                for name in dep.static_names():
                    self._global_ns[name] = None

                obj_shaders.setdefault(dep, []).append(shader_name)

        #
        # 2. Assign new object names
        #
        name_index = {}
        for obj, shaders in obj_shaders.items():
            name = obj.name
            if self._name_available(obj, name, shaders):
                # hooray, we get to keep this name
                self._assign_name(obj, name, shaders)
            else:
                # boo, find a new name
                while True:
                    index = name_index.get(name, 0) + 1
                    name_index[name] = index
                    ext = '_%d' % index
                    new_name = name[:32-len(ext)] + ext
                    if self._name_available(obj, new_name, shaders):
                        self._assign_name(obj, new_name, shaders)
                        break


Instruction:
Can you write a function in Python 3 where it
returns True if name is available for obj in all shaders.

Response:
def _name_available(self, obj, name, shaders):
        """ Return True if *name* is available for *obj* in *shaders*.
        """
        if name in self._global_ns:
            return False
        shaders = self.shaders if self._is_global(obj) else shaders
        for shader in shaders:
            if name in self._shader_ns[shader]:
                return False
        return True


Instruction:
Write a Python 3 script for
assigning name to obj in all shaders.

Response:
def _assign_name(self, obj, name, shaders):
        """ Assign *name* to *obj* in *shaders*.
        """
        if self._is_global(obj):
            assert name not in self._global_ns
            self._global_ns[name] = obj
        else:
            for shader in shaders:
                ns = self._shader_ns[shader]
                assert name not in ns
                ns[name] = obj
        self._object_names[obj] = name


Instruction:
Can you tell what is the following Python 3 function doing
def _update(self):

        x, y = self._pos
        halfw, halfh = self._halfdim

        # test that width and height are non-zero
        if halfw <= 0:
            raise ValueError("half-width must be positive and non-zero"
                             ", not %s" % halfw)
        if halfh <= 0:
            raise ValueError("half-height must be positive and non-zero"
                             ", not %s" % halfh)

        # test that the given width and height is consistent
        # with the orientation
        if (self._orientation == "bottom" or self._orientation == "top"):
                if halfw < halfh:
                    raise ValueError("half-width(%s) < half-height(%s) for"
                                     "%s orientation,"
                                     " expected half-width >= half-height" %
                                     (halfw, halfh, self._orientation, ))
        else:  # orientation == left or orientation == right
            if halfw > halfh:
                raise ValueError("half-width(%s) > half-height(%s) for"
                                 "%s orientation,"
                                 " expected half-width <= half-height" %
                                 (halfw, halfh, self._orientation, ))

        # Set up the attributes that the shaders require
        vertices = np.array([[x - halfw, y - halfh],
                             [x + halfw, y - halfh],
                             [x + halfw, y + halfh],
                             # tri 2
                             [x - halfw, y - halfh],
                             [x + halfw, y + halfh],
                             [x - halfw, y + halfh]],
                            dtype=np.float32)

        self.shared_program['a_position'] = vertices

Response: Updates the internal state of the object store.


Instruction:
Can you tell what is the following Python 3 function doing
def _update(self):
        self._colorbar.halfdim = self._halfdim
        self._border.halfdim = self._halfdim

        self._label.text = self._label_str
        self._ticks[0].text = str(self._clim[0])
        self._ticks[1].text = str(self._clim[1])

        self._update_positions()

        self._colorbar._update()
        self._border._update()

Response:
Updates the colorbar and border based on the objects
           that are used internally by the ColorBarVisual
       .


Instruction:
How would you explain what the following Python 3 function does
def _update_positions(self):
        self._colorbar.pos = self._pos
        self._border.pos = self._pos

        if self._orientation == "right" or self._orientation == "left":
            self._label.rotation = -90

        x, y = self._pos
        halfw, halfh = self._halfdim

        label_anchors = \
            ColorBarVisual._get_label_anchors(center=self._pos,
                                              halfdim=self._halfdim,
                                              orientation=self._orientation,
                                              transforms=self.label.transforms)
        self._label.anchors = label_anchors

        ticks_anchors = \
            ColorBarVisual._get_ticks_anchors(center=self._pos,
                                              halfdim=self._halfdim,
                                              orientation=self._orientation,
                                              transforms=self.label.transforms)

        self._ticks[0].anchors = ticks_anchors
        self._ticks[1].anchors = ticks_anchors

        (label_pos, ticks_pos) = \
            ColorBarVisual._calc_positions(center=self._pos,
                                           halfdim=self._halfdim,
                                           border_width=self.border_width,
                                           orientation=self._orientation,
                                           transforms=self.transforms)

        self._label.pos = label_pos
        self._ticks[0].pos = ticks_pos[0]
        self._ticks[1].pos = ticks_pos[1]

Response: Updates the positions of the colorbars and labels based on the current state of the object.


Instruction:
Create a Python 3 function to
calculate the text centeritions of the ColorBar object.

Response:
def _calc_positions(center, halfdim, border_width,
                        orientation, transforms):
        """
        Calculate the text centeritions given the ColorBar
        parameters.

        Note
        ----
        This is static because in principle, this
        function does not need access to the state of the ColorBar
        at all. It's a computation function that computes coordinate
        transforms

        Parameters
        ----------
        center: tuple (x, y)
            Center of the ColorBar
        halfdim: tuple (halfw, halfh)
            Half of the dimensions measured from the center
        border_width: float
            Width of the border of the ColorBar
        orientation: "top" | "bottom" | "left" | "right"
            Position of the label with respect to the ColorBar
        transforms: TransformSystem
            the transforms of the ColorBar
        """
        (x, y) = center
        (halfw, halfh) = halfdim

        visual_to_doc = transforms.get_transform('visual', 'document')
        doc_to_visual = transforms.get_transform('document', 'visual')

        # doc_widths = visual_to_doc.map(np.array([halfw, halfh, 0, 0],
        #                                         dtype=np.float32))

        doc_x = visual_to_doc.map(np.array([halfw, 0, 0, 0], dtype=np.float32))
        doc_y = visual_to_doc.map(np.array([0, halfh, 0, 0], dtype=np.float32))

        if doc_x[0] < 0:
            doc_x *= -1

        if doc_y[1] < 0:
            doc_y *= -1

        # doc_halfw = np.abs(doc_widths[0])
        # doc_halfh = np.abs(doc_widths[1])

        if orientation == "top":
            doc_perp_vector = -doc_y
        elif orientation == "bottom":
            doc_perp_vector = doc_y
        elif orientation == "left":
            doc_perp_vector = -doc_x
        if orientation == "right":
            doc_perp_vector = doc_x

        perp_len = np.linalg.norm(doc_perp_vector)
        doc_perp_vector /= perp_len
        perp_len += border_width
        perp_len += 5  # pixels
        perp_len *= ColorBarVisual.text_padding_factor
        doc_perp_vector *= perp_len

        doc_center = visual_to_doc.map(np.array([x, y, 0, 0],
                                                dtype=np.float32))
        doc_label_pos = doc_center + doc_perp_vector
        visual_label_pos = doc_to_visual.map(doc_label_pos)[:3]

        # next, calculate tick positions
        if orientation in ["top", "bottom"]:
            doc_ticks_pos = [doc_label_pos - doc_x,
                             doc_label_pos + doc_x]
        else:
            doc_ticks_pos = [doc_label_pos + doc_y,
                             doc_label_pos - doc_y]

        visual_ticks_pos = []
        visual_ticks_pos.append(doc_to_visual.map(doc_ticks_pos[0])[:3])
        visual_ticks_pos.append(doc_to_visual.map(doc_ticks_pos[1])[:3])

        return (visual_label_pos, visual_ticks_pos)


Instruction:
Explain what the following Python 3 code does
def add_pseudo_fields(self):
        fields = []
        if self.backlight_on != enums.BACKLIGHT_ON_NEVER:
            fields.append(
                display_fields.BacklightPseudoField(ref='0', backlight_rule=self.backlight_on)
            )

        fields.append(
            display_fields.PriorityPseudoField(
                ref='0',
                priority_playing=self.priority_playing,
                priority_not_playing=self.priority_not_playing,
            )
        )

        self.pattern.add_pseudo_fields(fields, self.screen)

Response: Add pseudo fields ( e. g non - displayed fields to the display.


Instruction:
Can you create a Python 3 function that
returns a new Rect padded by padding on all sides of the rectangle.

Response:
def padded(self, padding):
        """Return a new Rect padded (smaller) by padding on all sides

        Parameters
        ----------
        padding : float
            The padding.

        Returns
        -------
        rect : instance of Rect
            The padded rectangle.
        """
        return Rect(pos=(self.pos[0]+padding, self.pos[1]+padding),
                    size=(self.size[0]-2*padding, self.size[1]-2*padding))


Instruction:
Make a summary of the following Python 3 code
def normalized(self):
        return Rect(pos=(min(self.left, self.right),
                         min(self.top, self.bottom)),
                    size=(abs(self.width), abs(self.height)))

Response: Return a Rect covering the same area but with height and width as positive.


Instruction:
Create a Python 3 function to
return a Rect with the same bounds but with axes inverted

Response:
def flipped(self, x=False, y=True):
        """Return a Rect with the same bounds but with axes inverted

        Parameters
        ----------
        x : bool
            Flip the X axis.
        y : bool
            Flip the Y axis.

        Returns
        -------
        rect : instance of Rect
            The flipped rectangle.
        """
        pos = list(self.pos)
        size = list(self.size)
        for i, flip in enumerate((x, y)):
            if flip:
                pos[i] += size[i]
                size[i] *= -1
        return Rect(pos, size)


Instruction:
Write a Python 3 function for
returning array of coordinates that can be mapped by Transform classes.

Response:
def _transform_in(self):
        """Return array of coordinates that can be mapped by Transform
        classes."""
        return np.array([
            [self.left, self.bottom, 0, 1],
            [self.right, self.top, 0, 1]])


Instruction:
Can you generate the documentation for the following Python 3 function
def configure(self, viewport=None, fbo_size=None, fbo_rect=None,
                  canvas=None):
        """Automatically configure the TransformSystem:

        * canvas_transform maps from the Canvas logical pixel
          coordinate system to the framebuffer coordinate system, taking into
          account the logical/physical pixel scale factor, current FBO
          position, and y-axis inversion.
        * framebuffer_transform maps from the current GL viewport on the
          framebuffer coordinate system to clip coordinates (-1 to 1).

        Parameters
        ==========
        viewport : tuple or None
            The GL viewport rectangle (x, y, w, h). If None, then it
            is assumed to cover the entire canvas.
        fbo_size : tuple or None
            The size of the active FBO. If None, then it is assumed to have the
            same size as the canvas's framebuffer.
        fbo_rect : tuple or None
            The position and size (x, y, w, h) of the FBO in the coordinate
            system of the canvas's framebuffer. If None, then the bounds are
            assumed to cover the entire active framebuffer.
        canvas : Canvas instance
            Optionally set the canvas for this TransformSystem. See the
            `canvas` property.
        """
        # TODO: check that d2f and f2r transforms still contain a single
        # STTransform (if the user has modified these, then auto-config should
        # either fail or replace the transforms)
        if canvas is not None:
            self.canvas = canvas
        canvas = self._canvas
        if canvas is None:
            raise RuntimeError("No canvas assigned to this TransformSystem.")

        # By default, this should invert the y axis--canvas origin is in top
        # left, whereas framebuffer origin is in bottom left.
        map_from = [(0, 0), canvas.size]
        map_to = [(0, canvas.physical_size[1]), (canvas.physical_size[0], 0)]
        self._canvas_transform.transforms[1].set_mapping(map_from, map_to)

        if fbo_rect is None:
            self._canvas_transform.transforms[0].scale = (1, 1, 1)
            self._canvas_transform.transforms[0].translate = (0, 0, 0)
        else:
            # Map into FBO coordinates
            map_from = [(fbo_rect[0], fbo_rect[1]),
                        (fbo_rect[0] + fbo_rect[2], fbo_rect[1] + fbo_rect[3])]
            map_to = [(0, 0), fbo_size]
            self._canvas_transform.transforms[0].set_mapping(map_from,  map_to)

        if viewport is None:
            if fbo_size is None:
                # viewport covers entire canvas
                map_from = [(0, 0), canvas.physical_size]
            else:
                # viewport covers entire FBO
                map_from = [(0, 0), fbo_size]
        else:
            map_from = [viewport[:2],
                        (viewport[0] + viewport[2], viewport[1] + viewport[3])]
        map_to = [(-1, -1), (1, 1)]
        self._framebuffer_transform.transforms[0].set_mapping(map_from, map_to)

Response: Automatically configure the TransformSystem.


Instruction:
Create a Python 3 function to
return the physical resolution of the document coordinate system.

Response:
def dpi(self):
        """ Physical resolution of the document coordinate system (dots per
        inch).
        """
        if self._dpi is None:
            if self._canvas is None:
                return None
            else:
                return self.canvas.dpi
        else:
            return self._dpi


Instruction:
How would you explain what the following Python 3 function does
def get_transform(self, map_from='visual', map_to='render'):
        tr = ['visual', 'scene', 'document', 'canvas', 'framebuffer', 'render']
        ifrom = tr.index(map_from)
        ito = tr.index(map_to)

        if ifrom < ito:
            trs = [getattr(self, '_' + t + '_transform')
                   for t in tr[ifrom:ito]][::-1]
        else:
            trs = [getattr(self, '_' + t + '_transform').inverse
                   for t in tr[ito:ifrom]]
        return self._cache.get(trs)

Response: Returns a transform mapping between any two coordinate systems.


Instruction:
Can you tell what is the following Python 3 function doing
def _calculate_delta_pos(adjacency_arr, pos, t, optimal):
    # XXX eventually this should be refactored for the sparse case to only
    # do the necessary pairwise distances
    delta = pos[:, np.newaxis, :] - pos

    # Distance between points
    distance2 = (delta*delta).sum(axis=-1)
    # Enforce minimum distance of 0.01
    distance2 = np.where(distance2 < 0.0001, 0.0001, distance2)
    distance = np.sqrt(distance2)
    # Displacement "force"
    displacement = np.zeros((len(delta), 2))
    for ii in range(2):
        displacement[:, ii] = (
            delta[:, :, ii] *
            ((optimal * optimal) / (distance*distance) -
             (adjacency_arr * distance) / optimal)).sum(axis=1)

    length = np.sqrt((displacement**2).sum(axis=1))
    length = np.where(length < 0.01, 0.1, length)
    delta_pos = displacement * t / length[:, np.newaxis]
    return delta_pos

Response: Helper function to calculate the delta position of a single object in a sequence of points.


Instruction:
Explain what the following Python 3 code does
def use(app=None, gl=None):
    if app is None and gl is None:
        raise TypeError('Must specify at least one of "app" or "gl".')

    # Example for future. This wont work (yet).
    if app == 'ipynb_webgl':
        app = 'headless'
        gl = 'webgl'

    if app == 'osmesa':
        from ..util.osmesa_gl import fix_osmesa_gl_lib
        fix_osmesa_gl_lib()
        if gl is not None:
            raise ValueError("Do not specify gl when using osmesa")

    # Apply now
    if gl:
        from .. import gloo, config
        config['gl_backend'] = gl
        gloo.gl.use_gl(gl)
    if app:
        from ..app import use_app
        use_app(app)

Response: Set the usage options for the specified app and GL backend.


Instruction:
Can you create a Python 3 function that
runs command using subprocess. Popen and return the output of the subprocess. CalledProcessError is raised if the return code is zero.

Response:
def run_subprocess(command, return_code=False, **kwargs):
    """Run command using subprocess.Popen

    Run command and wait for command to complete. If the return code was zero
    then return, otherwise raise CalledProcessError.
    By default, this will also add stdout= and stderr=subproces.PIPE
    to the call to Popen to suppress printing to the terminal.

    Parameters
    ----------
    command : list of str
        Command to run as subprocess (see subprocess.Popen documentation).
    return_code : bool
        If True, the returncode will be returned, and no error checking
        will be performed (so this function should always return without
        error).
    **kwargs : dict
        Additional kwargs to pass to ``subprocess.Popen``.

    Returns
    -------
    stdout : str
        Stdout returned by the process.
    stderr : str
        Stderr returned by the process.
    code : int
        The command exit code. Only returned if ``return_code`` is True.
    """
    # code adapted with permission from mne-python
    use_kwargs = dict(stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    use_kwargs.update(kwargs)

    p = subprocess.Popen(command, **use_kwargs)
    output = p.communicate()

    # communicate() may return bytes, str, or None depending on the kwargs
    # passed to Popen(). Convert all to unicode str:
    output = ['' if s is None else s for s in output]
    output = [s.decode('utf-8') if isinstance(s, bytes) else s for s in output]
    output = tuple(output)

    if not return_code and p.returncode:
        print(output[0])
        print(output[1])
        err_fun = subprocess.CalledProcessError.__init__
        if 'output' in inspect.getargspec(err_fun).args:
            raise subprocess.CalledProcessError(p.returncode, command, output)
        else:
            raise subprocess.CalledProcessError(p.returncode, command)
    if return_code:
        output = output + (p.returncode,)
    return output


Instruction:
Can you write a function in Python 3 where it
starts the timer. A timeout event will be generated every *interval* seconds. If *interval* is None, then self.interval will be used. If *iterations* is specified, the timer will stop after emitting that number of events. If unspecified, then the previous value of self.iterations will be used. If the value is negative, then the timer will continue running until stop() is called. If the timer is already running when this function is called, nothing happens (timer continues running as it did previously, without changing the interval, number of iterations, or emitting a timer start event).

Response:
def start(self, interval=None, iterations=None):
        """Start the timer.

        A timeout event will be generated every *interval* seconds.
        If *interval* is None, then self.interval will be used.

        If *iterations* is specified, the timer will stop after
        emitting that number of events. If unspecified, then
        the previous value of self.iterations will be used. If the value is
        negative, then the timer will continue running until stop() is called.

        If the timer is already running when this function is called, nothing
        happens (timer continues running as it did previously, without
        changing the interval, number of iterations, or emitting a timer
        start event).
        """
        if self.running:
            return  # don't do anything if already running
        self.iter_count = 0
        if interval is not None:
            self.interval = interval
        if iterations is not None:
            self.max_iterations = iterations
        self._backend._vispy_start(self.interval)
        self._running = True
        self._first_emit_time = precision_time()
        self._last_emit_time = precision_time()
        self.events.start(type='timer_start')


Instruction:
Implement a function in Python 3 to
return a numpy array of all the HEALPix indexes contained in the MOC at its max order.

Response:
def _best_res_pixels(self):
        """
        Returns a numpy array of all the HEALPix indexes contained in the MOC at its max order.

        Returns
        -------
        result : `~numpy.ndarray`
            The array of HEALPix at ``max_order``
        """
        factor = 2 * (AbstractMOC.HPY_MAX_NORDER - self.max_order)
        pix_l = []
        for iv in self._interval_set._intervals:
            for val in range(iv[0] >> factor, iv[1] >> factor):
                pix_l.append(val)

        return np.asarray(pix_l)


Instruction:
Create a Python 3 function for
returning a boolean array of the positions lying inside or outside the MOC.

Response:
def contains(self, ra, dec, keep_inside=True):
        """
        Returns a boolean mask array of the positions lying inside (or outside) the MOC instance.

        Parameters
        ----------
        ra : `astropy.units.Quantity`
            Right ascension array
        dec : `astropy.units.Quantity`
            Declination array
        keep_inside : bool, optional
            True by default. If so the mask describes coordinates lying inside the MOC. If ``keep_inside``
            is false, contains will return the mask of the coordinates lying outside the MOC.

        Returns
        -------
        array : `~np.ndarray`
            A mask boolean array
        """
        depth = self.max_order
        m = np.zeros(nside2npix(1 << depth), dtype=bool)

        pix_id = self._best_res_pixels()
        m[pix_id] = True

        if not keep_inside:
            m = np.logical_not(m)

        hp = HEALPix(nside=(1 << depth), order='nested')
        pix = hp.lonlat_to_healpix(ra, dec)

        return m[pix]


Instruction:
Can you tell what is the following Python 3 function doing
def add_neighbours(self):
        # Get the pixels array of the MOC at the its max order.
        ipix = self._best_res_pixels()

        hp = HEALPix(nside=(1 << self.max_order), order='nested')
        # Get the HEALPix array containing the neighbors of ``ipix``.
        # This array "extends" ``ipix`` by one degree of neighbors.
        extend_ipix = AbstractMOC._neighbour_pixels(hp, ipix)

        # Compute the difference between ``extend_ipix`` and ``ipix`` to get only the neighboring pixels
        # located at the border of the MOC.
        neigh_ipix = np.setdiff1d(extend_ipix, ipix)

        shift = 2 * (AbstractMOC.HPY_MAX_NORDER - self.max_order)
        neigh_itv = np.vstack((neigh_ipix << shift, (neigh_ipix + 1) << shift)).T
        # This array of HEALPix neighbors are added to the MOC to get an ``extended`` MOC at its max order.
        self._interval_set = self._interval_set.union(IntervalSet(neigh_itv))
        return self

Response: Adds the neighbours of the MOC to the MOC instance.


Instruction:
Make a summary of the following Python 3 code
def remove_neighbours(self):
        # Get the HEALPix cells of the MOC at its max depth
        ipix = self._best_res_pixels()

        hp = HEALPix(nside=(1 << self.max_order), order='nested')
        # Extend it to include the max depth neighbor cells.
        extend_ipix = AbstractMOC._neighbour_pixels(hp, ipix)

        # Get only the max depth HEALPix cells lying at the border of the MOC
        neigh_ipix = np.setxor1d(extend_ipix, ipix)

        # Remove these pixels from ``ipix``
        border_ipix = AbstractMOC._neighbour_pixels(hp, neigh_ipix)
        reduced_ipix = np.setdiff1d(ipix, border_ipix)

        # Build the reduced MOC, i.e. MOC without its pixels which were located at its border.
        shift = 2 * (AbstractMOC.HPY_MAX_NORDER - self.max_order)
        reduced_itv = np.vstack((reduced_ipix << shift, (reduced_ipix + 1) << shift)).T
        self._interval_set = IntervalSet(reduced_itv)
        return self

Response: Removes all HEALPix cells from the MOC instance.


Instruction:
Explain what the following Python 3 code does
def fill(self, ax, wcs, **kw_mpl_pathpatch):
        fill.fill(self, ax, wcs, **kw_mpl_pathpatch)

Response: Fills the MOC with the WCS and the MOCs.


Instruction:
Explain what the following Python 3 code does
def border(self, ax, wcs, **kw_mpl_pathpatch):
        border.border(self, ax, wcs, **kw_mpl_pathpatch)

Response: Draws the border of the MOC on a matplotlib axis.


Instruction:
Write a Python 3 function that can
create a MOC from an image stored as a FITS file.

Response:
def from_image(cls, header, max_norder, mask=None):
        """
        Creates a `~mocpy.moc.MOC` from an image stored as a FITS file.

        Parameters
        ----------
        header : `astropy.io.fits.Header`
            FITS header containing all the info of where the image is located (position, size, etc...)
        max_norder : int
            The moc resolution.
        mask : `numpy.ndarray`, optional
            A boolean array of the same size of the image where pixels having the value 1 are part of
            the final MOC and pixels having the value 0 are not.

        Returns
        -------
        moc : `~mocpy.moc.MOC`
            The resulting MOC.
        """
        # load the image data
        height = header['NAXIS2']
        width = header['NAXIS1']

        # use wcs from astropy to locate the image in the world coordinates
        w = wcs.WCS(header)

        if mask is not None:
            # We have an array of pixels that are part of of survey
            y, x = np.where(mask)
            pix_crd = np.dstack((x, y))[0]
        else:
            # If we do not have a mask array we create the moc of all the image
            #
            step_pix = 1
            """
            Coords returned by wcs_pix2world method correspond to pixel centers. We want to retrieve the moc pix
            crossing the borders of the image so we have to add 1/2 to the pixels coords before computing the lonlat.

            The step between two pix_crd is set to `step_pix` but can be diminished to have a better precision at the
            borders so that all the image is covered (a too big step does not retrieve all
            the moc pix crossing the borders of the image).
            """
            x, y = np.mgrid[0.5:(width + 0.5 + step_pix):step_pix, 0.5:(height + 0.5 + step_pix):step_pix]
            pix_crd = np.dstack((x.ravel(), y.ravel()))[0]

        frame = wcs.utils.wcs_to_celestial_frame(w)
        world_pix_crd = SkyCoord(w.wcs_pix2world(pix_crd, 1), unit='deg', frame=frame)

        hp = HEALPix(nside=(1 << max_norder), order='nested', frame=ICRS())
        ipix = hp.skycoord_to_healpix(world_pix_crd)
        # remove doubles
        ipix = np.unique(ipix)

        shift = 2 * (AbstractMOC.HPY_MAX_NORDER - max_norder)
        intervals_arr = np.vstack((ipix << shift, (ipix + 1) << shift)).T

        # This MOC will be consistent when one will do operations on the moc (union, inter, ...) or
        # simply write it to a fits or json file
        interval_set = IntervalSet(intervals_arr)

        return cls(interval_set=interval_set)


Instruction:
Can you tell what is the following Python 3 function doing
def from_fits_images(cls, path_l, max_norder):
        moc = MOC()
        for path in path_l:
            header = fits.getheader(path)
            current_moc = MOC.from_image(header=header, max_norder=max_norder)
            moc = moc.union(current_moc)

        return moc

Response: Loads a MOC from a set of FITS file images.


Instruction:
Write a Python 3 function that can
create a MOC object from a VizieR table.

Response:
def from_vizier_table(cls, table_id, nside=256):
        """
        Creates a `~mocpy.moc.MOC` object from a VizieR table.

        **Info**: This method is already implemented in `astroquery.cds <https://astroquery.readthedocs.io/en/latest/cds/cds.html>`__. You can ask to get a `mocpy.moc.MOC` object
        from a vizier catalog ID.

        Parameters
        ----------
        table_id : str
            table index
        nside : int, optional
            256 by default

        Returns
        -------
        result : `~mocpy.moc.MOC`
            The resulting MOC.
        """
        nside_possible_values = (8, 16, 32, 64, 128, 256, 512)
        if nside not in nside_possible_values:
            raise ValueError('Bad value for nside. Must be in {0}'.format(nside_possible_values))

        result = cls.from_ivorn('ivo://CDS/' + table_id, nside)
        return result


Instruction:
Can you generate the documentation for the following Python 3 function
def from_ivorn(cls, ivorn, nside=256):
        return cls.from_url('%s?%s' % (MOC.MOC_SERVER_ROOT_URL,
                                       urlencode({
                                           'ivorn': ivorn,
                                           'get': 'moc',
                                           'order': int(np.log2(nside))
                                       })))

Response: Creates a MOC object from a given ivorn.


Instruction:
Write a Python 3 function that can
create a ~mocpy. moc. MOC object from a given url.

Response:
def from_url(cls, url):
        """
        Creates a `~mocpy.moc.MOC` object from a given url.

        Parameters
        ----------
        url : str
            The url of a FITS file storing a MOC.

        Returns
        -------
        result : `~mocpy.moc.MOC`
            The resulting MOC.
        """
        path = download_file(url, show_progress=False, timeout=60)
        return cls.from_fits(path)


Instruction:
Here you have a function in Python 3, explain what it does
def from_skycoords(cls, skycoords, max_norder):
        hp = HEALPix(nside=(1 << max_norder), order='nested')
        ipix = hp.lonlat_to_healpix(skycoords.icrs.ra, skycoords.icrs.dec)

        shift = 2 * (AbstractMOC.HPY_MAX_NORDER - max_norder)
        intervals = np.vstack((ipix << shift, (ipix + 1) << shift)).T

        interval_set = IntervalSet(intervals)
        return cls(interval_set)

Response: Creates a MOC from an astropy. coordinates. SkyCoord object.


Instruction:
Create a Python 3 function for
creating a MOC from an astropy lon lat and max_norder.

Response:
def from_lonlat(cls, lon, lat, max_norder):
        """
        Creates a MOC from astropy lon, lat `astropy.units.Quantity`.

        Parameters
        ----------
        lon : `astropy.units.Quantity`
            The longitudes of the sky coordinates belonging to the MOC.
        lat : `astropy.units.Quantity`
            The latitudes of the sky coordinates belonging to the MOC.
        max_norder : int
            The depth of the smallest HEALPix cells contained in the MOC.

        Returns
        -------
        result : `~mocpy.moc.MOC`
            The resulting MOC
        """
        hp = HEALPix(nside=(1 << max_norder), order='nested')
        ipix = hp.lonlat_to_healpix(lon, lat)

        shift = 2 * (AbstractMOC.HPY_MAX_NORDER - max_norder)
        intervals = np.vstack((ipix << shift, (ipix + 1) << shift)).T

        interval_set = IntervalSet(intervals)
        return cls(interval_set)


Instruction:
How would you implement a function in Python 3 that
creates a MOC from a polygon.

Response:
def from_polygon_skycoord(cls, skycoord, inside=None, max_depth=10):
        """
        Creates a MOC from a polygon.

        The polygon is given as an `astropy.coordinates.SkyCoord` that contains the
        vertices of the polygon. Concave and convex polygons are accepted but
        self-intersecting ones are currently not properly handled.

        Parameters
        ----------
        skycoord : `astropy.coordinates.SkyCoord`
            The sky coordinates defining the vertices of a polygon. It can describe a convex or
            concave polygon but not a self-intersecting one.
        inside : `astropy.coordinates.SkyCoord`, optional
            A point that will be inside the MOC is needed as it is not possible to determine the inside area of a polygon
            on the unit sphere (there is no infinite area that can be considered as the outside because on the sphere,
            a closed polygon delimits two finite areas).
            Possible improvement: take the inside area as the one covering the smallest region on the sphere.

            If inside=None (default behavior), the mean of all the vertices is taken as lying inside the polygon. That approach may not work for
            concave polygons.
        max_depth : int, optional
            The resolution of the MOC. Set to 10 by default.

        Returns
        -------
        result : `~mocpy.moc.MOC`
            The resulting MOC
        """
        return MOC.from_polygon(lon=skycoord.icrs.ra, lat=skycoord.icrs.dec,
                                inside=inside, max_depth=max_depth)


Instruction:
Implement a Python 3 function for
creating a MOC from a polygon.

Response:
def from_polygon(cls, lon, lat, inside=None, max_depth=10):
        """
        Creates a MOC from a polygon

        The polygon is given as lon and lat `astropy.units.Quantity` that define the
        vertices of the polygon. Concave and convex polygons are accepted but
        self-intersecting ones are currently not properly handled.

        Parameters
        ----------
        lon : `astropy.units.Quantity`
            The longitudes defining the polygon. Can describe convex and
            concave polygons but not self-intersecting ones.
        lat : `astropy.units.Quantity`
            The latitudes defining the polygon. Can describe convex and concave
            polygons but not self-intersecting ones.
        inside : `astropy.coordinates.SkyCoord`, optional
            A point that will be inside the MOC is needed as it is not possible to determine the inside area of a polygon
            on the unit sphere (there is no infinite area that can be considered as the outside because on the sphere,
            a closed polygon delimits two finite areas).
            Possible improvement: take the inside area as the one covering the smallest region on the sphere.

            If inside=None (default behavior), the mean of all the vertices is taken as lying inside the polygon. That approach may not work for
            concave polygons.
        max_depth : int, optional
            The resolution of the MOC. Set to 10 by default.

        Returns
        -------
        result : `~mocpy.moc.MOC`
            The resulting MOC
        """
        from .polygon import PolygonComputer

        polygon_computer = PolygonComputer(lon, lat, inside, max_depth)
        # Create the moc from the python dictionary

        moc = MOC.from_json(polygon_computer.ipix)
        # We degrade it to the user-requested order
        if polygon_computer.degrade_to_max_depth:
            moc = moc.degrade_to_order(max_depth)

        return moc


Instruction:
Here you have a function in Python 3, explain what it does
def sky_fraction(self):
        pix_id = self._best_res_pixels()
        nb_pix_filled = pix_id.size
        return nb_pix_filled / float(3 << (2*(self.max_order + 1)))

Response: Return the sky fraction covered by the MOC


Instruction:
Can you generate the documentation for the following Python 3 function
def plot(self, title='MOC', frame=None):
        frame = ICRS() if frame is None else frame

        from matplotlib.colors import LinearSegmentedColormap
        import matplotlib.pyplot as plt

        plot_order = 8
        if self.max_order > plot_order:
            plotted_moc = self.degrade_to_order(plot_order)
        else:
            plotted_moc = self

        num_pixels_map = 1024
        delta = 2. * np.pi / num_pixels_map

        x = np.arange(-np.pi, np.pi, delta)
        y = np.arange(-np.pi/2, np.pi/2, delta)
        lon_rad, lat_rad = np.meshgrid(x, y)
        hp = HEALPix(nside=(1 << plotted_moc.max_order), order='nested')

        if frame and not isinstance(frame, BaseCoordinateFrame):
            raise ValueError("Only Galactic/ICRS coordinate systems are supported."
                             "Please set `coord` to either 'C' or 'G'.")

        pix_map = hp.lonlat_to_healpix(lon_rad * u.rad, lat_rad * u.rad)

        m = np.zeros(nside2npix(1 << plotted_moc.max_order))
        pix_id = plotted_moc._best_res_pixels()

        # change the HEALPix cells if the frame of the MOC is not the same as the one associated with the plot method.
        if isinstance(frame, Galactic):
            lon, lat = hp.boundaries_lonlat(pix_id, step=2)
            sky_crd = SkyCoord(lon, lat, unit='deg')
            pix_id = hp.lonlat_to_healpix(sky_crd.galactic.l, sky_crd.galactic.b)

        m[pix_id] = 1

        z = np.flip(m[pix_map], axis=1)

        plt.figure(figsize=(10, 10))

        ax = plt.subplot(111, projection="mollweide")
        ax.set_xticklabels(['150°', '120°', '90°', '60°', '30°', '0°', '330°', '300°', '270°', '240°', '210°', '180°'])

        color_map = LinearSegmentedColormap.from_list('w2r', ['#eeeeee', '#aa0000'])
        color_map.set_under('w')
        color_map.set_bad('gray')

        ax.pcolormesh(x, y, z, cmap=color_map, vmin=0, vmax=1)
        ax.tick_params(labelsize=14, labelcolor='#000000')
        plt.title(title)
        plt.grid(True, linestyle='--', linewidth=1, color='#555555')

        plt.show()

Response: Plots the MOC object using a mollweide projection.


Instruction:
How would you explain what the following Python 3 function does
def inverse(self):
        if self._inverse is None:
            self._inverse = InverseTransform(self)
        return self._inverse

Response: Returns the inverse of this transform.


Instruction:
Given the following Python 3 function, write the documentation
def _tile_ticks(self, frac, tickvec):
        origins = np.tile(self.axis._vec, (len(frac), 1))
        origins = self.axis.pos[0].T + (origins.T*frac).T
        endpoints = tickvec + origins
        return origins, endpoints

Response: Tiles tick marks along the axis.


Instruction:
Can you tell what is the following Python 3 function doing
def _get_tick_frac_labels(self):
        minor_num = 4  # number of minor ticks per major division
        if (self.axis.scale_type == 'linear'):
            domain = self.axis.domain
            if domain[1] < domain[0]:
                flip = True
                domain = domain[::-1]
            else:
                flip = False
            offset = domain[0]
            scale = domain[1] - domain[0]

            transforms = self.axis.transforms
            length = self.axis.pos[1] - self.axis.pos[0]  # in logical coords
            n_inches = np.sqrt(np.sum(length ** 2)) / transforms.dpi

            # major = np.linspace(domain[0], domain[1], num=11)
            # major = MaxNLocator(10).tick_values(*domain)
            major = _get_ticks_talbot(domain[0], domain[1], n_inches, 2)

            labels = ['%g' % x for x in major]
            majstep = major[1] - major[0]
            minor = []
            minstep = majstep / (minor_num + 1)
            minstart = 0 if self.axis._stop_at_major[0] else -1
            minstop = -1 if self.axis._stop_at_major[1] else 0
            for i in range(minstart, len(major) + minstop):
                maj = major[0] + i * majstep
                minor.extend(np.linspace(maj + minstep,
                                         maj + majstep - minstep,
                                         minor_num))
            major_frac = (major - offset) / scale
            minor_frac = (np.array(minor) - offset) / scale
            major_frac = major_frac[::-1] if flip else major_frac
            use_mask = (major_frac > -0.0001) & (major_frac < 1.0001)
            major_frac = major_frac[use_mask]
            labels = [l for li, l in enumerate(labels) if use_mask[li]]
            minor_frac = minor_frac[(minor_frac > -0.0001) &
                                    (minor_frac < 1.0001)]
        elif self.axis.scale_type == 'logarithmic':
            return NotImplementedError
        elif self.axis.scale_type == 'power':
            return NotImplementedError
        return major_frac, minor_frac, labels

Response: Get the ticks minor ticks and major labels


Instruction:
Implement a function in Python 3 to
interleave planes in the input image data.

Response:
def interleave_planes(ipixels, apixels, ipsize, apsize):
    """
    Interleave (colour) planes, e.g. RGB + A = RGBA.

    Return an array of pixels consisting of the `ipsize` elements of
    data from each pixel in `ipixels` followed by the `apsize` elements
    of data from each pixel in `apixels`.  Conventionally `ipixels`
    and `apixels` are byte arrays so the sizes are bytes, but it
    actually works with any arrays of the same type.  The returned
    array is the same type as the input arrays which should be the
    same type as each other.
    """

    itotal = len(ipixels)
    atotal = len(apixels)
    newtotal = itotal + atotal
    newpsize = ipsize + apsize
    # Set up the output buffer
    # See http://www.python.org/doc/2.4.4/lib/module-array.html#l2h-1356
    out = array(ipixels.typecode)
    # It's annoying that there is no cheap way to set the array size :-(
    out.extend(ipixels)
    out.extend(apixels)
    # Interleave in the pixel data
    for i in range(ipsize):
        out[i:newtotal:newpsize] = ipixels[i:itotal:ipsize]
    for i in range(apsize):
        out[i+ipsize:newtotal:newpsize] = apixels[i:atotal:apsize]
    return out


Instruction:
Create a Python 3 function for
writing out the PNG file by writing out the chunks.

Response:
def write_chunks(out, chunks):
    """Create a PNG file by writing out the chunks."""

    out.write(_signature)
    for chunk in chunks:
        write_chunk(out, *chunk)


Instruction:
Explain what the following Python 3 code does
def filter_scanline(type, line, fo, prev=None):

    assert 0 <= type < 5

    # The output array.  Which, pathetically, we extend one-byte at a
    # time (fortunately this is linear).
    out = array('B', [type])

    def sub():
        ai = -fo
        for x in line:
            if ai >= 0:
                x = (x - line[ai]) & 0xff
            out.append(x)
            ai += 1
    def up():
        for i,x in enumerate(line):
            x = (x - prev[i]) & 0xff
            out.append(x)
    def average():
        ai = -fo
        for i,x in enumerate(line):
            if ai >= 0:
                x = (x - ((line[ai] + prev[i]) >> 1)) & 0xff
            else:
                x = (x - (prev[i] >> 1)) & 0xff
            out.append(x)
            ai += 1
    def paeth():
        # http://www.w3.org/TR/PNG/#9Filter-type-4-Paeth
        ai = -fo # also used for ci
        for i,x in enumerate(line):
            a = 0
            b = prev[i]
            c = 0

            if ai >= 0:
                a = line[ai]
                c = prev[ai]
            p = a + b - c
            pa = abs(p - a)
            pb = abs(p - b)
            pc = abs(p - c)
            if pa <= pb and pa <= pc:
                Pr = a
            elif pb <= pc:
                Pr = b
            else:
                Pr = c

            x = (x - Pr) & 0xff
            out.append(x)
            ai += 1

    if not prev:
        # We're on the first line.  Some of the filters can be reduced
        # to simpler cases which makes handling the line "off the top"
        # of the image simpler.  "up" becomes "none"; "paeth" becomes
        # "left" (non-trivial, but true). "average" needs to be handled
        # specially.
        if type == 2: # "up"
            type = 0
        elif type == 3:
            prev = [0]*len(line)
        elif type == 4: # "paeth"
            type = 1
    if type == 0:
        out.extend(line)
    elif type == 1:
        sub()
    elif type == 2:
        up()
    elif type == 3:
        average()
    else: # type == 4
        paeth()
    return out

Response: Apply a filter to a scanline.


Instruction:
Explain what the following Python 3 code does
def from_array(a, mode=None, info={}):

    # We abuse the *info* parameter by modifying it.  Take a copy here.
    # (Also typechecks *info* to some extent).
    info = dict(info)

    # Syntax check mode string.
    bitdepth = None
    try:
        # Assign the 'L' or 'RGBA' part to `gotmode`.
        if mode.startswith('L'):
            gotmode = 'L'
            mode = mode[1:]
        elif mode.startswith('RGB'):
            gotmode = 'RGB'
            mode = mode[3:]
        else:
            raise Error()
        if mode.startswith('A'):
            gotmode += 'A'
            mode = mode[1:]

        # Skip any optional ';'
        while mode.startswith(';'):
            mode = mode[1:]

        # Parse optional bitdepth
        if mode:
            try:
                bitdepth = int(mode)
            except (TypeError, ValueError):
                raise Error()
    except Error:
        raise Error("mode string should be 'RGB' or 'L;16' or similar.")
    mode = gotmode

    # Get bitdepth from *mode* if possible.
    if bitdepth:
        if info.get('bitdepth') and bitdepth != info['bitdepth']:
            raise Error("mode bitdepth (%d) should match info bitdepth (%d)." %
              (bitdepth, info['bitdepth']))
        info['bitdepth'] = bitdepth

    # Fill in and/or check entries in *info*.
    # Dimensions.
    if 'size' in info:
        # Check width, height, size all match where used.
        for dimension,axis in [('width', 0), ('height', 1)]:
            if dimension in info:
                if info[dimension] != info['size'][axis]:
                    raise Error(
                      "info[%r] should match info['size'][%r]." %
                      (dimension, axis))
        info['width'],info['height'] = info['size']
    if 'height' not in info:
        try:
            l = len(a)
        except TypeError:
            raise Error(
              "len(a) does not work, supply info['height'] instead.")
        info['height'] = l
    # Colour format.
    if 'greyscale' in info:
        if bool(info['greyscale']) != ('L' in mode):
            raise Error("info['greyscale'] should match mode.")
    info['greyscale'] = 'L' in mode
    if 'alpha' in info:
        if bool(info['alpha']) != ('A' in mode):
            raise Error("info['alpha'] should match mode.")
    info['alpha'] = 'A' in mode

    planes = len(mode)
    if 'planes' in info:
        if info['planes'] != planes:
            raise Error("info['planes'] should match mode.")

    # In order to work out whether we the array is 2D or 3D we need its
    # first row, which requires that we take a copy of its iterator.
    # We may also need the first row to derive width and bitdepth.
    a,t = itertools.tee(a)
    row = t.next()
    del t
    try:
        row[0][0]
        threed = True
        testelement = row[0]
    except (IndexError, TypeError):
        threed = False
        testelement = row
    if 'width' not in info:
        if threed:
            width = len(row)
        else:
            width = len(row) // planes
        info['width'] = width

    # Not implemented yet
    assert not threed

    if 'bitdepth' not in info:
        try:
            dtype = testelement.dtype
            # goto the "else:" clause.  Sorry.
        except AttributeError:
            try:
                # Try a Python array.array.
                bitdepth = 8 * testelement.itemsize
            except AttributeError:
                # We can't determine it from the array element's
                # datatype, use a default of 8.
                bitdepth = 8
        else:
            # If we got here without exception, we now assume that
            # the array is a numpy array.
            if dtype.kind == 'b':
                bitdepth = 1
            else:
                bitdepth = 8 * dtype.itemsize
        info['bitdepth'] = bitdepth

    for thing in 'width height bitdepth greyscale alpha'.split():
        assert thing in info
    return Image(a, info)

Response: Create a PNG image object from a 2 - dimensional array.


Instruction:
Here you have a function in Python 3, explain what it does
def make_palette(self):

        p = array('B')
        t = array('B')

        for x in self.palette:
            p.extend(x[0:3])
            if len(x) > 3:
                t.append(x[3])
        p = tostring(p)
        t = tostring(t)
        if t:
            return p,t
        return p,None

Response:
Create the byte sequences for a PLY and if necessary a
 tRNS chunk. Returned as a pair ( p t ) will be a pair ( t p ) will be a pair ( t ) will be a pair ( p t )


Instruction:
Explain what the following Python 3 code does
def write(self, outfile, rows):

        if self.interlace:
            fmt = 'BH'[self.bitdepth > 8]
            a = array(fmt, itertools.chain(*rows))
            return self.write_array(outfile, a)

        nrows = self.write_passes(outfile, rows)
        if nrows != self.height:
            raise ValueError(
              "rows supplied (%d) does not match height (%d)" %
              (nrows, self.height))

Response: Write a PNG image to the output file.


Instruction:
Can you create a Python 3 function that
writes a PNG image to the output file.

Response:
def write_passes(self, outfile, rows, packed=False):
        """
        Write a PNG image to the output file.

        Most users are expected to find the :meth:`write` or
        :meth:`write_array` method more convenient.

        The rows should be given to this method in the order that
        they appear in the output file.  For straightlaced images,
        this is the usual top to bottom ordering, but for interlaced
        images the rows should have already been interlaced before
        passing them to this function.

        `rows` should be an iterable that yields each row.  When
        `packed` is ``False`` the rows should be in boxed row flat pixel
        format; when `packed` is ``True`` each row should be a packed
        sequence of bytes.
        """

        # http://www.w3.org/TR/PNG/#5PNG-file-signature
        outfile.write(_signature)

        # http://www.w3.org/TR/PNG/#11IHDR
        write_chunk(outfile, 'IHDR',
                    struct.pack("!2I5B", self.width, self.height,
                                self.bitdepth, self.color_type,
                                0, 0, self.interlace))

        # See :chunk:order
        # http://www.w3.org/TR/PNG/#11gAMA
        if self.gamma is not None:
            write_chunk(outfile, 'gAMA',
                        struct.pack("!L", int(round(self.gamma*1e5))))

        # See :chunk:order
        # http://www.w3.org/TR/PNG/#11sBIT
        if self.rescale:
            write_chunk(outfile, 'sBIT',
                struct.pack('%dB' % self.planes,
                            *[self.rescale[0]]*self.planes))

        # :chunk:order: Without a palette (PLTE chunk), ordering is
        # relatively relaxed.  With one, gAMA chunk must precede PLTE
        # chunk which must precede tRNS and bKGD.
        # See http://www.w3.org/TR/PNG/#5ChunkOrdering
        if self.palette:
            p,t = self.make_palette()
            write_chunk(outfile, 'PLTE', p)
            if t:
                # tRNS chunk is optional. Only needed if palette entries
                # have alpha.
                write_chunk(outfile, 'tRNS', t)

        # http://www.w3.org/TR/PNG/#11tRNS
        if self.transparent is not None:
            if self.greyscale:
                write_chunk(outfile, 'tRNS',
                            struct.pack("!1H", *self.transparent))
            else:
                write_chunk(outfile, 'tRNS',
                            struct.pack("!3H", *self.transparent))

        # http://www.w3.org/TR/PNG/#11bKGD
        if self.background is not None:
            if self.greyscale:
                write_chunk(outfile, 'bKGD',
                            struct.pack("!1H", *self.background))
            else:
                write_chunk(outfile, 'bKGD',
                            struct.pack("!3H", *self.background))

        # http://www.w3.org/TR/PNG/#11IDAT
        if self.compression is not None:
            compressor = zlib.compressobj(self.compression)
        else:
            compressor = zlib.compressobj()

        # Choose an extend function based on the bitdepth.  The extend
        # function packs/decomposes the pixel values into bytes and
        # stuffs them onto the data array.
        data = array('B')
        if self.bitdepth == 8 or packed:
            extend = data.extend
        elif self.bitdepth == 16:
            # Decompose into bytes
            def extend(sl):
                fmt = '!%dH' % len(sl)
                data.extend(array('B', struct.pack(fmt, *sl)))
        else:
            # Pack into bytes
            assert self.bitdepth < 8
            # samples per byte
            spb = int(8/self.bitdepth)
            def extend(sl):
                a = array('B', sl)
                # Adding padding bytes so we can group into a whole
                # number of spb-tuples.
                l = float(len(a))
                extra = math.ceil(l / float(spb))*spb - l
                a.extend([0]*int(extra))
                # Pack into bytes
                l = group(a, spb)
                l = map(lambda e: reduce(lambda x,y:
                                           (x << self.bitdepth) + y, e), l)
                data.extend(l)
        if self.rescale:
            oldextend = extend
            factor = \
              float(2**self.rescale[1]-1) / float(2**self.rescale[0]-1)
            def extend(sl):
                oldextend(map(lambda x: int(round(factor*x)), sl))

        # Build the first row, testing mostly to see if we need to
        # changed the extend function to cope with NumPy integer types
        # (they cause our ordinary definition of extend to fail, so we
        # wrap it).  See
        # http://code.google.com/p/pypng/issues/detail?id=44
        enumrows = enumerate(rows)
        del rows

        # First row's filter type.
        data.append(0)
        # :todo: Certain exceptions in the call to ``.next()`` or the
        # following try would indicate no row data supplied.
        # Should catch.
        i,row = enumrows.next()
        try:
            # If this fails...
            extend(row)
        except:
            # ... try a version that converts the values to int first.
            # Not only does this work for the (slightly broken) NumPy
            # types, there are probably lots of other, unknown, "nearly"
            # int types it works for.
            def wrapmapint(f):
                return lambda sl: f(map(int, sl))
            extend = wrapmapint(extend)
            del wrapmapint
            extend(row)

        for i,row in enumrows:
            # Add "None" filter type.  Currently, it's essential that
            # this filter type be used for every scanline as we do not
            # mark the first row of a reduced pass image; that means we
            # could accidentally compute the wrong filtered scanline if
            # we used "up", "average", or "paeth" on such a line.
            data.append(0)
            extend(row)
            if len(data) > self.chunk_limit:
                compressed = compressor.compress(tostring(data))
                if len(compressed):
                    write_chunk(outfile, 'IDAT', compressed)
                # Because of our very witty definition of ``extend``,
                # above, we must re-use the same ``data`` object.  Hence
                # we use ``del`` to empty this one, rather than create a
                # fresh one (which would be my natural FP instinct).
                del data[:]
        if len(data):
            compressed = compressor.compress(tostring(data))
        else:
            compressed = strtobytes('')
        flushed = compressor.flush()
        if len(compressed) or len(flushed):
            write_chunk(outfile, 'IDAT', compressed + flushed)
        # http://www.w3.org/TR/PNG/#11IEND
        write_chunk(outfile, 'IEND')
        return i+1


Instruction:
Create a Python 3 function to
write PNG file to outfile.

Response:
def write_packed(self, outfile, rows):
        """
        Write PNG file to `outfile`.  The pixel data comes from `rows`
        which should be in boxed row packed format.  Each row should be
        a sequence of packed bytes.

        Technically, this method does work for interlaced images but it
        is best avoided.  For interlaced images, the rows should be
        presented in the order that they appear in the file.

        This method should not be used when the source image bit depth
        is not one naturally supported by PNG; the bit depth should be
        1, 2, 4, 8, or 16.
        """

        if self.rescale:
            raise Error("write_packed method not suitable for bit depth %d" %
              self.rescale[0])
        return self.write_passes(outfile, rows, packed=True)


Instruction:
How would you explain what the following Python 3 function does
def convert_pnm(self, infile, outfile):

        if self.interlace:
            pixels = array('B')
            pixels.fromfile(infile,
                            (self.bitdepth/8) * self.color_planes *
                            self.width * self.height)
            self.write_passes(outfile, self.array_scanlines_interlace(pixels))
        else:
            self.write_passes(outfile, self.file_scanlines(infile))

Response: Convert a PNM file into PNG.


Instruction:
Here you have a function in Python 3, explain what it does
def convert_ppm_and_pgm(self, ppmfile, pgmfile, outfile):
        pixels = array('B')
        pixels.fromfile(ppmfile,
                        (self.bitdepth/8) * self.color_planes *
                        self.width * self.height)
        apixels = array('B')
        apixels.fromfile(pgmfile,
                         (self.bitdepth/8) *
                         self.width * self.height)
        pixels = interleave_planes(pixels, apixels,
                                   (self.bitdepth/8) * self.color_planes,
                                   (self.bitdepth/8))
        if self.interlace:
            self.write_passes(outfile, self.array_scanlines_interlace(pixels))
        else:
            self.write_passes(outfile, self.array_scanlines(pixels))

Response: Convert a PPM and PGM file containing raw pixel data into PNG outfile.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def file_scanlines(self, infile):

        # Values per row
        vpr = self.width * self.planes
        row_bytes = vpr
        if self.bitdepth > 8:
            assert self.bitdepth == 16
            row_bytes *= 2
            fmt = '>%dH' % vpr
            def line():
                return array('H', struct.unpack(fmt, infile.read(row_bytes)))
        else:
            def line():
                scanline = array('B', infile.read(row_bytes))
                return scanline
        for y in range(self.height):
            yield line()

Response:
Generates boxed rows in flat pixel format from the input file
        infile.


Instruction:
Write a Python 3 script to
undo the filter for a scanline.

Response:
def undo_filter(self, filter_type, scanline, previous):
        """Undo the filter for a scanline.  `scanline` is a sequence of
        bytes that does not include the initial filter type byte.
        `previous` is decoded previous scanline (for straightlaced
        images this is the previous pixel row, but for interlaced
        images, it is the previous scanline in the reduced image, which
        in general is not the previous pixel row in the final image).
        When there is no previous scanline (the first row of a
        straightlaced image, or the first row in one of the passes in an
        interlaced image), then this argument should be ``None``.

        The scanline will have the effects of filtering removed, and the
        result will be returned as a fresh sequence of bytes.
        """

        # :todo: Would it be better to update scanline in place?
        # Yes, with the Cython extension making the undo_filter fast,
        # updating scanline inplace makes the code 3 times faster
        # (reading 50 images of 800x800 went from 40s to 16s)
        result = scanline

        if filter_type == 0:
            return result

        if filter_type not in (1,2,3,4):
            raise FormatError('Invalid PNG Filter Type.'
              '  See http://www.w3.org/TR/2003/REC-PNG-20031110/#9Filters .')

        # Filter unit.  The stride from one pixel to the corresponding
        # byte from the previous pixel.  Normally this is the pixel
        # size in bytes, but when this is smaller than 1, the previous
        # byte is used instead.
        fu = max(1, self.psize)

        # For the first line of a pass, synthesize a dummy previous
        # line.  An alternative approach would be to observe that on the
        # first line 'up' is the same as 'null', 'paeth' is the same
        # as 'sub', with only 'average' requiring any special case.
        if not previous:
            previous = array('B', [0]*len(scanline))

        def sub():
            """Undo sub filter."""

            ai = 0
            # Loop starts at index fu.  Observe that the initial part
            # of the result is already filled in correctly with
            # scanline.
            for i in range(fu, len(result)):
                x = scanline[i]
                a = result[ai]
                result[i] = (x + a) & 0xff
                ai += 1

        def up():
            """Undo up filter."""

            for i in range(len(result)):
                x = scanline[i]
                b = previous[i]
                result[i] = (x + b) & 0xff

        def average():
            """Undo average filter."""

            ai = -fu
            for i in range(len(result)):
                x = scanline[i]
                if ai < 0:
                    a = 0
                else:
                    a = result[ai]
                b = previous[i]
                result[i] = (x + ((a + b) >> 1)) & 0xff
                ai += 1

        def paeth():
            """Undo Paeth filter."""

            # Also used for ci.
            ai = -fu
            for i in range(len(result)):
                x = scanline[i]
                if ai < 0:
                    a = c = 0
                else:
                    a = result[ai]
                    c = previous[ai]
                b = previous[i]
                p = a + b - c
                pa = abs(p - a)
                pb = abs(p - b)
                pc = abs(p - c)
                if pa <= pb and pa <= pc:
                    pr = a
                elif pb <= pc:
                    pr = b
                else:
                    pr = c
                result[i] = (x + pr) & 0xff
                ai += 1

        # Call appropriate filter algorithm.  Note that 0 has already
        # been dealt with.
        (None,
         pngfilters.undo_filter_sub,
         pngfilters.undo_filter_up,
         pngfilters.undo_filter_average,
         pngfilters.undo_filter_paeth)[filter_type](fu, scanline, previous, result)
        return result