Instruction:
Can you generate the documentation for the following Python 3 function
def summarize(requestContext, seriesList, intervalString, func='sum',
              alignToFrom=False):
    """
    Summarize the data into interval buckets of a certain size.

    By default, the contents of each interval bucket are summed together.
    This is useful for counters where each increment represents a discrete
    event and retrieving a "per X" value requires summing all the events in
    that interval.

    Specifying 'avg' instead will return the mean for each bucket, which can
    be more useful when the value is a gauge that represents a certain value
    in time.

    'max', 'min' or 'last' can also be specified.

    By default, buckets are calculated by rounding to the nearest interval.
    This works well for intervals smaller than a day. For example, 22:32 will
    end up in the bucket 22:00-23:00 when the interval=1hour.

    Passing alignToFrom=true will instead create buckets starting at the from
    time. In this case, the bucket for 22:32 depends on the from time. If
    from=6:30 then the 1hour bucket for 22:32 is 22:30-23:30.

    Example::

        # total errors per hour
        &target=summarize(counter.errors, "1hour")

        # new users per week
        &target=summarize(nonNegativeDerivative(gauge.num_users), "1week")

        # average queue size per hour
        &target=summarize(queue.size, "1hour", "avg")

        # maximum queue size during each hour
        &target=summarize(queue.size, "1hour", "max")

        # 2010 Q1-4
        &target=summarize(metric, "13week", "avg", true)&from=midnight+20100101
    """
    results = []
    delta = parseTimeOffset(intervalString)
    interval = to_seconds(delta)

    for series in seriesList:
        buckets = {}

        timestamps = range(int(series.start), int(series.end) + 1,
                           int(series.step))
        datapoints = zip_longest(timestamps, series)

        for timestamp, value in datapoints:
            if timestamp is None:
                continue
            if alignToFrom:
                bucketInterval = int((timestamp - series.start) / interval)
            else:
                bucketInterval = timestamp - (timestamp % interval)

            if bucketInterval not in buckets:
                buckets[bucketInterval] = []

            if value is not None:
                buckets[bucketInterval].append(value)

        if alignToFrom:
            newStart = series.start
            newEnd = series.end
        else:
            newStart = series.start - (series.start % interval)
            newEnd = series.end - (series.end % interval) + interval

        newValues = []
        for timestamp in range(newStart, newEnd, interval):
            if alignToFrom:
                newEnd = timestamp
                bucketInterval = int((timestamp - series.start) / interval)
            else:
                bucketInterval = timestamp - (timestamp % interval)

            bucket = buckets.get(bucketInterval, [])

            if bucket:
                if func == 'avg':
                    newValues.append(float(sum(bucket)) / float(len(bucket)))
                elif func == 'last':
                    newValues.append(bucket[len(bucket)-1])
                elif func == 'max':
                    newValues.append(max(bucket))
                elif func == 'min':
                    newValues.append(min(bucket))
                else:
                    newValues.append(sum(bucket))
            else:
                newValues.append(None)

        if alignToFrom:
            newEnd += interval

        newName = "summarize(%s, \"%s\", \"%s\"%s)" % (
            series.name, intervalString, func, alignToFrom and ", true" or "")
        newSeries = TimeSeries(newName, newStart, newEnd, interval, newValues)
        newSeries.pathExpression = newName
        results.append(newSeries)

    return results

Response: Summarize the data into a list of buckets.


Instruction:
How would you implement a function in Python 3 that
estimates the hit count of a list of time series.

Response:
def hitcount(requestContext, seriesList, intervalString,
             alignToInterval=False):
    """
    Estimate hit counts from a list of time series.

    This function assumes the values in each time series represent
    hits per second.    It calculates hits per some larger interval
    such as per day or per hour.    This function is like summarize(),
    except that it compensates automatically for different time scales
    (so that a similar graph results from using either fine-grained
    or coarse-grained records) and handles rarely-occurring events
    gracefully.
    """
    results = []
    delta = parseTimeOffset(intervalString)
    interval = to_seconds(delta)

    if alignToInterval:
        requestContext = requestContext.copy()
        tzinfo = requestContext['tzinfo']
        s = requestContext['startTime']
        if interval >= DAY:
            requestContext['startTime'] = datetime(s.year, s.month, s.day,
                                                   tzinfo=tzinfo)
        elif interval >= HOUR:
            requestContext['startTime'] = datetime(s.year, s.month, s.day,
                                                   s.hour, tzinfo=tzinfo)
        elif interval >= MINUTE:
            requestContext['startTime'] = datetime(s.year, s.month, s.day,
                                                   s.hour, s.minute,
                                                   tzinfo=tzinfo)

        # Gather all paths first, then the data
        paths = []
        for series in seriesList:
            paths.extend(pathsFromTarget(requestContext,
                                         series.pathExpression))
        data_store = fetchData(requestContext, paths)

        for series in seriesList:
            newSeries = evaluateTarget(requestContext,
                                       series.pathExpression,
                                       data_store)[0]
            intervalCount = int((series.end - series.start) / interval)
            series[0:len(series)] = newSeries
            series.start = newSeries.start
            series.end = newSeries.start + (
                intervalCount * interval) + interval
            series.step = newSeries.step

    for series in seriesList:
        step = int(series.step)
        bucket_count = int(math.ceil(
            float(series.end - series.start) / interval))
        buckets = [[] for _ in range(bucket_count)]
        newStart = int(series.end - bucket_count * interval)

        for i, value in enumerate(series):
            if value is None:
                continue

            start_time = int(series.start + i * step)
            start_bucket, start_mod = divmod(start_time - newStart, interval)
            end_time = start_time + step
            end_bucket, end_mod = divmod(end_time - newStart, interval)

            if end_bucket >= bucket_count:
                end_bucket = bucket_count - 1
                end_mod = interval

            if start_bucket == end_bucket:
                # All of the hits go to a single bucket.
                if start_bucket >= 0:
                    buckets[start_bucket].append(value * (end_mod - start_mod))

            else:
                # Spread the hits among 2 or more buckets.
                if start_bucket >= 0:
                    buckets[start_bucket].append(
                        value * (interval - start_mod))
                hits_per_bucket = value * interval
                for j in range(start_bucket + 1, end_bucket):
                    buckets[j].append(hits_per_bucket)
                if end_mod > 0:
                    buckets[end_bucket].append(value * end_mod)

        newValues = []
        for bucket in buckets:
            if bucket:
                newValues.append(sum(bucket))
            else:
                newValues.append(None)

        newName = 'hitcount(%s, "%s"%s)' % (series.name, intervalString,
                                            alignToInterval and ", true" or "")
        newSeries = TimeSeries(newName, newStart, series.end, interval,
                               newValues)
        newSeries.pathExpression = newName
        results.append(newSeries)

    return results


Instruction:
How would you implement a function in Python 3 that
shorts Alias: time() Just returns the timestamp for each X value. T Example:: &target=time("The.time.series") This would create a series named "The.time.series" that contains in Y the same value (in seconds) as X. A second argument can be provided as a step parameter (default is 60 secs)

Response:
def timeFunction(requestContext, name, step=60):
    """
    Short Alias: time()

    Just returns the timestamp for each X value. T

    Example::

        &target=time("The.time.series")

    This would create a series named "The.time.series" that contains in Y
    the same value (in seconds) as X.

    A second argument can be provided as a step parameter (default is 60 secs)

    """
    start = int(epoch(requestContext["startTime"]))
    end = int(epoch(requestContext["endTime"]))
    delta = timedelta(seconds=step)
    when = requestContext["startTime"]
    values = []

    while when < requestContext["endTime"]:
        values.append(epoch(when))
        when += delta

    series = TimeSeries(name, start, end, step, values)
    series.pathExpression = name

    return [series]


Instruction:
Can you implement a function in Python 3 that
functions that returns the sine of the current time.

Response:
def sinFunction(requestContext, name, amplitude=1, step=60):
    """
    Short Alias: sin()

    Just returns the sine of the current time. The optional amplitude parameter
    changes the amplitude of the wave.

    Example::

        &target=sin("The.time.series", 2)

    This would create a series named "The.time.series" that contains sin(x)*2.

    A third argument can be provided as a step parameter (default is 60 secs).
    """
    delta = timedelta(seconds=step)
    when = requestContext["startTime"]
    values = []

    while when < requestContext["endTime"]:
        values.append(math.sin(epoch(when))*amplitude)
        when += delta

    series = TimeSeries(
        name, int(epoch(requestContext["startTime"])),
        int(epoch(requestContext["endTime"])),
        step, values)
    series.pathExpression = 'sin({0})'.format(name)
    return [series]


Instruction:
Can you tell what is the following Python 3 function doing
def randomWalkFunction(requestContext, name, step=60):
    delta = timedelta(seconds=step)
    when = requestContext["startTime"]
    values = []
    current = 0
    while when < requestContext["endTime"]:
        values.append(current)
        current += random.random() - 0.5
        when += delta

    return [TimeSeries(
        name, int(epoch(requestContext["startTime"])),
        int(epoch(requestContext["endTime"])),
        step, values)]

Response: This function is used to generate a random walk of the time series.


Instruction:
How would you explain what the following Python 3 function does
def validate(self, model, checks=[]):
        custom = [
            check_partial(reaction_id_check,
                          frozenset(r.id for r in model.reactions))
        ]
        super(Medium, self).validate(model=model, checks=checks + custom)

Response: Use a defined schema to validate the medium table format.


Instruction:
Write a Python 3 function that can
set the defined medium on the given model.

Response:
def apply(self, model):
        """Set the defined medium on the given model."""
        model.medium = {row.exchange: row.uptake
                        for row in self.data.itertuples(index=False)}


Instruction:
Make a summary of the following Python 3 code
def add_environment_information(meta):
        meta["timestamp"] = datetime.utcnow().isoformat(" ")
        meta["platform"] = platform.system()
        meta["release"] = platform.release()
        meta["python"] = platform.python_version()
        meta["packages"] = get_pkg_info("memote")

Response: Add environment information to the metadata dictionary.


Instruction:
Here you have a function in Python 3, explain what it does
def find_transported_elements(rxn):
    element_dist = defaultdict()
    # Collecting elements for each metabolite.
    for met in rxn.metabolites:
        if met.compartment not in element_dist:
            # Multiplication by the metabolite stoichiometry.
            element_dist[met.compartment] = \
                {k: v * rxn.metabolites[met]
                 for (k, v) in iteritems(met.elements)}
        else:
            x = {k: v * rxn.metabolites[met] for (k, v) in
                 iteritems(met.elements)}
            y = element_dist[met.compartment]
            element_dist[met.compartment] = \
                {k: x.get(k, 0) + y.get(k, 0) for k in set(x) | set(y)}
    delta_dict = defaultdict()
    # Simplification of the resulting dictionary of dictionaries.
    for elements in itervalues(element_dist):
        delta_dict.update(elements)
    # Only non-zero values get included in the returned delta-dict.
    delta_dict = {k: abs(v) for (k, v) in iteritems(delta_dict) if v != 0}
    return delta_dict

