Instruction:
Can you generate a brief explanation for the following Python 3 code
def find_prf_cpu(idxPrc, aryFuncChnk, aryPrfTc, aryMdlParams, strVersion,
                 lgcXval, varNumXval, queOut, lgcRstr=None, lgcPrint=True):
    """
    Find best fitting pRF model for voxel time course, using the CPU.

    Parameters
    ----------
    idxPrc : int
        Process ID of the process calling this function (for CPU
        multi-threading). In GPU version, this parameter is 0 (just one thread
        on CPU).
    aryFunc : np.array
        2D array with functional MRI data, with shape aryFunc[voxel, time].
    aryPrfTc : np.array
        Array with pRF model time courses, with shape
        aryPrfTc[x-pos*y-pos*SD, number of feautures, number of volumes]
    aryMdlParams : np.array
        2D array with all pRF model parameter combinations.
    strVersion : str
        Which version to use for pRF finding; 'numpy' or 'cython'.
    lgcXval: boolean
        Logical to determine whether we cross-validate.
    varNumXval: int
        Number of folds for k-fold cross-validation.
    queOut : multiprocessing.queues.Queue
        Queue to put the results on.
    lgcRstr : boolean numpy array or None, default None
        Logical to restrict certain models to particular voxels.
    lgcPrint : boolean
        Whether print statements should be executed.

    Returns
    -------
    lstOut : list
        List containing the following objects:
        idxPrc : int
            Process ID of the process calling this function (for CPU
            multi-threading). In GPU version, this parameter is 0.
        vecBstXpos : np.array
            1D array with best fitting x-position for each voxel, with shape
            vecBstXpos[voxel].
        vecBstYpos : np.array
            1D array with best fitting y-position for each voxel, with shape
            vecBstYpos[voxel].
        vecBstSd : np.array
            1D array with best fitting pRF size for each voxel, with shape
            vecBstSd[voxel].
        vecBstR2 : np.array
            1D array with R2 value of 'winning' pRF model for each voxel, with
            shape vecBstR2[voxel].
        aryBstBts : np.array
            2D array with beta parameter estimates of 'winning' pRF model for
            each voxel, with shape aryBstBts[voxel, feautures].

    Notes
    -----
    The list with results is not returned directly, but placed on a
    multiprocessing queue. This version performs the model finding on the CPU,
    using numpy or cython (depending on the value of `strVersion`).

    """

    # Number of models in the visual space:
    varNumMdls = aryPrfTc.shape[0]

    # Number of feautures
    varNumFtr = aryPrfTc.shape[1]

    # Number of voxels to be fitted in this chunk:
    varNumVoxChnk = aryFuncChnk.shape[0]

    # Vectors for pRF finding results [number-of-voxels times one]:
    # make sure they have the same precision as aryMdlParams, since this
    # is important for later comparison
    vecBstXpos = np.zeros(varNumVoxChnk, dtype=aryMdlParams.dtype)
    vecBstYpos = np.zeros(varNumVoxChnk, dtype=aryMdlParams.dtype)
    vecBstSd = np.zeros(varNumVoxChnk, dtype=aryMdlParams.dtype)

    # Vector for best R-square value. For each model fit, the R-square value is
    # compared to this, and updated if it is lower than the best-fitting
    # solution so far. We initialise with an arbitrary, high value
    vecBstRes = np.add(np.zeros(varNumVoxChnk), np.inf).astype(np.float32)

    # array for best beta values. If we update the residual value above because
    # it is lower, we also update the beta values of these voxels
    aryBstBts = np.zeros((varNumVoxChnk, varNumFtr)).astype(np.float32)

    # In case we cross-validate we also save and replace the best
    # residual values for every fold (not only mean across folds):
    if lgcXval:
        aryBstResFlds = np.zeros((varNumVoxChnk, varNumXval), dtype=np.float32)

    # We reshape the voxel time courses, so that time goes down the column,
    # i.e. from top to bottom.
    aryFuncChnk = aryFuncChnk.T

    # Change type to float 32:
    aryFuncChnk = aryFuncChnk.astype(np.float32)
    aryPrfTc = aryPrfTc.astype(np.float32)

    # if lgc for Xval is true we already prepare indices for xvalidation
    if lgcXval:
        # obtain iterator for cross-validation
        itXval = KFold(n_splits=varNumXval)
        vecSplts = np.arange(aryPrfTc.shape[-1], dtype=np.int32)

        # prepare lists that will hold indices for xvalidation
        lstIdxTrn = []
        lstIdxtst = []
        # Loop over the cross-validations to put indcies in array
        for idxTrn, idxTst in itXval.split(vecSplts):
            lstIdxTrn.append(idxTrn)
            lstIdxtst.append(idxTst)
        # trun lists into array
        aryIdxTrn = np.stack(lstIdxTrn, axis=-1).astype(np.int32)
        aryIdxTst = np.stack(lstIdxtst, axis=-1).astype(np.int32)

    # Prepare status indicator if this is the first of the parallel processes:
    if idxPrc == 0:

        # We create a status indicator for the time consuming pRF model finding
        # algorithm. Number of steps of the status indicator:
        varStsStpSze = 20

        # Vector with pRF values at which to give status feedback:
        vecStatPrf = np.linspace(0,
                                 varNumMdls,
                                 num=(varStsStpSze+1),
                                 endpoint=True)
        vecStatPrf = np.ceil(vecStatPrf)
        vecStatPrf = vecStatPrf.astype(int)

        # Vector with corresponding percentage values at which to give status
        # feedback:
        vecStatPrc = np.linspace(0,
                                 100,
                                 num=(varStsStpSze+1),
                                 endpoint=True)
        vecStatPrc = np.ceil(vecStatPrc)
        vecStatPrc = vecStatPrc.astype(int)

        # Counter for status indicator:
        varCntSts01 = 0
        varCntSts02 = 0

    # If user does not restrict model space for particular voxels, select
    # all voxels
    if lgcRstr is None:
        lgcVxl = np.arange(varNumVoxChnk, dtype=np.int32)

    # There can be pRF model time courses with a variance of zero (i.e. pRF
    # models that are not actually responsive to the stimuli). For time
    # efficiency, and in order to avoid division by zero, we ignore these
    # model time courses.
    aryPrfTcVar = np.var(aryPrfTc, axis=-1)

    # Zero with float32 precision for comparison:
    varZero32 = np.array(([0.0])).astype(np.float32)[0]

    # Loop through pRF models:
    for idxMdl in range(0, varNumMdls):

        # If desired by user, restrict the model fitting such that certain
        # models are restricted to particular voxels
        if lgcRstr is not None:
            # Apply flatnonzero, so we can use cascaded integer indexing later
            lgcVxl = np.flatnonzero(lgcRstr[:, idxMdl])

        # Status indicator (only used in the first of the parallel
        # processes):
        if idxPrc == 0:

            # Status indicator:
            if varCntSts02 == vecStatPrf[varCntSts01]:

                # Prepare status message:
                strStsMsg = ('------------Progress: ' +
                             str(vecStatPrc[varCntSts01]) +
                             ' % --- ' +
                             str(vecStatPrf[varCntSts01]) +
                             ' pRF models out of ' +
                             str(varNumMdls))
                if lgcPrint:
                    print(strStsMsg)

                # Only increment counter if the last value has not been
                # reached yet:
                if varCntSts01 < varStsStpSze:
                    varCntSts01 = varCntSts01 + int(1)

        # Only fit pRF model if:
        # 1) all feature predictors have a variance greater than zero AND
        # 2) at least one voxel is being tested
        if np.logical_and(np.all(np.greater(aryPrfTcVar[idxMdl], varZero32),
                                 axis=0),
                          np.greater(lgcVxl.size, 0)):

            # Get predictor time courses for this specific model
            vecMdl = aryPrfTc[idxMdl, :, :].T

            # Check whether we need to crossvalidate
            if lgcXval:
                # We do crossvalidate. In this case, we loop through
                # the different folds of the crossvalidation and
                # calculate the cross-validation error for the current
                # model for all voxel time courses.

                # Cython version:
                if strVersion == 'cython':

                    # A cython function is used to calculate the residuals and
                    # beta parameter estimates of the current model:
                    if varNumFtr == 1:
                        # For time course with one predictors
                        aryResXval = cy_lst_sq_xval_one(np.squeeze(vecMdl),
                                                        aryFuncChnk[:, lgcVxl],
                                                        aryIdxTrn,
                                                        aryIdxTst)

                    elif varNumFtr == 2:
                        # For time course with two predictors
                        aryResXval = cy_lst_sq_xval_two(vecMdl,
                                                        aryFuncChnk[:, lgcVxl],
                                                        aryIdxTrn,
                                                        aryIdxTst)

                    else:
                        if lgcPrint:
                            print('Cython currently not implemented for ' +
                                  'more than two predictors.')

                # Numpy version:
                elif strVersion == 'numpy':

                    aryResXval = np_lst_sq_xval(vecMdl, aryFuncChnk[:, lgcVxl],
                                                aryIdxTrn, aryIdxTst)

                # calculate the average cross validation error across
                # all folds
                vecTmpRes = np.mean(aryResXval, axis=1)

            else:
                # We do not crossvalidate. In this case, we calculate
                # the ratio of the explained variance (R squared)
                # for the current model for all voxel time courses.

                # Cython version:
                if strVersion == 'cython':

                    # A cython function is used to calculate the residuals and
                    # beta parameter estimates of the current model:
                    if varNumFtr == 1:
                        # For time course with one predictor
                        aryTmpBts, vecTmpRes = cy_lst_sq_one(
                            np.squeeze(vecMdl), aryFuncChnk[:, lgcVxl])

                    elif varNumFtr == 2:
                        # For time course with two predictors
                        aryTmpBts, vecTmpRes = \
                            cy_lst_sq_two(vecMdl, aryFuncChnk[:, lgcVxl])
                    else:
                        if lgcPrint:
                            print('Cython currently not implemented for ' +
                                  'more than two two predictors.')

                # Numpy version:
                elif strVersion == 'numpy':

                    # Numpy linalg.lstsq is used to calculate the
                    # beta values and residuals of the current model:
                    aryTmpBts, vecTmpRes = np_lst_sq(vecMdl,
                                                     aryFuncChnk[:, lgcVxl])

            # Check whether current crossvalidation error (xval=True)
            # or residuals (xval=False) are lower than previously
            # calculated ones:
            vecLgcTmpRes = np.less(vecTmpRes, vecBstRes[lgcVxl])
            # Apply np.flatnonzero for cascaded integer-indexing
            vecLgcTmpRes = np.flatnonzero(vecLgcTmpRes)

            # Replace best x and y position values, and SD values:
            vecBstXpos[lgcVxl[vecLgcTmpRes]] = aryMdlParams[idxMdl, 0]
            vecBstYpos[lgcVxl[vecLgcTmpRes]] = aryMdlParams[idxMdl, 1]
            vecBstSd[lgcVxl[vecLgcTmpRes]] = aryMdlParams[idxMdl, 2]

            # Replace best mean residual values:
            vecBstRes[lgcVxl[vecLgcTmpRes]] = vecTmpRes[vecLgcTmpRes]

            if not lgcXval:
                # Replace best beta values:
                aryBstBts[lgcVxl[vecLgcTmpRes], :] = \
                    aryTmpBts[:, vecLgcTmpRes].T

            # In case we cross-validate we also save and replace the best
            # residual values for every fold (not only mean across folds):
            if lgcXval:
                aryBstResFlds[lgcVxl[vecLgcTmpRes], :] = \
                    aryResXval[vecLgcTmpRes, :]

        # Status indicator (only used in the first of the parallel
        # processes):
        if idxPrc == 0:

            # Increment status indicator counter:
            varCntSts02 = varCntSts02 + 1

    # After finding the best fitting model for each voxel, we still have to
    # calculate the average correlation coefficient between predicted and
    # measured time course (xval=True) or the coefficient of determination
    # (xval=False) for each voxel.

    if lgcXval:

        # create vector that allows to check whether every voxel is visited
        # exactly once
        vecVxlTst = np.zeros(aryFuncChnk.shape[1])

        # Since we did not do this during finding the best model, we still need
        # to calculate deviation from a mean model for every voxel and fold
        # arySsTotXval as well as calculate the best betas for the full model

        # concatenate vectors with best x, y, sigma params
        aryBstPrm = np.stack((vecBstXpos, vecBstYpos, vecBstSd), axis=1)

        # Find unique rows
        aryUnqRows = fnd_unq_rws(aryBstPrm, return_index=False,
                                 return_inverse=False)

        # Calculate deviation from a mean model for every voxel and fold
        arySsTotXval = np.zeros((aryBstResFlds.shape),
                                dtype=aryBstResFlds.dtype)

        # Loop over all best-fitting model parameter combinations found
        for vecPrm in aryUnqRows:
            # Get logical for voxels for which this prm combi was the best
            lgcPrm = np.isclose(aryBstPrm, vecPrm, atol=1e-04).all(axis=1)
            # Get logical index for the model number
            # This can only be 1 index, so we directly get 1st entry of array
            lgcIndMdl = np.where(np.isclose(aryMdlParams, vecPrm,
                                            atol=1e-04).all(axis=1))[0][0]

            if np.all(np.invert(lgcPrm)):
                if lgcPrint:
                    print('------------No voxel found, process ' + str(idxPrc))
            # Mark those voxels that were visited
            vecVxlTst[lgcPrm] += 1

            # Get voxel time course
            aryVxlTc = aryFuncChnk[:, lgcPrm]

            # Get model time courses
            aryMdlTc = aryPrfTc[lgcIndMdl, :, :].T

            # Calculate beta parameter estimates for entire model
            aryBstBts[lgcPrm, :] = np.linalg.lstsq(aryMdlTc,
                                                   aryVxlTc,
                                                   rcond=-1)[0].T

            # loop over cross-validation folds
            for idxXval in range(varNumXval):
                # Get functional data for tst:
                aryFuncChnkTst = aryVxlTc[
                    aryIdxTst[:, idxXval], :]
                # Deviation from the mean for each datapoint:
                aryFuncDev = np.subtract(aryFuncChnkTst,
                                         np.mean(aryFuncChnkTst,
                                                 axis=0)[None, :])
                # Sum of squares:
                vecSsTot = np.sum(np.power(aryFuncDev,
                                           2.0),
                                  axis=0)
                arySsTotXval[lgcPrm, idxXval] = vecSsTot

        # check that every voxel was visited exactly once
        errMsg = 'At least one voxel visited more than once for SStot calc'
        assert len(vecVxlTst) == np.sum(vecVxlTst), errMsg

        # Calculate coefficient of determination by comparing:
        # aryBstResFlds vs. arySsTotXval

        # get logical to check that arySsTotXval is greater than zero in all
        # voxels and folds
        lgcExclZeros = np.all(np.greater(arySsTotXval,  np.array([0.0])),
                              axis=1)
        if lgcPrint:
            print('------------Nr of voxels: ' + str(len(lgcExclZeros)))
            print('------------Nr of voxels avove 0: ' +
                  str(np.sum(lgcExclZeros)))

        # Calculate R2 for every crossvalidation fold seperately
        aryBstR2fld = np.subtract(
            1.0, np.divide(aryBstResFlds,
                           arySsTotXval))

        # Calculate mean R2 across folds here
        vecBstR2 = np.subtract(
            1.0, np.mean(np.divide(aryBstResFlds,
                                   arySsTotXval),
                         axis=1))

        # Output list:
        lstOut = [idxPrc,
                  vecBstXpos,
                  vecBstYpos,
                  vecBstSd,
                  vecBstR2,
                  aryBstBts,
                  aryBstR2fld]

        queOut.put(lstOut)

    else:
        # To calculate the coefficient of determination, we start with the
        # total sum of squares (i.e. the deviation of the data from the mean).
        # The mean of each time course:
        vecFuncMean = np.mean(aryFuncChnk, axis=0)
        # Deviation from the mean for each datapoint:
        aryFuncDev = np.subtract(aryFuncChnk, vecFuncMean[None, :])
        # Sum of squares:
        vecSsTot = np.sum(np.power(aryFuncDev,
                                   2.0),
                          axis=0)
        # Coefficient of determination:
        vecBstR2 = np.subtract(1.0,
                               np.divide(vecBstRes,
                                         vecSsTot))

        # Output list:
        lstOut = [idxPrc,
                  vecBstXpos,
                  vecBstYpos,
                  vecBstSd,
                  vecBstR2,
                  aryBstBts]

        queOut.put(lstOut)

