nodes: 0, module; 1, function_definition; 2, function_name:connections_from_graph; 3, parameters; 4, block; 5, identifier:env; 6, identifier:G; 7, default_parameter; 8, expression_statement; 9, if_statement; 10, if_statement; 11, expression_statement; 12, if_statement; 13, comment:# Sort agent addresses to the order they were added to the environment.; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, expression_statement; 18, identifier:edge_data; 19, False; 20, comment:"""Create connections for agents in the given environment from the given
      NetworkX graph structure.
  
      :param env:
          Environment where the agents live. The environment should be derived
          from :class:`~creamas.core.environment.Environment`,
          :class:`~creamas.mp.MultiEnvironment` or
          :class:`~creamas.ds.DistributedEnvironment`.
  
      :param G:
          NetworkX graph structure, either :class:`networkx.graph.Graph` or
          :class:`networkx.digraph.DiGraph`. The graph needs to have the same
          number of nodes as the environment has agents (excluding the managers).
  
      :param bool edge_data:
          If ``True``, edge data from the given graph is copied to the agents'
          :attr:`connections`.
  
      .. 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`.
      """; 21, not_operator; 22, block; 23, not_operator; 24, block; 25, assignment; 26, comparison_operator:len(addrs) != len(G); 27, block; 28, assignment; 29, call; 30, assignment; 31, call; 32, call; 33, raise_statement; 34, call; 35, raise_statement; 36, identifier:addrs; 37, call; 38, call; 39, call; 40, raise_statement; 41, identifier:addrs; 42, call; 43, identifier:_addrs2nodes; 44, argument_list; 45, identifier:conn_map; 46, call; 47, attribute; 48, argument_list; 49, identifier:issubclass; 50, argument_list; 51, call; 52, identifier:hasattr; 53, argument_list; 54, call; 55, attribute; 56, argument_list; 57, identifier:len; 58, argument_list; 59, identifier:len; 60, argument_list; 61, call; 62, identifier:sort_addrs; 63, argument_list; 64, identifier:addrs; 65, identifier:G; 66, identifier:_edges2conns; 67, argument_list; 68, identifier:env; 69, identifier:create_connections; 70, identifier:conn_map; 71, attribute; 72, tuple; 73, identifier:TypeError; 74, argument_list; 75, identifier:env; 76, string; 77, identifier:TypeError; 78, argument_list; 79, identifier:env; 80, identifier:get_agents; 81, keyword_argument; 82, identifier:addrs; 83, identifier:G; 84, identifier:ValueError; 85, argument_list; 86, identifier:addrs; 87, identifier:G; 88, identifier:edge_data; 89, identifier:G; 90, identifier:__class__; 91, identifier:Graph; 92, identifier:DiGraph; 93, concatenated_string; 94, string_content:get_agents; 95, string:"Parameter 'env' must have get_agents."; 96, identifier:addr; 97, True; 98, call; 99, string:"Graph structure must be derived from Networkx's "; 100, string:"Graph or DiGraph."; 101, attribute; 102, argument_list; 103, concatenated_string; 104, identifier:format; 105, call; 106, call; 107, string:"The number of graph nodes and agents in the "; 108, string:"environment (excluding the manager agent) must "; 109, string:"match. Now got {} nodes and {} agents."; 110, identifier:len; 111, argument_list; 112, identifier:len; 113, argument_list; 114, identifier:G; 115, identifier:addrs
code: def connections_from_graph(env, G, edge_data=False):
      """Create connections for agents in the given environment from the given
      NetworkX graph structure.
  
      :param env:
          Environment where the agents live. The environment should be derived
          from :class:`~creamas.core.environment.Environment`,
          :class:`~creamas.mp.MultiEnvironment` or
          :class:`~creamas.ds.DistributedEnvironment`.
  
      :param G:
          NetworkX graph structure, either :class:`networkx.graph.Graph` or
          :class:`networkx.digraph.DiGraph`. The graph needs to have the same
          number of nodes as the environment has agents (excluding the managers).
  
      :param bool edge_data:
          If ``True``, edge data from the given graph is copied to the agents'
          :attr:`connections`.
  
      .. 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)
      _addrs2nodes(addrs, G)
      conn_map = _edges2conns(G, edge_data)
      env.create_connections(conn_map)