# Path: cameo/core/result.py
# class Result(object):
#     def __init__(self, *args, **kwargs):
#         super(Result, self).__init__(*args, **kwargs)
#         self._meta_information = MetaInformation()
# 
#     @property
#     def meta_information(self):
#         return self._meta_information
# 
#     @property
#     def data_frame(self):
#         raise NotImplementedError
# 
#     def plot(self, grid=None, width=None, height=None, title=None, *args, **kwargs):
#         raise NotImplementedError
# 
# Path: cameo/core/target.py
# class EnsembleTarget(Target):
#     """
#     A Target resulting of merging multiple Targets.
#     For example:
#         1. ReactionKnockinTarget
#         2. ReactionModulationTarget
# 
#     The Targets are prioritized by what should happen first in order to don't break.
# 
#     """
# 
#     def __init__(self, id, targets):
#         super(EnsembleTarget, self).__init__(id)
#         assert all(t.id == id for t in targets)
#         self.targets = list(sorted(targets))
# 
#     def apply(self, model):
#         for target in self.targets:
#             target.apply(model)
# 
#     def __repr__(self):
#         head = "<EnsembleTarget %s" % self.id
#         body = ", ".join("%i - %s" % (i, str(target)) for i, target in enumerate(self.targets))
#         end = ">"
# 
#         return head + "|" + body + "|" + end
# 
#     def to_gnomic(self):
#         raise NotImplementedError
# 
#     def _repr_html_(self):
#         return "|" + ";".join(target._repr_html_() for target in self.targets) + '|'
# 
#     def __gt__(self, other):
#         if isinstance(other, EnsembleTarget):
#             return self.id > other.id
# 
#         else:
#             is_greater = False
#             for t in self.targets:
#                 is_greater = is_greater or t >= other
# 
#     def __eq__(self, other):
#         if isinstance(other, EnsembleTarget):
#             if len(self.targets) == len(other.targets):
#                 return all(target == other.targets[i] for i, target in enumerate(self.targets))
# 
#         return False
# 
#     def __str__(self):
#         return "%s[%s]" % (self.id, ", ".join(str(t) for t in self.targets))
# 
#     def __hash__(self):
#         return hash(str(self))
# 
# class Target(object):
#     """
#     A Target is element of a COBRA model that will change to achieve a given phenotype.
#     They are identified by StrainDesignMethod.run when identifying which manipulations
#     are necessary to improve some fitness function.
# 
#     Attributes
#     ----------
#     id : str
#         The identifier of the target. The id must be present in the COBRA model.
#     accession_id : str (optional)
#         An accession identifier in a database.
#     accession_db : str (optional)
#         The database corresponding to `accession_id`.
#     """
# 
#     def __init__(self, id, accession_id=None, accession_db=None):
#         self.id = id
#         self.accession_id = accession_id
#         self.accession_db = accession_db
# 
#     def apply(self, model):
#         """Apply the modification to the target, depending on the type."""
#         raise NotImplementedError
# 
#     def __eq__(self, other):
#         if isinstance(other, Target):
#             return other.id == self.id
#         else:
#             return False
# 
#     def __gt__(self, other):
#         return self.id > other.id
# 
#     def to_gnomic(self):
#         """
#         If gnomic is available, return a Gnomic representation of the Target.
# 
#         """
#         if self.accession_id:
#             if self.accession_db:
#                 return Accession(identifier=self.accession_id, database=self.accession_db)
#             else:
#                 return Accession(identifier=self.accession_id)
#         else:
#             return None
# 
#     def __repr__(self):
#         return "<Target %s>" % self.id
# 
#     def __str__(self):
#         return self.id
# 
#     def __hash__(self):
#         return hash(str(self))


import sys
from cobra import DictList
from pandas import DataFrame
from cameo.core.result import Result
from cameo.core.target import EnsembleTarget, Target
from gnomic import Genotype
        targets = {}
        for target in self.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)

        for target in other.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)

        targets = [next(iter(t)) if len(t) == 1 else EnsembleTarget(id, t) for id, t in targets.items()]

        return StrainDesign(targets)

    def __iadd__(self, other):
        if not isinstance(other, StrainDesign):
            raise AssertionError("Only instances of StrainDesign can be added together")

        targets = {}
        for target in self.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)

        for target in other.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)