Response: Find transported elements of a reaction.


Instruction:
Explain what the following Python 3 code does
def find_transport_reactions(model):
    transport_reactions = []
    transport_rxn_candidates = set(model.reactions) - set(model.boundary) \
        - set(find_biomass_reaction(model))
    transport_rxn_candidates = set(
        [rxn for rxn in transport_rxn_candidates if len(rxn.compartments) >= 2]
    )
    # Add all labeled transport reactions
    sbo_matches = set([rxn for rxn in transport_rxn_candidates if
                       rxn.annotation is not None and
                       'sbo' in rxn.annotation and
                       rxn.annotation['sbo'] in TRANSPORT_RXN_SBO_TERMS])
    if len(sbo_matches) > 0:
        transport_reactions += list(sbo_matches)
    # Find unlabeled transport reactions via formula or annotation checks
    for rxn in transport_rxn_candidates:
        # Check if metabolites have formula field
        rxn_mets = set([met.formula for met in rxn.metabolites])
        if (None not in rxn_mets) and (len(rxn_mets) != 0):
            if is_transport_reaction_formulae(rxn):
                transport_reactions.append(rxn)
        elif is_transport_reaction_annotations(rxn):
            transport_reactions.append(rxn)

    return set(transport_reactions)

Response: Returns a list of all transport reactions in the given metabolite model.


Instruction:
How would you explain what the following Python 3 function does
def is_transport_reaction_formulae(rxn):
    # Collecting criteria to classify transporters by.
    rxn_reactants = set([met.formula for met in rxn.reactants])
    rxn_products = set([met.formula for met in rxn.products])
    # Looking for formulas that stay the same on both side of the reaction.
    transported_mets = \
        [formula for formula in rxn_reactants if formula in rxn_products]
    # Collect information on the elemental differences between
    # compartments in the reaction.
    delta_dicts = find_transported_elements(rxn)
    non_zero_array = [v for (k, v) in iteritems(delta_dicts) if v != 0]
    # Excluding reactions such as oxidoreductases where no net
    # transport of Hydrogen is occurring, but rather just an exchange of
    # electrons or charges effecting a change in protonation.
    if set(transported_mets) != set('H') and list(
        delta_dicts.keys()
    ) == ['H']:
        pass
    # All other reactions for which the amount of transported elements is
    # not zero, which are not part of the model's exchange nor
    # biomass reactions, are defined as transport reactions.
    # This includes reactions where the transported metabolite reacts with
    # a carrier molecule.
    elif sum(non_zero_array):
        return True

Response: Returns a boolean if a reaction is a transport reaction.


Instruction:
Explain what the following Python 3 code does
def is_transport_reaction_annotations(rxn):
    reactants = set([(k, tuple(v)) for met in rxn.reactants
                     for k, v in iteritems(met.annotation)
                     if met.id != "H"
                     and k is not None and k != 'sbo' and v is not None])
    products = set([(k, tuple(v)) for met in rxn.products
                    for k, v in iteritems(met.annotation)
                    if met.id != "H"
                    and k is not None and k != 'sbo' and v is not None])
    # Find intersection between reactant annotations and
    # product annotations to find common metabolites between them,
    # satisfying the requirements for a transport reaction. Reactions such
    # as those involving oxidoreductases (where no net transport of
    # Hydrogen is occurring, but rather just an exchange of electrons or
    # charges effecting a change in protonation) are excluded.
    transported_mets = reactants & products
    if len(transported_mets) > 0:
        return True

Response: Returns a boolean if a reaction is a transport reaction.


Instruction:
Here you have a function in Python 3, explain what it does
def find_converting_reactions(model, pair):
    first = set(find_met_in_model(model, pair[0]))
    second = set(find_met_in_model(model, pair[1]))
    hits = list()
    for rxn in model.reactions:
        # FIXME: Use `set.issubset` much more idiomatic.
        if len(first & set(rxn.reactants)) > 0 and len(
                second & set(rxn.products)) > 0:
            hits.append(rxn)
        elif len(first & set(rxn.products)) > 0 and len(
                second & set(rxn.reactants)) > 0:
            hits.append(rxn)
    return frozenset(hits)

Response: Find all reactions which convert a given metabolite pair.


Instruction:
Write a Python 3 function that can
return a list of the biomass reaction(s) of the model. This function identifies possible biomass reactions using two steps: 1. Return reactions that include the SBO annotation "SBO:0000629" for biomass. If no reactions can be identifies this way: 2. Look for the ``buzzwords`` "biomass", "growth" and "bof" in reaction IDs. 3. Look for metabolite IDs or names that contain the ``buzzword`` "biomass" and obtain the set of reactions they are involved in. 4. Remove boundary reactions from this set. 5. Return the union of reactions that match the buzzwords and of the reactions that metabolites are involved in that match the buzzword. Parameters ---------- model : cobra.Model The metabolic model under investigation. Returns ------- list Identified biomass reactions.

Response:
def find_biomass_reaction(model):
    """
    Return a list of the biomass reaction(s) of the model.

    This function identifies possible biomass reactions using two steps:
    1. Return reactions that include the SBO annotation "SBO:0000629" for
    biomass.
    If no reactions can be identifies this way:
    2. Look for the ``buzzwords`` "biomass", "growth" and "bof" in reaction IDs.
    3. Look for metabolite IDs or names that contain the ``buzzword`` "biomass"
    and obtain the set of reactions they are involved in.
    4. Remove boundary reactions from this set.
    5. Return the union of reactions that match the buzzwords and of the
    reactions that metabolites are involved in that match the buzzword.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    Returns
    -------
    list
        Identified biomass reactions.

    """
    sbo_matches = set([rxn for rxn in model.reactions if
                       rxn.annotation is not None and
                       'sbo' in rxn.annotation and
                       rxn.annotation['sbo'] == 'SBO:0000629'])

    if len(sbo_matches) > 0:
        return list(sbo_matches)

    buzzwords = ['biomass', 'growth', 'bof']

    buzzword_matches = set([rxn for rxn in model.reactions if any(
        string in rxn.id.lower() for string in buzzwords)])

    biomass_met = []
    for met in model.metabolites:
        if 'biomass' in met.id.lower() or (
                met.name is not None and 'biomass' in met.name.lower()):
            biomass_met.append(met)
    if biomass_met == 1:
        biomass_met_matches = set(
            biomass_met.reactions
        ) - set(model.boundary)
    else:
        biomass_met_matches = set()

    return list(buzzword_matches | biomass_met_matches)


Instruction:
Can you generate the documentation for the following Python 3 function
def find_demand_reactions(model):
    try:
        extracellular = find_compartment_id_in_model(model, 'e')
    except KeyError:
        extracellular = None
    return find_boundary_types(model, 'demand', extracellular)

Response: u Returns a list of demand reactions in the given metabolic model.


Instruction:
Can you create a Python 3 function that
returns the set of all transport boundary and biomass reactions.

Response:
def find_interchange_biomass_reactions(model, biomass=None):
    """
    Return the set of all transport, boundary, and biomass reactions.

    These reactions are either pseudo-reactions, or incorporated to allow
    metabolites to pass between compartments. Some tests focus on purely
    metabolic reactions and hence exclude this set.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.
    biomass : list or cobra.Reaction, optional
        A list of cobrapy biomass reactions.

    """
    boundary = set(model.boundary)
    transporters = find_transport_reactions(model)
    if biomass is None:
        biomass = set(find_biomass_reaction(model))
    return boundary | transporters | biomass


Instruction:
Make a summary of the following Python 3 code
def run_fba(model, rxn_id, direction="max", single_value=True):
    model.objective = model.reactions.get_by_id(rxn_id)
    model.objective_direction = direction
    if single_value:
        try:
            return model.slim_optimize()
        except Infeasible:
            return np.nan
    else:
        try:
            solution = model.optimize()
            return solution
        except Infeasible:
            return np.nan

Response: Runs a FBA problem on a set of reactions.


Instruction:
Can you tell what is the following Python 3 function doing
def close_boundaries_sensibly(model):
    for rxn in model.reactions:
        if rxn.reversibility:
            rxn.bounds = -1, 1
        else:
            rxn.bounds = 0, 1
    for boundary in model.boundary:
        boundary.bounds = (0, 0)

Response: Solve a metabolic model with all boundaries closed and changed constraints.


Instruction:
How would you code a function in Python 3 to
return a list of all metabolites belonging to a given compartment.

Response:
def metabolites_per_compartment(model, compartment_id):
    """
    Identify all metabolites that belong to a given compartment.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.
    compartment_id : string
        Model specific compartment identifier.

    Returns
    -------
    list
        List of metabolites belonging to a given compartment.

    """
    return [met for met in model.metabolites
            if met.compartment == compartment_id]


Instruction:
Can you generate a brief explanation for the following Python 3 code
def largest_compartment_id_met(model):
    # Sort compartments by decreasing size and extract the largest two.
    candidate, second = sorted(
        ((c, len(metabolites_per_compartment(model, c)))
         for c in model.compartments), reverse=True, key=itemgetter(1))[:2]
    # Compare the size of the compartments.
    if candidate[1] == second[1]:
        raise RuntimeError("There is a tie for the largest compartment. "
                           "Compartment {} and {} have equal amounts of "
                           "metabolites.".format(candidate[0], second[0]))
    else:
        return candidate[0]

Response: Returns the ID of the largest compartment with the most metabolites.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def find_compartment_id_in_model(model, compartment_id):
    if compartment_id not in COMPARTMENT_SHORTLIST.keys():
        raise KeyError("{} is not in the COMPARTMENT_SHORTLIST! Make sure "
                       "you typed the ID correctly, if yes, update the "
                       "shortlist manually.".format(compartment_id))

    if len(model.compartments) == 0:
        raise KeyError(
            "It was not possible to identify the "
            "compartment {}, since the "
            "model has no compartments at "
            "all.".format(COMPARTMENT_SHORTLIST[compartment_id][0])
        )

    if compartment_id in model.compartments.keys():
        return compartment_id

    for name in COMPARTMENT_SHORTLIST[compartment_id]:
        for c_id, c_name in model.compartments.items():
            if c_name.lower() == name:
                return c_id

    if compartment_id == 'c':
        return largest_compartment_id_met(model)