Response: This function finds the best fitting pRF model for a specific voxel time course using the CPU.


Instruction:
Write a Python 3 script to
check the revert status of a revision. With this method, you can determine whether an edit is a 'reverting' edit, was 'reverted' by another edit and/or was 'reverted_to' by another edit. :Parameters: session : :class:`mwapi.Session` An API session to make use of rev_id : int the ID of the revision to check page_id : int the ID of the page the revision occupies (slower if not provided) radius : int a positive integer indicating the maximum number of revisions that can be reverted before : :class:`mwtypes.Timestamp` if set, limits the search for *reverting* revisions to those which were saved before this timestamp window : int if set, limits the search for *reverting* revisions to those which were saved within `window` seconds after the reverted edit rvprop : set( str ) a set of properties to include in revisions :Returns: A triple :class:`mwreverts.Revert` | `None` * reverting -- If this edit reverted other edit(s) * reverted -- If this edit was reverted by another edit * reverted_to -- If this edit was reverted to by another edit :Example: >>> import mwdb >>> import mwreverts.api >>> >>> schema = mwdb.Schema("mysql+pymysql://enwiki.labsdb/enwiki_p" + "?read_default_file=~/replica.my.cnf") >>> >>> def print_revert(revert): ... if revert is None: ... print(None) ... else: ... print(revert.reverting['rev_id'], ... [r['rev_id'] for r in revert.reverteds], ... revert.reverted_to['rev_id']) ... >>> reverting, reverted, reverted_to = \\ ... mwreverts.db.check(schema, 679778587) >>> print_revert(reverting) None >>> print_revert(reverted) 679778743 [679778587] 679742862 >>> print_revert(reverted_to) None

