Instruction:
Write a Python 3 script for
calculating the range of an axis of a viewBox.

Response:
def viewBoxAxisRange(viewBox, axisNumber):
    """ Calculates the range of an axis of a viewBox.
    """
    rect = viewBox.childrenBoundingRect() # taken from viewBox.autoRange()
    if rect is not None:
        if axisNumber == X_AXIS:
            return rect.left(), rect.right()
        elif axisNumber == Y_AXIS:
            return rect.bottom(), rect.top()
        else:
            raise ValueError("axisNumber should be 0 or 1, got: {}".format(axisNumber))
    else:
        # Does this happen? Probably when the plot is empty.
        raise AssertionError("No children bbox. Plot range not updated.")


Instruction:
Write a Python 3 function that can
calculate the range from the sliced array.

Response:
def inspectorDataRange(inspector, percentage):
    """ Calculates the range from the inspectors' sliced array. Discards percentage of the minimum
        and percentage of the maximum values of the inspector.slicedArray

        Meant to be used with functools.partial for filling the autorange methods combobox.
        The first parameter is an inspector, it's not an array, because we would then have to
        regenerate the range function every time sliced array of an inspector changes.
    """
    logger.debug("Discarding {}% from id: {}".format(percentage, id(inspector.slicedArray)))
    return maskedNanPercentile(inspector.slicedArray, (percentage, 100-percentage) )


Instruction:
Make a summary of the following Python 3 code
def defaultAutoRangeMethods(inspector, intialItems=None):
    rangeFunctions = OrderedDict({} if intialItems is None else intialItems)
    rangeFunctions['use all data'] = partial(inspectorDataRange, inspector, 0.0)
    for percentage in [0.1, 0.2, 0.5, 1, 2, 5, 10, 20]:
        label = "discard {}%".format(percentage)
        rangeFunctions[label] = partial(inspectorDataRange, inspector, percentage)
    return rangeFunctions

Response: Returns an ordered dict with default autorange methods for an inspector.


Instruction:
Explain what the following Python 3 code does
def setXYAxesAutoRangeOn(commonCti, xAxisRangeCti, yAxisRangeCti, axisNumber):
    assert axisNumber in VALID_AXIS_NUMBERS, \
        "Axis number should be one of {}, got {}".format(VALID_AXIS_NUMBERS, axisNumber)

    logger.debug("setXYAxesAutoRangeOn, axisNumber: {}".format(axisNumber))
    if axisNumber == X_AXIS or axisNumber == BOTH_AXES:
        xAxisRangeCti.autoRangeCti.data = True

    if axisNumber == Y_AXIS or axisNumber == BOTH_AXES:
        yAxisRangeCti.autoRangeCti.data = True

    commonCti.model.sigItemChanged.emit(commonCti)

Response: Turn on the auto range of an X and Y axes simultaneously.


Instruction:
Write a Python 3 function that can
update the config settings of the node from the target node.

Response:
def _refreshNodeFromTarget(self):
        """ Updates the config settings
        """
        for key, value in self.viewBox.state.items():
            if key != "limits":
                childItem = self.childByNodeName(key)
                childItem.data = value
            else:
                # limits contains a dictionary as well
                for limitKey, limitValue in value.items():
                    limitChildItem = self.limitsItem.childByNodeName(limitKey)
                    limitChildItem.data = limitValue


Instruction:
Given the following Python 3 function, write the documentation
def autoRangeMethod(self):
        if self.methodCti:
            return self.methodCti.configValue
        else:
            assert len(self._rangeFunctions) == 1, \
                "Assumed only one _rangeFunctions. Got: {}".format(self._rangeFunctions)
            return list(self._rangeFunctions.keys())[0]

Response: Returns the auto range method for the current CTI.


Instruction:
Create a Python 3 function for
refreshing the min max config values from the axes state.

Response:
def _forceRefreshMinMax(self):
        """ Refreshes the min max config values from the axes' state.
        """
        #logger.debug("_forceRefreshMinMax", stack_info=True)

        # Set the precision from by looking how many decimals are needed to show the difference
        # between the minimum and maximum, given the maximum. E.g. if min = 0.04 and max = 0.07,
        # we would only need zero decimals behind the point as we can write the range as
        # [4e-2, 7e-2]. However if min = 1.04 and max = 1.07, we need 2 decimals behind the point.
        # So, while the range is the same size we need more decimals because we are not zoomed in
        # around zero.
        rangeMin, rangeMax = self.getTargetRange() # [[xmin, xmax], [ymin, ymax]]
        maxOrder = np.log10(np.abs(max(rangeMax, rangeMin)))
        diffOrder = np.log10(np.abs(rangeMax - rangeMin))

        extraDigits = 2 # add some extra digits to make each pan/zoom action show a new value.
        precisionF = np.clip(abs(maxOrder - diffOrder) + extraDigits, extraDigits + 1, 25)
        precision = int(precisionF) if np.isfinite(precisionF) else extraDigits + 1
        #logger.debug("maxOrder: {}, diffOrder: {}, precision: {}"
        #             .format(maxOrder, diffOrder, precision))

        self.rangeMinCti.precision = precision
        self.rangeMaxCti.precision = precision
        self.rangeMinCti.data, self.rangeMaxCti.data = rangeMin, rangeMax

        # Update values in the tree
        self.model.emitDataChanged(self.rangeMinCti)
        self.model.emitDataChanged(self.rangeMaxCti)


Instruction:
Write a Python 3 script to
refresh the min max config values from the axes state.

Response:
def refreshMinMax(self):
        """ Refreshes the min max config values from the axes' state.
            Does nothing when self.getRefreshBlocked() returns True.
        """
        if self.getRefreshBlocked():
            logger.debug("refreshMinMax blocked for {}".format(self.nodeName))
            return

        self._forceRefreshMinMax()


Instruction:
Can you write a function in Python 3 where it
forces refreshing the auto range.

Response:
def _forceRefreshAutoRange(self):
        """ The min and max config items will be disabled if auto range is on.
        """
        enabled = self.autoRangeCti and self.autoRangeCti.configValue
        self.rangeMinCti.enabled = not enabled
        self.rangeMaxCti.enabled = not enabled
        self.model.emitDataChanged(self)


Instruction:
Can you write a function in Python 3 where it
turns off the auto range checkbox.

Response:
def setAutoRangeOff(self):
        """ Turns off the auto range checkbox.
            Calls _refreshNodeFromTarget, not _updateTargetFromNode, because setting auto range off
            does not require a redraw of the target.
        """
        # TODO: catch exceptions. How?
        # /argos/hdf-eos/DeepBlue-SeaWiFS-1.0_L3_20100101_v002-20110527T191319Z.h5/aerosol_optical_thickness_stddev_ocean
        if self.getRefreshBlocked():
            logger.debug("setAutoRangeOff blocked for {}".format(self.nodeName))
            return

        if self.autoRangeCti:
            self.autoRangeCti.data = False

        self._forceRefreshAutoRange()


Instruction:
Can you generate the documentation for the following Python 3 function
def setAutoRangeOn(self):
        if self.getRefreshBlocked():
            logger.debug("Set autorange on blocked for {}".format(self.nodeName))
            return

        if self.autoRangeCti:
            self.autoRangeCti.data = True
        self.model.sigItemChanged.emit(self)

Response: Turns on the auto range checkbox for the equivalent axes


Instruction:
Explain what the following Python 3 code does
def calculateRange(self):
        if not self.autoRangeCti or not self.autoRangeCti.configValue:
            return (self.rangeMinCti.data, self.rangeMaxCti.data)
        else:
            rangeFunction = self._rangeFunctions[self.autoRangeMethod]
            return rangeFunction()

Response: Calculates the range depending on the autoRangeCti and autoRangeMethod settings.


Instruction:
Implement a function in Python 3 to
update the target axis to match the current configuration.

Response:
def _updateTargetFromNode(self):
        """ Applies the configuration to the target axis.
        """
        if not self.autoRangeCti or not self.autoRangeCti.configValue:
            padding = 0
        elif self.paddingCti.configValue == -1: # specialValueText
            # PyQtGraph dynamic padding: between 0.02 and 0.1 dep. on the size of the ViewBox
            padding = None
        else:
            padding = self.paddingCti.configValue / 100

        targetRange = self.calculateRange()
        #logger.debug("axisRange: {}, padding={}".format(targetRange, padding))
        if not np.all(np.isfinite(targetRange)):
            logger.warn("New target range is not finite. Plot range not updated")
            return

        self.setTargetRange(targetRange, padding=padding)


Instruction:
How would you code a function in Python 3 to
disconnect signals. Is called by self. finalize when the cti is deleted.

Response:
def _closeResources(self):
        """ Disconnects signals.
            Is called by self.finalize when the cti is deleted.
        """
        self.viewBox.sigRangeChangedManually.disconnect(self.setAutoRangeOff)
        self.viewBox.sigRangeChanged.disconnect(self.refreshMinMax)


Instruction:
Implement a function in Python 3 to
set the range of the target.

Response:
def setTargetRange(self, targetRange, padding=None):
        """ Sets the range of the target.
        """
        # viewBox.setRange doesn't accept an axis number :-(
        if self.axisNumber == X_AXIS:
            xRange, yRange = targetRange, None
        else:
            xRange, yRange = None, targetRange

        # Do not set disableAutoRange to True in setRange; it triggers 'one last' auto range.
        # This is why the viewBox' autorange must be False at construction.
        self.viewBox.setRange(xRange = xRange, yRange=yRange, padding=padding,
                              update=False, disableAutoRange=False)


Instruction:
Implement a function in Python 3 to
disconnect signals. Is called by self. finalize when the cti is deleted.

Response:
def _closeResources(self):
        """ Disconnects signals.
            Is called by self.finalize when the cti is deleted.
        """
        self.histLutItem.sigLevelsChanged.disconnect(self.setAutoRangeOff)
        self.histLutItem.sigLevelsChanged.disconnect(self.refreshMinMax)


Instruction:
Here you have a function in Python 3, explain what it does
def setTargetRange(self, targetRange, padding=None):
        rangeMin, rangeMax = targetRange
        self.histLutItem.setLevels(rangeMin, rangeMax)

Response: Sets the range of the histogram LUT item.


Instruction:
Create a Python 3 function for
applying the configuration to its target axis.

Response:
def _updateTargetFromNode(self):
        """ Applies the configuration to its target axis
        """
        self.viewBox.setAspectLocked(lock=self.configValue, ratio=self.aspectRatioCti.configValue)


Instruction:
Given the following Python 3 function, write the documentation
def _updateTargetFromNode(self):
        if self.axisNumber == X_AXIS:
            self.viewBox.invertX(self.configValue)
        else:
            self.viewBox.invertY(self.configValue)