Response: Find a model compartment by looking up names in COMPARTMENT_SHORTLIST.


Instruction:
Here you have a function in Python 3, explain what it does
def find_met_in_model(model, mnx_id, compartment_id=None):
    def compare_annotation(annotation):
        """
        Return annotation IDs that match to METANETX_SHORTLIST references.

        Compares the set of METANETX_SHORTLIST references for a given mnx_id
        and the annotation IDs stored in a given annotation dictionary.
        """
        query_values = set(utils.flatten(annotation.values()))
        ref_values = set(utils.flatten(METANETX_SHORTLIST[mnx_id]))
        return query_values & ref_values

    # Make sure that the MNX ID we're looking up exists in the metabolite
    # shortlist.
    if mnx_id not in METANETX_SHORTLIST.columns:
        raise ValueError(
            "{} is not in the MetaNetX Shortlist! Make sure "
            "you typed the ID correctly, if yes, update the "
            "shortlist by updating and re-running the script "
            "generate_mnx_shortlists.py.".format(mnx_id)
        )
    candidates = []
    # The MNX ID used in the model may or may not be tagged with a compartment
    # tag e.g. `MNXM23141_c` vs. `MNXM23141`, which is tested with the
    # following regex.
    # If the MNX ID itself cannot be found as an ID, we try all other
    # identifiers that are provided by our shortlist of MetaNetX' mapping
    # table.
    regex = re.compile('^{}(_[a-zA-Z0-9]+)?$'.format(mnx_id))
    if model.metabolites.query(regex):
        candidates = model.metabolites.query(regex)
    elif model.metabolites.query(compare_annotation, attribute='annotation'):
        candidates = model.metabolites.query(
            compare_annotation, attribute='annotation'
        )
    else:
        for value in METANETX_SHORTLIST[mnx_id]:
            if value:
                for ident in value:
                    regex = re.compile('^{}(_[a-zA-Z0-9]+)?$'.format(ident))
                    if model.metabolites.query(regex, attribute='id'):
                        candidates.extend(
                            model.metabolites.query(regex, attribute='id'))

    # Return a list of all possible candidates if no specific compartment ID
    # is provided.
    # Otherwise, just return the candidate in one specific compartment. Raise
    # an exception if there are more than one possible candidates for a given
    # compartment.
    if compartment_id is None:
        print("compartment_id = None?")
        return candidates
    else:
        candidates_in_compartment = \
            [cand for cand in candidates if cand.compartment == compartment_id]

    if len(candidates_in_compartment) == 0:
        raise RuntimeError("It was not possible to identify "
                           "any metabolite in compartment {} corresponding to "
                           "the following MetaNetX identifier: {}."
                           "Make sure that a cross-reference to this ID in "
                           "the MetaNetX Database exists for your "
                           "identifier "
                           "namespace.".format(compartment_id, mnx_id))
    elif len(candidates_in_compartment) > 1:
        raise RuntimeError("It was not possible to uniquely identify "
                           "a single metabolite in compartment {} that "
                           "corresponds to the following MetaNetX "
                           "identifier: {}."
                           "Instead these candidates were found: {}."
                           "Check that metabolite compartment tags are "
                           "correct. Consider switching to a namespace scheme "
                           "where identifiers are truly "
                           "unique.".format(compartment_id,
                                            mnx_id,
                                            utils.get_ids(
                                                candidates_in_compartment
                                            ))
                           )
    else:
        return candidates_in_compartment

Response: Find metabolites in a given model.


Instruction:
Implement a Python 3 function for
finding the median upper and lower bound of the metabolic model.

Response:
def find_bounds(model):
    """
    Return the median upper and lower bound of the metabolic model.

    Bounds can vary from model to model. Cobrapy defaults to (-1000, 1000) but
    this may not be the case for merged or autogenerated models. In these
    cases, this function is used to iterate over all the bounds of all the
    reactions and find the median bound values in the model, which are
    then used as the 'most common' bounds.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    """
    lower_bounds = np.asarray([rxn.lower_bound for rxn in model.reactions],
                              dtype=float)
    upper_bounds = np.asarray([rxn.upper_bound for rxn in model.reactions],
                              dtype=float)
    lower_bound = np.nanmedian(lower_bounds[lower_bounds != 0.0])
    upper_bound = np.nanmedian(upper_bounds[upper_bounds != 0.0])
    if np.isnan(lower_bound):
        LOGGER.warning("Could not identify a median lower bound.")
        lower_bound = -1000.0
    if np.isnan(upper_bound):
        LOGGER.warning("Could not identify a median upper bound.")
        upper_bound = 1000.0
    return lower_bound, upper_bound


Instruction:
Given the following Python 3 function, write the documentation
def render_html(self):
        return self._template.safe_substitute(
            report_type=self._report_type,
            results=self.render_json()
        )

Response: Render an HTML report.


Instruction:
Can you tell what is the following Python 3 function doing
def compute_score(self):
        # LOGGER.info("Begin scoring")
        cases = self.get_configured_tests() | set(self.result.cases)
        scores = DataFrame({"score": 0.0, "max": 1.0},
                           index=sorted(cases))
        self.result.setdefault("score", dict())
        self.result["score"]["sections"] = list()
        # Calculate the scores for each test individually.
        for test, result in iteritems(self.result.cases):
            # LOGGER.info("Calculate score for test: '%s'.", test)
            # Test metric may be a dictionary for a parametrized test.
            metric = result["metric"]
            if hasattr(metric, "items"):
                result["score"] = test_score = dict()
                total = 0.0
                for key, value in iteritems(metric):
                    value = 1.0 - value
                    total += value
                    test_score[key] = value
                # For some reason there are parametrized tests without cases.
                if len(metric) == 0:
                    metric = 0.0
                else:
                    metric = total / len(metric)
            else:
                metric = 1.0 - metric
            scores.at[test, "score"] = metric
            scores.loc[test, :] *= self.config["weights"].get(test, 1.0)
        score = 0.0
        maximum = 0.0
        # Calculate the scores for each section considering the individual test
        # case scores.
        for section_id, card in iteritems(
            self.config['cards']['scored']['sections']
        ):
            # LOGGER.info("Calculate score for section: '%s'.", section_id)
            cases = card.get("cases", None)
            if cases is None:
                continue
            card_score = scores.loc[cases, "score"].sum()
            card_total = scores.loc[cases, "max"].sum()
            # Format results nicely to work immediately with Vega Bar Chart.
            section_score = {"section": section_id,
                             "score": card_score / card_total}
            self.result["score"]["sections"].append(section_score)
            # Calculate the final score for the entire model.
            weight = card.get("weight", 1.0)
            score += card_score * weight
            maximum += card_total * weight
        self.result["score"]["total_score"] = score / maximum

Response: Calculate the overall test score using the configuration.


Instruction:
Here you have a function in Python 3, explain what it does
def find_components_without_sbo_terms(model, components):
    return [elem for elem in getattr(model, components) if
            elem.annotation is None or 'sbo' not in elem.annotation]

Response: Returns a list of model components that are not annotated with any SBO terms.


Instruction:
Given the following Python 3 function, write the documentation
def check_component_for_specific_sbo_term(items, term):
    # check for multiple allowable SBO terms
    if isinstance(term, list):
        return [elem for elem in items if
                elem.annotation is None or
                'sbo' not in elem.annotation or
                not any(i in elem.annotation['sbo'] for i in term)]
    else:
        return [elem for elem in items if
                elem.annotation is None or
                'sbo' not in elem.annotation or
                term not in elem.annotation['sbo']]

Response: r Checks if a specific SBO term is present in the model components.


Instruction:
Write a Python 3 script for
returning the smallest KEGG compound identifier from a list of mixed KEGG identifiers.

Response:
def get_smallest_compound_id(compounds_identifiers):
    """
    Return the smallest KEGG compound identifier from a list.

    KEGG identifiers may map to compounds, drugs or glycans prefixed
    respectively with "C", "D", and "G" followed by at least 5 digits. We
    choose the lowest KEGG identifier with the assumption that several
    identifiers are due to chirality and that the lower one represents the
    more common form.

    Parameters
    ----------
    compounds_identifiers : list
        A list of mixed KEGG identifiers.

    Returns
    -------
    str
        The KEGG compound identifier with the smallest number.

    Raises
    ------
    ValueError
        When compound_identifiers contains no KEGG compound identifiers.

    """
    return min((c for c in compounds_identifiers if c.startswith("C")),
               key=lambda c: int(c[1:]))


Instruction:
Here you have a function in Python 3, explain what it does
def map_metabolite2kegg(metabolite):
    logger.debug("Looking for KEGG compound identifier for %s.", metabolite.id)
    kegg_annotation = metabolite.annotation.get("kegg.compound")
    if kegg_annotation is None:
        # TODO (Moritz Beber): Currently name matching is very slow and
        #  inaccurate. We disable it until there is a better solution.
        # if metabolite.name:
        #     # The compound matcher uses regular expression and chokes
        #     # with a low level error on `[` in the name, for example.
        #     df = compound_matcher.match(metabolite.name)
        #     try:
        #         return df.loc[df["score"] > threshold, "CID"].iat[0]
        #     except (IndexError, AttributeError):
        #         logger.warning(
        #             "Could not match the name %r to any kegg.compound "
        #             "annotation for metabolite %s.",
        #             metabolite.name, metabolite.id
        #         )
        #         return
        # else:
        logger.warning("No kegg.compound annotation for metabolite %s.",
                       metabolite.id)
        return
    if isinstance(kegg_annotation, string_types) and \
            kegg_annotation.startswith("C"):
        return kegg_annotation
    elif isinstance(kegg_annotation, Iterable):
        try:
            return get_smallest_compound_id(kegg_annotation)
        except ValueError:
            return
    logger.warning(
        "No matching kegg.compound annotation for metabolite %s.",
        metabolite.id
    )
    return

Response: Map a metabolite to its KEGG compound identifier.


Instruction:
Make a summary of the following Python 3 code
def translate_reaction(reaction, metabolite_mapping):
    # Transport reactions where the same metabolite occurs in different
    # compartments should have been filtered out but just to be sure, we add
    # coefficients in the mapping.
    stoichiometry = defaultdict(float)
    for met, coef in iteritems(reaction.metabolites):
        kegg_id = metabolite_mapping.setdefault(met, map_metabolite2kegg(met))
        if kegg_id is None:
            continue
        stoichiometry[kegg_id] += coef
    return dict(stoichiometry)