Response:
def check(schema, rev_id, page_id=None, radius=defaults.RADIUS,
          before=None, window=None):
    """
    Checks the revert status of a revision.  With this method, you can
    determine whether an edit is a 'reverting' edit, was 'reverted' by another
    edit and/or was 'reverted_to' by another edit.

    :Parameters:
        session : :class:`mwapi.Session`
            An API session to make use of
        rev_id : int
            the ID of the revision to check
        page_id : int
            the ID of the page the revision occupies (slower if not provided)
        radius : int
            a positive integer indicating the maximum number of revisions
            that can be reverted
        before : :class:`mwtypes.Timestamp`
            if set, limits the search for *reverting* revisions to those which
            were saved before this timestamp
        window : int
            if set, limits the search for *reverting* revisions to those which
            were saved within `window` seconds after the reverted edit
        rvprop : set( str )
            a set of properties to include in revisions

    :Returns:
        A triple :class:`mwreverts.Revert` | `None`

        * reverting -- If this edit reverted other edit(s)
        * reverted -- If this edit was reverted by another edit
        * reverted_to -- If this edit was reverted to by another edit

    :Example:

        >>> import mwdb
        >>> import mwreverts.api
        >>>
        >>> schema = mwdb.Schema("mysql+pymysql://enwiki.labsdb/enwiki_p" +
                                 "?read_default_file=~/replica.my.cnf")
        >>>
        >>> def print_revert(revert):
        ...     if revert is None:
        ...         print(None)
        ...     else:
        ...         print(revert.reverting['rev_id'],
        ...               [r['rev_id'] for r in revert.reverteds],
        ...               revert.reverted_to['rev_id'])
        ...
        >>> reverting, reverted, reverted_to = \\
        ...     mwreverts.db.check(schema, 679778587)
        >>> print_revert(reverting)
        None
        >>> print_revert(reverted)
        679778743 [679778587] 679742862
        >>> print_revert(reverted_to)
        None

    """

    rev_id = int(rev_id)
    radius = int(radius)
    if radius < 1:
        raise TypeError("invalid radius.  Expected a positive integer.")

    page_id = int(page_id) if page_id is not None else None
    before = Timestamp(before) if before is not None else None

    # If we don't have the page_id, we're going to need to look them up
    if page_id is None:
        page_id = get_page_id(schema, rev_id)

    # Load history and current rev
    current_and_past_revs = list(n_edits_before(
        schema, rev_id + 1, page_id, n=radius + 1))

    if len(current_and_past_revs) < 1:
        raise KeyError("Revision {0} not found in page {1}."
                       .format(rev_id, page_id))

    current_rev, past_revs = (
        current_and_past_revs[-1],  # Current rev is the last one returned
        current_and_past_revs[:-1]  # The rest are past revs
    )
    if current_rev.rev_id != rev_id:
        raise KeyError("Revision {0} not found in page {1}."
                       .format(rev_id, page_id))

    if window is not None and before is None:
        before = Timestamp(current_rev.rev_timestamp) + window

    # Load future revisions
    future_revs = list(n_edits_after(
        schema, rev_id, page_id, n=radius, before=before))

    return build_revert_tuple(
        rev_id, past_revs, current_rev, future_revs, radius)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def check_archive(schema, rev_id, namespace=None, title=None, timestamp=None,
                  radius=defaults.RADIUS,
                  before=None, window=None):
    """
    Checks the revert status of an archived revision (from a deleted page).
    With this method, you can determine whether an edit is a 'reverting'
    edit, was 'reverted' by another edit and/or was 'reverted_to' by
    another edit.

    :Parameters:
        session : :class:`mwapi.Session`
            An API session to make use of
        rev_id : int
            the ID of the revision to check
        namespace : int
            the namespace ID of the page the revision exists in
        title : str
            the title of the page the revision exists in
        timestamp : :class:`mwtypes.Timestamp`
            the timestamp that the revision for `rev_id` was saved
        radius : int
            a positive integer indicating the maximum number of revisions
            that can be reverted
        before : :class:`mwtypes.Timestamp`
            if set, limits the search for *reverting* revisions to those which
            were saved before this timestamp
        window : int
            if set, limits the search for *reverting* revisions to those which
            were saved within `window` seconds after the reverted edit
        rvprop : set( str )
            a set of properties to include in revisions

    :Returns:
        A triple :class:`mwreverts.Revert`

        * reverting -- If this edit reverted other edit(s)
        * reverted -- If this edit was reverted by another edit
        * reverted_to -- If this edit was reverted to by another edit

    """

    rev_id = int(rev_id)
    radius = int(radius)
    if radius < 1:
        raise TypeError("invalid radius.  Expected a positive integer.")

    namespace = int(namespace) if namespace is not None else None
    title = str(title) if title is not None else None
    timestamp = Timestamp(timestamp) if timestamp is not None else None
    before = Timestamp(before) if before is not None else None

    # If we don't have the page_id, we're going to need to look them up
    if namespace is None or title is None or timestamp is None:
        namespace, title, timestamp = \
            get_archived_namespace_title_and_timestamp(schema, rev_id)

    # Load history and current rev
    current_and_past_revs = list(n_archived_edits_before(
        schema, rev_id + 1, namespace, title, timestamp + 1, n=radius + 1))

    if len(current_and_past_revs) < 1:
        raise KeyError("Revision {0} not found in page {1}(ns={2}) @ {3}."
                       .format(rev_id, title, namespace, timestamp))

    current_rev, past_revs = (
        current_and_past_revs[-1],  # Current rev is the last one returned
        current_and_past_revs[:-1]  # The rest are past revs
    )
    if current_rev.ar_rev_id != rev_id:
        raise KeyError("Revision {0} not found in page {1}(ns={2}) @ {3}."
                       .format(rev_id, title, namespace, timestamp))

    if window is not None and before is None:
        before = Timestamp(current_rev.ar_timestamp) + window

    # Load future revisions
    future_revs = list(n_archived_edits_after(
        schema, rev_id, namespace, title, timestamp, n=radius, before=before))

    return build_revert_tuple(
        rev_id, past_revs, current_rev, future_revs, radius)

Response: Checks the revert status of an archived revision.


Instruction:
Write a Python 3 function that can
convert the given value to a JSON object.

Response:
def _get_json(value):
    """Convert the given value to a JSON object."""
    if hasattr(value, 'replace'):
        value = value.replace('\n', ' ')
    try:
        return json.loads(value)
    except json.JSONDecodeError:
        # Escape double quotes.
        if hasattr(value, 'replace'):
            value = value.replace('"', '\\"')
        # try putting the value into a string
        return json.loads('"{}"'.format(value))


Instruction:
Given the following Python 3 function, write the documentation
def save_list(key, *values):
    return json.dumps({key: [_get_json(value) for value in values]})

Response: Convert the given list of parameters to a JSON object.


Instruction:
Can you implement a function in Python 3 that
converts the given parameters to a special JSON object.

Response:
def save_file(key, file_path, *refs):
    """Convert the given parameters to a special JSON object.

    JSON object is of the form:
    { key: {"file": file_path}}, or
    { key: {"file": file_path, "refs": [refs[0], refs[1], ... ]}}

    """
    if not os.path.isfile(file_path):
        return error("Output '{}' set to a missing file: '{}'.".format(key, file_path))

    result = {key: {"file": file_path}}

    if refs:
        missing_refs = [
            ref for ref in refs if not (os.path.isfile(ref) or os.path.isdir(ref))
        ]
        if len(missing_refs) > 0:
            return error(
                "Output '{}' set to missing references: '{}'.".format(
                    key, ', '.join(missing_refs)
                )
            )
        result[key]['refs'] = refs

    return json.dumps(result)


Instruction:
Implement a function in Python 3 to
convert the given parameters to a special JSON object.

Response:
def save_file_list(key, *files_refs):
    """Convert the given parameters to a special JSON object.

    Each parameter is a file-refs specification of the form:
    <file-path>:<reference1>,<reference2>, ...,
    where the colon ':' and the list of references are optional.

    JSON object is of the form:
    { key: {"file": file_path}}, or
    { key: {"file": file_path, "refs": [refs[0], refs[1], ... ]}}

    """
    file_list = []
    for file_refs in files_refs:
        if ':' in file_refs:
            try:
                file_name, refs = file_refs.split(':')
            except ValueError as e:
                return error("Only one colon ':' allowed in file-refs specification.")
        else:
            file_name, refs = file_refs, None
        if not os.path.isfile(file_name):
            return error(
                "Output '{}' set to a missing file: '{}'.".format(key, file_name)
            )
        file_obj = {'file': file_name}

        if refs:
            refs = [ref_path.strip() for ref_path in refs.split(',')]
            missing_refs = [
                ref for ref in refs if not (os.path.isfile(ref) or os.path.isdir(ref))
            ]
            if len(missing_refs) > 0:
                return error(
                    "Output '{}' set to missing references: '{}'.".format(
                        key, ', '.join(missing_refs)
                    )
                )
            file_obj['refs'] = refs

        file_list.append(file_obj)

    return json.dumps({key: file_list})


Instruction:
Here you have a function in Python 3, explain what it does
def save_dir(key, dir_path, *refs):
    if not os.path.isdir(dir_path):
        return error(
            "Output '{}' set to a missing directory: '{}'.".format(key, dir_path)
        )

    result = {key: {"dir": dir_path}}

    if refs:
        missing_refs = [
            ref for ref in refs if not (os.path.isfile(ref) or os.path.isdir(ref))
        ]
        if len(missing_refs) > 0:
            return error(
                "Output '{}' set to missing references: '{}'.".format(
                    key, ', '.join(missing_refs)
                )
            )
        result[key]["refs"] = refs

    return json.dumps(result)

Response: Convert the given parameters to a special JSON object.


Instruction:
Here you have a function in Python 3, explain what it does
def save_dir_list(key, *dirs_refs):
    dir_list = []
    for dir_refs in dirs_refs:
        if ':' in dir_refs:
            try:
                dir_path, refs = dir_refs.split(':')
            except ValueError as e:
                return error("Only one colon ':' allowed in dir-refs specification.")
        else:
            dir_path, refs = dir_refs, None
        if not os.path.isdir(dir_path):
            return error(
                "Output '{}' set to a missing directory: '{}'.".format(key, dir_path)
            )
        dir_obj = {'dir': dir_path}

        if refs:
            refs = [ref_path.strip() for ref_path in refs.split(',')]
            missing_refs = [
                ref for ref in refs if not (os.path.isfile(ref) or os.path.isdir(ref))
            ]
            if len(missing_refs) > 0:
                return error(
                    "Output '{}' set to missing references: '{}'.".format(
                        key, ', '.join(missing_refs)
                    )
                )
            dir_obj['refs'] = refs

        dir_list.append(dir_obj)

    return json.dumps({key: dir_list})

Response: Convert the given parameters to a special JSON object.


Instruction:
Can you tell what is the following Python 3 function doing
def progress(progress):
    if isinstance(progress, int) or isinstance(progress, float):
        progress = float(progress)
    else:
        try:
            progress = float(json.loads(progress))
        except (TypeError, ValueError):
            return warning("Progress must be a float.")

    if not 0 <= progress <= 1:
        return warning("Progress must be a float between 0 and 1.")

    return json.dumps({'proc.progress': progress})

Response: Convert given progress to a JSON object.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def checkrc(rc, *args):
    try:
        rc = int(rc)
    except (TypeError, ValueError):
        return error("Invalid return code: '{}'.".format(rc))

    acceptable_rcs = []
    error_msg = ""

    if len(args):
        for code in args[:-1]:
            try:
                acceptable_rcs.append(int(code))
            except (TypeError, ValueError):
                return error("Invalid return code: '{}'.".format(code))

        try:
            acceptable_rcs.append(int(args[-1]))
        except (TypeError, ValueError):
            error_msg = args[-1]

    if rc in acceptable_rcs:
        rc = 0

    ret = {'proc.rc': rc}
    if rc and error_msg:
        ret['proc.error'] = error_msg

    return json.dumps(ret)

Response: Check if return code is in list that contains acceptable return codes.