# Path: cameo/core/result.py
# class Result(object):
#     def __init__(self, *args, **kwargs):
#         super(Result, self).__init__(*args, **kwargs)
#         self._meta_information = MetaInformation()
# 
#     @property
#     def meta_information(self):
#         return self._meta_information
# 
#     @property
#     def data_frame(self):
#         raise NotImplementedError
# 
#     def plot(self, grid=None, width=None, height=None, title=None, *args, **kwargs):
#         raise NotImplementedError
# 
# Path: cameo/core/target.py
# class EnsembleTarget(Target):
#     """
#     A Target resulting of merging multiple Targets.
#     For example:
#         1. ReactionKnockinTarget
#         2. ReactionModulationTarget
# 
#     The Targets are prioritized by what should happen first in order to don't break.
# 
#     """
# 
#     def __init__(self, id, targets):
#         super(EnsembleTarget, self).__init__(id)
#         assert all(t.id == id for t in targets)
#         self.targets = list(sorted(targets))
# 
#     def apply(self, model):
#         for target in self.targets:
#             target.apply(model)
# 
#     def __repr__(self):
#         head = "<EnsembleTarget %s" % self.id
#         body = ", ".join("%i - %s" % (i, str(target)) for i, target in enumerate(self.targets))
#         end = ">"
# 
#         return head + "|" + body + "|" + end
# 
#     def to_gnomic(self):
#         raise NotImplementedError
# 
#     def _repr_html_(self):
#         return "|" + ";".join(target._repr_html_() for target in self.targets) + '|'
# 
#     def __gt__(self, other):
#         if isinstance(other, EnsembleTarget):
#             return self.id > other.id
# 
#         else:
#             is_greater = False
#             for t in self.targets:
#                 is_greater = is_greater or t >= other
# 
#     def __eq__(self, other):
#         if isinstance(other, EnsembleTarget):
#             if len(self.targets) == len(other.targets):
#                 return all(target == other.targets[i] for i, target in enumerate(self.targets))
# 
#         return False
# 
#     def __str__(self):
#         return "%s[%s]" % (self.id, ", ".join(str(t) for t in self.targets))
# 
#     def __hash__(self):
#         return hash(str(self))
# 
# class Target(object):
#     """
#     A Target is element of a COBRA model that will change to achieve a given phenotype.
#     They are identified by StrainDesignMethod.run when identifying which manipulations
#     are necessary to improve some fitness function.
# 
#     Attributes
#     ----------
#     id : str
#         The identifier of the target. The id must be present in the COBRA model.
#     accession_id : str (optional)
#         An accession identifier in a database.
#     accession_db : str (optional)
#         The database corresponding to `accession_id`.
#     """
# 
#     def __init__(self, id, accession_id=None, accession_db=None):
#         self.id = id
#         self.accession_id = accession_id
#         self.accession_db = accession_db
# 
#     def apply(self, model):
#         """Apply the modification to the target, depending on the type."""
#         raise NotImplementedError
# 
#     def __eq__(self, other):
#         if isinstance(other, Target):
#             return other.id == self.id
#         else:
#             return False
# 
#     def __gt__(self, other):
#         return self.id > other.id
# 
#     def to_gnomic(self):
#         """
#         If gnomic is available, return a Gnomic representation of the Target.
# 
#         """
#         if self.accession_id:
#             if self.accession_db:
#                 return Accession(identifier=self.accession_id, database=self.accession_db)
#             else:
#                 return Accession(identifier=self.accession_id)
#         else:
#             return None
# 
#     def __repr__(self):
#         return "<Target %s>" % self.id
# 
#     def __str__(self):
#         return self.id
# 
#     def __hash__(self):
#         return hash(str(self))


# Path: cameo/core/strain_design.py
import sys
from cobra import DictList
from pandas import DataFrame
from cameo.core.result import Result
from cameo.core.target import EnsembleTarget, Target
from gnomic import Genotype

        targets = {}
        for target in self.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)

        for target in other.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)

        targets = [next(iter(t)) if len(t) == 1 else EnsembleTarget(id, t) for id, t in targets.items()]

        return StrainDesign(targets)

    def __iadd__(self, other):
        if not isinstance(other, StrainDesign):
            raise AssertionError("Only instances of StrainDesign can be added together")

        targets = {}
        for target in self.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)

        for target in other.targets:
            if target.id not in targets:
                targets[target.id] = set()
            targets[target.id].add(target)


        targets = [next(iter(t)) if len(t) == 1 else EnsembleTarget(id, t) for id, t in targets.items()]