Response: Translate a reaction into a KEGG compound identifier to coefficients.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def find_thermodynamic_reversibility_index(reactions):
    incomplete_mapping = []
    problematic_calculation = []
    reversibility_indexes = []
    unbalanced = []
    metabolite_mapping = {}

    for rxn in reactions:
        stoich = translate_reaction(rxn, metabolite_mapping)
        if len(stoich) < len(rxn.metabolites):
            incomplete_mapping.append(rxn)
            continue
        try:
            # Remove protons from stoichiometry.
            if "C00080" in stoich:
                del stoich["C00080"]
            eq_rxn = Reaction(stoich, rxn.id)
        except KeyError:
            incomplete_mapping.append(rxn)
            continue
        if eq_rxn.check_full_reaction_balancing():
            try:
                ln_rev_index = eq_rxn.reversibility_index()
            # TODO (Moritz Beber): Which exceptions can we expect here?
            except Exception:
                problematic_calculation.append(rxn)
                continue
            reversibility_indexes.append((rxn, ln_rev_index))
        else:
            unbalanced.append(rxn)
    reversibility_indexes.sort(key=lambda p: abs(p[1]), reverse=True)
    return (
        reversibility_indexes, incomplete_mapping, problematic_calculation,
        unbalanced
    )

Response: u This function returns the reversibility index of the given reactions.


Instruction:
Explain what the following Python 3 code does
def check_stoichiometric_consistency(model):
    problem = model.problem
    # The transpose of the stoichiometric matrix N.T in the paper.
    stoich_trans = problem.Model()
    internal_rxns = con_helpers.get_internals(model)
    metabolites = set(met for rxn in internal_rxns for met in rxn.metabolites)
    LOGGER.info("model '%s' has %d internal reactions", model.id,
                len(internal_rxns))
    LOGGER.info("model '%s' has %d internal metabolites", model.id,
                len(metabolites))

    stoich_trans.add([problem.Variable(m.id, lb=1) for m in metabolites])
    stoich_trans.update()
    con_helpers.add_reaction_constraints(
        stoich_trans, internal_rxns, problem.Constraint)
    # The objective is to minimize the metabolite mass vector.
    stoich_trans.objective = problem.Objective(
        Zero, direction="min", sloppy=True)
    stoich_trans.objective.set_linear_coefficients(
        {var: 1. for var in stoich_trans.variables})
    status = stoich_trans.optimize()
    if status == OPTIMAL:
        return True
    elif status == INFEASIBLE:
        return False
    else:
        raise RuntimeError(
            "Could not determine stoichiometric consistencty."
            " Solver status is '{}'"
            " (only optimal or infeasible expected).".format(status))

Response: Verify consistency of the metabolic model s stoichiometry.


Instruction:
Here you have a function in Python 3, explain what it does
def find_unconserved_metabolites(model):
    problem = model.problem
    stoich_trans = problem.Model()
    internal_rxns = con_helpers.get_internals(model)
    metabolites = set(met for rxn in internal_rxns for met in rxn.metabolites)
    # The binary variables k[i] in the paper.
    k_vars = list()
    for met in metabolites:
        # The element m[i] of the mass vector.
        m_var = problem.Variable(met.id)
        k_var = problem.Variable("k_{}".format(met.id), type="binary")
        k_vars.append(k_var)
        stoich_trans.add([m_var, k_var])
        # This constraint is equivalent to 0 <= k[i] <= m[i].
        stoich_trans.add(problem.Constraint(
            k_var - m_var, ub=0, name="switch_{}".format(met.id)))
    stoich_trans.update()
    con_helpers.add_reaction_constraints(
        stoich_trans, internal_rxns, problem.Constraint)
    # The objective is to maximize the binary indicators k[i], subject to the
    # above inequality constraints.
    stoich_trans.objective = problem.Objective(
        Zero, sloppy=True, direction="max")
    stoich_trans.objective.set_linear_coefficients(
        {var: 1. for var in k_vars})
    status = stoich_trans.optimize()
    if status == OPTIMAL:
        # TODO: See if that could be a Boolean test `bool(var.primal)`.
        return set([model.metabolites.get_by_id(var.name[2:])
                    for var in k_vars if var.primal < 0.8])
    else:
        raise RuntimeError(
            "Could not compute list of unconserved metabolites."
            " Solver status is '{}' (only optimal expected).".format(status))

Response:
Detect unconserved metabolites.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    Notes
    -----
    See [1]_ section 3.2 for a complete description of the algorithm.

    .. [1] Gevorgyan, A., M. G Poolman, and D. A Fell.
           "Detection of Stoichiometric Inconsistencies in Biomolecular
           Models."
           Bioinformatics 24, no. 19 (2008): 2245.


Instruction:
Can you implement a function in Python 3 that
detects inconsistent minimal net stoichiometries in Biomolecular Models.

Response:
def find_inconsistent_min_stoichiometry(model, atol=1e-13):
    """
    Detect inconsistent minimal net stoichiometries.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.
    atol : float, optional
        Values below the absolute tolerance are treated as zero. Expected to be
        very small but larger than zero.

    Notes
    -----
    See [1]_ section 3.3 for a complete description of the algorithm.

    References
    ----------
    .. [1] Gevorgyan, A., M. G Poolman, and D. A Fell.
           "Detection of Stoichiometric Inconsistencies in Biomolecular
           Models."
           Bioinformatics 24, no. 19 (2008): 2245.

    """
    if check_stoichiometric_consistency(model):
        return set()
    Model, Constraint, Variable, Objective = con_helpers.get_interface(model)
    unconserved_mets = find_unconserved_metabolites(model)
    LOGGER.info("model has %d unconserved metabolites", len(unconserved_mets))
    internal_rxns = con_helpers.get_internals(model)
    internal_mets = set(
        met for rxn in internal_rxns for met in rxn.metabolites)
    get_id = attrgetter("id")
    reactions = sorted(internal_rxns, key=get_id)
    metabolites = sorted(internal_mets, key=get_id)
    stoich, met_index, rxn_index = con_helpers.stoichiometry_matrix(
        metabolites, reactions)
    left_ns = con_helpers.nullspace(stoich.T)
    # deal with numerical instabilities
    left_ns[np.abs(left_ns) < atol] = 0.0
    LOGGER.info("nullspace has dimension %d", left_ns.shape[1])
    inc_minimal = set()
    (problem, indicators) = con_helpers.create_milp_problem(
        left_ns, metabolites, Model, Variable, Constraint, Objective)
    LOGGER.debug(str(problem))
    cuts = list()
    for met in unconserved_mets:
        row = met_index[met]
        if (left_ns[row] == 0.0).all():
            LOGGER.debug("%s: singleton minimal unconservable set", met.id)
            # singleton set!
            inc_minimal.add((met,))
            continue
        # expect a positive mass for the unconserved metabolite
        problem.variables[met.id].lb = 1e-3
        status = problem.optimize()
        while status == "optimal":
            LOGGER.debug("%s: status %s", met.id, status)
            LOGGER.debug("sum of all primal values: %f",
                         sum(problem.primal_values.values()))
            LOGGER.debug("sum of binary indicators: %f",
                         sum(var.primal for var in indicators))
            solution = [model.metabolites.get_by_id(var.name[2:])
                        for var in indicators if var.primal > 0.2]
            LOGGER.debug("%s: set size %d", met.id, len(solution))
            inc_minimal.add(tuple(solution))
            if len(solution) == 1:
                break
            cuts.append(con_helpers.add_cut(
                problem, indicators, len(solution) - 1, Constraint))
            status = problem.optimize()
        LOGGER.debug("%s: last status %s", met.id, status)
        # reset
        problem.variables[met.id].lb = 0.0
        problem.remove(cuts)
        cuts.clear()
    return inc_minimal


Instruction:
Here you have a function in Python 3, explain what it does
def detect_energy_generating_cycles(model, metabolite_id):
    main_comp = helpers.find_compartment_id_in_model(model, 'c')
    met = helpers.find_met_in_model(model, metabolite_id, main_comp)[0]

    dissipation_rxn = Reaction('Dissipation')
    if metabolite_id in ['MNXM3', 'MNXM63', 'MNXM51', 'MNXM121', 'MNXM423']:
        # build nucleotide-type dissipation reaction
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM2', main_comp)[0]: -1,
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]: 1,
            helpers.find_met_in_model(model, 'MNXM9', main_comp)[0]: 1,
        })
    elif metabolite_id in ['MNXM6', 'MNXM10']:
        # build nicotinamide-type dissipation reaction
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]: 1
        })
    elif metabolite_id in ['MNXM38', 'MNXM208', 'MNXM191', 'MNXM223',
                           'MNXM7517', 'MNXM12233', 'MNXM558']:
        # build redox-partner-type dissipation reaction
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]: 2
        })
    elif metabolite_id == 'MNXM21':
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM2', main_comp)[0]: -1,
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]: 1,
            helpers.find_met_in_model(model, 'MNXM26', main_comp)[0]: 1,
        })
    elif metabolite_id == 'MNXM89557':
        dissipation_rxn.add_metabolites({
            helpers.find_met_in_model(model, 'MNXM2', main_comp)[0]: -1,
            helpers.find_met_in_model(model, 'MNXM1', main_comp)[0]: 2,
            helpers.find_met_in_model(model, 'MNXM15', main_comp)[0]: 1,
        })

    dissipation_product = helpers.find_met_in_model(
        model,
        ENERGY_COUPLES[metabolite_id],
        main_comp)[0]

    dissipation_rxn.add_metabolites(
        {met: -1, dissipation_product: 1})
    helpers.close_boundaries_sensibly(model)
    model.add_reactions([dissipation_rxn])
    model.objective = dissipation_rxn
    solution = model.optimize(raise_error=True)

    if solution.objective_value > 0.0:
        return solution.fluxes[solution.fluxes.abs() > 0.0].index. \
            drop(["Dissipation"]).tolist()
    else:
        return []

Response: u Detect erroneous energy - generating cycles for a single metabolite.


Instruction:
Here you have a function in Python 3, explain what it does
def find_stoichiometrically_balanced_cycles(model):
    helpers.close_boundaries_sensibly(model)
    fva_result = flux_variability_analysis(model, loopless=False)
    return fva_result.index[
        (fva_result["minimum"] <= (-1 + TOLERANCE_THRESHOLD)) |
        (fva_result["maximum"] >= (1 - TOLERANCE_THRESHOLD))
    ].tolist()

Response: u Find metabolic reactions that carry a non - balanced cycle.


Instruction:
Can you write a function in Python 3 where it
returns metabolites that are only consumed in reactions and are not involved in exchange.