Instruction:
Given the following Python 3 function, write the documentation
def import_file(
    src,
    file_name,
    imported_format=ImportedFormat.BOTH,
    progress_from=0.0,
    progress_to=None,
):
    """Import file to working directory.

    :param src: Source file path or URL
    :param file_name: Source file name
    :param imported_format: Import file format (extracted, compressed or both)
    :param progress_from: Initial progress value
    :param progress_to: Final progress value
    :return: Destination file path (if extracted and compressed, extracted path given)
    """

    if progress_to is not None:
        if not isinstance(progress_from, float) or not isinstance(progress_to, float):
            raise ValueError("Progress_from and progress_to must be float")

        if progress_from < 0 or progress_from > 1:
            raise ValueError("Progress_from must be between 0 and 1")

        if progress_to < 0 or progress_to > 1:
            raise ValueError("Progress_to must be between 0 and 1")

        if progress_from >= progress_to:
            raise ValueError("Progress_to must be higher than progress_from")

    print("Importing and compressing {}...".format(file_name))

    def importGz():
        """Import gzipped file.

        The file_name must have .gz extension.
        """
        if imported_format != ImportedFormat.COMPRESSED:  # Extracted file required
            with open(file_name[:-3], 'wb') as f_out, gzip.open(src, 'rb') as f_in:
                try:
                    shutil.copyfileobj(f_in, f_out, CHUNK_SIZE)
                except zlib.error:
                    raise ValueError("Invalid gzip file format: {}".format(file_name))

        else:  # Extracted file not-required
            # Verify the compressed file.
            with gzip.open(src, 'rb') as f:
                try:
                    while f.read(CHUNK_SIZE) != b'':
                        pass
                except zlib.error:
                    raise ValueError("Invalid gzip file format: {}".format(file_name))

        if imported_format != ImportedFormat.EXTRACTED:  # Compressed file required
            try:
                shutil.copyfile(src, file_name)
            except shutil.SameFileError:
                pass  # Skip copy of downloaded files

        if imported_format == ImportedFormat.COMPRESSED:
            return file_name
        else:
            return file_name[:-3]

    def import7z():
        """Import compressed file in various formats.

        Supported extensions: .bz2, .zip, .rar, .7z, .tar.gz, and .tar.bz2.
        """
        extracted_name, _ = os.path.splitext(file_name)
        destination_name = extracted_name
        temp_dir = 'temp_{}'.format(extracted_name)

        cmd = '7z x -y -o{} {}'.format(shlex.quote(temp_dir), shlex.quote(src))
        try:
            subprocess.check_call(cmd, shell=True)
        except subprocess.CalledProcessError as err:
            if err.returncode == 2:
                raise ValueError("Failed to extract file: {}".format(file_name))
            else:
                raise

        paths = os.listdir(temp_dir)
        if len(paths) == 1 and os.path.isfile(os.path.join(temp_dir, paths[0])):
            # Single file in archive.
            temp_file = os.path.join(temp_dir, paths[0])

            if imported_format != ImportedFormat.EXTRACTED:  # Compressed file required
                with open(temp_file, 'rb') as f_in, gzip.open(
                    extracted_name + '.gz', 'wb'
                ) as f_out:
                    shutil.copyfileobj(f_in, f_out, CHUNK_SIZE)

            if imported_format != ImportedFormat.COMPRESSED:  # Extracted file required
                shutil.move(temp_file, './{}'.format(extracted_name))

                if extracted_name.endswith('.tar'):
                    with tarfile.open(extracted_name) as tar:
                        tar.extractall()

                    os.remove(extracted_name)
                    destination_name, _ = os.path.splitext(extracted_name)
            else:
                destination_name = extracted_name + '.gz'
        else:
            # Directory or several files in archive.
            if imported_format != ImportedFormat.EXTRACTED:  # Compressed file required
                with tarfile.open(extracted_name + '.tar.gz', 'w:gz') as tar:
                    for fname in glob.glob(os.path.join(temp_dir, '*')):
                        tar.add(fname, os.path.basename(fname))

            if imported_format != ImportedFormat.COMPRESSED:  # Extracted file required
                for path in os.listdir(temp_dir):
                    shutil.move(os.path.join(temp_dir, path), './{}'.format(path))
            else:
                destination_name = extracted_name + '.tar.gz'

        shutil.rmtree(temp_dir)
        return destination_name

    def importUncompressed():
        """Import uncompressed file."""
        if imported_format != ImportedFormat.EXTRACTED:  # Compressed file required
            with open(src, 'rb') as f_in, gzip.open(file_name + '.gz', 'wb') as f_out:
                shutil.copyfileobj(f_in, f_out, CHUNK_SIZE)

        if imported_format != ImportedFormat.COMPRESSED:  # Extracted file required
            try:
                shutil.copyfile(src, file_name)
            except shutil.SameFileError:
                pass  # Skip copy of downloaded files

        return (
            file_name + '.gz'
            if imported_format == ImportedFormat.COMPRESSED
            else file_name
        )

    # Large file download from Google Drive requires cookie and token.
    try:
        response = None
        if re.match(
            r'^https://drive.google.com/[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]$',
            src,
        ):
            session = requests.Session()
            response = session.get(src, stream=True)

            token = None
            for key, value in response.cookies.items():
                if key.startswith('download_warning'):
                    token = value
                    break

            if token is not None:
                params = {'confirm': token}
                response = session.get(src, params=params, stream=True)

        elif re.match(
            r'^(https?|ftp)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]$',
            src,
        ):
            response = requests.get(src, stream=True)
    except requests.exceptions.ConnectionError:
        raise requests.exceptions.ConnectionError("Could not connect to {}".format(src))

    if response:
        with open(file_name, 'wb') as f:
            total = response.headers.get('content-length')
            total = float(total) if total else None
            downloaded = 0
            current_progress = 0
            for content in response.iter_content(chunk_size=CHUNK_SIZE):
                f.write(content)

                if total is not None and progress_to is not None:
                    downloaded += len(content)
                    progress_span = progress_to - progress_from
                    next_progress = progress_from + progress_span * downloaded / total
                    next_progress = round(next_progress, 2)

                    if next_progress > current_progress:
                        print(progress(next_progress))
                        current_progress = next_progress

        # Check if a temporary file exists.
        if not os.path.isfile(file_name):
            raise ValueError("Downloaded file not found {}".format(file_name))

        src = file_name
    else:
        if not os.path.isfile(src):
            raise ValueError("Source file not found {}".format(src))

    # Decide which import should be used.
    if re.search(r'\.(bz2|zip|rar|7z|tgz|tar\.gz|tar\.bz2)$', file_name):
        destination_file_name = import7z()
    elif file_name.endswith('.gz'):
        destination_file_name = importGz()
    else:
        destination_file_name = importUncompressed()

    if progress_to is not None:
        print(progress(progress_to))

    return destination_file_name

Response: Imports a file from a source file to a target file.


Instruction:
Write a Python 3 script to
load nii data from nii files

Response:
def loadNiiData(lstNiiFls,
                strPathNiiMask=None,
                strPathNiiFunc=None):
    """load nii data.

        Parameters
        ----------
        lstNiiFls : list, list of str with nii file names
        strPathNiiMask : str, path to nii file with mask (optional)
        strPathNiiFunc : str, parent path to nii files (optional)
        Returns
        -------
        aryFunc : np.array
            Nii data
    """
    print('---------Loading nii data')
    # check whether  a mask is available
    if strPathNiiMask is not None:
        aryMask = nb.load(strPathNiiMask).get_data().astype('bool')
    # check a parent path is available that needs to be preprended to nii files
    if strPathNiiFunc is not None:
        lstNiiFls = [os.path.join(strPathNiiFunc, i) for i in lstNiiFls]

    aryFunc = []
    for idx, path in enumerate(lstNiiFls):
        print('------------Loading run: ' + str(idx+1))
        # Load 4D nii data:
        niiFunc = nb.load(path).get_data()
        # append to list
        if strPathNiiMask is not None:
            aryFunc.append(niiFunc[aryMask, :])
        else:
            aryFunc.append(niiFunc)
    # concatenate arrys in list along time dimension
    aryFunc = np.concatenate(aryFunc, axis=-1)
    # set to type float32
    aryFunc = aryFunc.astype('float32')

    return aryFunc


Instruction:
Write a Python 3 script for
calculating coefficient of determination. Assumes that axis = 0 is time

Response:
def calcR2(predTst, yTest, axis=0):
    """calculate coefficient of determination. Assumes that axis=0 is time

        Parameters
        ----------
        predTst : np.array, predicted reponse for yTest
        yTest : np.array, acxtually observed response for yTest
        Returns
        -------
        aryFunc : np.array
            R2
    """
    rss = np.sum((yTest - predTst) ** 2, axis=axis)
    tss = np.sum((yTest - yTest.mean()) ** 2, axis=axis)

    return 1 - rss/tss


Instruction:
Can you tell what is the following Python 3 function doing
def calcFstats(predTst, yTest, p, axis=0):
    rss = np.sum((yTest - predTst) ** 2, axis=axis)
    tss = np.sum((yTest - yTest.mean()) ** 2, axis=axis)
    # derive number of measurements
    n = yTest.shape[0]
    # calculate Fvalues
    vecFvals = ((tss - rss)/p)/(rss/(n-p-1))
    # calculate corresponding po values
    df1 = p - 1
    df2 = n-1
    vecPvals = stats.f.cdf(vecFvals, df1, df2)

    return vecFvals, vecPvals

Response: calculate coefficient of determination. Assumes that axis = 0 is time


Instruction:
Can you generate a brief explanation for the following Python 3 code
def calcMse(predTst, yTest, axis=0):
    return np.mean((yTest - predTst) ** 2, axis=axis)

Response:
calculate mean squared error. Assumes that axis = 0 is time
 getTerminal


Instruction:
Write a Python 3 script for
detecting reverts that occur in a sequence of revisions.

Response:
def detect(checksum_revisions, radius=defaults.RADIUS):
    """
    Detects reverts that occur in a sequence of revisions.  Note that,
    `revision` data meta will simply be returned in the case of a revert.

    This function serves as a convenience wrapper around calls to
    :class:`mwreverts.Detector`'s :func:`~mwreverts.Detector.process`
    method.

    :Parameters:
        checksum_revisions : `iterable` ( (checksum, revision) )
            an iterable over tuples of checksum and revision meta data
        radius : int
            a positive integer indicating the maximum revision distance that a
            revert can span.

    :Return:
        a iterator over :class:`mwreverts.Revert`

    :Example:
        >>> import mwreverts
        >>>
        >>> checksum_revisions = [
        ...     ("aaa", {'rev_id': 1}),
        ...     ("bbb", {'rev_id': 2}),
        ...     ("aaa", {'rev_id': 3}),
        ...     ("ccc", {'rev_id': 4})
        ... ]
        >>>
        >>> list(mwreverts.detect(checksum_revisions))
        [Revert(reverting={'rev_id': 3},
                reverteds=[{'rev_id': 2}],
                reverted_to={'rev_id': 1})]

    """

    revert_detector = Detector(radius)

    for checksum, revision in checksum_revisions:
        revert = revert_detector.process(checksum, revision)
        if revert is not None:
            yield revert


Instruction:
Can you tell what is the following Python 3 function doing
def getChargeInfo(self, CorpNum, ItemCode, UserID=None):
        if ItemCode == None or ItemCode == '':
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        return self._httpget('/Statement/ChargeInfo/' + ItemCode, CorpNum, UserID)

Response: 요청번호 Returns a list of ChargeInfo objects.


Instruction:
Can you generate the documentation for the following Python 3 function
def getUnitCost(self, CorpNum, ItemCode):
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        result = self._httpget('/Statement/' + str(ItemCode) + '?cfg=UNITCOST', CorpNum)
        return float(result.unitCost)

Response: 전자번호 전자번호 정서 �


Instruction:
Given the following Python 3 function, write the documentation
def registIssue(self, CorpNum, statement, Memo=None, UserID=None):
        if statement == None:
            raise PopbillException(-99999999, "등록할 전자명세서 정보가 입력되지 않았습니다.")

        if Memo != None or Memo != '':
            statement.memo = Memo

        postData = self._stringtify(statement)

        return self._httppost('/Statement', postData, CorpNum, UserID, "ISSUE")

Response:
즉시발행
            args
                CorpNum : 팝빌회원 사업자번호
                statement : 등록할 전자명세서 object. made with Statement(...)
                Memo : 즉시발행메모

                UserID : 팝빌회원 아이디
            return
                처리결과. consist of code and message
            raise
                PopbillException


Instruction:
How would you explain what the following Python 3 function does
def register(self, CorpNum, statement, UserID=None):
        if statement == None:
            raise PopbillException(-99999999, "등록할 전자명세서 정보가 입력되지 않았습니다.")

        postData = self._stringtify(statement)

        return self._httppost('/Statement', postData, CorpNum, UserID)

Response:
임시저장
            args
                CorpNum : 팝빌회원 사업자번호
                statement : 등록할 전자명세서 object. made with Statement(...)
                UserID : 팝빌회원 아이디
            return
                처리결과. consist of code and message
            raise
                PopbillException


Instruction:
Given the following Python 3 function, write the documentation
def update(self, CorpNum, ItemCode, MgtKey, Statement, UserID=None):

        if Statement == None:
            raise PopbillException(-99999999, "등록할 전자명세서 정보가 입력되지 않았습니다.")
        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        postData = self._stringtify(Statement)

        return self._httppost('/Statement/' + str(ItemCode) + '/' + MgtKey, postData, CorpNum, UserID, 'PATCH')

Response:
임시저장
            args
                CorpNum : 팝빌회원 사업자번호
                ItemCode : 명세서 종류 코드
                    [121 - 거래명세서], [122 - 청구서], [123 - 견적서],
                    [124 - 발주서], [125 - 입금표], [126 - 영수증]
                MgtKey : 파트너 문서관리번호
                Statement : 등록할 전자명세서 object. made with Statement(...)
                UserID : 팝빌회원 아이디
            return
                처리결과. consist of code and message
            raise
                PopbillException


Instruction:
Create a Python 3 function for
issuing a new item from the given CorpNum.

Response:
def issue(self, CorpNum, ItemCode, MgtKey, Memo=None, EmailSubject=None, UserID=None):
        """ 발행
            args
                CorpNum : 팝빌회원 사업자번호
                ItemCode : 명세서 종류 코드
                    [121 - 거래명세서], [122 - 청구서], [123 - 견적서],
                    [124 - 발주서], [125 - 입금표], [126 - 영수증]
                MgtKey : 파트너 문서관리번호
                Memo : 처리메모
                EmailSubject : 발행메일 제목(미기재시 기본양식으로 전송)
                UserID : 팝빌회원 아이디
            return
                처리결과. consist of code and message
            raise
                PopbillException
        """
        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        req = {}
        postData = ""

        if Memo != None and Memo != '':
            req["memo"] = Memo
        if EmailSubject != None and EmailSubject != '':
            req["emailSubject"] = EmailSubject

        postData = self._stringtify(req)

        return self._httppost('/Statement/' + str(ItemCode) + '/' + MgtKey, postData, CorpNum, UserID, "ISSUE")


Instruction:
Make a summary of the following Python 3 code
def cancel(self, CorpNum, ItemCode, MgtKey, Memo=None, UserID=None):

        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        postData = ''

        if Memo != None and Memo != '':
            postData = self._stringtify({"memo": Memo})

        return self._httppost('/Statement/' + str(ItemCode) + '/' + MgtKey, postData, CorpNum, UserID, "CANCEL")

Response: Cancel a single item from a given CorpNum.


Instruction:
Write a Python 3 function for
getting Info from Alembic.

Response:
def getInfo(self, CorpNum, ItemCode, MgtKey):
        """ 상태/요약 정보 확인
            args
                CorpNum : 팝빌회원 사업자번호
                ItemCode : 명세서 종류 코드
                    [121 - 거래명세서], [122 - 청구서], [123 - 견적서],
                    [124 - 발주서], [125 - 입금표], [126 - 영수증]
                MgtKey : 파트너 문서관리번호
            return
                문서 상태/요약정보 object
            raise
                PopbillException
        """
        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        return self._httpget('/Statement/' + str(ItemCode) + '/' + MgtKey, CorpNum)


Instruction:
Given the following Python 3 function, write the documentation
def getDetailInfo(self, CorpNum, ItemCode, MgtKey):
        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        return self._httpget('/Statement/' + str(ItemCode) + '/' + MgtKey + '?Detail', CorpNum)

Response: Get the details of a particular item in a particular CorpNum.


Instruction:
How would you implement a function in Python 3 that
attaches File to CorpNum

Response:
def attachFile(self, CorpNum, ItemCode, MgtKey, FilePath, UserID=None):
        """ 파일 첨부
            args
                CorpNum : 팝빌회원 사업자번호
                ItemCode : 명세서 종류 코드
                    [121 - 거래명세서], [122 - 청구서], [123 - 견적서],
                    [124 - 발주서], [125 - 입금표], [126 - 영수증]
                MgtKey : 파트너 문서관리번호
                FilePath : 첨부파일의 경로
                UserID : 팝빌 회원아이디
            return
                처리결과. consist of code and message
            raise
                PopbillException
        """
        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if FilePath == None or FilePath == "":
            raise PopbillException(-99999999, "파일경로가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")
        files = []

        try:
            with open(FilePath, "rb") as F:
                files = [File(fieldName='Filedata',
                              fileName=F.name,
                              fileData=F.read())]
        except IOError:
            raise PopbillException(-99999999, "해당경로에 파일이 없거나 읽을 수 없습니다.")

        return self._httppost_files('/Statement/' + str(ItemCode) + '/' + MgtKey + '/Files', None, files, CorpNum,
                                    UserID)


Instruction:
Implement a function in Python 3 to
delete a file from the given CorpNum and MgtKey.

Response:
def deleteFile(self, CorpNum, ItemCode, MgtKey, FileID, UserID=None):
        """ 첨부파일 삭제
            args
                CorpNum : 팝빌회원 사업자번호
                ItemCode : 명세서 종류 코드
                    [121 - 거래명세서], [122 - 청구서], [123 - 견적서],
                    [124 - 발주서], [125 - 입금표], [126 - 영수증]
                MgtKey : 파트너 문서관리번호
                FileID : 파일아이디, 첨부파일 목록확인(getFiles) API 응답전문의 AttachedFile 변수값
                UserID : 팝빌회원 아이디
            return
                첨부파일 정보 목록 as List
            raise
                PopbillException
        """
        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")
        if FileID == None or FileID == "":
            raise PopbillException(-99999999, "파일아이디가 입력되지 않았습니다.")

        postData = ''

        return self._httppost('/Statement/' + str(ItemCode) + '/' + MgtKey + '/Files/' + FileID, postData, CorpNum,
                              UserID, 'DELETE')