Response: Applies the configuration to its target axis.


Instruction:
Given the following Python 3 function, write the documentation
def _updateTargetFromNode(self):
        rtiInfo = self.collector.rtiInfo
        self.plotItem.setLabel(self.axisPosition, self.configValue.format(**rtiInfo))
        self.plotItem.showLabel(self.axisPosition, self.configValue != self.NO_LABEL)

Response: Applies the configuration to the target axis it monitors.


Instruction:
Can you generate the documentation for the following Python 3 function
def _updateTargetFromNode(self):
        logger.debug("showAxis: {}, {}".format(self.axisPosition, self.configValue))
        self.plotItem.showAxis(self.axisPosition, show=self.configValue)

Response: Applies the configuration to its target axis


Instruction:
How would you explain what the following Python 3 function does
def _updateTargetFromNode(self):
        if self.axisNumber == X_AXIS:
            xMode, yMode = self.configValue, None
        else:
            xMode, yMode = None, self.configValue

        self.plotItem.setLogMode(x=xMode, y=yMode)

Response: Applies the configuration to its target axis and updates the plotItem s log mode.


Instruction:
Here you have a function in Python 3, explain what it does
def _updateTargetFromNode(self):
        self.plotItem.showGrid(x=self.xGridCti.configValue, y=self.yGridCti.configValue,
                               alpha=self.alphaCti.configValue)
        self.plotItem.updateGrid()

Response: Updates the grid of the target of the item.


Instruction:
Given the following Python 3 function, write the documentation
def createPlotDataItem(self):
        antialias = self.antiAliasCti.configValue

        color = self.penColor
        if self.lineCti.configValue:
            pen = QtGui.QPen()
            pen.setCosmetic(True)
            pen.setColor(color)
            pen.setWidthF(self.lineWidthCti.configValue)
            pen.setStyle(self.lineStyleCti.configValue)
            shadowCti = self.lineCti.findByNodePath('shadow')
            shadowPen = shadowCti.createPen(altStyle=pen.style(), altWidth=2.0 * pen.widthF())
        else:
            pen = None
            shadowPen = None

        drawSymbols = self.symbolCti.configValue
        symbolShape = self.symbolShapeCti.configValue if drawSymbols else None
        symbolSize  = self.symbolSizeCti.configValue if drawSymbols else 0.0
        symbolPen = None # otherwise the symbols will also have dotted/solid line.
        symbolBrush = QtGui.QBrush(color) if drawSymbols else None

        plotDataItem = pg.PlotDataItem(antialias=antialias, pen=pen, shadowPen=shadowPen,
                                       symbol=symbolShape, symbolSize=symbolSize,
                                       symbolPen=symbolPen, symbolBrush=symbolBrush)
        return plotDataItem

Response: Creates a PyQtGraph PlotDataItem from the config values.


Instruction:
Can you tell what is the following Python 3 function doing
def _drawContents(self, currentRti=None):
        table = self.table
        table.setUpdatesEnabled(False)
        try:
            table.clearContents()
            verticalHeader = table.verticalHeader()
            verticalHeader.setSectionResizeMode(QtWidgets.QHeaderView.Fixed)

            if currentRti is None:
                return

            # Each column in the repo tree corresponds to a row in this detail pane.
            repoModel = self._repoTreeView.model()
            propNames = RepoTreeModel.HEADERS
            table.setRowCount(len(propNames))

            for row, propName in enumerate(propNames):
                nameItem = QtWidgets.QTableWidgetItem(propName)
                nameItem.setToolTip(propName)
                table.setItem(row, self.COL_PROP_NAME, nameItem)
                propValue = repoModel.itemData(currentRti, row)
                propItem = QtWidgets.QTableWidgetItem(propValue)
                propItem.setToolTip(propValue)
                table.setItem(row, self.COL_VALUE, propItem)
                table.resizeRowToContents(row)

            verticalHeader.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        finally:
            table.setUpdatesEnabled(True)

Response: Draw the attributes of the currentRTI and the details pane.