Response:
def find_orphans(model):
    """
    Return metabolites that are only consumed in reactions.

    Metabolites that are involved in an exchange reaction are never
    considered to be orphaned.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    """
    exchange = frozenset(model.exchanges)
    return [
        met for met in model.metabolites
        if (len(met.reactions) > 0) and all(
            (not rxn.reversibility) and (rxn not in exchange) and
            (rxn.metabolites[met] < 0) for rxn in met.reactions
        )
    ]


Instruction:
Write a Python 3 function for
finding metabolites that cannot be produced with open exchange reactions.

Response:
def find_metabolites_not_produced_with_open_bounds(model):
    """
    Return metabolites that cannot be produced with open exchange reactions.

    A perfect model should be able to produce each and every metabolite when
    all medium components are available.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    Returns
    -------
    list
        Those metabolites that could not be produced.

    """
    mets_not_produced = list()
    helpers.open_exchanges(model)
    for met in model.metabolites:
        with model:
            exch = model.add_boundary(
                met, type="irrex", reaction_id="IRREX", lb=0, ub=1000)
            solution = helpers.run_fba(model, exch.id)
            if np.isnan(solution) or solution < TOLERANCE_THRESHOLD:
                mets_not_produced.append(met)
    return mets_not_produced


Instruction:
Explain what the following Python 3 code does
def find_metabolites_not_consumed_with_open_bounds(model):
    mets_not_consumed = list()
    helpers.open_exchanges(model)
    for met in model.metabolites:
        with model:
            exch = model.add_boundary(
                met, type="irrex", reaction_id="IRREX", lb=-1000, ub=0)
            solution = helpers.run_fba(model, exch.id, direction="min")
            if np.isnan(solution) or abs(solution) < TOLERANCE_THRESHOLD:
                mets_not_consumed.append(met)
    return mets_not_consumed

Response: Finds metabolites that cannot be consumed with open boundary reactions.


Instruction:
Explain what the following Python 3 code does
def find_reactions_with_unbounded_flux_default_condition(model):
    try:
        fva_result = flux_variability_analysis(model, fraction_of_optimum=1.0)
    except Infeasible as err:
        LOGGER.error("Failed to find reactions with unbounded flux "
                     "because '{}'. This may be a bug.".format(err))
        raise Infeasible("It was not possible to run flux variability "
                         "analysis on the model. Make sure that the model "
                         "can be solved! Check if the constraints are not "
                         "too strict.")
    # Per reaction (row) the flux is below threshold (close to zero).
    conditionally_blocked = fva_result.loc[
        fva_result.abs().max(axis=1) < TOLERANCE_THRESHOLD
    ].index.tolist()
    small, large = helpers.find_bounds(model)
    # Find those reactions whose flux is close to or outside of the median
    # upper or lower bound, i.e., appears unconstrained.
    unlimited_flux = fva_result.loc[
        np.isclose(fva_result["maximum"], large, atol=TOLERANCE_THRESHOLD) |
        (fva_result["maximum"] > large) |
        np.isclose(fva_result["minimum"], small, atol=TOLERANCE_THRESHOLD) |
        (fva_result["minimum"] < small)
    ].index.tolist()
    try:
        fraction = len(unlimited_flux) / \
            (len(model.reactions) - len(conditionally_blocked))
    except ZeroDivisionError:
        LOGGER.error("Division by Zero! Failed to calculate the "
                     "fraction of unbounded reactions. Does this model "
                     "have any reactions at all?")
        raise ZeroDivisionError("It was not possible to calculate the "
                                "fraction of unbounded reactions to "
                                "un-blocked reactions. This may be because"
                                "the model doesn't have any reactions at "
                                "all or that none of the reactions can "
                                "carry a flux larger than zero!")

    return unlimited_flux, fraction, conditionally_blocked

Response: Find reactions whose flux is unbounded in the default condition.


Instruction:
Make a summary of the following Python 3 code
def read_tabular(filename, dtype_conversion=None):
    if dtype_conversion is None:
        dtype_conversion = {}
    name, ext = filename.split(".", 1)
    ext = ext.lower()
    # Completely empty columns are interpreted as float by default.
    dtype_conversion["comment"] = str
    if "csv" in ext:
        df = pd.read_csv(filename, dtype=dtype_conversion, encoding="utf-8")
    elif "tsv" in ext:
        df = pd.read_table(filename, dtype=dtype_conversion, encoding="utf-8")
    elif "xls" in ext or "xlsx" in ext:
        df = pd.read_excel(filename, dtype=dtype_conversion, encoding="utf-8")
    # TODO: Add a function to parse ODS data into a pandas data frame.
    else:
        raise ValueError("Unknown file format '{}'.".format(ext))
    return df

Response: Read a tabular data file which can be CSV TSV XLS XLSX or ExcelX.


Instruction:
Implement a function in Python 3 to
take a snapshot of a model and generate a report.

Response:
def snapshot(model, filename, pytest_args, exclusive, skip, solver,
             experimental, custom_tests, custom_config):
    """
    Take a snapshot of a model's state and generate a report.

    MODEL: Path to model file. Can also be supplied via the environment variable
    MEMOTE_MODEL or configured in 'setup.cfg' or 'memote.ini'.
    """
    model_obj, sbml_ver, notifications = api.validate_model(
        model)
    if model_obj is None:
        LOGGER.critical(
            "The model could not be loaded due to the following SBML errors.")
        utils.stdout_notifications(notifications)
        api.validation_report(model, notifications, filename)
        sys.exit(1)
    if not any(a.startswith("--tb") for a in pytest_args):
        pytest_args = ["--tb", "no"] + pytest_args
    # Add further directories to search for tests.
    pytest_args.extend(custom_tests)
    config = ReportConfiguration.load()
    # Update the default test configuration with custom ones (if any).
    for custom in custom_config:
        config.merge(ReportConfiguration.load(custom))
    model_obj.solver = solver
    _, results = api.test_model(model_obj, sbml_version=sbml_ver, results=True,
                                pytest_args=pytest_args, skip=skip,
                                exclusive=exclusive, experimental=experimental)
    with open(filename, "w", encoding="utf-8") as file_handle:
        LOGGER.info("Writing snapshot report to '%s'.", filename)
        file_handle.write(api.snapshot_report(results, config))


Instruction:
Can you write a function in Python 3 where it
generates a report over a model s git commit history.

Response:
def history(location, model, filename, deployment, custom_config):
    """Generate a report over a model's git commit history."""
    callbacks.git_installed()
    LOGGER.info("Initialising history report generation.")
    if location is None:
        raise click.BadParameter("No 'location' given or configured.")
    try:
        repo = git.Repo()
    except git.InvalidGitRepositoryError:
        LOGGER.critical(
            "The history report requires a git repository in order to check "
            "the model's commit history.")
        sys.exit(1)
    LOGGER.info("Obtaining history of results from "
                "the deployment branch {}.".format(deployment))
    repo.git.checkout(deployment)
    try:
        manager = managers.SQLResultManager(repository=repo, location=location)
    except (AttributeError, ArgumentError):
        manager = managers.RepoResultManager(
            repository=repo, location=location)
    config = ReportConfiguration.load()
    # Update the default test configuration with custom ones (if any).
    for custom in custom_config:
        config.merge(ReportConfiguration.load(custom))
    LOGGER.info("Tracing the commit history.")
    history = managers.HistoryManager(repository=repo, manager=manager)
    history.load_history(model, skip={deployment})
    LOGGER.info("Composing the history report.")
    report = api.history_report(history, config=config)
    with open(filename, "w", encoding="utf-8") as file_handle:
        file_handle.write(report)


Instruction:
Given the following Python 3 function, write the documentation
def diff(models, filename, pytest_args, exclusive, skip, solver,
         experimental, custom_tests, custom_config):
    """
    Take a snapshot of all the supplied models and generate a diff report.

    MODELS: List of paths to two or more model files.
    """
    if not any(a.startswith("--tb") for a in pytest_args):
        pytest_args = ["--tb", "no"] + pytest_args
    # Add further directories to search for tests.
    pytest_args.extend(custom_tests)
    config = ReportConfiguration.load()
    # Update the default test configuration with custom ones (if any).
    for custom in custom_config:
        config.merge(ReportConfiguration.load(custom))
    # Build the diff report specific data structure
    diff_results = dict()
    model_and_model_ver_tuple = list()
    for model_path in models:
        try:
            model_filename = os.path.basename(model_path)
            diff_results.setdefault(model_filename, dict())
            model, model_ver, notifications = api.validate_model(model_path)
            if model is None:
                head, tail = os.path.split(filename)
                report_path = os.path.join(
                    head, '{}_structural_report.html'.format(model_filename))
                api.validation_report(
                    model_path, notifications, report_path)
                LOGGER.critical(
                    "The model {} could not be loaded due to SBML errors "
                    "reported in {}.".format(model_filename, report_path))
                continue
            model.solver = solver
            model_and_model_ver_tuple.append((model, model_ver))
        except (IOError, SBMLError):
            LOGGER.debug(exc_info=True)
            LOGGER.warning("An error occurred while loading the model '%s'. "
                           "Skipping.", model_filename)
    # Abort the diff report unless at least two models can be loaded
    # successfully.
    if len(model_and_model_ver_tuple) < 2:
        LOGGER.critical(
            "Out of the %d provided models only %d could be loaded. Please, "
            "check if the models that could not be loaded are valid SBML. "
            "Aborting.",
            len(models), len(model_and_model_ver_tuple))
        sys.exit(1)
    # Running pytest in individual processes to avoid interference
    partial_test_diff = partial(_test_diff, pytest_args=pytest_args,
                                skip=skip, exclusive=exclusive,
                                experimental=experimental)
    pool = Pool(min(len(models), cpu_count()))
    results = pool.map(partial_test_diff, model_and_model_ver_tuple)

    for model_path, result in zip(models, results):
        model_filename = os.path.basename(model_path)
        diff_results[model_filename] = result

    with open(filename, "w", encoding="utf-8") as file_handle:
        LOGGER.info("Writing diff report to '%s'.", filename)
        file_handle.write(api.diff_report(diff_results, config))

Response: Generate a diff report for all the supplied models.


Instruction:
Can you create a Python 3 function that
inspects and record the repo s branches and their history.

