# Path: wallace/models.py
# class Info(Base, SharedMixin):
#     """A unit of information."""
# 
#     __tablename__ = "info"
# 
#     #: a String giving the name of the class. Defaults to "info".
#     #: This allows subclassing.
#     type = Column(String(50))
#     __mapper_args__ = {
#         'polymorphic_on': type,
#         'polymorphic_identity': 'info'
#     }
# 
#     #: the id of the Node that created the info
#     origin_id = Column(Integer, ForeignKey('node.id'), index=True)
# 
#     #: the Node that created the info.
#     origin = relationship(Node, backref='all_infos')
# 
#     #: the id of the network the info is in
#     network_id = Column(Integer, ForeignKey('network.id'), index=True)
# 
#     #: the network the info is in
#     network = relationship(Network, backref="all_infos")
# 
#     #: the contents of the info. Must be stored as a String.
#     contents = Column(Text(), default=None)
# 
#     def __init__(self, origin, contents=None):
#         """Create an info."""
#         # check the origin hasn't failed
#         if origin.failed:
#             raise ValueError("{} cannot create an info as it has failed"
#                              .format(origin))
# 
#         self.origin = origin
#         self.origin_id = origin.id
#         self.contents = contents
#         self.network_id = origin.network_id
#         self.network = origin.network
# 
#     @validates("contents")
#     def _write_once(self, key, value):
#         existing = getattr(self, key)
#         if existing is not None:
#             raise ValueError("The contents of an info is write-once.")
#         return value
# 
#     def __repr__(self):
#         """The string representation of an info."""
#         return "Info-{}-{}".format(self.id, self.type)
# 
#     def __json__(self):
#         """The json representation of an info."""
#         return {
#             "id": self.id,
#             "type": self.type,
#             "origin_id": self.origin_id,
#             "network_id": self.network_id,
#             "creation_time": self.creation_time,
#             "failed": self.failed,
#             "time_of_death": self.time_of_death,
#             "contents": self.contents,
#             "property1": self.property1,
#             "property2": self.property2,
#             "property3": self.property3,
#             "property4": self.property4,
#             "property5": self.property5
#         }
# 
#     def fail(self):
#         """Fail an info.
# 
#         Set info.failed to True and :attr:`~wallace.models.Info.time_of_death`
#         to now. Instruct all transmissions and transformations involving this
#         info to fail.
#         """
#         if self.failed is True:
#             raise AttributeError(
#                 "Cannot fail {} - it has already failed.".format(self))
#         else:
#             self.failed = True
#             self.time_of_death = timenow()
# 
#             for t in self.transmissions():
#                 t.fail()
#             for t in self.transformations():
#                 t.fail()
# 
#     def transmissions(self, status="all"):
#         """Get all the transmissions of this info.
# 
#         status can be all/pending/received.
#         """
#         if status not in ["all", "pending", "received"]:
#             raise(ValueError("You cannot get transmission of status {}."
#                              .format(status) +
#                              "Status can only be pending, received or all"))
#         if status == "all":
#             return Transmission\
#                 .query\
#                 .filter_by(info_id=self.id,
#                            failed=False)\
#                 .all()
#         else:
#             return Transmission\
#                 .query\
#                 .filterby(info_id=self.id,
#                           status=status,
#                           failed=False)\
#                 .all()
# 
#     def transformations(self, relationship="all"):
#         """Get all the transformations of this info.
# 
#         Return a list of transformations involving this info. ``relationship``
#         can be "parent" (in which case only transformations where the info is
#         the ``info_in`` are returned), "child" (in which case only
#         transformations where the info is the ``info_out`` are returned) or
#         ``all`` (in which case any transformations where the info is the
#         ``info_out`` or the ``info_in`` are returned). The default is ``all``
# 
#         """
#         if relationship not in ["all", "parent", "child"]:
#             raise(ValueError(
#                 "You cannot get transformations of relationship {}"
#                 .format(relationship) +
#                 "Relationship can only be parent, child or all."))
# 
#         if relationship == "all":
#             return Transformation\
#                 .query\
#                 .filter(and_(Transformation.failed == False,
#                              or_(Transformation.info_in == self,
#                                  Transformation.info_out == self)))\
#                 .all()
# 
#         if relationship == "parent":
#             return Transformation\
#                 .query\
#                 .filter_by(info_in_id=self.id,
#                            failed=False)\
#                 .all()
# 
#         if relationship == "child":
#             return Transformation\
#                 .query\
#                 .filter_by(info_out_id=self.id,
#                            failed=False)\
#                 .all()
# 
#     def _mutated_contents(self):
#         """The mutated contents of an info.
# 
#         When an info is asked to mutate, this method will be executed
#         in order to determine the contents of the new info created.
# 
#         The base class function raises an error and so must be overwritten
#         to be used.
#         """
#         raise NotImplementedError(
#             "_mutated_contents needs to be overwritten in class {}"
#             .format(type(self)))


from .models import Info
"""Subclasses of information."""



class Gene(Info):
    """A gene."""

    __mapper_args__ = {
        "polymorphic_identity": "gene"
    }