Instruction:
Given the following Python 3 function, write the documentation
def getMassPrintURL(self, CorpNum, ItemCode, MgtKeyList, UserID=None):
        if MgtKeyList == None:
            raise PopbillException(-99999999, "관리번호 배열이 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        postData = self._stringtify(MgtKeyList)

        result = self._httppost('/Statement/' + str(ItemCode) + '?Print', postData, CorpNum, UserID)

        return result.url

Response: 인쇄 URL 확인 확인


Instruction:
How would you explain what the following Python 3 function does
def attachStatement(self, CorpNum, ItemCode, MgtKey, SubItemCode, SubMgtKey, UserID=None):
        if MgtKey == None or MgtKey == "":
            raise PopbillException(-99999999, "관리번호가 입력되지 않았습니다.")
        if ItemCode == None or ItemCode == "":
            raise PopbillException(-99999999, "명세서 종류 코드가 입력되지 않았습니다.")

        uri = '/Statement/' + ItemCode + '/' + MgtKey + '/AttachStmt'

        postData = self._stringtify({"ItemCode": ItemCode, "MgtKey": SubMgtKey})

        return self._httppost(uri, postData, CorpNum, UserID)

Response: A method to attach a statement to a CorpNum.


Instruction:
Can you generate the documentation for the following Python 3 function
def process(self, article):
        if self.article is not None and not self.collection:
            log.warning('Could not process additional article. Package only \
handles one article unless collection mode is set.')
            return False

        if article.publisher is None:
            log.error('''Package cannot be generated for an Article \
without a publisher!''')
            return
        self.article = article
        self.article_doi = self.article.doi.split('/')[1]
        self.all_dois.append(self.article.doi)

        #Analyze the article to add entries to the spine
        dash_doi = self.article_doi.replace('.', '-')

        #Entry for the main content document
        main_idref = 'main-{0}-xhtml'.format(dash_doi)
        self.spine_list.append(spine_item(main_idref, True))

        #Entry for the biblio content document
        biblio_idref = 'biblio-{0}-xhtml'.format(dash_doi)
        if self.article.root.xpath('./back/ref-list/ref'):
                self.spine_list.append(spine_item(biblio_idref, True))

        #Entry for the tables content document
        tables_idref = 'tables-{0}-xhtml'.format(dash_doi)
        if self.article.publisher.has_out_of_flow_tables():
            self.spine_list.append(spine_item(tables_idref, False))

        self.acquire_metadata()

Response: Processes an article and adds the appropriate spine items to the internal spine list.


Instruction:
How would you explain what the following Python 3 function does
def acquire_metadata(self):
        #For space economy
        publisher = self.article.publisher

        if self.collection:  # collection mode metadata gathering
            pass
        else:  # single mode metadata gathering
            self.pub_id = publisher.package_identifier()
            self.title = publisher.package_title()
            for date in publisher.package_date():
                self.dates.add(date)

        #Common metadata gathering
        for lang in publisher.package_language():
            self.languages.add(lang)  # languages
        for contributor in publisher.package_contributors():  # contributors
            self.contributors.add(contributor)
        self.publishers.add(publisher.package_publisher())  # publisher names
        desc = publisher.package_description()
        if desc is not None:
            self.descriptions.add(desc)
        for subj in publisher.package_subject():
            self.subjects.add(subj)  # subjects
        #Rights
        art_rights = publisher.package_rights()
        self.rights.add(art_rights)
        if art_rights not in self.rights_associations:
            self.rights_associations[art_rights] = [self.article.doi]
        else:
            self.rights_associations[art_rights].append(self.article.doi)

Response: Handles the acquisition of metadata for both collection mode and single mode.


Instruction:
Explain what the following Python 3 code does
def file_manifest(self, location):
        #Maps file extensions to mimetypes
        mimetypes = {'.jpg': 'image/jpeg',
                     '.jpeg': 'image/jpeg',
                     '.xml': 'application/xhtml+xml',
                     '.png': 'image/png',
                     '.css': 'text/css',
                     '.ncx': 'application/x-dtbncx+xml',
                     '.gif': 'image/gif',
                     '.tif': 'image/tif',
                     '.pdf': 'application/pdf',
                     '.xhtml': 'application/xhtml+xml',
                     '.ttf': 'application/vnd.ms-opentype',
                     '.otf': 'application/vnd.ms-opentype'}

        current_dir = os.getcwd()
        os.chdir(location)
        for dirpath, _dirnames, filenames in os.walk('.'):
            dirpath = dirpath[2:]  # A means to avoid dirpath prefix of './'
            for fn in filenames:
                fn_ext = os.path.splitext(fn)[-1]
                item = etree.Element('item')
                #Here we set three attributes: href, media-type, and id
                if not dirpath:
                    item.attrib['href'] = fn
                else:
                    item.attrib['href'] = '/'.join([dirpath, fn])
                item.attrib['media-type'] = mimetypes[fn_ext]
                #Special handling for common image types
                if fn_ext in ['.jpg', '.png', '.tif', '.jpeg']:
                    #the following lines assume we are using the convention
                    #where the article doi is prefixed by 'images-'
                    item.attrib['id'] = '-'.join([dirpath[7:],
                                                  fn.replace('.', '-')])
                else:
                    item.attrib['id'] = fn.replace('.', '-')
                yield item
        os.chdir(current_dir)

Response: Returns an iterator over the files in a location which yields item elements that can be inserted into the package manifest.


Instruction:
Write a Python 3 script for
returning an appropriate Name and File - As - Name for a contrib element.

Response:
def get_contrib_names(self, contrib):
        """
        Returns an appropriate Name and File-As-Name for a contrib element.

        This code was refactored out of nav_contributors and
        package_contributors to provide a single definition point for a common
        job. This is a useful utility that may be well-employed for other
        publishers as well.
        """
        collab = contrib.find('collab')
        anon = contrib.find('anonymous')
        if collab is not None:
            proper_name = serialize(collab, strip=True)
            file_as_name = proper_name
        elif anon is not None:
            proper_name = 'Anonymous'
            file_as_name = proper_name
        else:
            name = contrib.find('name')
            surname = name.find('surname').text
            given = name.find('given-names')
            if given is not None:
                if given.text:  # Sometimes these tags are empty
                    proper_name = ' '.join([surname, given.text])
                    #File-as name is <surname>, <given-initial-char>
                    file_as_name = ', '.join([surname, given.text[0]])
                else:
                    proper_name = surname
                    file_as_name = proper_name
            else:
                proper_name = surname
                file_as_name = proper_name
        return proper_name, file_as_name


Instruction:
Can you implement a function in Python 3 that
returns the article description for the current article.

Response:
def package_description(self):
        """
        Given an Article class instance, this is responsible for returning an
        article description. For this method I have taken the approach of
        serializing the article's first abstract, if it has one. This results
        in 0 or 1 descriptions per article.
        """
        abstract = self.article.root.xpath('./front/article-meta/abstract')
        return serialize(abstract[0], strip=True) if abstract else None


Instruction:
Can you tell what is the following Python 3 function doing
def heading_title(self):
        art_title = self.article.root.xpath('./front/article-meta/title-group/article-title')[0]
        article_title = deepcopy(art_title)
        article_title.tag = 'h1'
        article_title.attrib['id'] = 'title'
        article_title.attrib['class'] = 'article-title'
        return article_title

Response: Makes the Article Title for the Heading.


Instruction:
Can you generate the documentation for the following Python 3 function
def make_heading_authors(self, authors):
        author_element = etree.Element('h3', {'class': 'authors'})
        #Construct content for the author element
        first = True
        for author in authors:
            if first:
                first = False
            else:
                append_new_text(author_element, ',', join_str='')
            collab = author.find('collab')
            anon = author.find('anon')
            if collab is not None:
                append_all_below(author_element, collab)
            elif anon is not None:  # If anonymous, just add "Anonymous"
                append_new_text(author_element, 'Anonymous')
            else:  # Author is neither Anonymous or a Collaboration
                author_name, _ = self.get_contrib_names(author)
                append_new_text(author_element, author_name)
            #TODO: Handle author footnote references, also put footnotes in the ArticleInfo
            #Example: journal.pbio.0040370.xml
            first = True
            for xref in author.xpath("./xref[@ref-type='corresp' or @ref-type='aff']"):
                _sup = xref.find('sup')
                sup_text = all_text(_sup) if _sup is not None else ''
                auth_sup = etree.SubElement(author_element, 'sup')
                sup_link = etree.SubElement(auth_sup,
                                            'a',
                                            {'href': self.main_fragment.format(xref.attrib['rid'])})
                sup_link.text = sup_text
                if first:
                    first = False
                else:
                    append_new_text(auth_sup, ', ', join_str='')
            #for xref in author.findall('xref'):
                #if xref.attrs['ref-type'] in ['corresp', 'aff']:

                    #try:
                        #sup_element = xref.sup[0].node
                    #except IndexError:
                        #sup_text = ''
                    #else:
                        #sup_text = all_text(sup_element)
                    #new_sup = etree.SubElement(author_element, 'sup')
                    #sup_link = etree.SubElement(new_sup, 'a')
                    #sup_link.attrib['href'] = self.main_fragment.format(xref.attrs['rid'])
                    #sup_link.text = sup_text
                    #if first:
                        #first = False
                    #else:
                        #new_sup.text = ','
        return author_element

Response: Constructs the Authors element for the Heading element. This should display the Heading element directly after the Article Title. This should display the Heading element directly after the Article Title.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def make_heading_affiliations(self, heading_div):
        #Get all of the aff element tuples from the metadata
        affs = self.article.root.xpath('./front/article-meta/aff')
        #Create a list of all those pertaining to the authors
        author_affs = [i for i in affs if 'aff' in i.attrib['id']]
        #Count them, used for formatting
        if len(author_affs) == 0:
            return None
        else:
            affs_list = etree.SubElement(heading_div,
                                         'ul',
                                         {'id': 'affiliations',
                                          'class': 'simple'})

        for aff in author_affs:
            #Create a span element to accept extracted content
            aff_item = etree.SubElement(affs_list, 'li')
            aff_item.attrib['id'] = aff.attrib['id']
            #Get the first label node and the first addr-line node
            label = aff.find('label')
            addr_line = aff.find('addr-line')
            if label is not None:
                bold = etree.SubElement(aff_item, 'b')
                bold.text = all_text(label) + ' '
            if addr_line is not None:
                append_new_text(aff_item, all_text(addr_line))
            else:
                append_new_text(aff_item, all_text(aff))

Response: Makes the content for the Author Affiliations element displays after the Heading.


Instruction:
Can you tell what is the following Python 3 function doing
def make_heading_abstracts(self, heading_div):
        for abstract in self.article.root.xpath('./front/article-meta/abstract'):
            #Make a copy of the abstract
            abstract_copy = deepcopy(abstract)
            abstract_copy.tag = 'div'
            #Abstracts are a rather diverse bunch, keep an eye on them!
            title_text = abstract_copy.xpath('./title[1]/text()')
            for title in abstract_copy.findall('.//title'):
                remove(title)
            #Create a header for the abstract
            abstract_header = etree.Element('h2')
            remove_all_attributes(abstract_copy)
            #Set the header text and abstract id according to abstract type
            abstract_type = abstract.attrib.get('abstract-type')
            log.debug('Handling Abstrace of with abstract-type="{0}"'.format(abstract_type))
            if abstract_type == 'summary':
                abstract_header.text = 'Author Summary'
                abstract_copy.attrib['id'] = 'author-summary'
            elif abstract_type == 'editors-summary':
                abstract_header.text = 'Editors\' Summary'
                abstract_copy.attrib['id'] = 'editor-summary'
            elif abstract_type == 'synopsis':
                abstract_header.text = 'Synopsis'
                abstract_copy.attrib['id'] = 'synopsis'
            elif abstract_type == 'alternate':
                #Right now, these will only be included if there is a title to
                #give it
                if title_text:
                    abstract_header.text= title_text[0]
                    abstract_copy.attrib['id'] = 'alternate'
                else:
                    continue
            elif abstract_type is None:
                abstract_header.text = 'Abstract'
                abstract_copy.attrib['id'] = 'abstract'
            elif abstract_type == 'toc':  # We don't include these
                continue
            else:  # Warn about these, then skip
                log.warning('No handling for abstract-type="{0}"'.format(abstract_type))
                continue
                #abstract_header.text = abstract_type
                #abstract_copy.attrib['id'] = abstract_type
            heading_div.append(abstract_header)
            heading_div.append(abstract_copy)

Response: This method creates the headings for all abstracts in the article.


Instruction:
Create a Python 3 function to
create the Article Info element for the current article.

Response:
def make_article_info(self):
        """
        The Article Info contains the (self) Citation, Editors, Dates,
        Copyright, Funding Statement, Competing Interests Statement,
        Correspondence, and Footnotes. Maybe more...

        This content follows the Heading and precedes the Main segment in the
        output.

        This function accepts the receiving_node argument, which will receive
        all generated output as new childNodes.
        """
        body = self.main.getroot().find('body')
        #Create a div for ArticleInfo, exposing it to linking and formatting
        article_info_div = etree.Element('div', {'id': 'ArticleInfo'})
        body.insert(1, article_info_div)
        #Creation of the self Citation
        article_info_div.append(self.make_article_info_citation())
        #Creation of the Editors
        editors = self.article.root.xpath("./front/article-meta/contrib-group/contrib[@contrib-type='editor']")
        self.make_article_info_editors(editors, article_info_div)
        #Creation of the important Dates segment
        article_info_div.append(self.make_article_info_dates())
        #Creation of the Copyright statement
        self.make_article_info_copyright(article_info_div)
        #Creation of the Funding statement
        self.make_article_info_funding(article_info_div)
        #Creation of the Competing Interests statement
        self.make_article_info_competing_interests(article_info_div)
        #Creation of the Correspondences (contact information) for the article
        self.make_article_info_correspondences(article_info_div)
        #Creation of the Footnotes (other) for the ArticleInfo
        self.make_article_info_footnotes_other(article_info_div)


Instruction:
Can you create a Python 3 function that
creates a self citation node for the ArticleInfo of the article.

Response:
def make_article_info_citation(self):
        """
        Creates a self citation node for the ArticleInfo of the article.

        This method uses code from this page as a reference implementation:
        https://github.com/PLOS/ambra/blob/master/base/src/main/resources/articleTransform-v3.xsl
        """
        citation_div = etree.Element('div', {'id': 'article-citation'})
        b = etree.SubElement(citation_div, 'b')
        b.text = 'Citation: '

        #Add author stuff to the citation
        authors = self.article.root.xpath("./front/article-meta/contrib-group/contrib[@contrib-type='author']")
        for author in authors:
            author_index = authors.index(author)
            #At the 6th author, simply append an et al., then stop iterating
            if author_index == 5:
                append_new_text(citation_div, 'et al.', join_str='')
                break
            else:
                #Check if the author contrib has a collab
                collab = author.find('collab')
                if collab is not None:
                    collab_copy = deepcopy(collab)
                    for contrib_group in collab_copy.findall('contrib_group'):
                        remove(contrib_group)
                    append_all_below(citation_div, collab, join_str='')
                else:  # Author element is not a collab
                    name = author.find('name')
                    #Note that this does not support eastern names
                    #Grab the surname information
                    surname = name.find('surname')
                    given_names = name.find('given-names')
                    suffix = name.find('suffix')
                    append_new_text(citation_div, surname.text, join_str='')
                    #Make initials from the given-name information
                    if given_names is not None:
                        #Add a space
                        append_new_text(citation_div, ' ', join_str='')
                        #Split by whitespace and take first character
                        given_initials = [i[0] for i in given_names.text.split() if i]
                        for initial in given_initials:
                            append_new_text(citation_div, initial, join_str='')
                    #If there is a suffix, add its text, but don't include the
                    #trailing period if there is one
                    if suffix is not None:
                        #Add a space
                        append_new_text(citation_div, ' ', join_str='')
                        suffix_text = suffix.text
                        #Check for the trailing period
                        if suffix_text[-1] == '.':
                            suffix_text = suffix_text[:-1]
                        append_new_text(citation_div, suffix_text, join_str='')
                #If this is not the last author to be added, add a ", "
                #This is satisfied by being less than the 6th author, or less
                #than the length of the author_list - 1
                if author_index < 5 or author_index < len(author_list) -1:
                    append_new_text(citation_div, ', ', join_str='')
        #Add Publication Year to the citation
        #Find pub-date elements, use pub-type=collection, or else pub-type=ppub
        d = './front/article-meta/pub-date'
        coll = self.article.root.xpath(d + "[@pub-type='collection']")
        ppub = self.article.root.xpath(d + "[@pub-type='ppub']")
        if coll:
            pub_year = coll[0].find('year').text
        elif ppub:
            pub_year = ppub[0].find('year').text
        append_new_text(citation_div, ' ({0}) '.format(pub_year), join_str='')
        #Add the Article Title to the Citation
        #As best as I can tell from the reference implementation, they
        #serialize the article title to text-only, and expunge redundant spaces
        #This might need later review
        article_title = self.article.root.xpath('./front/article-meta/title-group/article-title')[0]
        article_title_text = serialize(article_title)
        normalized = ' '.join(article_title_text.split())  # Remove redundant whitespace
        #Add a period unless there is some other valid punctuation
        if normalized[-1] not in '.?!':
            normalized += '.'
        append_new_text(citation_div, normalized + ' ', join_str='')
        #Add the article's journal name using the journal-id of type "nlm-ta"
        journal = self.article.root.xpath("./front/journal-meta/journal-id[@journal-id-type='nlm-ta']")
        append_new_text(citation_div, journal[0].text + ' ', join_str='')
        #Add the article's volume, issue, and elocation_id  values
        volume = self.article.root.xpath('./front/article-meta/volume')[0].text
        issue = self.article.root.xpath('./front/article-meta/issue')[0].text
        elocation_id = self.article.root.xpath('./front/article-meta/elocation-id')[0].text
        form = '{0}({1}): {2}. '.format(volume, issue, elocation_id)
        append_new_text(citation_div, form, join_str='')
        append_new_text(citation_div, 'doi:{0}'.format(self.article.doi), join_str='')

        return citation_div


Instruction:
Explain what the following Python 3 code does
def make_article_info_dates(self):
        dates_div = etree.Element('div', {'id': 'article-dates'})

        d = './front/article-meta/history/date'
        received = self.article.root.xpath(d + "[@date-type='received']")
        accepted = self.article.root.xpath(d + "[@date-type='accepted']")
        if received:
            b = etree.SubElement(dates_div, 'b')
            b.text = 'Received: '
            dt = self.date_tuple_from_date(received[0], 'Received')
            formatted_date_string = self.format_date_string(dt)
            append_new_text(dates_div, formatted_date_string + '; ')
        if accepted:
            b = etree.SubElement(dates_div, 'b')
            b.text = 'Accepted: '
            dt = self.date_tuple_from_date(accepted[0], 'Accepted')
            formatted_date_string = self.format_date_string(dt)
            append_new_text(dates_div, formatted_date_string + '; ')
        #Published date is required
        pub_date = self.article.root.xpath("./front/article-meta/pub-date[@pub-type='epub']")[0]
        b = etree.SubElement(dates_div, 'b')
        b.text = 'Published: '
        dt = self.date_tuple_from_date(pub_date, 'Published')
        formatted_date_string = self.format_date_string(dt)
        append_new_text(dates_div, formatted_date_string)

        return dates_div

Response: Makes the section containing important dates for the article.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def make_article_info_funding(self, article_info_div):
        funding_group = self.article.root.xpath('./front/article-meta/funding-group')
        if funding_group:
            funding_div = etree.SubElement(article_info_div,
                                           'div',
                                           {'id': 'funding'})
            funding_b = etree.SubElement(funding_div, 'b')
            funding_b.text = 'Funding: '
            #As far as I can tell, PLoS only uses one funding-statement
            funding_statement = funding_group[0].find('funding-statement')
            append_all_below(funding_div, funding_statement)

Response: Creates the element for declaring Funding in the article info.


Instruction:
Here you have a function in Python 3, explain what it does
def make_article_info_competing_interests(self, article_info_div):
        #Check for author-notes
        con_expr = "./front/article-meta/author-notes/fn[@fn-type='conflict']"
        conflict = self.article.root.xpath(con_expr)
        if not conflict:
            return
        conflict_div = etree.SubElement(article_info_div,
                                        'div',
                                        {'id': 'conflict'})
        b = etree.SubElement(conflict_div, 'b')
        b.text = 'Competing Interests: '
        fn_p = conflict[0].find('p')
        if fn_p is not None:
            append_all_below(conflict_div, fn_p)

Response: Creates the element for declaring competing interests in the article.


Instruction:
How would you implement a function in Python 3 that
adds the corresponding articles to the article_info_div.

Response:
def make_article_info_correspondences(self, article_info_div):
        """
        Articles generally provide a first contact, typically an email address
        for one of the authors. This will supply that content.
        """
        corresps = self.article.root.xpath('./front/article-meta/author-notes/corresp')
        if corresps:
            corresp_div = etree.SubElement(article_info_div,
                                           'div',
                                           {'id': 'correspondence'})
        for corresp in corresps:
            sub_div = etree.SubElement(corresp_div,
                                       'div',
                                       {'id': corresp.attrib['id']})
            append_all_below(sub_div, corresp)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def make_article_info_footnotes_other(self, article_info_div):
        other_fn_expr = "./back/fn-group/fn[@fn-type='other']"
        other_fns = self.article.root.xpath(other_fn_expr)
        if other_fns:
            other_fn_div = etree.SubElement(article_info_div,
                                            'div',
                                            {'class': 'back-fn-other'})
        for other_fn in other_fns:
            append_all_below(other_fn_div, other_fn)

Response: This will create the other footnotes in the article info div.


Instruction:
Can you tell what is the following Python 3 function doing
def move_back_boxed_texts(self):
        body = self.main.getroot().find('body')
        back = self.article.root.find('back')
        if back is None:
            return
        boxed_texts = back.xpath('.//boxed-text')
        for boxed_text in boxed_texts:
            body.append(deepcopy(boxed_text))

Response: Move anyboxed - text elements over to the receiving element.


Instruction:
Write a Python 3 function for
making the back - acks element.

Response:
def make_back_acknowledgments(self):
        """
        The <ack> is an important piece of back matter information, and will be
        including immediately after the main text.

        This element should only occur once, optionally, for PLoS, if a need
        becomes known, then multiple instances may be supported.
        """
        acks = self.article.root.xpath('./back/ack')
        if not acks:
            return
        ack = deepcopy(acks[0])
        #Modify the tag to div
        ack.tag = 'div'
        #Give it an id
        ack.attrib['id'] = 'acknowledgments'
        #Give it a title element--this is not an EPUB element but doing so will
        #allow it to later be depth-formatted by self.convert_div_titles()
        ack_title = etree.Element('title')
        ack_title.text = 'Acknowledgments'
        ack.insert(0, ack_title)  # Make it the first element
        return ack


Instruction:
Make a summary of the following Python 3 code
def make_back_glossary(self, body):
        for glossary in self.article.root.xpath('./back/glossary'):
            gloss_copy = deepcopy(glossary)
            gloss_copy.tag = 'div'
            gloss_copy.attrib['class'] = 'back-glossary'
            body.append(gloss_copy)

Response:
Glossaries are a fairly common item in papers for PLoS, but it also
        seems that they are rarely incorporated into the PLoS web-site or PDF
        formats. They are included in the ePub output however because they are
        helpful and because we can.


Instruction:
Can you generate the documentation for the following Python 3 function
def make_back_notes(self, body):
        for notes in self.article.root.xpath('./back/notes'):
            notes_sec = deepcopy(notes.find('sec'))
            notes_sec.tag = 'div'
            notes_sec.attrib['class'] = 'back-notes'
            body.append(notes_sec)

Response: Make back - notes elements.


Instruction:
Create a Python 3 function to
convert the disp - formula elements to conforming elements

Response:
def convert_disp_formula_elements(self):
        """
        <disp-formula> elements must be converted to conforming elements
        """
        for disp in self.main.getroot().findall('.//disp-formula'):
            #find label element
            label_el = disp.find('label')
            graphic_el = disp.find('graphic')
            if graphic_el is None:  # No graphic, assume math as text instead
                text_span = etree.Element('span', {'class': 'disp-formula'})
                if 'id' in disp.attrib:
                    text_span.attrib['id'] = disp.attrib['id']
                append_all_below(text_span, disp)
                #Insert the text span before the disp-formula
                insert_before(disp, text_span)
                #If a label exists, modify and insert before text_span
                if label_el is not None:
                    label_el.tag = 'b'
                    insert_before(text_span, label_el)
                #Remove the disp-formula
                remove(disp)
                #Skip the rest, which deals with the graphic element
                continue
            #The graphic element is present
            #Create a file reference for the image
            xlink_href = ns_format(graphic_el, 'xlink:href')
            graphic_xlink_href = graphic_el.attrib[xlink_href]
            file_name = graphic_xlink_href.split('.')[-1] + '.png'
            img_dir = 'images-' + self.doi_suffix()
            img_path = '/'.join([img_dir, file_name])

            #Create the img element
            img_element = etree.Element('img', {'alt': 'A Display Formula',
                                                'class': 'disp-formula',
                                                'src': img_path})
            #Transfer the id attribute
            if 'id' in disp.attrib:
                img_element.attrib['id'] = disp.attrib['id']
            #Insert the img element
            insert_before(disp, img_element)
            #Create content for the label
            if label_el is not None:
                label_el.tag = 'b'
                insert_before(img_element, label_el)
            #Remove the old disp-formula element
            remove(disp)


Instruction:
Write a Python 3 script to
convert inline - formula elements to the corresponding image elements.

Response:
def convert_inline_formula_elements(self):
        """
        <inline-formula> elements must be converted to be conforming

        These elements may contain <inline-graphic> elements, textual content,
        or both.
        """
        for inline in self.main.getroot().findall('.//inline-formula'):
            #inline-formula elements will be modified in situ
            remove_all_attributes(inline)
            inline.tag = 'span'
            inline.attrib['class'] = 'inline-formula'
            inline_graphic = inline.find('inline-graphic')
            if inline_graphic is None:
                # Do nothing more if there is no graphic
                continue
            #Need to conver the inline-graphic element to an img element
            inline_graphic.tag = 'img'
            #Get a copy of the attributes, then remove them
            inline_graphic_attributes = copy(inline_graphic.attrib)
            remove_all_attributes(inline_graphic)
            #Create a file reference for the image
            xlink_href = ns_format(inline_graphic, 'xlink:href')
            graphic_xlink_href = inline_graphic_attributes[xlink_href]
            file_name = graphic_xlink_href.split('.')[-1] + '.png'
            img_dir = 'images-' + self.doi_suffix()
            img_path = '/'.join([img_dir, file_name])
            #Set the source to the image path
            inline_graphic.attrib['src'] = img_path
            inline_graphic.attrib['class'] = 'inline-formula'
            inline_graphic.attrib['alt'] = 'An Inline Formula'


Instruction:
Can you tell what is the following Python 3 function doing
def convert_disp_quote_elements(self):
        for disp_quote in self.main.getroot().findall('.//disp-quote'):
            if disp_quote.getparent().tag == 'p':
                elevate_element(disp_quote)
            disp_quote.tag = 'div'
            disp_quote.attrib['class'] = 'disp-quote'

Response: Convert disp - quote elements to divs.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def convert_boxed_text_elements(self):
        for boxed_text in self.main.getroot().findall('.//boxed-text'):
            sec_el = boxed_text.find('sec')
            if sec_el is not None:
                sec_el.tag = 'div'
                title = sec_el.find('title')
                if title is not None:
                    title.tag = 'b'
                sec_el.attrib['class'] = 'boxed-text'
                if 'id' in boxed_text.attrib:
                    sec_el.attrib['id'] = boxed_text.attrib['id']
                replace(boxed_text, sec_el)
            else:
                div_el = etree.Element('div', {'class': 'boxed-text'})
                if 'id' in boxed_text.attrib:
                    div_el.attrib['id'] = boxed_text.attrib['id']
                append_all_below(div_el, boxed_text)
                replace(boxed_text, div_el)

Response: Convert all the boxed - text elements in the main XML file into a single boxed - text element.


Instruction:
Write a Python 3 script to
convert supplementary material elements into a div element.

Response:
def convert_supplementary_material_elements(self):
        """
        Supplementary material are not, nor are they generally expected to be,
        packaged into the epub file. Though this is a technical possibility,
        and certain epub reading systems (such as those run on a PC) might be
        reasonably capable of the external handling of diverse file formats
        I presume that supplementary material will remain separate from the
        document. So special cases aside, external links to supplementary
        material will be employed; this will require internet connection for
        access.

        As for content in <supplementary-material>, they appear to strictly
        contain 1 <label> element, followed by a <caption><title><p></caption>
        substructure.
        """
        for supplementary in self.main.getroot().findall('.//supplementary-material'):
            #Create a div element to hold the supplementary content
            suppl_div = etree.Element('div')
            if 'id' in supplementary.attrib:
                suppl_div.attrib['id'] = supplementary.attrib['id']
            insert_before(supplementary, suppl_div)
            #Get the sub elements
            label = supplementary.find('label')
            caption = supplementary.find('caption')
            #Get the external resource URL for the supplementary information
            ns_xlink_href = ns_format(supplementary, 'xlink:href')
            xlink_href = supplementary.attrib[ns_xlink_href]
            resource_url = self.fetch_single_representation(xlink_href)
            if label is not None:
                label.tag = 'a'
                label.attrib['href'] = resource_url
                append_new_text(label, '. ', join_str='')
                suppl_div.append(label)
            if caption is not None:
                title = caption.find('title')
                paragraphs = caption.findall('p')
                if title is not None:
                    title.tag = 'b'
                    suppl_div.append(title)
                for paragraph in paragraphs:
                    suppl_div.append(paragraph)
            #This is a fix for odd articles with <p>s outside of <caption>
            #See journal.pctr.0020006, PLoS themselves fail to format this for
            #the website, though the .pdf is good
            #It should be noted that journal.pctr.0020006 does not pass
            #validation because it places a <p> before a <caption>
            #By placing this at the end of the method, it conforms to the spec
            #by expecting such p tags after caption. This causes a hiccup in
            #the rendering for journal.pctr.0020006, but it's better than
            #skipping the data entirely AND it should also work for conforming
            #articles.
            for paragraph in supplementary.findall('p'):
                suppl_div.append(paragraph)
            remove(supplementary)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def fetch_single_representation(self, item_xlink_href):
        #A dict of URLs for PLoS subjournals
        journal_urls = {'pgen': 'http://www.plosgenetics.org/article/{0}',
                        'pcbi': 'http://www.ploscompbiol.org/article/{0}',
                        'ppat': 'http://www.plospathogens.org/article/{0}',
                        'pntd': 'http://www.plosntds.org/article/{0}',
                        'pmed': 'http://www.plosmedicine.org/article/{0}',
                        'pbio': 'http://www.plosbiology.org/article/{0}',
                        'pone': 'http://www.plosone.org/article/{0}',
                        'pctr': 'http://clinicaltrials.ploshubs.org/article/{0}'}
        #Identify subjournal name for base URl
        subjournal_name = self.article.doi.split('.')[2]
        base_url = journal_urls[subjournal_name]
        #Compose the address for fetchSingleRepresentation
        resource = 'fetchSingleRepresentation.action?uri=' + item_xlink_href
        return base_url.format(resource)

Response: This function will render a formatted URL for accessing the PLoS serverSingleRepresentation of an object.


Instruction:
Here you have a function in Python 3, explain what it does
def convert_fig_elements(self):
        for fig in self.main.getroot().findall('.//fig'):
            if fig.getparent().tag == 'p':
                elevate_element(fig)
        for fig in self.main.getroot().findall('.//fig'):
            #self.convert_fn_elements(fig)
            #self.convert_disp_formula_elements(fig)
            #Find label and caption
            label_el = fig.find('label')
            caption_el = fig.find('caption')
            #Get the graphic node, this should be mandatory later on
            graphic_el = fig.find('graphic')
            #Create a file reference for the image
            xlink_href = ns_format(graphic_el, 'xlink:href')
            graphic_xlink_href = graphic_el.attrib[xlink_href]
            file_name = graphic_xlink_href.split('.')[-1] + '.png'
            img_dir = 'images-' + self.doi_suffix()
            img_path = '/'.join([img_dir, file_name])

            #Create the content: using image path, label, and caption
            img_el = etree.Element('img', {'alt': 'A Figure', 'src': img_path,
                                           'class': 'figure'})
            if 'id' in fig.attrib:
                img_el.attrib['id'] = fig.attrib['id']
            insert_before(fig, img_el)

            #Create content for the label and caption
            if caption_el is not None or label_el is not None:
                img_caption_div = etree.Element('div', {'class': 'figure-caption'})
                img_caption_div_b = etree.SubElement(img_caption_div, 'b')
                if label_el is not None:
                    append_all_below(img_caption_div_b, label_el)
                    append_new_text(img_caption_div_b, '. ', join_str='')
                if caption_el is not None:
                    caption_title = caption_el.find('title')
                    if caption_title is not None:
                        append_all_below(img_caption_div_b, caption_title)
                        append_new_text(img_caption_div_b, ' ', join_str='')
                    for each_p in caption_el.findall('p'):
                        append_all_below(img_caption_div, each_p)
                insert_before(fig, img_caption_div)

            #Remove the original <fig>
            remove(fig)

Response: Converts the JPTS 3. 0 <fig > elements to EPUB 3. 0 <img > elements to EPUB 3. 0 <fig > elements to EPUB 3. 0 <img > elements to EPUB 3. 0 <fig > elements to EPUB 3. 0 <fig > elements to EPUB 3. 0 <fig > elements to EPUB 3. 0 <fig > elements to EPUB 3. 0 <fig > elements to EPUB 3. 0.


Instruction:
How would you explain what the following Python 3 function does
def convert_verse_group_elements(self):
        for verse_group in self.main.getroot().findall('.//verse-group'):
            #Find some possible sub elements for the heading
            label = verse_group.find('label')
            title = verse_group.find('title')
            subtitle = verse_group.find('subtitle')
            #Modify the verse-group element
            verse_group.tag = 'div'
            verse_group.attrib['id'] = 'verse-group'
            #Create a title for the verse_group
            if label is not None or title is not None or subtitle is not None:
                new_verse_title = etree.Element('b')
                #Insert it at the beginning
                verse_group.insert(0, new_verse_title)
                #Induct the title elements into the new title
                if label is not None:
                    append_all_below(new_verse_title, label)
                    remove(label)
                if title is not None:
                    append_all_below(new_verse_title, title)
                    remove(title)
                if subtitle is not None:
                    append_all_below(new_verse_title, subtitle)
                    remove(subtitle)
            for verse_line in verse_group.findall('verse-line'):
                verse_line.tag = 'p'
                verse_line.attrib['class'] = 'verse-line'

Response: Convert the verse - group elements into italicized lines.