Response:
def build_branch_structure(self, model, skip):
        """Inspect and record the repo's branches and their history."""
        self._history = dict()
        self._history["commits"] = commits = dict()
        self._history["branches"] = branches = dict()
        for branch in self._repo.refs:
            LOGGER.debug(branch.name)
            if branch.name in skip:
                continue
            branches[branch.name] = branch_history = list()
            latest = branch.commit
            history = [latest] + list(latest.iter_parents())
            for commit in history:
                # Find model in committed files.
                if not is_modified(model, commit):
                    LOGGER.info(
                        "The model was not modified in commit '{}'. "
                        "Skipping.".format(commit))
                    continue
                branch_history.append(commit.hexsha)
                if commit.hexsha not in commits:
                    commits[commit.hexsha] = sub = dict()
                    sub["timestamp"] = commit.authored_datetime.isoformat(" ")
                    sub["author"] = commit.author.name
                    sub["email"] = commit.author.email
        LOGGER.debug("%s", json.dumps(self._history, indent=2))


Instruction:
Given the following Python 3 function, write the documentation
def load_history(self, model, skip={"gh-pages"}):
        if self._history is None:
            self.build_branch_structure(model, skip)
        self._results = dict()
        all_commits = list(self._history["commits"])
        for commit in all_commits:
            try:
                self._results[commit] = self.manager.load(commit)
            except (IOError, NoResultFound) as err:
                LOGGER.error("Could not load result '%s'.", commit)
                LOGGER.debug("%s", str(err))

Response: Load the entire results history into memory.


Instruction:
Can you create a Python 3 function that
returns an individual result from the history if it exists.

Response:
def get_result(self, commit, default=MemoteResult()):
        """Return an individual result from the history if it exists."""
        assert self._results is not None, \
            "Please call the method `load_history` first."
        return self._results.get(commit, default)


Instruction:
Write a Python 3 script for
returning the maximum and minimum absolute non - zero coefficients.

Response:
def absolute_extreme_coefficient_ratio(model):
    """
    Return the maximum and minimum absolute, non-zero coefficients.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    """
    s_matrix, _, _ = con_helpers.stoichiometry_matrix(
        model.metabolites, model.reactions
    )
    abs_matrix = np.abs(s_matrix)
    return abs_matrix.max(), abs_matrix[abs_matrix > 0].min()


Instruction:
Can you generate a brief explanation for the following Python 3 code
def number_independent_conservation_relations(model):
    s_matrix, _, _ = con_helpers.stoichiometry_matrix(
        model.metabolites, model.reactions
    )
    ln_matrix = con_helpers.nullspace(s_matrix.T)
    return ln_matrix.shape[1]

Response: Returns the number of independent conserved metabolite pools.


Instruction:
Can you write a function in Python 3 where it
returns the rank of the stoichiometric matrix of the metabolic model.

Response:
def matrix_rank(model):
    """
    Return the rank of the model's stoichiometric matrix.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    """
    s_matrix, _, _ = con_helpers.stoichiometry_matrix(
        model.metabolites, model.reactions
    )
    return con_helpers.rank(s_matrix)


Instruction:
Make a summary of the following Python 3 code
def degrees_of_freedom(model):
    s_matrix, _, _ = con_helpers.stoichiometry_matrix(
        model.metabolites, model.reactions
    )
    return s_matrix.shape[1] - matrix_rank(model)

Response: Returns the degrees of freedom of the system.


Instruction:
Write a Python 3 function for
loading all information from an experimental configuration file.

Response:
def load(self, model):
        """
        Load all information from an experimental configuration file.

        Parameters
        ----------
        model : cobra.Model
            The metabolic model under investigation.

        """
        self.load_medium(model)
        self.load_essentiality(model)
        self.load_growth(model)
        # self.load_experiment(config.config.get("growth"), model)
        return self


Instruction:
Can you implement a function in Python 3 that
validates the configuration file.

Response:
def validate(self):
        """Validate the configuration file."""
        validator = Draft4Validator(self.SCHEMA)
        if not validator.is_valid(self.config):
            for err in validator.iter_errors(self.config):
                LOGGER.error(str(err.message))
            validator.validate(self.config)


Instruction:
Can you tell what is the following Python 3 function doing
def load_medium(self, model):
        media = self.config.get("medium")
        if media is None:
            return
        definitions = media.get("definitions")
        if definitions is None or len(definitions) == 0:
            return
        path = self.get_path(media, join("data", "experimental", "media"))
        for medium_id, medium in iteritems(definitions):
            if medium is None:
                medium = dict()
            filename = medium.get("filename")
            if filename is None:
                filename = join(path, "{}.csv".format(medium_id))
            elif not isabs(filename):
                filename = join(path, filename)
            tmp = Medium(identifier=medium_id, obj=medium, filename=filename)
            tmp.load()
            tmp.validate(model)
            self.media[medium_id] = tmp

Response: Load and validate all media.


Instruction:
Can you implement a function in Python 3 that
loads and validate all data files.

Response:
def load_essentiality(self, model):
        """Load and validate all data files."""
        data = self.config.get("essentiality")
        if data is None:
            return
        experiments = data.get("experiments")
        if experiments is None or len(experiments) == 0:
            return
        path = self.get_path(data,
                             join("data", "experimental", "essentiality"))
        for exp_id, exp in iteritems(experiments):
            if exp is None:
                exp = dict()
            filename = exp.get("filename")
            if filename is None:
                filename = join(path, "{}.csv".format(exp_id))
            elif not isabs(filename):
                filename = join(path, filename)
            experiment = EssentialityExperiment(
                identifier=exp_id, obj=exp, filename=filename)
            if experiment.medium is not None:
                assert experiment.medium in self.media, \
                    "Experiment '{}' has an undefined medium '{}'.".format(
                        exp_id, experiment.medium)
                experiment.medium = self.media[experiment.medium]
            experiment.load()
            experiment.validate(model)
            self.essentiality[exp_id] = experiment


Instruction:
How would you explain what the following Python 3 function does
def load_growth(self, model):
        data = self.config.get("growth")
        if data is None:
            return
        experiments = data.get("experiments")
        if experiments is None or len(experiments) == 0:
            return
        path = self.get_path(data,
                             join("data", "experimental", "growth"))
        for exp_id, exp in iteritems(experiments):
            if exp is None:
                exp = dict()
            filename = exp.get("filename")
            if filename is None:
                filename = join(path, "{}.csv".format(exp_id))
            elif not isabs(filename):
                filename = join(path, filename)
            growth = GrowthExperiment(
                identifier=exp_id, obj=exp, filename=filename)
            if growth.medium is not None:
                assert growth.medium in self.media, \
                    "Growth-experiment '{}' has an undefined medium '{}'." \
                    "".format(exp_id, growth.medium)
                growth.medium = self.media[growth.medium]
            growth.load()
            growth.validate(model)
            self.growth[exp_id] = growth

Response: Load and validate all data files.


Instruction:
Given the following Python 3 function, write the documentation
def get_path(self, obj, default):
        path = obj.get("path")
        if path is None:
            path = join(self._base, default)
        if not isabs(path):
            path = join(self._base, path)
        return path

Response: Return a relative or absolute path to experimental data.


Instruction:
Create a Python 3 function for
finding model components with empty annotation attributes.

Response:
def find_components_without_annotation(model, components):
    """
    Find model components with empty annotation attributes.

    Parameters
    ----------
    model : cobra.Model
        A cobrapy metabolic model.
    components : {"metabolites", "reactions", "genes"}
        A string denoting `cobra.Model` components.

    Returns
    -------
    list
        The components without any annotation.

    """
    return [elem for elem in getattr(model, components) if
            elem.annotation is None or len(elem.annotation) == 0]


Instruction:
How would you implement a function in Python 3 that
returns a list of elements whose annotation matches the pattern for the given MIRIAM database identifier.

Response:
def generate_component_annotation_miriam_match(elements, component, db):
    """
    Tabulate which MIRIAM databases the element's annotation match.

    If the relevant MIRIAM identifier is not in an element's annotation it is
    ignored.

    Parameters
    ----------
    elements : list
        Elements of a model, either metabolites or reactions.
    component : {"metabolites", "reactions"}
        A string denoting a type of ``cobra.Model`` component.
    db : str
        One of the MIRIAM database identifiers.

    Returns
    -------
    list
        The components whose annotation does not match the pattern for the
        MIRIAM database.

    """
    def is_faulty(annotation, key, pattern):
        # Ignore missing annotation for this database.
        if key not in annotation:
            return False
        test = annotation[key]
        if isinstance(test, native_str):
            return pattern.match(test) is None
        else:
            return any(pattern.match(elem) is None for elem in test)

    pattern = {
        "metabolites": METABOLITE_ANNOTATIONS,
        "reactions": REACTION_ANNOTATIONS,
        "genes": GENE_PRODUCT_ANNOTATIONS
    }[component][db]
    return [elem for elem in elements
            if is_faulty(elem.annotation, db, pattern)]


Instruction:
Can you write a function in Python 3 where it
generates a table of unique component identifiers for a given set of components.

Response:
def generate_component_id_namespace_overview(model, components):
    """
    Tabulate which MIRIAM databases the component's identifier matches.

    Parameters
    ----------
    model : cobra.Model
        A cobrapy metabolic model.
    components : {"metabolites", "reactions", "genes"}
        A string denoting `cobra.Model` components.

    Returns
    -------
    pandas.DataFrame
        The index of the table is given by the component identifiers. Each
        column corresponds to one MIRIAM database and a Boolean entry
        determines whether the annotation matches.

    """
    patterns = {
        "metabolites": METABOLITE_ANNOTATIONS,
        "reactions": REACTION_ANNOTATIONS,
        "genes": GENE_PRODUCT_ANNOTATIONS
    }[components]
    databases = list(patterns)
    data = list()
    index = list()
    for elem in getattr(model, components):
        index.append(elem.id)
        data.append(tuple(patterns[db].match(elem.id) is not None
                          for db in databases))
    df = pd.DataFrame(data, index=index, columns=databases)
    if components != "genes":
        # Clean up of the dataframe. Unfortunately the Biocyc patterns match
        # broadly. Hence, whenever a Metabolite or Reaction ID matches to any
        # DB pattern AND the Biocyc pattern we have to assume that this is a
        # false positive.
        # First determine all rows in which 'biocyc' and other entries are
        # True simultaneously and use this Boolean series to create another
        # column temporarily.
        df['duplicate'] = df[df['biocyc']].sum(axis=1) >= 2
        # Replace all nan values with False
        df['duplicate'].fillna(False, inplace=True)
        # Use the additional column to index the original dataframe to identify
        # false positive biocyc hits and set them to False.
        df.loc[df['duplicate'], 'biocyc'] = False
        # Delete the additional column
        del df['duplicate']
    return df


Instruction:
Write a Python 3 script for
computing a representation of the confusion matrix.