Instruction:
Can you generate the documentation for the following Python 3 function
def itemData(self, treeItem, column, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            if column == self.COL_NODE_NAME:
                return treeItem.nodeName
            elif column == self.COL_NODE_PATH:
                return treeItem.nodePath
            elif column == self.COL_SHAPE:
                if treeItem.isSliceable:
                    return " x ".join(str(elem) for elem in treeItem.arrayShape)
                else:
                    return ""
            elif column == self.COL_IS_OPEN:
                # Only show for RTIs that actually open resources.
                # TODO: this must be clearer. Use CanFetchChildren? Set is Open to None by default?
                if treeItem.hasChildren():
                    return str(treeItem.isOpen)
                else:
                    return ""
            elif column == self.COL_ELEM_TYPE:
                return treeItem.elementTypeName
            elif column == self.COL_FILE_NAME:
                return treeItem.fileName if hasattr(treeItem, 'fileName') else ''
            elif column == self.COL_UNIT:
                return treeItem.unit
            elif column == self.COL_MISSING_DATA:
                return to_string(treeItem.missingDataValue, noneFormat='') # empty str for Nones
            elif column == self.COL_RTI_TYPE:
                return type_name(treeItem)
            elif column == self.COL_EXCEPTION:
                return str(treeItem.exception) if treeItem.exception else ''
            else:
                raise ValueError("Invalid column: {}".format(column))

        elif role == Qt.ToolTipRole:
            if treeItem.exception:
                return str(treeItem.exception)
            if column == self.COL_NODE_NAME:
                return treeItem.nodePath # Also path when hovering over the name
            elif column == self.COL_NODE_PATH:
                return treeItem.nodePath
            elif column == self.COL_SHAPE:
                if treeItem.isSliceable:
                    return " x ".join(str(elem) for elem in treeItem.arrayShape)
                else:
                    return ""
            elif column == self.COL_UNIT:
                return treeItem.unit
            elif column == self.COL_MISSING_DATA:
                return to_string(treeItem.missingDataValue, noneFormat='') # empty str for Nones
            elif column == self.COL_RTI_TYPE:
                return type_name(treeItem)
            elif column == self.COL_ELEM_TYPE:
                return treeItem.elementTypeName
            elif column == self.COL_FILE_NAME:
                return treeItem.fileName if hasattr(treeItem, 'fileName') else ''
            else:
                return None
        else:
            return super(RepoTreeModel, self).itemData(treeItem, column, role=role)

Response: Returns the data stored under the given role for the item.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def canFetchMore(self, parentIndex):
        parentItem = self.getItem(parentIndex)
        if not parentItem:
            return False

        return parentItem.canFetchChildren()

Response: Returns true if there is more data available for the parent item ; otherwise returns false.


Instruction:
Make a summary of the following Python 3 code
def fetchMore(self, parentIndex):  # TODO: Make LazyLoadRepoTreeModel?
        parentItem = self.getItem(parentIndex)
        if not parentItem:
            return

        if not parentItem.canFetchChildren():
            return

        # TODO: implement InsertItems to optimize?
        for childItem in parentItem.fetchChildren():
            self.insertItem(childItem, parentIndex=parentIndex)

        # Check that Rti implementation correctly sets canFetchChildren
        assert not parentItem.canFetchChildren(), \
            "not all children fetched: {}".format(parentItem)

Response: Fetches any available data for the items with the parent specified by the parent index.


Instruction:
Can you generate the documentation for the following Python 3 function
def findFileRtiIndex(self, childIndex):
        parentIndex = childIndex.parent()
        if not parentIndex.isValid():
            return childIndex
        else:
            parentItem = self.getItem(parentIndex)
            childItem = self.getItem(childIndex)
            if parentItem.fileName == childItem.fileName:
                return self.findFileRtiIndex(parentIndex)
            else:
                return childIndex

Response: Finds the tree item at the given index and returns the index of the file that represents the item at the given index.


Instruction:
Explain what the following Python 3 code does
def reloadFileAtIndex(self, itemIndex, rtiClass=None):
        fileRtiParentIndex = itemIndex.parent()
        fileRti = self.getItem(itemIndex)
        position = fileRti.childNumber()
        fileName = fileRti.fileName

        if rtiClass is None:
            rtiClass = type(fileRti)

        # Delete old RTI and Insert a new one instead.
        self.deleteItemAtIndex(itemIndex) # this will close the items resources.
        return self.loadFile(fileName, rtiClass, position=position, parentIndex=fileRtiParentIndex)

Response: Reloads the item at the index by removing the old one and inserting a new one.


Instruction:
Write a Python 3 function for
loading a file in the repository as a repo tree item of class rtiClass.

Response:
def loadFile(self, fileName, rtiClass=None,
                 position=None, parentIndex=QtCore.QModelIndex()):
        """ Loads a file in the repository as a repo tree item of class rtiClass.
            Autodetects the RTI type if rtiClass is None.
            If position is None the child will be appended as the last child of the parent.
            Returns the index of the newly inserted RTI
        """
        logger.info("Loading data from: {!r}".format(fileName))
        if rtiClass is None:
            repoTreeItem = createRtiFromFileName(fileName)
        else:
            repoTreeItem = rtiClass.createFromFileName(fileName)
        assert repoTreeItem.parentItem is None, "repoTreeItem {!r}".format(repoTreeItem)
        return self.insertItem(repoTreeItem, position=position, parentIndex=parentIndex)


Instruction:
Can you write a function in Python 3 where it
disconnects signals and frees resources

Response:
def finalize(self):
        """ Disconnects signals and frees resources
        """
        self.model().sigItemChanged.disconnect(self.repoTreeItemChanged)

        selectionModel = self.selectionModel() # need to store reference to prevent crash in PySide
        selectionModel.currentChanged.disconnect(self.currentItemChanged)


Instruction:
Can you tell what is the following Python 3 function doing
def contextMenuEvent(self, event):
        menu = QtWidgets.QMenu(self)

        for action in self.actions():
            menu.addAction(action)

        openAsMenu = self.createOpenAsMenu(parent=menu)
        menu.insertMenu(self.closeItemAction, openAsMenu)

        menu.exec_(event.globalPos())

Response: Creates and executes the context menu for the tree view


Instruction:
Can you tell what is the following Python 3 function doing
def createOpenAsMenu(self, parent=None):
        openAsMenu = QtWidgets.QMenu(parent=parent)
        openAsMenu.setTitle("Open Item As")

        registry = globalRtiRegistry()
        for rtiRegItem in registry.items:
            #rtiRegItem.tryImportClass()
            def createTrigger():
                """Function to create a closure with the regItem"""
                _rtiRegItem = rtiRegItem # keep reference in closure
                return lambda: self.reloadFileOfCurrentItem(_rtiRegItem)

            action = QtWidgets.QAction("{}".format(rtiRegItem.name), self,
                enabled=bool(rtiRegItem.successfullyImported is not False),
                triggered=createTrigger())
            openAsMenu.addAction(action)

        return openAsMenu

Response: Creates the menu for the Open Item As choice


Instruction:
How would you implement a function in Python 3 that
opens the current item in the repository.

Response:
def openCurrentItem(self):
        """ Opens the current item in the repository.
        """
        logger.debug("openCurrentItem")
        _currentItem, currentIndex = self.getCurrentItem()
        if not currentIndex.isValid():
            return

        # Expanding the node will call indirectly call RepoTreeModel.fetchMore which will call
        # BaseRti.fetchChildren, which will call BaseRti.open and thus open the current RTI.
        # BaseRti.open will emit the self.model.sigItemChanged signal, which is connected to
        # RepoTreeView.onItemChanged.
        self.expand(currentIndex)


Instruction:
Can you write a function in Python 3 where it
closes the current item in the repository.

Response:
def closeCurrentItem(self):
        """ Closes the current item in the repository.
            All its children will be unfetched and closed.
        """
        logger.debug("closeCurrentItem")
        currentItem, currentIndex = self.getCurrentItem()
        if not currentIndex.isValid():
            return

        # First we remove all the children, this will close them as well.
        self.model().removeAllChildrenAtIndex(currentIndex)

        # Close the current item. BaseRti.close will emit the self.model.sigItemChanged signal,
        # which is connected to RepoTreeView.onItemChanged.
        currentItem.close()
        self.dataChanged(currentIndex, currentIndex)
        self.collapse(currentIndex)


Instruction:
Make a summary of the following Python 3 code
def removeCurrentItem(self):
        logger.debug("removeCurrentFile")
        currentIndex = self.getRowCurrentIndex()
        if not currentIndex.isValid():
            return

        self.model().deleteItemAtIndex(currentIndex)

Response: Removes the current item from the repository tree.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def reloadFileOfCurrentItem(self, rtiRegItem=None):
        logger.debug("reloadFileOfCurrentItem, rtiClass={}".format(rtiRegItem))

        currentIndex = self.getRowCurrentIndex()
        if not currentIndex.isValid():
            return

        currentItem, _ = self.getCurrentItem()
        oldPath = currentItem.nodePath

        fileRtiIndex = self.model().findFileRtiIndex(currentIndex)
        isExpanded = self.isExpanded(fileRtiIndex)

        if rtiRegItem is None:
            rtiClass = None
        else:
            rtiRegItem.tryImportClass()
            rtiClass = rtiRegItem.cls

        newRtiIndex = self.model().reloadFileAtIndex(fileRtiIndex, rtiClass=rtiClass)

        try:
            # Expand and select the name with the old path
            _lastItem, lastIndex = self.expandPath(oldPath)
            self.setCurrentIndex(lastIndex)
            return lastIndex
        except Exception as ex:
            # The old path may not exist anymore. In that case select file RTI
            logger.warning("Unable to select {!r} beause of: {}".format(oldPath, ex))
            self.setExpanded(newRtiIndex, isExpanded)
            self.setCurrentIndex(newRtiIndex)
            return newRtiIndex

Response: Reloads the file of the current item.


Instruction:
Write a Python 3 function for
calling when the repo tree item has changed

Response:
def repoTreeItemChanged(self, rti):
        """ Called when repo tree item has changed (the item itself, not a new selection)

            If the item is the currently selected item, the the collector (inspector) and
            metadata widgets are updated.
        """
        logger.debug("onItemChanged: {}".format(rti))
        currentItem, _currentIndex = self.getCurrentItem()

        if rti == currentItem:
            self.currentRepoTreeItemChanged()
        else:
            logger.debug("Ignoring changed item as is not the current item: {}".format(rti))


Instruction:
Create a Python 3 function for
calling when a new repo tree item has changed or a new one was selected.

Response:
def currentRepoTreeItemChanged(self):
        """ Called to update the GUI when a repo tree item has changed or a new one was selected.
        """
        # When the model is empty the current index may be invalid and the currentItem may be None.
        currentItem, currentIndex = self.getCurrentItem()

        hasCurrent = currentIndex.isValid()
        assert hasCurrent == (currentItem is not None), \
            "If current idex is valid, currentIndex may not be None" # sanity check

        # Set the item in the collector, will will subsequently update the inspector.
        if hasCurrent:
            logger.info("Adding rti to collector: {}".format(currentItem.nodePath))
            self.collector.setRti(currentItem)
            #if rti.asArray is not None: # TODO: maybe later, first test how robust it is now
            #    self.collector.setRti(rti)

        # Update context menus in the repo tree
        self.currentItemActionGroup.setEnabled(hasCurrent)
        isTopLevel = hasCurrent and self.model().isTopLevelIndex(currentIndex)
        self.topLevelItemActionGroup.setEnabled(isTopLevel)
        self.openItemAction.setEnabled(currentItem is not None
                                       and currentItem.hasChildren()
                                       and not currentItem.isOpen)
        self.closeItemAction.setEnabled(currentItem is not None
                                        and currentItem.hasChildren()
                                        and currentItem.isOpen)

        # Emit sigRepoItemChanged signal so that, for example, details panes can update.
        logger.debug("Emitting sigRepoItemChanged: {}".format(currentItem))
        self.sigRepoItemChanged.emit(currentItem)


Instruction:
How would you explain what the following Python 3 function does
def initQApplication():
    # PyQtGraph recommends raster graphics system for OS-X.
    if 'darwin' in sys.platform:
        graphicsSystem = "raster" # raster, native or opengl
        os.environ.setdefault('QT_GRAPHICSSYSTEM', graphicsSystem)
        logger.info("Setting QT_GRAPHICSSYSTEM to: {}".format(graphicsSystem))

    app = QtWidgets.QApplication(sys.argv)
    initArgosApplicationSettings(app)
    return app

Response: Initializes the QtWidgets. QApplication instance. Creates one if it doesn t exist.


Instruction:
Can you write a function in Python 3 where it
initializes the Argos application settings.

Response:
def initArgosApplicationSettings(app): # TODO: this is Argos specific. Move somewhere else.
    """ Sets Argos specific attributes, such as the OrganizationName, so that the application
        persistent settings are read/written to the correct settings file/winreg. It is therefore
        important to call this function at startup. The ArgosApplication constructor does this.
    """
    assert app, \
        "app undefined. Call QtWidgets.QApplication.instance() or QtCor.QApplication.instance() first."

    logger.debug("Setting Argos QApplication settings.")
    app.setApplicationName(info.REPO_NAME)
    app.setApplicationVersion(info.VERSION)
    app.setOrganizationName(info.ORGANIZATION_NAME)
    app.setOrganizationDomain(info.ORGANIZATION_DOMAIN)


Instruction:
Write a Python 3 function that can
remove a group from the persistent settings

Response:
def removeSettingsGroup(groupName, settings=None):
    """ Removes a group from the persistent settings
    """
    logger.debug("Removing settings group: {}".format(groupName))
    settings = QtCore.QSettings() if settings is None else settings
    settings.remove(groupName)


Instruction:
Explain what the following Python 3 code does
def containsSettingsGroup(groupName, settings=None):
    def _containsPath(path, settings):
        "Aux function for containsSettingsGroup. Does the actual recursive search."
        if len(path) == 0:
            return True
        else:
            head = path[0]
            tail = path[1:]
            if head not in settings.childGroups():
                return False
            else:
                settings.beginGroup(head)
                try:
                    return _containsPath(tail, settings)
                finally:
                    settings.endGroup()

    # Body starts here
    path = os.path.split(groupName)
    logger.debug("Looking for path: {}".format(path))
    settings = QtCore.QSettings() if settings is None else settings
    return _containsPath(path, settings)

Response: Returns True if the settings contains a group with the name groupName.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def printAllWidgets(qApplication, ofType=None):
    print ("Application's widgets {}".format(('of type: ' + str(ofType)) if ofType else ''))
    for widget in qApplication.allWidgets():
        if ofType is None or isinstance(widget, ofType):
            print ("  {!r}".format(widget))

Response: Prints list of all widgets in the given application to stdout.


Instruction:
How would you implement a function in Python 3 that
returns the rectangle of a check box drawn as a sub element of widget

Response:
def widgetSubCheckBoxRect(widget, option):
    """ Returns the rectangle of a check box drawn as a sub element of widget
    """
    opt = QtWidgets.QStyleOption()
    opt.initFrom(widget)
    style = widget.style()
    return style.subElementRect(QtWidgets.QStyle.SE_ViewItemCheckIndicator, opt, widget)


Instruction:
Here you have a function in Python 3, explain what it does
def resizeEvent(self, event):
        result = super(ResizeDetailsMessageBox, self).resizeEvent(event)

        details_box = self.findChild(QtWidgets.QTextEdit)
        if details_box is not None:
            #details_box.setFixedSize(details_box.sizeHint())
            details_box.setFixedSize(QtCore.QSize(self.detailsBoxWidth, self.detailBoxHeight))

        return result

Response: Resizes the details box if present.


Instruction:
Explain what the following Python 3 code does
def _drawContents(self, currentRti=None):
        #logger.debug("_drawContents: {}".format(currentRti))
        table = self.table
        table.setUpdatesEnabled(False)
        try:
            table.clearContents()
            verticalHeader = table.verticalHeader()
            verticalHeader.setSectionResizeMode(QtWidgets.QHeaderView.Fixed)

            attributes = currentRti.attributes if currentRti is not None else {}
            table.setRowCount(len(attributes))

            for row, (attrName, attrValue) in enumerate(sorted(attributes.items())):
                attrStr = to_string(attrValue, decode_bytes='utf-8')

                try:
                    type_str = type_name(attrValue)
                except Exception as ex:
                    logger.exception(ex)
                    type_str = "<???>"

                nameItem = QtWidgets.QTableWidgetItem(attrName)
                nameItem.setToolTip(attrName)
                table.setItem(row, self.COL_ATTR_NAME, nameItem)
                valItem = QtWidgets.QTableWidgetItem(attrStr)
                valItem.setToolTip(attrStr)
                table.setItem(row, self.COL_VALUE, valItem)
                table.setItem(row, self.COL_ELEM_TYPE, QtWidgets.QTableWidgetItem(type_str))
                table.resizeRowToContents(row)

            verticalHeader.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        finally:
            table.setUpdatesEnabled(True)

Response: Draw the contents of the current RTI and all of its children.


Instruction:
Can you write a function in Python 3 where it
raises ValueError if the reason is not one of the enumerations .

Response:
def checkValid(cls, reason):
        """ Raises ValueError if the reason is not one of the valid enumerations
        """
        if reason not in cls.__VALID_REASONS:
            raise ValueError("reason must be one of {}, got {}".format(cls.__VALID_REASONS, reason))


Instruction:
Can you write a function in Python 3 where it
updates the contents of the current item in the configuration tree.

Response:
def updateContents(self, reason=None, initiator=None): # TODO: reason mandatory?
        """ Tries to draw the widget contents with the updated RTI.
            Shows the error page in case an exception is raised while drawing the contents.
            Descendants should override _drawContents, not updateContents.

            During the call of _drawContents, the updating of the configuration tree is blocked to
            avoid circular effects. After that, a call to self.config.refreshFromTarget() is
            made to refresh the configuration tree with possible new values from the inspector
            (the inspector is the configuration's target, hence the name).

            The reason parameter is a string (one of the UpdateReason values) that indicates why
            the inspector contents whas updated. This can, for instance, be used to optimize
            drawing the inspector contents. Note that the reason may be undefined (None).

            The initiator may contain the object that initiated the updated. The type depends on the
            reason. At the moment the initiator is only implemented for the "config changed" reason. In
            this case the initiator will be the Config Tree Item (CTI that has changed).
        """
        UpdateReason.checkValid(reason)
        logger.debug("---- Inspector updateContents, reason: {}, initiator: {}"
                     .format(reason, initiator))
        logger.debug("Inspector: {}".format(self))
        logger.debug("RTI: {}".format(self.collector.rti))
        try:
            self.setCurrentIndex(self.CONTENTS_PAGE_IDX)

            wasBlocked = self.config.model.setRefreshBlocked(True)
            try:
                self._drawContents(reason=reason, initiator=initiator)
                logger.debug("_drawContents finished successfully")

                # Update the config tree from the (possibly) new state of the PgLinePlot1d inspector,
                # e.g. the axis range may have changed while drawing.
                # self.config.updateTarget() # TODO: enable this here (instead of doing it in the inspector._drawContents when needed)?
            finally:
                self.config.model.setRefreshBlocked(wasBlocked)

            # Call refreshFromTarget in case the newly applied configuration resulted in a change
            # of the state of the configuration's target's (i.e. the inspector state)
            logger.debug("_drawContents finished successfully, calling refreshFromTarget...")
            self.config.refreshFromTarget()
            logger.debug("refreshFromTarget finished successfully")

        except InvalidDataError as ex:
            logger.info("Unable to draw the inspector contents: {}".format(ex))

        except Exception as ex:
            if DEBUGGING:  # TODO: enable
                raise
            logger.error("Error while drawing the inspector: {} ----".format(ex))
            logger.exception(ex)
            self._clearContents()
            self.setCurrentIndex(self.ERROR_PAGE_IDX)
            self._showError(msg=str(ex), title=type_name(ex))
        else:
            logger.debug("---- updateContents finished successfully")


Instruction:
Can you create a Python 3 function that
shows an error message.

Response:
def _showError(self, msg="", title="Error"):
        """ Shows an error message.
        """
        self.errorWidget.setError(msg=msg, title=title)


Instruction:
Given the following Python 3 function, write the documentation
def _enforceDataType(self, data):
        idx = int(data)
        if idx < 0:
            idx += len(self._displayValues)
        assert 0 <= idx < len(self._displayValues), \
            "Index should be >= 0 and < {}. Got {}".format(len(self._displayValues), idx)
        return idx

Response: Converts the data to int so that this CTI always stores that type.


Instruction:
Make a summary of the following Python 3 code
def _nodeGetNonDefaultsDict(self):
        dct = super(ChoiceCti, self)._nodeGetNonDefaultsDict()
        if self._configValues != self._defaultConfigValues:
            dct['choices'] = self._configValues

        return dct

Response: Returns this nodes values as a dictionary to be used for persistence. getNonDefaultsDict


Instruction:
Can you generate the documentation for the following Python 3 function
def _nodeSetValuesFromDict(self, dct):
        if 'choices' in dct:
            self._configValues = list(dct['choices'])
            self._displayValues = list(dct['choices'])
        super(ChoiceCti, self)._nodeSetValuesFromDict(dct)

Response: Sets values from a dictionary in the current node.


Instruction:
Can you generate the documentation for the following Python 3 function
def createEditor(self, delegate, parent, option):
        return ChoiceCtiEditor(self, delegate, parent=parent)

Response: Creates a ChoiceCtiEditor object for the given option.


Instruction:
Here you have a function in Python 3, explain what it does
def insertValue(self, pos, configValue, displayValue=None):
        self._configValues.insert(pos, configValue)
        self._displayValues.insert(pos, displayValue if displayValue is not None else configValue)

Response: Insert a value into the configValues and displayValues list at the given position.


Instruction:
Create a Python 3 function to
disconnect signals and restores the object.

Response:
def finalize(self):
        """ Is called when the editor is closed. Disconnect signals.
        """
        self._comboboxListView.removeEventFilter(self)
        self.comboBox.model().rowsInserted.disconnect(self.comboBoxRowsInserted)
        self.comboBox.activated.disconnect(self.comboBoxActivated)
        super(ChoiceCtiEditor, self).finalize()


Instruction:
Write a Python 3 script for
calling when the user has entered a new value in the combobox. This method inserts the new value into the cti.

Response:
def comboBoxRowsInserted(self, _parent, start, end):
        """ Called when the user has entered a new value in the combobox.
            Puts the combobox values back into the cti.
        """
        assert start == end, "Bug, please report: more than one row inserted"
        configValue = self.comboBox.itemText(start)
        logger.debug("Inserting {!r} at position {} in {}"
                     .format(configValue, start, self.cti.nodePath))
        self.cti.insertValue(start, configValue)


Instruction:
How would you implement a function in Python 3 that
removes an item from an editable combobox when the delete or backspace key is pressed in the combobox list view.

Response:
def eventFilter(self, watchedObject, event):
        """ Deletes an item from an editable combobox when the delete or backspace key is pressed
            in the list of items, or when ctrl-delete or ctrl-back space is pressed in the
            line-edit.

            When the combobox is not editable the filter does nothing.
        """
        if self.comboBox.isEditable() and event.type() == QtCore.QEvent.KeyPress:
            key = event.key()
            if key in (Qt.Key_Delete, Qt.Key_Backspace):
                if (watchedObject == self._comboboxListView
                    or (watchedObject == self.comboBox
                        and event.modifiers() == Qt.ControlModifier)):

                    index = self._comboboxListView.currentIndex()
                    if index.isValid():
                        row = index.row()
                        logger.debug("Removing item {} from the combobox: {}"
                                     .format(row, self._comboboxListView.model().data(index)))
                        self.cti.removeValueByIndex(row)
                        self.comboBox.removeItem(row)
                        return True

        # Calling parent event filter, which may filter out other events.
        return super(ChoiceCtiEditor, self).eventFilter(watchedObject, event)


Instruction:
Explain what the following Python 3 code does
def debug(self, topLeftIndex, bottomRightIndex):
        if topLeftIndex.isValid() and bottomRightIndex.isValid():
            topRow = topLeftIndex.row()
            bottomRow = bottomRightIndex.row()
            for row in range(topRow, bottomRow + 1):
                index = topLeftIndex.sibling(row, 0)
                childItem = self.getItem(index)
                logger.debug("Data changed in: {}".format(childItem.nodePath))

Response: Test the dataChanged signal.


Instruction:
Write a Python 3 function that can
return the item flags for the given index.

Response:
def flags(self, index):
        """ Returns the item flags for the given index.
        """
        if not index.isValid():
            return 0

        cti = self.getItem(index)

        result = Qt.ItemIsSelectable

        if cti.enabled:
            result |= Qt.ItemIsEnabled

        if index.column() == self.COL_VALUE:
            result |= cti.valueColumnItemFlags

        return result


Instruction:
Can you create a Python 3 function that
inserts a top level group tree item.

Response:
def insertTopLevelGroup(self, groupName, position=None):
        """ Inserts a top level group tree item.
            Used to group all config nodes of (for instance) the current inspector,
            Returns the newly created CTI
        """
        groupCti = GroupCti(groupName)
        return self._invisibleRootItem.insertChild(groupCti, position=position)


Instruction:
Write a Python 3 function that can
return the data stored under the given role for the item.

Response:
def itemData(self, treeItem, column, role=Qt.DisplayRole):
        """ Returns the data stored under the given role for the item.
        """
        if role == Qt.DisplayRole:
            if column == self.COL_NODE_NAME:
                return treeItem.nodeName
            elif column == self.COL_NODE_PATH:
                return treeItem.nodePath
            elif column == self.COL_VALUE:
                return treeItem.displayValue
            elif column == self.COL_DEF_VALUE:
                return treeItem.displayDefaultValue
            elif column == self.COL_CTI_TYPE:
                return type_name(treeItem)
            elif column == self.COL_DEBUG:
                return treeItem.debugInfo
            else:
                raise ValueError("Invalid column: {}".format(column))

        elif role == Qt.EditRole:
            if column == self.COL_VALUE:
                return treeItem.data
            else:
                raise ValueError("Invalid column: {}".format(column))

        elif role == Qt.ToolTipRole:
            if column == self.COL_NODE_NAME or column == self.COL_NODE_PATH:
                return treeItem.nodePath
            elif column == self.COL_VALUE:
                # Give Access to exact values. In particular in scientific-notation spin boxes
                return repr(treeItem.configValue)
            elif column == self.COL_DEF_VALUE:
                return treeItem.displayDefaultValue
            elif column == self.COL_CTI_TYPE:
                return type_name(treeItem)
            elif column == self.COL_DEBUG:
                return treeItem.debugInfo
            else:
                return None

        elif role == Qt.CheckStateRole:
            if column != self.COL_VALUE:
                # The CheckStateRole is called for each cell so return None here.
                return None
            else:
                return treeItem.checkState
        else:
            return super(ConfigTreeModel, self).itemData(treeItem, column, role=role)


Instruction:
Can you implement a function in Python 3 that
sets the role data for the item at the given index.

Response:
def setItemData(self, treeItem, column, value, role=Qt.EditRole):
        """ Sets the role data for the item at index to value.
        """
        if role == Qt.CheckStateRole:
            if column != self.COL_VALUE:
                return False
            else:
                logger.debug("Setting check state (col={}): {!r}".format(column, value))
                treeItem.checkState = value
                return True

        elif role == Qt.EditRole:
            if column != self.COL_VALUE:
                return False
            else:
                logger.debug("Set Edit value (col={}): {!r}".format(column, value))
                treeItem.data = value
                return True
        else:
            raise ValueError("Unexpected edit role: {}".format(role))


Instruction:
Write a Python 3 script to
set the expanded flag of the item specified by the index.

Response:
def setExpanded(self, index, expanded):
        """ Expands the model item specified by the index.
            Overridden from QTreeView to make it persistent (between inspector changes).
        """
        if index.isValid():
            item = self.getItem(index)
            item.expanded = expanded


Instruction:
Can you write a function in Python 3 where it
returns the first column model index and last column model index for a configTreeItem

Response:
def indexTupleFromItem(self, treeItem): # TODO: move to BaseTreeItem?
        """ Return (first column model index, last column model index) tuple for a configTreeItem
        """
        if not treeItem:
            return (QtCore.QModelIndex(), QtCore.QModelIndex())

        if not treeItem.parentItem: # TODO: only necessary because of childNumber?
            return (QtCore.QModelIndex(), QtCore.QModelIndex())

        # Is there a bug in Qt in QStandardItemModel::indexFromItem?
        # It passes the parent in createIndex. TODO: investigate

        row =  treeItem.childNumber()
        return (self.createIndex(row, 0, treeItem),
                self.createIndex(row, self.columnCount() - 1, treeItem))


Instruction:
Can you create a Python 3 function that
emits the data changed for the model indices for this treeItem

Response:
def emitDataChanged(self, treeItem):  # TODO: move to BaseTreeItem?
        """ Emits the data changed for the model indices (all columns) for this treeItem
        """
        indexLeft, indexRight = self.indexTupleFromItem(treeItem)
        checkItem = self.getItem(indexLeft)
        assert checkItem is treeItem, "{} != {}".format(checkItem, treeItem) # TODO: remove
        self.dataChanged.emit(indexLeft, indexRight)


Instruction:
Explain what the following Python 3 code does
def setRefreshBlocked(self, blocked):
        wasBlocked = self._refreshBlocked
        logger.debug("Setting refreshBlocked from {} to {}".format(wasBlocked, blocked))
        self._refreshBlocked = blocked
        return wasBlocked

Response: Set to True to indicate that the configuration should not be updated.


Instruction:
Can you create a Python 3 function that
uses numpy. load to open the underlying file

Response:
def _openResources(self):
        """ Uses numpy.load to open the underlying file
        """
        arr = np.load(self._fileName, allow_pickle=ALLOW_PICKLE)
        check_is_an_array(arr)
        self._array = arr


Instruction:
Create a Python 3 function for
using numpy. load to open the underlying file

Response:
def _openResources(self):
        """ Uses numpy.load to open the underlying file
        """
        dct = np.load(self._fileName, allow_pickle=ALLOW_PICKLE)
        check_class(dct, NpzFile)
        self._dictionary = dct


Instruction:
Given the following Python 3 function, write the documentation
def data(self, data):
        # Descendants should convert the data to the desired type here
        self._data = self._enforceDataType(data)

        #logger.debug("BoolCti.setData: {} for {}".format(data, self))
        enabled = self.enabled
        self.enableBranch(enabled and self.data != self.childrenDisabledValue)
        self.enabled = enabled

Response: Sets the data of this item.


Instruction:
Given the following Python 3 function, write the documentation
def insertChild(self, childItem, position=None):
        childItem = super(BoolCti, self).insertChild(childItem, position=None)

        enableChildren = self.enabled and self.data != self.childrenDisabledValue
        #logger.debug("BoolCti.insertChild: {} enableChildren={}".format(childItem, enableChildren))
        childItem.enableBranch(enableChildren)
        childItem.enabled = enableChildren
        return childItem

Response: Inserts a child item into the current item.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def checkState(self):
        if self.data is True:
            return Qt.Checked
        elif self.data is False:
            return Qt.Unchecked
        else:
            raise ValueError("Unexpected data: {!r}".format(self.data))

Response: Returns Qt. Checked or Qt. Unchecked.


Instruction:
Write a Python 3 script for
setting the data to given a Qt. CheckState.

Response:
def checkState(self, checkState):
        """ Sets the data to given a Qt.CheckState (Qt.Checked or Qt.Unchecked).
        """
        if checkState == Qt.Checked:
            logger.debug("BoolCti.checkState setting to True")
            self.data = True
        elif checkState == Qt.Unchecked:
            logger.debug("BoolCti.checkState setting to False")
            self.data = False
        else:
            raise ValueError("Unexpected check state: {!r}".format(checkState))


Instruction:
Implement a function in Python 3 to
set the enabled member to True or False for a node and all its children.

Response:
def enableBranch(self, enabled):
        """ Sets the enabled member to True or False for a node and all it's children
        """
        self.enabled = enabled

        # Disabled children and further descendants
        enabled = enabled and self.data != self.childrenDisabledValue

        for child in self.childItems:
            child.enableBranch(enabled)


Instruction:
Write a Python 3 script to
check if all children are checked or unchecked and returns Qt. Checked if all children are unchecked else returns Qt. PartiallyChecked

Response:
def checkState(self):
        """ Returns Qt.Checked or Qt.Unchecked if all children are checked or unchecked, else
            returns Qt.PartiallyChecked
        """
        #commonData = self.childItems[0].data if self.childItems else Qt.PartiallyChecked
        commonData = None

        for child in self.childItems:
            if isinstance(child, BoolCti):
                if commonData is not None and child.data != commonData:
                    return Qt.PartiallyChecked
                commonData = child.data

        if commonData is True:
            return Qt.Checked
        elif commonData is False:
            return Qt.Unchecked
        else:
            raise AssertionError("Please report this bug: commonData: {!r}".format(commonData))


Instruction:
Write a Python 3 function that can
set the data to given a Qt. CheckState.

Response:
def checkState(self, checkState):
        """ Sets the data to given a Qt.CheckState (Qt.Checked or Qt.Unchecked).
        """
        logger.debug("checkState setter: {}".format(checkState))
        if checkState == Qt.Checked:
            commonData = True
        elif checkState == Qt.Unchecked:
            commonData = False
        elif checkState == Qt.PartiallyChecked:
            commonData = None
            # This never occurs, see remarks above in the classes' docstring
            assert False, "This never happens. Please report if it does."
        else:
            raise ValueError("Unexpected check state: {!r}".format(checkState))

        for child in self.childItems:
            if isinstance(child, BoolCti):
                child.data = commonData


Instruction:
Create a Python 3 function for
creating a BaseRti given a file name.

Response:
def createFromFileName(cls, fileName):
        """ Creates a BaseRti (or descendant), given a file name.
        """
        # See https://julien.danjou.info/blog/2013/guide-python-static-class-abstract-methods
        #logger.debug("Trying to create object of class: {!r}".format(cls))
        basename = os.path.basename(os.path.realpath(fileName)) # strips trailing slashes
        return cls(nodeName=basename, fileName=fileName)


Instruction:
Write a Python 3 script for
opening underlying resources and sets isOpen flag.

Response:
def open(self):
        """ Opens underlying resources and sets isOpen flag.
            It calls _openResources. Descendants should usually override the latter
            function instead of this one.
        """
        self.clearException()
        try:
            if self._isOpen:
                logger.warn("Resources already open. Closing them first before opening.")
                self._closeResources()
                self._isOpen = False

            assert not self._isOpen, "Sanity check failed: _isOpen should be false"
            logger.debug("Opening {}".format(self))
            self._openResources()
            self._isOpen = True

            if self.model:
                self.model.sigItemChanged.emit(self)
            else:
                logger.warning("Model not set yet: {}".format(self))

        except Exception as ex:
            if DEBUGGING:
                raise
            logger.exception("Error during tree item open: {}".format(ex))
            self.setException(ex)


Instruction:
Write a Python 3 script for
closing underlying resources and un - sets the isOpen flag.

Response:
def close(self):
        """ Closes underlying resources and un-sets the isOpen flag.
            Any exception that occurs is caught and put in the exception property.
            This method calls _closeResources, which does the actual resource cleanup. Descendants
            should typically override the latter instead of this one.
        """
        self.clearException()
        try:
            if self._isOpen:
                logger.debug("Closing {}".format(self))
                self._closeResources()
                self._isOpen = False
            else:
                logger.debug("Resources already closed (ignored): {}".format(self))

            if self.model:
                self.model.sigItemChanged.emit(self)
            else:
                logger.warning("Model not set yet: {}".format(self))

        except Exception as ex:
            if DEBUGGING:
                raise
            logger.error("Error during tree item close: {}".format(ex))
            self.setException(ex)


Instruction:
Can you tell what is the following Python 3 function doing
def _checkFileExists(self):
        if self._fileName and not os.path.exists(self._fileName):
            msg = "File not found: {}".format(self._fileName)
            logger.error(msg)
            self.setException(IOError(msg))
            return False
        else:
            return True

Response: Checks that the underlying file exists and sets the _exception attribute if not.


Instruction:
Implement a function in Python 3 to
create child items and returns them.

Response:
def fetchChildren(self):
        """ Creates child items and returns them.
            Opens the tree item first if it's not yet open.
        """
        assert self._canFetchChildren, "canFetchChildren must be True"
        try:
            self.clearException()

            if not self.isOpen:
                self.open() # Will set self._exception in case of failure

            if not self.isOpen:
                logger.warn("Opening item failed during fetch (aborted)")
                return [] # no need to continue if opening failed.

            childItems = []
            try:
                childItems = self._fetchAllChildren()
                assert is_a_sequence(childItems), "ChildItems must be a sequence"

            except Exception as ex:
                # This can happen, for example, when a NCDF/HDF5 file contains data types that
                # are not supported by the Python library that is used to read them.
                if DEBUGGING:
                    raise
                logger.error("Unable fetch tree item children: {}".format(ex))
                self.setException(ex)

            return childItems
        finally:
            self._canFetchChildren = False


Instruction:
How would you explain what the following Python 3 function does
def decoration(self):
        rtiIconFactory = RtiIconFactory.singleton()

        if self._exception:
            return rtiIconFactory.getIcon(rtiIconFactory.ERROR, isOpen=False,
                                          color=rtiIconFactory.COLOR_ERROR)
        else:
            return rtiIconFactory.getIcon(self.iconGlyph, isOpen=not self.canFetchChildren(),
                                          color=self.iconColor)

Response:
The displayed icon.

            Shows open icon when node was visited (children are fetched). This allows users
            for instance to collapse a directory node but still see that it was visited, which
            may be useful if there is a huge list of directories.


Instruction:
Explain what the following Python 3 code does
def _drawContents(self, currentRti=None):
        table = self.table
        table.setUpdatesEnabled(False)

        sizeAlignment = Qt.AlignRight | Qt.AlignVCenter

        try:
            table.clearContents()
            verticalHeader = table.verticalHeader()
            verticalHeader.setSectionResizeMode(QtWidgets.QHeaderView.Fixed)

            if currentRti is None or not currentRti.isSliceable:
                return

            nDims = currentRti.nDims
            dimNames = currentRti.dimensionNames
            dimGroups = currentRti.dimensionGroupPaths
            dimSizes = currentRti.arrayShape

            # Sanity check
            assert len(dimNames) == nDims, "dimNames size {} != {}".format(len(dimNames), nDims)
            assert len(dimGroups) == nDims, "dimGroups size {} != {}".format(len(dimGroups), nDims)
            assert len(dimSizes) == nDims, "dimSizes size {} != {}".format(len(dimSizes), nDims)

            table.setRowCount(nDims)
            for row, (dimName, dimSize, dimGroup) in enumerate(zip(dimNames, dimSizes, dimGroups)):
                table.setItem(row, self.COL_NAME, QtWidgets.QTableWidgetItem(dimName))
                table.setItem(row, self.COL_SIZE, QtWidgets.QTableWidgetItem(str(dimSize)))
                table.item(row, self.COL_SIZE).setTextAlignment(sizeAlignment)
                table.setItem(row, self.COL_GROUP, QtWidgets.QTableWidgetItem(str(dimGroup)))
                table.resizeRowToContents(row)

            verticalHeader.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        finally:
            table.setUpdatesEnabled(True)

Response: Draws the attributes of the currentRTI and the currentRTI.


Instruction:
Explain what the following Python 3 code does
def format_float(value): # not used
    string = "{:g}".format(value).replace("e+", "e")
    string = re.sub("e(-?)0*(\d+)", r"e\1\2", string)
    return string

Response: Modified form of the g format specifier.


Instruction:
How would you code a function in Python 3 to
set the number of small steps that go in a large one.

Response:
def smallStepsPerLargeStep(self, smallStepsPerLargeStep):
        """ Sets the number of small steps that go in a large one.

        """
        self._smallStepsPerLargeStep = smallStepsPerLargeStep
        self._smallStepFactor = np.power(self.largeStepFactor, 1.0 / smallStepsPerLargeStep)


Instruction:
How would you code a function in Python 3 to
function that is called whenever the user presses a key.

Response:
def stepBy(self, steps):
        """ Function that is called whenever the user triggers a step. The steps parameter
            indicates how many steps were taken, e.g. Pressing Qt::Key_Down will trigger a call to
            stepBy(-1), whereas pressing Qt::Key_Prior will trigger a call to stepBy(10).
        """
        oldValue = self.value()

        if oldValue == 0:
            newValue = steps
        elif steps == 1:
            newValue = self.value() * self.smallStepFactor
        elif steps == -1:
            newValue = self.value() / self.smallStepFactor
        elif steps == 10:
            newValue = self.value() * self.largeStepFactor
        elif steps == -10:
            newValue = self.value() / self.largeStepFactor
        else:
            raise ValueError("Invalid step size: {!r}, value={}".format(steps, oldValue))

        newValue = float(newValue)

        if newValue < self.minimum():
            newValue = self.minimum()

        if newValue > self.maximum():
            newValue = self.maximum()

        #logger.debug("stepBy {}: {} -> {}".format(steps, oldValue, newValue))
        try:
            self.setValue(newValue)
        except Exception:
            # TODO: does this ever happen? Better validation (e.g. catch underflows)
            logger.warn("Unable to set spinbox to: {!r}".format(newValue))
            self.setValue(oldValue)


Instruction:
How would you code a function in Python 3 to
import the module and sets version information.

Response:
def tryImportModule(self, name):
        """ Imports the module and sets version information
            If the module cannot be imported, the version is set to empty values.
        """
        self._name = name
        try:
            import importlib
            self._module = importlib.import_module(name)
        except ImportError:
            self._module = None
            self._version = ''
            self._packagePath = ''
        else:
            if self._versionAttribute:
                self._version = getattr(self._module, self._versionAttribute, '???')
            if self._pathAttribute:
                self._packagePath = getattr(self._module, self._pathAttribute, '???')


Instruction:
Explain what the following Python 3 code does
def setPgConfigOptions(**kwargs):
    for key, value in kwargs.items():
        logger.debug("Setting PyQtGraph config option: {} = {}".format(key, value))

    pg.setConfigOptions(**kwargs)

Response: Sets the PyQtGraph config options and emits a log message


Instruction:
Explain what the following Python 3 code does
def model(self):
        if self._model is None and self.parentItem is not None:
            self._model = self.parentItem.model
        return self._model

Response: Returns the ConfigTreeModel this item belongs to.


Instruction:
Explain what the following Python 3 code does
def nodeName(self, nodeName):
        assert '/' not in nodeName, "nodeName may not contain slashes"
        self._nodeName = nodeName
        self._recursiveSetNodePath(self._constructNodePath())

Response: The name of the node.


Instruction:
Create a Python 3 function for
setting the nodePath property and updates it for all children.

Response:
def _recursiveSetNodePath(self, nodePath):
        """ Sets the nodePath property and updates it for all children.
        """
        self._nodePath = nodePath
        for childItem in self.childItems:
            childItem._recursiveSetNodePath(nodePath + '/' + childItem.nodeName)


Instruction:
Make a summary of the following Python 3 code
def parentItem(self, value):
        self._parentItem = value
        self._recursiveSetNodePath(self._constructNodePath())

Response: Sets the parent item of the item


Instruction:
How would you code a function in Python 3 to
get the first direct child that has the nodeName.

Response:
def childByNodeName(self, nodeName):
        """ Gets first (direct) child that has the nodeName.
        """
        assert '/' not in nodeName, "nodeName can not contain slashes"
        for child in self.childItems:
            if child.nodeName == nodeName:
                return child

        raise IndexError("No child item found having nodeName: {}".format(nodeName))


Instruction:
Implement a Python 3 function for
finding the child with the nodePath. Starts at self.

Response:
def findByNodePath(self, nodePath):
        """ Recursively searches for the child having the nodePath. Starts at self.
        """
        def _auxGetByPath(parts, item):
            "Aux function that does the actual recursive search"
            #logger.debug("_auxGetByPath item={}, parts={}".format(item, parts))

            if len(parts) == 0:
                return item

            head, tail = parts[0], parts[1:]
            if head == '':
                # Two consecutive slashes. Just go one level deeper.
                return _auxGetByPath(tail, item)
            else:
                childItem = item.childByNodeName(head)
                return _auxGetByPath(tail, childItem)

        # The actual body of findByNodePath starts here

        check_is_a_string(nodePath)
        assert not nodePath.startswith('/'), "nodePath may not start with a slash"

        if not nodePath:
            raise IndexError("Item not found: {!r}".format(nodePath))

        return _auxGetByPath(nodePath.split('/'), self)


Instruction:
Make a summary of the following Python 3 code
def insertChild(self, childItem, position=None):
        if position is None:
            position = self.nChildren()

        assert childItem.parentItem is None, "childItem already has a parent: {}".format(childItem)
        assert childItem._model is None, "childItem already has a model: {}".format(childItem)

        childItem.parentItem = self
        childItem.model = self.model
        self.childItems.insert(position, childItem)
        return childItem

Response: Inserts a child item into the current item.


Instruction:
Make a summary of the following Python 3 code
def removeChild(self, position):
        assert 0 <= position <= len(self.childItems), \
            "position should be 0 < {} <= {}".format(position, len(self.childItems))

        self.childItems[position].finalize()
        self.childItems.pop(position)

Response: Removes the child at the specified position.


Instruction:
Given the following Python 3 function, write the documentation
def logBranch(self, indent=0, level=logging.DEBUG):
        if 0:
            print(indent * "    " + str(self))
        else:
            logger.log(level, indent * "    " + str(self))
        for childItems in self.childItems:
            childItems.logBranch(indent + 1, level=level)

Response: Logs the item and all descendants one line per child


Instruction:
Can you generate a brief explanation for the following Python 3 code
def fetchChildren(self):
        assert self._canFetchChildren, "canFetchChildren must be True"
        try:
            childItems = self._fetchAllChildren()
        finally:
            self._canFetchChildren = False # Set to True, even if tried and failed.

        return childItems

Response:
Fetches children.

            The actual work is done by _fetchAllChildren. Descendant classes should typically
            override that method instead of this one.


Instruction:
Write a Python 3 script to
create an inspector of the registered and passes the collector to the constructor.

Response:
def create(self, collector, tryImport=True):
        """ Creates an inspector of the registered and passes the collector to the constructor.
            Tries to import the class if tryImport is True.
            Raises ImportError if the class could not be imported.
        """
        cls = self.getClass(tryImport=tryImport)
        if not self.successfullyImported:
            raise ImportError("Class not successfully imported: {}".format(self.exception))
        return cls(collector)


Instruction:
How would you code a function in Python 3 to
register an Inspector class.

Response:
def registerInspector(self, fullName, fullClassName, pythonPath=''):
        """ Registers an Inspector class.
        """
        regInspector = InspectorRegItem(fullName, fullClassName, pythonPath=pythonPath)
        self.registerItem(regInspector)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getDefaultItems(self):
        plugins = [
            InspectorRegItem(DEFAULT_INSPECTOR,
                             'argos.inspector.qtplugins.table.TableInspector'),
            InspectorRegItem('Qt/Text',
                             'argos.inspector.qtplugins.text.TextInspector'),
            InspectorRegItem('PyQtGraph/1D Line Plot',
                             'argos.inspector.pgplugins.lineplot1d.PgLinePlot1d'),
            InspectorRegItem('PyQtGraph/2D Image Plot',
                             'argos.inspector.pgplugins.imageplot2d.PgImagePlot2d'),
            ]
        if DEBUGGING:
            plugins.append(InspectorRegItem('Debug Inspector',
                                            'argos.inspector.debug.DebugInspector'))
        return plugins

Response: Returns a list with the default plugins in the inspector registry.


Instruction:
Given the following Python 3 function, write the documentation
def _createConfig(self):
        rootItem = MainGroupCti('debug inspector')

        if DEBUGGING:
            # Some test config items.
            import numpy as np
            from argos.config.untypedcti import UntypedCti
            from argos.config.stringcti import StringCti
            from argos.config.intcti import IntCti
            from argos.config.floatcti import FloatCti, SnFloatCti
            from argos.config.boolcti import BoolCti, BoolGroupCti
            from argos.config.choicecti import ChoiceCti
            from argos.config.qtctis import PenCti

            grpItem = GroupCti("group")
            rootItem.insertChild(grpItem)

            lcItem = UntypedCti('line color', 123)
            grpItem.insertChild(lcItem)

            disabledItem = rootItem.insertChild(StringCti('disabled', "Can't touch me"))
            disabledItem.enabled=False

            grpItem.insertChild(IntCti('line-1 color', 7, minValue = -5, stepSize=2,
                                       prefix="@", suffix="%", specialValueText="I'm special"))
            rootItem.insertChild(StringCti('letter', 'aa', maxLength = 1))
            grpItem.insertChild(FloatCti('width', 2, minValue =5, stepSize=0.45, decimals=3,
                                         prefix="@", suffix="%", specialValueText="so very special"))
            grpItem.insertChild(SnFloatCti('scientific', defaultData=-np.inf))

            gridItem = rootItem.insertChild(BoolGroupCti('grid', True))
            gridItem.insertChild(BoolCti('X-Axis', True))
            gridItem.insertChild(BoolCti('Y-Axis', False))

            rootItem.insertChild(ChoiceCti('hobbit', 2, editable=True,
                                           configValues=['Frodo', 'Sam', 'Pippin', 'Merry']))
            myPen = QtGui.QPen(QtGui.QColor('#1C8857'))
            myPen.setWidth(2)
            myPen.setStyle(Qt.DashDotDotLine)
            rootItem.insertChild(PenCti('line', False, resetTo=myPen))

        return rootItem

Response: Creates a config tree item containing default children.


Instruction:
How would you explain what the following Python 3 function does
def _drawContents(self, reason=None, initiator=None):
        logger.debug("DebugInspector._drawContents: {}".format(self))

        slicedArray = self.collector.getSlicedArray()
        if slicedArray is None:
            text = "<None>"
        else:
            text = ("data = {!r}, masked = {!r}, fill_value = {!r} (?= {}: {})"
                    .format(slicedArray.data, slicedArray.mask, slicedArray.fill_value,
                            slicedArray.data.item(),
                            slicedArray.data.item() == slicedArray.fill_value))

        logger.debug("_drawContents: {}".format(text))
        logger.debug("_drawContents: {!r}".format(slicedArray))

        if DEBUGGING:
            self.label.setText(text)

Response: Draw the table contents from the sliced array of the collected repo tree item.


Instruction:
Explain what the following Python 3 code does
def data(self, index, role=Qt.DisplayRole):
        try:
            if index.isValid():
                item = self.getItem(index, altItem=self.invisibleRootItem)
                return self.itemData(item, index.column(), role=role)
            else:
                return None
        except Exception as ex:
            # This Qt slot is called directly from the event loop so uncaught exception make the
            # application crash (exceptions can come from plugins here). Instead of crashing we
            # show the error message in the table/tree and hope the users report the error.
            if not DEBUGGING and role in (Qt.DisplayRole, Qt.EditRole, Qt.ToolTipRole,
                                          Qt.StatusTipRole, Qt.WhatsThisRole):
                return repr(ex)
            else:
                raise

Response: Returns the data stored under the given role for the item referred to by the index.


Instruction:
Make a summary of the following Python 3 code
def itemData(self, item, column, role=Qt.DisplayRole):
        if role == Qt.DecorationRole:
            if column == self.COL_DECORATION:
                return item.decoration

        elif role == Qt.FontRole:
            return item.font

        elif role == Qt.ForegroundRole:
            return item.foregroundBrush

        elif role == Qt.BackgroundRole:
            return item.backgroundBrush

        elif role == Qt.SizeHintRole:
            return self.cellSizeHint if item.sizeHint is None else item.sizeHint

        return None

Response: Returns the data stored under the given role for the item.


Instruction:
Implement a Python 3 function for
returning the index of the item in the model specified by the given row column and parentIndex.

Response:
def index(self, row, column, parentIndex=QtCore.QModelIndex()):
        """ Returns the index of the item in the model specified by the given row, column and parent
            index.

            Since each item contains information for an entire row of data, we create a model index
            to uniquely identify it by calling createIndex() it with the row and column numbers and
            a pointer to the item. (In the data() function, we will use the item pointer and column
            number to access the data associated with the model index; in this model, the row number
            is not needed to identify data.)

            When reimplementing this function in a subclass, call createIndex() to generate
            model indexes that other components can use to refer to items in your model.
        """
#        logger.debug("  called index({}, {}, {}) {}"
#                     .format(parentIndex.row(), parentIndex.column(), parentIndex.isValid(),
#                             parentIndex.isValid() and parentIndex.column() != 0))

        parentItem = self.getItem(parentIndex, altItem=self.invisibleRootItem)
        #logger.debug("    Getting row {} from parentItem: {}".format(row, parentItem))

        if not (0 <= row < parentItem.nChildren()):
            # Can happen when deleting the last child.
            #logger.warn("Index row {} invalid for parent item: {}".format(row, parentItem))
            return QtCore.QModelIndex()

        if not (0 <= column < self.columnCount()):
            #logger.warn("Index column {} invalid for parent item: {}".format(column, parentItem))
            return QtCore.QModelIndex()

        childItem = parentItem.child(row)
        if childItem:
            return self.createIndex(row, column, childItem)
        else:
            logger.warn("No child item found at row {} for parent item: {}".format(row, parentItem))
            return QtCore.QModelIndex()


Instruction:
Implement a function in Python 3 to
return the parent of the model item with the given index.

Response:
def parent(self, index):
        """ Returns the parent of the model item with the given index. If the item has no parent,
            an invalid QModelIndex is returned.

            A common convention used in models that expose tree data structures is that only items
            in the first column have children. For that case, when reimplementing this function in
            a subclass the column of the returned QModelIndex would be 0. (This is done here.)

            When reimplementing this function in a subclass, be careful to avoid calling QModelIndex
            member functions, such as QModelIndex.parent(), since indexes belonging to your model
            will simply call your implementation, leading to infinite recursion.
        """
        if not index.isValid():
            return QtCore.QModelIndex()

        childItem = self.getItem(index, altItem=self.invisibleRootItem)
        parentItem = childItem.parentItem

        if parentItem == self.invisibleRootItem:
            return QtCore.QModelIndex()

        return self.createIndex(parentItem.childNumber(), 0, parentItem)


Instruction:
Write a Python 3 script for
returning the number of rows under the given parent.

Response:
def rowCount(self, parentIndex=QtCore.QModelIndex()):
        """ Returns the number of rows under the given parent. When the parent is valid it means
            that rowCount is returning the number of children of parent.

            Note: When implementing a table based model, rowCount() should return 0 when the parent
            is valid.
        """
        parentItem = self.getItem(parentIndex, altItem=self.invisibleRootItem)
        return parentItem.nChildren()


Instruction:
Can you tell what is the following Python 3 function doing
def hasChildren(self, parentIndex=QtCore.QModelIndex()):
        parentItem = self.getItem(parentIndex, altItem=self.invisibleRootItem)
        return parentItem.hasChildren()

Response: Returns true if the parent has any children ; otherwise returns false.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def setData(self, index, value, role=Qt.EditRole):
        if role != Qt.CheckStateRole and role != Qt.EditRole:
            return False

        treeItem = self.getItem(index, altItem=self.invisibleRootItem)
        try:
            result = self.setItemData(treeItem, index.column(), value, role=role)
            if result:
                # Emit dataChanged to update the tree view
                # TODO, update the entire tree?
                # A check box can have a tristate checkbox as parent which state depends
                # on the state of this child check box. Therefore we update the parentIndex
                # and the descendants.
                self.emitDataChanged(treeItem)

                # Emit sigItemChanged to update other widgets.
                self.sigItemChanged.emit(treeItem)
            return result

        except Exception as ex:
            # When does this still happen? Can we remove it?
            logger.warn("Unable to set data: {}".format(ex))
            if DEBUGGING:
                raise
            return False

Response: Sets the role data for the item at the given index to value. Returns true if successful otherwise returns false.


Instruction:
Create a Python 3 function for
returning the TreeItem for the given index.

Response:
def getItem(self, index, altItem=None):
        """ Returns the TreeItem for the given index. Returns the altItem if the index is invalid.
        """
        if index.isValid():
            item = index.internalPointer()
            if item:
                return item

        #return altItem if altItem is not None else self.invisibleRootItem # TODO: remove
        return altItem


Instruction:
Make a summary of the following Python 3 code
def insertItem(self, childItem, position=None, parentIndex=None):
        if parentIndex is None:
            parentIndex=QtCore.QModelIndex()

        parentItem = self.getItem(parentIndex, altItem=self.invisibleRootItem)

        nChildren = parentItem.nChildren()
        if position is None:
            position = nChildren

        assert 0 <= position <= nChildren, \
            "position should be 0 < {} <= {}".format(position, nChildren)

        self.beginInsertRows(parentIndex, position, position)
        try:
            parentItem.insertChild(childItem, position)
        finally:
            self.endInsertRows()

        childIndex = self.index(position, 0, parentIndex)
        assert childIndex.isValid(), "Sanity check failed: childIndex not valid"
        return childIndex

Response: Inserts a childItem at the specified position under the parent index.


Instruction:
Given the following Python 3 function, write the documentation
def removeAllChildrenAtIndex(self, parentIndex):
        if not parentIndex.isValid():
            logger.debug("No valid item selected for deletion (ignored).")
            return

        parentItem = self.getItem(parentIndex, None)
        logger.debug("Removing children of {!r}".format(parentItem))
        assert parentItem, "parentItem not found"

        #firstChildRow = self.index(0, 0, parentIndex).row()
        #lastChildRow = self.index(parentItem.nChildren()-1, 0, parentIndex).row()
        #logger.debug("Removing rows: {} to {}".format(firstChildRow, lastChildRow))
        #self.beginRemoveRows(parentIndex, firstChildRow, lastChildRow)

        self.beginRemoveRows(parentIndex, 0, parentItem.nChildren()-1)
        try:
            parentItem.removeAllChildren()
        finally:
            self.endRemoveRows()

        logger.debug("removeAllChildrenAtIndex completed")

Response: Removes all children of the item at the parentIndex.


Instruction:
Make a summary of the following Python 3 code
def deleteItemAtIndex(self, itemIndex):
        if not itemIndex.isValid():
            logger.debug("No valid item selected for deletion (ignored).")
            return

        item = self.getItem(itemIndex, "<no item>")
        logger.debug("deleteItemAtIndex: removing {}".format(item))

        parentIndex = itemIndex.parent()
        parentItem = self.getItem(parentIndex, altItem=self.invisibleRootItem)
        row = itemIndex.row()
        self.beginRemoveRows(parentIndex, row, row)
        try:
            parentItem.removeChild(row)
        finally:
            self.endRemoveRows()

        logger.debug("deleteItemAtIndex completed")

Response: Removes the item at the itemIndex.


Instruction:
Create a Python 3 function to
remove the item at the itemIndex and inserts a new item instead. Returns the index of the item inserted.

Response:
def replaceItemAtIndex(self, newItem, oldItemIndex):
        """ Removes the item at the itemIndex and insert a new item instead.
        """
        oldItem = self.getItem(oldItemIndex)
        childNumber = oldItem.childNumber()
        parentIndex = oldItemIndex.parent()
        self.deleteItemAtIndex(oldItemIndex)
        insertedIndex = self.insertItem(newItem, position=childNumber, parentIndex=parentIndex)
        return insertedIndex


Instruction:
Create a Python 3 function for
finding the top level ancestor item that is direct children of the given child item.

Response:
def findTopLevelItemIndex(self, childIndex):
        """ Traverses the tree upwards from childItem until its top level ancestor item is found.
            Top level items are items that are direct children of the (invisible) root item.
            This function therefore raises an exception when called with the root item.
        """
        if self.isTopLevelIndex(childIndex):
            return childIndex
        else:
            return self.findTopLevelItemIndex(childIndex.parent())


Instruction:
How would you explain what the following Python 3 function does
def findItemAndIndexPath(self, path, startIndex=None):
        def _getIndexAndItemByName(nodeName, parentItem, parentIndex):
            """ Searches the parent for a direct child having the nodeName.
                Returns (item, itemIndex) tuple. Raises IndexError if the item cannot be found.
            """
            if self.canFetchMore(parentIndex):
                self.fetchMore(parentIndex)

            for rowNr, childItem in enumerate(parentItem.childItems):
                if childItem.nodeName == nodeName:
                    childIndex = self.index(rowNr, 0, parentIndex=parentIndex)
                    return (childItem, childIndex)
            raise IndexError("Item not found: {!r}".format(path))

        def _auxGetByPath(parts, item, index):
            "Aux function that does the actual recursive search"
            #logger.debug("_auxGetByPath item={}, parts={}".format(item, parts))

            if len(parts) == 0:
                return [(item, index)]

            head, tail = parts[0], parts[1:]
            if head == '':
                # Two consecutive slashes. Just go one level deeper.
                return _auxGetByPath(tail, item, index)
            else:
                childItem, childIndex = _getIndexAndItemByName(head, item, index)
                return [(item, index)] + _auxGetByPath(tail, childItem, childIndex)

        # The actual body of findItemAndIndexPath starts here

        check_is_a_string(path)
        if not path:
            raise IndexError("Item not found: {!r}".format(path))

        if startIndex is None or path.startswith('/'):
            startIndex = QtCore.QModelIndex()
            startItem = self.invisibleRootItem
        else:
            startItem = self.getItem(startIndex, None)

        if not startItem:
            raise IndexError("Item not found: {!r}. No start item!".format(path))

        return _auxGetByPath(path.split('/'), startItem, startIndex)

Response: Searches all the model recursively for an item where the path is given.


Instruction:
Implement a Python 3 function for
logging the items in this item.

Response:
def logItems(self, level=logging.DEBUG):
        """ rootItem
        """
        rootItem = self.rootItem()
        if rootItem is None:
            logger.debug("No items in: {}".format(self))
        else:
            rootItem.logBranch(level=level)


Instruction:
Implement a function in Python 3 to
add the context menu from using header information.

Response:
def addHeaderContextMenu(self, checked = None, checkable = None, enabled = None):
        """ Adds the context menu from using header information

            checked can be a header_name -> boolean dictionary. If given, headers
            with the key name will get the checked value from the dictionary.
            The corresponding column will be hidden if checked is False.

            checkable can be a header_name -> boolean dictionary. If given, header actions
            with the key name will get the checkable value from the dictionary. (Default True)

            enabled can be a header_name -> boolean dictionary. If given, header actions
            with the key name will get the enabled value from the dictionary. (Default True)
        """
        checked = checked if checked is not None else {}
        checkable = checkable if checkable is not None else {}
        enabled = enabled if enabled is not None else {}

        horizontal_header = self.horizontalHeader()
        horizontal_header.setContextMenuPolicy(Qt.ActionsContextMenu)

        self.toggle_column_actions_group = QtWidgets.QActionGroup(self)
        self.toggle_column_actions_group.setExclusive(False)
        self.__toggle_functions = []  # for keeping references

        for col in range(horizontal_header.count()):
            column_label = self.model().headerData(col, Qt.Horizontal, Qt.DisplayRole)
            #logger.debug("Adding: col {}: {}".format(col, column_label))
            action = QtWidgets.QAction(str(column_label),
                                   self.toggle_column_actions_group,
                                   checkable = checkable.get(column_label, True),
                                   enabled = enabled.get(column_label, True),
                                   toolTip = "Shows or hides the {} column".format(column_label))
            func = self.__makeShowColumnFunction(col)
            self.__toggle_functions.append(func) # keep reference
            horizontal_header.addAction(action)
            is_checked = checked.get(column_label, not horizontal_header.isSectionHidden(col))
            horizontal_header.setSectionHidden(col, not is_checked)
            action.setChecked(is_checked)
            action.toggled.connect(func)


Instruction:
Make a summary of the following Python 3 code
def __makeShowColumnFunction(self, column_idx):
        show_column = lambda checked: self.setColumnHidden(column_idx, not checked)
        return show_column

Response: Creates a function that shows or hides a column.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def readViewSettings(self, key, settings=None):
        #logger.debug("Reading view settings for: {}".format(key))
        if settings is None:
            settings = QtCore.QSettings()

        horizontal_header = self.horizontalHeader()
        header_restored = horizontal_header.restoreState(settings.value(key))

        # update actions
        for col, action in enumerate(horizontal_header.actions()):
            is_checked = not horizontal_header.isSectionHidden(col)
            action.setChecked(is_checked)

        return header_restored

Response: Reads the persistent program settings for the specified key and returns True if the header state was restored otherwise returns False


Instruction:
Given the following Python 3 function, write the documentation
def saveProfile(self, key, settings=None):
        #logger.debug("Writing view settings for: {}".format(key))
        if settings is None:
            settings = QtCore.QSettings()
        settings.setValue(key, self.horizontalHeader().saveState())

Response: Writes the view settings to the persistent store.


Instruction:
Write a Python 3 function that can
try to import the registered class. Will set the exception property if and error occurred.

Response:
def tryImportClass(self):
        """ Tries to import the registered class.
            Will set the exception property if and error occurred.
        """
        logger.info("Importing: {}".format(self.fullClassName))
        self._triedImport = True
        self._exception = None
        self._cls = None
        try:
            for pyPath in self.pythonPath.split(':'):
                if pyPath and pyPath not in sys.path:
                    logger.debug("Appending {!r} to the PythonPath.".format(pyPath))
                    sys.path.append(pyPath)
            self._cls = import_symbol(self.fullClassName) # TODO: check class?
        except Exception as ex:
            self._exception = ex
            logger.warn("Unable to import {!r}: {}".format(self.fullClassName, ex))
            if DEBUGGING:
                raise


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getClass(self, tryImport=True):
        if not self.triedImport and tryImport:
            self.tryImportClass()

        return self._cls

Response: Gets the underlying class. Tries to import if tryImport is False.


Instruction:
Can you write a function in Python 3 where it
adds a ClassRegItem object to the registry.

Response:
def registerItem(self, regItem):
        """ Adds a ClassRegItem object to the registry.
        """
        check_class(regItem, ClassRegItem)
        if regItem.identifier in self._index:
            oldRegItem = self._index[regItem.identifier]
            logger.warn("Class key {!r} already registered as {}. Removing old regItem."
                        .format(regItem.identifier, oldRegItem.fullClassName))
            self.removeItem(oldRegItem)

        logger.info("Registering {!r} with {}".format(regItem.identifier, regItem.fullClassName))
        self._items.append(regItem)
        self._index[regItem.identifier] = regItem


Instruction:
Explain what the following Python 3 code does
def removeItem(self, regItem):
        check_class(regItem, ClassRegItem)
        logger.info("Removing {!r} containing {}".format(regItem.identifier, regItem.fullClassName))

        del self._index[regItem.identifier]
        idx = self._items.index(regItem)
        del self._items[idx]

Response: Removes a ClassRegItem object from the registry.


Instruction:
Can you implement a function in Python 3 that
reads the persistent settings store falls back on the default plugins if there are no settings in the store.

Response:
def loadOrInitSettings(self, groupName=None):
        """ Reads the registry items from the persistent settings store, falls back on the
            default plugins if there are no settings in the store for this registry.
        """
        groupName = groupName if groupName else self.settingsGroupName
        settings = QtCore.QSettings()

        #for key in sorted(settings.allKeys()):
        #    print(key)

        if containsSettingsGroup(groupName, settings):
            self.loadSettings(groupName)
        else:
            logger.info("Group {!r} not found, falling back on default settings".format(groupName))
            for item in self.getDefaultItems():
                self.registerItem(item)
            self.saveSettings(groupName)
            assert containsSettingsGroup(groupName, settings), \
                "Sanity check failed. {} not found".format(groupName)


Instruction:
Can you tell what is the following Python 3 function doing
def loadSettings(self, groupName=None):
        groupName = groupName if groupName else self.settingsGroupName
        settings = QtCore.QSettings()
        logger.info("Reading {!r} from: {}".format(groupName, settings.fileName()))

        settings.beginGroup(groupName)
        self.clear()
        try:
            for key in settings.childKeys():
                if key.startswith('item'):
                    dct = ast.literal_eval(settings.value(key))
                    regItem = self._itemClass.createFromDict(dct)
                    self.registerItem(regItem)
        finally:
            settings.endGroup()

Response: Reads the registry items from the persistent settings store.


Instruction:
Can you tell what is the following Python 3 function doing
def saveSettings(self, groupName=None):
        groupName = groupName if groupName else self.settingsGroupName
        settings = QtCore.QSettings()
        logger.info("Saving {} to: {}".format(groupName, settings.fileName()))

        settings.remove(groupName) # start with a clean slate
        settings.beginGroup(groupName)
        try:
            for itemNr, item in enumerate(self.items):
                key = "item-{:03d}".format(itemNr)
                value = repr(item.asDict())
                settings.setValue(key, value)
        finally:
            settings.endGroup()

Response: Writes the items into the persistent settings store.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def deleteSettings(self, groupName=None):
        groupName = groupName if groupName else self.settingsGroupName
        settings = QtCore.QSettings()
        logger.info("Deleting {} from: {}".format(groupName, settings.fileName()))
        removeSettingsGroup(groupName)

Response: Deletes the registry items from the persistent store.