# Path: creamas/util.py
# def sort_addrs(addrs):
#     """Return agent addresses in a sorted order.
# 
#     Agent addresses are sorted with following hierarchical criteria:
#         1. by the host of an agent's environment
#         2. by the port (interpreted as an integer) of an agent's environment
#         3. by the order in which the agents were created in their environment
# 
#     For example, the following list of addresses::
# 
#         ['tcp://bnode:5555/0',
#          'tcp://anode:5555/0',
#          'tcp://anode:50/1',
#          'tcp://anode:5555/2',
#          'tcp://anode:50/2',
#          'tcp://anode:18000/0',
#          'tcp://bnode:50/0',
#          'tcp://bnode:18000/0',
#          'tcp://anode:18000/1',
#          'tcp://anode:18000/2',
#          'tcp://bnode:50/1',
#          'tcp://bnode:5555/2',
#          'tcp://bnode:5555/1',
#          'tcp://bnode:50/2',
#          'tcp://bnode:18000/2',
#          'tcp://anode:50/0',
#          'tcp://bnode:18000/1',
#          'tcp://anode:5555/1']
# 
#     would be sorted into the following order::
# 
#         ['tcp://anode:50/0',
#          'tcp://anode:50/1',
#          'tcp://anode:50/2',
#          'tcp://anode:5555/0',
#          'tcp://anode:5555/1',
#          'tcp://anode:5555/2',
#          'tcp://anode:18000/0',
#          'tcp://anode:18000/1',
#          'tcp://anode:18000/2',
#          'tcp://bnode:50/0',
#          'tcp://bnode:50/1',
#          'tcp://bnode:50/2',
#          'tcp://bnode:5555/0',
#          'tcp://bnode:5555/1',
#          'tcp://bnode:5555/2',
#          'tcp://bnode:18000/0',
#          'tcp://bnode:18000/1',
#          'tcp://bnode:18000/2']
# 
#     :param list addrs: List of addresses to be sorted.
# 
#     :returns:
#         List of addresses in a sorted order.
#     """
#     return sorted(addrs, key=lambda x: _addr_key(x))


from networkx import Graph, DiGraph
from creamas.util import sort_addrs
    .. note::

        By design, manager agents are excluded from the connections and should
        not be counted towards environment's agent count.

    The created connections are stored in each agent's
    :attr:`~creamas.core.agent.CreativeAgent.connections` and the possible
    edge data is stored as key-value pairs in the connection dictionary.

    The agents are sorted by their environments' hosts and ports before each
    agent is mapped to a node in **G**. This should cause some network
    generation methods in NetworkX, e.g.
    :func:`~networkx.generators.random_graphs.connected_watts_strogatz_graph`,
    to create more connections between agents in the same environment and/or
    node when using :class:`~creamas.mp.MultiEnvironment` or
    :class:`~creamas.ds.DistributedEnvironment`.
    """
    if not issubclass(G.__class__, (Graph, DiGraph)):
        raise TypeError("Graph structure must be derived from Networkx's "
                        "Graph or DiGraph.")
    if not hasattr(env, 'get_agents'):
        raise TypeError("Parameter 'env' must have get_agents.")

    addrs = env.get_agents(addr=True)
    if len(addrs) != len(G):
        raise ValueError("The number of graph nodes and agents in the "
                         "environment (excluding the manager agent) must "
                         "match. Now got {} nodes and {} agents."
                         .format(len(G), len(addrs)))
    # Sort agent addresses to the order they were added to the environment.

# Path: creamas/util.py
# def sort_addrs(addrs):
#     """Return agent addresses in a sorted order.
# 
#     Agent addresses are sorted with following hierarchical criteria:
#         1. by the host of an agent's environment
#         2. by the port (interpreted as an integer) of an agent's environment
#         3. by the order in which the agents were created in their environment
# 
#     For example, the following list of addresses::
# 
#         ['tcp://bnode:5555/0',
#          'tcp://anode:5555/0',
#          'tcp://anode:50/1',
#          'tcp://anode:5555/2',
#          'tcp://anode:50/2',
#          'tcp://anode:18000/0',
#          'tcp://bnode:50/0',
#          'tcp://bnode:18000/0',
#          'tcp://anode:18000/1',
#          'tcp://anode:18000/2',
#          'tcp://bnode:50/1',
#          'tcp://bnode:5555/2',
#          'tcp://bnode:5555/1',
#          'tcp://bnode:50/2',
#          'tcp://bnode:18000/2',
#          'tcp://anode:50/0',
#          'tcp://bnode:18000/1',
#          'tcp://anode:5555/1']
# 
#     would be sorted into the following order::
# 
#         ['tcp://anode:50/0',
#          'tcp://anode:50/1',
#          'tcp://anode:50/2',
#          'tcp://anode:5555/0',
#          'tcp://anode:5555/1',
#          'tcp://anode:5555/2',
#          'tcp://anode:18000/0',
#          'tcp://anode:18000/1',
#          'tcp://anode:18000/2',
#          'tcp://bnode:50/0',
#          'tcp://bnode:50/1',
#          'tcp://bnode:50/2',
#          'tcp://bnode:5555/0',
#          'tcp://bnode:5555/1',
#          'tcp://bnode:5555/2',
#          'tcp://bnode:18000/0',
#          'tcp://bnode:18000/1',
#          'tcp://bnode:18000/2']
# 
#     :param list addrs: List of addresses to be sorted.
# 
#     :returns:
#         List of addresses in a sorted order.
#     """
#     return sorted(addrs, key=lambda x: _addr_key(x))


# Path: creamas/nx.py
from networkx import Graph, DiGraph
from creamas.util import sort_addrs

    .. note::

        By design, manager agents are excluded from the connections and should
        not be counted towards environment's agent count.

    The created connections are stored in each agent's
    :attr:`~creamas.core.agent.CreativeAgent.connections` and the possible
    edge data is stored as key-value pairs in the connection dictionary.

    The agents are sorted by their environments' hosts and ports before each
    agent is mapped to a node in **G**. This should cause some network
    generation methods in NetworkX, e.g.
    :func:`~networkx.generators.random_graphs.connected_watts_strogatz_graph`,
    to create more connections between agents in the same environment and/or
    node when using :class:`~creamas.mp.MultiEnvironment` or
    :class:`~creamas.ds.DistributedEnvironment`.
    """
    if not issubclass(G.__class__, (Graph, DiGraph)):
        raise TypeError("Graph structure must be derived from Networkx's "
                        "Graph or DiGraph.")
    if not hasattr(env, 'get_agents'):
        raise TypeError("Parameter 'env' must have get_agents.")

    addrs = env.get_agents(addr=True)
    if len(addrs) != len(G):
        raise ValueError("The number of graph nodes and agents in the "
                         "environment (excluding the manager agent) must "
                         "match. Now got {} nodes and {} agents."
                         .format(len(G), len(addrs)))
    # Sort agent addresses to the order they were added to the environment.

    addrs = sort_addrs(addrs)