Response:
def confusion_matrix(predicted_essential, expected_essential,
                     predicted_nonessential, expected_nonessential):
    """
    Compute a representation of the confusion matrix.

    Parameters
    ----------
    predicted_essential : set
    expected_essential : set
    predicted_nonessential : set
    expected_nonessential : set

    Returns
    -------
    dict
        Confusion matrix as different keys of a dictionary. The abbreviated
        keys correspond to the ones used in [1]_.

    References
    ----------
    .. [1] `Wikipedia entry for the Confusion matrix
           <https://en.wikipedia.org/wiki/Confusion_matrix>`_

    """
    true_positive = predicted_essential & expected_essential
    tp = len(true_positive)
    true_negative = predicted_nonessential & expected_nonessential
    tn = len(true_negative)
    false_positive = predicted_essential - expected_essential
    fp = len(false_positive)
    false_negative = predicted_nonessential - expected_nonessential
    fn = len(false_negative)
    # sensitivity or true positive rate
    try:
        tpr = tp / (tp + fn)
    except ZeroDivisionError:
        tpr = None
    # specificity or true negative rate
    try:
        tnr = tn / (tn + fp)
    except ZeroDivisionError:
        tnr = None
    # precision or positive predictive value
    try:
        ppv = tp / (tp + fp)
    except ZeroDivisionError:
        ppv = None
    # false discovery rate
    fdr = 1 - ppv
    # accuracy
    try:
        acc = (tp + tn) / (tp + tn + fp + fn)
    except ZeroDivisionError:
        acc = None
    # Compute Matthews correlation coefficient.
    try:
        mcc = (tp * tn - fp * fn) /\
              sqrt((tp + fp) * (tp + fn) * (tn + fp) * (tn + fn))
    except ZeroDivisionError:
        mcc = None
    return {
        "TP": list(true_positive),
        "TN": list(true_negative),
        "FP": list(false_positive),
        "FN": list(false_negative),
        "TPR": tpr,
        "TNR": tnr,
        "PPV": ppv,
        "FDR": fdr,
        "ACC": acc,
        "MCC": mcc
    }


Instruction:
Here you have a function in Python 3, explain what it does
def validate_model(path):
    notifications = {"warnings": [], "errors": []}
    model, sbml_ver = val.load_cobra_model(path, notifications)
    return model, sbml_ver, notifications

Response: Validate a metabolic model file and optionally store results as JSON.


Instruction:
Write a Python 3 function for
generating a snapshot report from a result set and configuration.

Response:
def snapshot_report(result, config=None, html=True):
    """
    Generate a snapshot report from a result set and configuration.

    Parameters
    ----------
    result : memote.MemoteResult
        Nested dictionary structure as returned from the test suite.
    config : dict, optional
        The final test report configuration (default None).
    html : bool, optional
        Whether to render the report as full HTML or JSON (default True).

    """
    if config is None:
        config = ReportConfiguration.load()
    report = SnapshotReport(result=result, configuration=config)
    if html:
        return report.render_html()
    else:
        return report.render_json()


Instruction:
Write a Python 3 function for
testing a model and save a history report.

Response:
def history_report(history, config=None, html=True):
    """
    Test a model and save a history report.

    Parameters
    ----------
    history : memote.HistoryManager
        The manager grants access to previous results.
    config : dict, optional
        The final test report configuration.
    html : bool, optional
        Whether to render the report as full HTML or JSON (default True).

    """
    if config is None:
        config = ReportConfiguration.load()
    report = HistoryReport(history=history, configuration=config)
    if html:
        return report.render_html()
    else:
        return report.render_json()


Instruction:
Explain what the following Python 3 code does
def diff_report(diff_results, config=None, html=True):
    if config is None:
        config = ReportConfiguration.load()
    report = DiffReport(diff_results=diff_results, configuration=config)
    if html:
        return report.render_html()
    else:
        return report.render_json()

Response: Generate a diff report from a result set and configuration.


Instruction:
Make a summary of the following Python 3 code
def validation_report(path, notifications, filename):
    env = Environment(
        loader=PackageLoader('memote.suite', 'templates'),
        autoescape=select_autoescape(['html', 'xml'])
    )
    template = env.get_template('validation_template.html')
    model = os.path.basename(path)
    with open(filename, "w") as file_h:
        file_h.write(template.render(model=model, notifications=notifications))

Response: Generate a validation report from a notification object.


Instruction:
Implement a Python 3 function for
loading a test report configuration.

Response:
def load(cls, filename=None):
        """Load a test report configuration."""
        if filename is None:
            LOGGER.debug("Loading default configuration.")
            with open_text(templates, "test_config.yml",
                           encoding="utf-8") as file_handle:
                content = yaml.load(file_handle)
        else:
            LOGGER.debug("Loading custom configuration '%s'.", filename)
            try:
                with open(filename, encoding="utf-8") as file_handle:
                    content = yaml.load(file_handle)
            except IOError as err:
                LOGGER.error(
                    "Failed to load the custom configuration '%s'. Skipping.",
                    filename)
                LOGGER.debug(str(err))
                content = dict()
        return cls(content)


Instruction:
Write a Python 3 function for
finding unique elements of both branches of the top level logical AND and the right of the top level logical AND.

Response:
def find_top_level_complex(gpr):
    """
    Find unique elements of both branches of the top level logical AND.

    Parameters
    ----------
    gpr : str
        The gene-protein-reaction association as a string.

    Returns
    -------
    int
        The size of the symmetric difference between the set of elements to
        the left of the top level logical AND and the right set.

    """
    logger.debug("%r", gpr)
    conform = logical_and.sub("and", gpr)
    conform = logical_or.sub("or", conform)
    conform = escape_chars.sub("_", conform)
    expression = ast.parse(conform)
    walker = GPRVisitor()
    walker.visit(expression)
    return len(walker.left ^ walker.right)


Instruction:
Create a Python 3 function to
set up recording of elements with this hook.

Response:
def visit_BoolOp(self, node):
        """Set up recording of elements with this hook."""
        if self._is_top and isinstance(node.op, ast.And):
            self._is_top = False
            self._current = self.left
            self.visit(node.values[0])
            self._current = self.right
            for successor in node.values[1:]:
                self.visit(successor)
        else:
            self.generic_visit(node)


Instruction:
Can you tell what is the following Python 3 function doing
def find_nonzero_constrained_reactions(model):
    lower_bound, upper_bound = helpers.find_bounds(model)
    return [rxn for rxn in model.reactions if
            0 > rxn.lower_bound > lower_bound or
            0 < rxn.upper_bound < upper_bound]

Response: Return list of reactions with non - zero non - maximal bounds.


Instruction:
Given the following Python 3 function, write the documentation
def find_zero_constrained_reactions(model):
    return [rxn for rxn in model.reactions if
            rxn.lower_bound == 0 and
            rxn.upper_bound == 0]

Response: Return list of reactions that are constrained to zero flux.


Instruction:
Can you generate the documentation for the following Python 3 function
def find_unconstrained_reactions(model):
    lower_bound, upper_bound = helpers.find_bounds(model)
    return [rxn for rxn in model.reactions if
            rxn.lower_bound <= lower_bound and
            rxn.upper_bound >= upper_bound]

Response: Return list of reactions that are not constrained at all.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def find_ngam(model):
    atp_adp_conv_rxns = helpers.find_converting_reactions(
        model, ("MNXM3", "MNXM7")
    )
    id_of_main_compartment = helpers.find_compartment_id_in_model(model, 'c')

    reactants = {
        helpers.find_met_in_model(model, "MNXM3", id_of_main_compartment)[0],
        helpers.find_met_in_model(model, "MNXM2", id_of_main_compartment)[0]
    }

    products = {
        helpers.find_met_in_model(model, "MNXM7", id_of_main_compartment)[0],
        helpers.find_met_in_model(model, "MNXM1", id_of_main_compartment)[0],
        helpers.find_met_in_model(model, "MNXM9", id_of_main_compartment)[0]
    }

    candidates = [rxn for rxn in atp_adp_conv_rxns
                  if rxn.reversibility is False and
                  set(rxn.reactants) == reactants and
                  set(rxn.products) == products]

    buzzwords = ['maintenance', 'atpm', 'requirement',
                 'ngam', 'non-growth', 'associated']

    refined_candidates = [rxn for rxn in candidates if any(
        string in filter_none(rxn.name, '').lower() for string in buzzwords
    )]

    if refined_candidates:
        return refined_candidates
    else:
        return candidates

Response: u Return all potential non growth - associated maintenance reactions.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def calculate_metabolic_coverage(model):
    if len(model.reactions) == 0 or len(model.genes) == 0:
        raise ValueError("The model contains no reactions or genes.")
    return float(len(model.reactions)) / float(len(model.genes))

Response: u Return the ratio of reactions and genes included in the given model.


Instruction:
Can you generate the documentation for the following Python 3 function
def find_protein_complexes(model):
    complexes = []
    for rxn in model.reactions:
        if not rxn.gene_reaction_rule:
            continue
        size = find_top_level_complex(rxn.gene_reaction_rule)
        if size >= 2:
            complexes.append(rxn)
    return complexes

Response: Returns a list of reactions that are catalyzed by at least one protein - reaction association.


Instruction:
Given the following Python 3 function, write the documentation
def is_constrained_reaction(model, rxn):
    lower_bound, upper_bound = helpers.find_bounds(model)
    if rxn.reversibility:
        return rxn.lower_bound > lower_bound or rxn.upper_bound < upper_bound
    else:
        return rxn.lower_bound > 0 or rxn.upper_bound < upper_bound

Response: Return whether a reaction has fixed constraints.


Instruction:
Here you have a function in Python 3, explain what it does
def find_oxygen_reactions(model):
    o2_in_model = helpers.find_met_in_model(model, "MNXM4")
    return set([rxn for met in model.metabolites for
                rxn in met.reactions if met.formula == "O2" or
                met in o2_in_model])

Response: Return list of oxygen - produces and - consuming reactions.


Instruction:
Here you have a function in Python 3, explain what it does
def find_unique_metabolites(model):
    unique = set()
    for met in model.metabolites:
        is_missing = True
        for comp in model.compartments:
            if met.id.endswith("_{}".format(comp)):
                unique.add(met.id[:-(len(comp) + 1)])
                is_missing = False
                break
        if is_missing:
            unique.add(met.id)
    return unique

Response: Return set of metabolite IDs without duplicates from compartments.


Instruction:
Create a Python 3 function to
return list of metabolites with duplicates in the same compartment. This function identifies duplicate metabolites in each compartment by determining if any two metabolites have identical InChI-key annotations. For instance, this function would find compounds with IDs ATP1 and ATP2 in the cytosolic compartment, with both having the same InChI annotations. Parameters ---------- model : cobra.Model The metabolic model under investigation. Returns ------- list A list of tuples of duplicate metabolites.