# Path: wallace/models.py
# class Info(Base, SharedMixin):
#     """A unit of information."""
# 
#     __tablename__ = "info"
# 
#     #: a String giving the name of the class. Defaults to "info".
#     #: This allows subclassing.
#     type = Column(String(50))
#     __mapper_args__ = {
#         'polymorphic_on': type,
#         'polymorphic_identity': 'info'
#     }
# 
#     #: the id of the Node that created the info
#     origin_id = Column(Integer, ForeignKey('node.id'), index=True)
# 
#     #: the Node that created the info.
#     origin = relationship(Node, backref='all_infos')
# 
#     #: the id of the network the info is in
#     network_id = Column(Integer, ForeignKey('network.id'), index=True)
# 
#     #: the network the info is in
#     network = relationship(Network, backref="all_infos")
# 
#     #: the contents of the info. Must be stored as a String.
#     contents = Column(Text(), default=None)
# 
#     def __init__(self, origin, contents=None):
#         """Create an info."""
#         # check the origin hasn't failed
#         if origin.failed:
#             raise ValueError("{} cannot create an info as it has failed"
#                              .format(origin))
# 
#         self.origin = origin
#         self.origin_id = origin.id
#         self.contents = contents
#         self.network_id = origin.network_id
#         self.network = origin.network
# 
#     @validates("contents")
#     def _write_once(self, key, value):
#         existing = getattr(self, key)
#         if existing is not None:
#             raise ValueError("The contents of an info is write-once.")
#         return value
# 
#     def __repr__(self):
#         """The string representation of an info."""
#         return "Info-{}-{}".format(self.id, self.type)
# 
#     def __json__(self):
#         """The json representation of an info."""
#         return {
#             "id": self.id,
#             "type": self.type,
#             "origin_id": self.origin_id,
#             "network_id": self.network_id,
#             "creation_time": self.creation_time,
#             "failed": self.failed,
#             "time_of_death": self.time_of_death,
#             "contents": self.contents,
#             "property1": self.property1,
#             "property2": self.property2,
#             "property3": self.property3,
#             "property4": self.property4,
#             "property5": self.property5
#         }
# 
#     def fail(self):
#         """Fail an info.
# 
#         Set info.failed to True and :attr:`~wallace.models.Info.time_of_death`
#         to now. Instruct all transmissions and transformations involving this
#         info to fail.
#         """
#         if self.failed is True:
#             raise AttributeError(
#                 "Cannot fail {} - it has already failed.".format(self))
#         else:
#             self.failed = True
#             self.time_of_death = timenow()
# 
#             for t in self.transmissions():
#                 t.fail()
#             for t in self.transformations():
#                 t.fail()
# 
#     def transmissions(self, status="all"):
#         """Get all the transmissions of this info.
# 
#         status can be all/pending/received.
#         """
#         if status not in ["all", "pending", "received"]:
#             raise(ValueError("You cannot get transmission of status {}."
#                              .format(status) +
#                              "Status can only be pending, received or all"))
#         if status == "all":
#             return Transmission\
#                 .query\
#                 .filter_by(info_id=self.id,
#                            failed=False)\
#                 .all()
#         else:
#             return Transmission\
#                 .query\
#                 .filterby(info_id=self.id,
#                           status=status,
#                           failed=False)\
#                 .all()
# 
#     def transformations(self, relationship="all"):
#         """Get all the transformations of this info.
# 
#         Return a list of transformations involving this info. ``relationship``
#         can be "parent" (in which case only transformations where the info is
#         the ``info_in`` are returned), "child" (in which case only
#         transformations where the info is the ``info_out`` are returned) or
#         ``all`` (in which case any transformations where the info is the
#         ``info_out`` or the ``info_in`` are returned). The default is ``all``
# 
#         """
#         if relationship not in ["all", "parent", "child"]:
#             raise(ValueError(
#                 "You cannot get transformations of relationship {}"
#                 .format(relationship) +
#                 "Relationship can only be parent, child or all."))
# 
#         if relationship == "all":
#             return Transformation\
#                 .query\
#                 .filter(and_(Transformation.failed == False,
#                              or_(Transformation.info_in == self,
#                                  Transformation.info_out == self)))\
#                 .all()
# 
#         if relationship == "parent":
#             return Transformation\
#                 .query\
#                 .filter_by(info_in_id=self.id,
#                            failed=False)\
#                 .all()
# 
#         if relationship == "child":
#             return Transformation\
#                 .query\
#                 .filter_by(info_out_id=self.id,
#                            failed=False)\
#                 .all()
# 
#     def _mutated_contents(self):
#         """The mutated contents of an info.
# 
#         When an info is asked to mutate, this method will be executed
#         in order to determine the contents of the new info created.
# 
#         The base class function raises an error and so must be overwritten
#         to be used.
#         """
#         raise NotImplementedError(
#             "_mutated_contents needs to be overwritten in class {}"
#             .format(type(self)))


# Path: wallace/information.py
from .models import Info

"""Subclasses of information."""



class Gene(Info):
    """A gene."""

    __mapper_args__ = {
        "polymorphic_identity": "gene"
    }



class Meme(Info):