Response:
def find_duplicate_metabolites_in_compartments(model):
    """
    Return list of metabolites with duplicates in the same compartment.

    This function identifies duplicate metabolites in each compartment by
    determining if any two metabolites have identical InChI-key annotations.
    For instance, this function would find compounds with IDs ATP1 and ATP2 in
    the cytosolic compartment, with both having the same InChI annotations.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    Returns
    -------
    list
        A list of tuples of duplicate metabolites.

    """
    unique_identifiers = ["inchikey", "inchi"]
    duplicates = []
    for met_1, met_2 in combinations(model.metabolites, 2):
        if met_1.compartment == met_2.compartment:
            for key in unique_identifiers:
                if key in met_1.annotation and key in met_2.annotation:
                    if met_1.annotation[key] == met_2.annotation[key]:
                        duplicates.append((met_1.id, met_2.id))
                        break
    return duplicates


Instruction:
Write a Python 3 script to
find duplicate reactions based on identical annotations.

Response:
def find_reactions_with_partially_identical_annotations(model):
    """
    Return duplicate reactions based on identical annotation.

    Identify duplicate reactions globally by checking if any two metabolic
    reactions have the same entries in their annotation attributes. This can be
    useful to identify one 'type' of reactions that occurs in several
    compartments, to curate merged models or to clean-up bulk model
    modifications. The heuristic looks at annotations with the keys
    "metanetx.reaction", "kegg.reaction", "brenda", "rhea", "biocyc",
    "bigg.reaction" only.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    Returns
    -------
    dict
        A mapping from sets of annotations to groups of reactions with those
        annotations.
    int
        The total number of unique reactions that are duplicated.

    """
    duplicates = {}
    rxn_db_identifiers = ["metanetx.reaction", "kegg.reaction", "brenda",
                          "rhea", "biocyc", "bigg.reaction"]
    # Build a list that associates a reaction with a set of its annotations.
    ann_rxns = []
    for rxn in model.reactions:
        ann = []
        for key in rxn_db_identifiers:
            if key in rxn.annotation:
                if isinstance(rxn.annotation[key], list):
                    ann.extend([(key, elem) for elem in rxn.annotation[key]])
                else:
                    ann.append((key, rxn.annotation[key]))
        ann_rxns.append((rxn, frozenset(ann)))
    # Compute the intersection between annotations and record the matching
    # reaction identifiers.
    for (rxn_a, ann_a), (rxn_b, ann_b) in combinations(ann_rxns, 2):
        mutual_pair = tuple(ann_a & ann_b)
        if len(mutual_pair) > 0:
            duplicates.setdefault(mutual_pair, set()).update(
                [rxn_a.id, rxn_b.id])
    # Transform the object for JSON compatibility
    num_duplicated = set()
    duplicated = {}
    for key in duplicates:
        # Object keys must be strings in JSON.
        new_key = ",".join(sorted("{}:{}".format(ns, term) for ns, term in key))
        duplicated[new_key] = rxns = list(duplicates[key])
        num_duplicated.update(rxns)
    return duplicated, len(num_duplicated)


Instruction:
Create a Python 3 function for
mapping metabolites to structural space indexes.

Response:
def map_metabolites_to_structures(metabolites, compartments):
    """
    Map metabolites from the identifier namespace to structural space.

    Metabolites who lack structural annotation (InChI or InChIKey) are ignored.

    Parameters
    ----------
    metabolites : iterable
        The cobra.Metabolites to map.
    compartments : iterable
        The different compartments to consider. Structures are treated
        separately for each compartment.

    Returns
    -------
    dict
        A mapping from a cobra.Metabolite to its compartment specific
        structure index.

    """
    # TODO (Moritz Beber): Consider SMILES?
    unique_identifiers = ["inchikey", "inchi"]
    met2mol = {}
    molecules = {c: [] for c in compartments}
    for met in metabolites:
        ann = []
        for key in unique_identifiers:
            mol = met.annotation.get(key)
            if mol is not None:
                ann.append(mol)
        # Ignore metabolites without the required information.
        if len(ann) == 0:
            continue
        ann = set(ann)
        # Compare with other structures in the same compartment.
        mols = molecules[met.compartment]
        for i, mol_group in enumerate(mols):
            if len(ann & mol_group) > 0:
                mol_group.update(ann)
                # We map to the index of the group because it is hashable and
                # cheaper to compare later.
                met2mol[met] = "{}-{}".format(met.compartment, i)
                break
        if met not in met2mol:
            # The length of the list corresponds to the 0-index after appending.
            met2mol[met] = "{}-{}".format(met.compartment, len(mols))
            mols.append(ann)
    return met2mol


Instruction:
Can you generate the documentation for the following Python 3 function
def find_duplicate_reactions(model):
    met2mol = map_metabolites_to_structures(model.metabolites,
                                            model.compartments)
    # Build a list associating reactions with their stoichiometry in molecular
    # structure space.
    structural = []
    for rxn in model.reactions:
        # Ignore reactions that have metabolites without structures.
        if not all(met in met2mol for met in rxn.metabolites):
            continue
        # We consider substrates and products separately since, for example,
        # the InChI for H2O and OH is the same.
        substrates = {
            met2mol[met]: rxn.get_coefficient(met) for met in rxn.reactants
        }
        products = {
            met2mol[met]: rxn.get_coefficient(met) for met in rxn.products
        }
        structural.append((rxn, substrates, products))
    # Compare reactions using their structure-based stoichiometries.
    num_duplicated = set()
    duplicates = []
    for (rxn_a, sub_a, prod_a), (rxn_b, sub_b, prod_b) in combinations(
            structural, 2):
        # Compare the substrates.
        if sub_a != sub_b:
            continue
        # Compare the products.
        if prod_a != prod_b:
            continue
        # Compare whether they are both (ir-)reversible.
        if rxn_a.reversibility != rxn_b.reversibility:
            continue
        # TODO (Moritz Beber): We could compare bounds here but it might be
        #  worth knowing about the reactions even if their bounds differ?
        duplicates.append((rxn_a.id, rxn_b.id))
        num_duplicated.add(rxn_a.id)
        num_duplicated.add(rxn_b.id)
    return duplicates, len(num_duplicated)

Response: Find duplicate reactions in a single structure.


Instruction:
Given the following Python 3 function, write the documentation
def find_reactions_with_identical_genes(model):
    duplicates = dict()
    for rxn_a, rxn_b in combinations(model.reactions, 2):
        if not (rxn_a.genes and rxn_b.genes):
            continue
        if rxn_a.genes == rxn_b.genes:
            # This works because the `genes` are frozen sets.
            identifiers = rxn_a.genes
            duplicates.setdefault(identifiers, set()).update(
                [rxn_a.id, rxn_b.id])
    # Transform the object for JSON compatibility
    num_duplicated = set()
    duplicated = {}
    for key in duplicates:
        # Object keys must be strings in JSON.
        new_key = ",".join(sorted(g.id for g in key))
        duplicated[new_key] = rxns = list(duplicates[key])
        num_duplicated.update(rxns)
    return duplicated, len(num_duplicated)

Response: Find reactions that have identical genes.


Instruction:
Write a Python 3 function that can
return the list of metabolites ingested by the model.

Response:
def find_medium_metabolites(model):
    """Return the list of metabolites ingested/excreted by the model."""
    return [met.id for rxn in model.medium
            for met in model.reactions.get_by_id(rxn).metabolites]


Instruction:
Given the following Python 3 function, write the documentation
def find_external_metabolites(model):
    ex_comp = find_external_compartment(model)
    return [met for met in model.metabolites if met.compartment == ex_comp]

Response: Return all metabolites in the external compartment.


Instruction:
Can you generate the documentation for the following Python 3 function
def store(self, result, filename, pretty=True):
        LOGGER.info("Storing result in '%s'.", filename)
        if filename.endswith(".gz"):
            with gzip.open(filename, "wb") as file_handle:
                file_handle.write(
                    jsonify(result, pretty=pretty).encode("utf-8")
                )
        else:
            with open(filename, "w", encoding="utf-8") as file_handle:
                file_handle.write(jsonify(result, pretty=pretty))

Response: Store a result in the given file.


Instruction:
Here you have a function in Python 3, explain what it does
def load(self, filename):
        LOGGER.info("Loading result from '%s'.", filename)
        if filename.endswith(".gz"):
            with gzip.open(filename, "rb") as file_handle:
                result = MemoteResult(
                    json.loads(file_handle.read().decode("utf-8"))
                )
        else:
            with open(filename, "r", encoding="utf-8") as file_handle:
                result = MemoteResult(json.load(file_handle))
        # TODO (Moritz Beber): Validate the read-in JSON maybe? Trade-off
        #  between extra time taken and correctness. Maybe we re-visit this
        #  issue when there was a new JSON format version needed.
        return result

Response: Load a result from the given JSON file.


Instruction:
Can you generate the documentation for the following Python 3 function
def load_cobra_model(path, notifications):
    doc = libsbml.readSBML(path)
    fbc = doc.getPlugin("fbc")
    sbml_ver = doc.getLevel(), doc.getVersion(), fbc if fbc is None else \
        fbc.getVersion()
    with catch_warnings(record=True) as warnings:
        simplefilter("always")
        try:
            model = read_sbml_model(path)
        except Exception as err:
            notifications['errors'].append(str(err))
            model = None
            validate = True
        else:
            validate = False
        notifications['warnings'].extend([str(w.message) for w in warnings])
    if validate:
        run_sbml_validation(doc, notifications)
    return model, sbml_ver

Response: Load a COBRA model with meta information from an SBML document.


Instruction:
How would you explain what the following Python 3 function does
def format_failure(failure):
    return "Line {}, Column {} - #{}: {} - Category: {}, Severity: {}".format(
        failure.getLine(),
        failure.getColumn(),
        failure.getErrorId(),
        failure.getMessage(),
        failure.getCategoryAsString(),
        failure.getSeverity()
    )

Response: Format a failure message.


Instruction:
Implement a Python 3 function for
validating an SBML document and report errors and warnings.

Response:
def run_sbml_validation(document, notifications):
    """Report errors and warnings found in an SBML document."""
    validator = libsbml.SBMLValidator()
    validator.validate(document)
    for i in range(document.getNumErrors()):
        notifications['errors'].append(format_failure(document.getError(i)))
    for i in range(validator.getNumFailures()):
        failure = validator.getFailure(i)
        if failure.isWarning():
            notifications['warnings'].append(format_failure(failure))
        else:
            notifications['errors'].append(format_failure(failure))