<commit_before>"""
-------
Convert
-------

This module provides functions to convert 
NetworkX graphs to and from other formats.

The preferred way of converting data to a NetworkX graph 
is through the graph constuctor.  The constructor calls
the from_whatever() function which attempts to guess the
input type and convert it automatically.

Examples
--------

Create a 10 node random graph from a numpy matrix

>>> import numpy
>>> a=numpy.reshape(numpy.random.random_integers(0,1,size=100),(10,10))
>>> D=nx.DiGraph(a) 

or equivalently

>>> D=nx.from_whatever(a,create_using=nx.DiGraph()) 

Create a graph with a single edge from a dictionary of dictionaries

>>> d={0: {1: 1}} # dict-of-dicts single edge (0,1)
>>> G=nx.Graph(d)


See Also
--------
For graphviz dot formats see networkx.drawing.nx_pygraphviz
or networkx.drawing.nx_pydot.

"""
__author__ = """<NAME> (<EMAIL>)"""
#    Copyright (C) 2006-2008 by 
#    <NAME> <<EMAIL>>
#    <NAME> <<EMAIL>>
#    <NAME> <<EMAIL>>
#    All rights reserved.
#    BSD license.


__all__ = ['from_whatever', 
           'from_dict_of_dicts', 'to_dict_of_dicts',
           'from_dict_of_lists', 'to_dict_of_lists',
           'from_edgelist', 'to_edgelist',
           'from_numpy_matrix', 'to_numpy_matrix',
           'from_scipy_sparse_matrix', 'to_scipy_sparse_matrix']

import networkx
import warnings

def _prep_create_using(create_using):
    """Return a graph object ready to be populated.

    If create_using is None return the default (just networkx.Graph())
    If create_using.clear() works, assume it returns a graph object.
    Otherwise raise an exception because create_using is not a networkx graph.

    """
    if create_using is None:
        G=networkx.Graph()
    else:
        G=create_using
        try:
            G.clear()
        except:
            raise TypeError("Input graph is not a networkx graph type")
    return G

def from_whatever(thing,create_using=None,multigraph_input=False):
    """Make a NetworkX graph from an known type.

    The preferred way to call this is automatically
    from the class constructor

    >>> d={0: {1: {'weight':1}}} # dict-of-dicts single edge (0,1)
    >>> G=nx.Graph(d)
    
    instead of the equivalent

    >>> G=nx.from_dict_of_dicts(d)

    Parameters
    ----------
    thing : a object to be converted
       Current known types are:
         any NetworkX graph
         dict-of-dicts
         dist-of-lists
         list of edges
         numpy matrix
         numpy ndarray
         scipy sparse matrix
         pygraphviz agraph

    create_using : NetworkX graph
       Use specified graph for result.  Otherwise a new graph is created.

    multigraph_input : bool (default False)
      If True and  thing is a dict_of_dicts,
      try to create a multigraph assuming dict_of_dict_of_lists.
      If thing and create_using are both multigraphs then create
      a multigraph from a multigraph.

    """
    # NX graph
    if hasattr(thing,"adj"):
        try:
            result= from_dict_of_dicts(thing.adj,\
                    create_using=create_using,\
                    multigraph_input=thing.is_multigraph())
            if hasattr(thing,'graph') and isinstance(thing.graph,dict):
                result.graph=thing.graph.copy()
            if hasattr(thing,'node') and isinstance(thing.node,dict):
                result.node=dict( (n,dd.copy()) for n,dd in thing.node.iteritems() )
            return result
        except:
            raise networkx.NetworkXError,\
                "Input is not a correct NetworkX graph."

    # pygraphviz  agraph
    if hasattr(thing,"is_strict"):
        try:
            return networkx.from_agraph(thing,create_using=create_using)
        except:
            raise networkx.NetworkXError,\
                  "Input is not a correct pygraphviz graph."

    # dict of dicts/lists
    if isinstance(thing,dict):
        try:
            return from_dict_of_dicts(thing,create_using=create_using,\
                    multigraph_input=multigraph_input)
        except:
            try:
                return from_dict_of_lists(thing,create_using=create_using)
            except:
                raise TypeError("Input is not known type.")

    # list or generator of edges
    if isinstance(thing,list) or hasattr(thing,'next'): 
        try:
            return from_edgelist(thing,create_using=create_using)
        except:
            raise networkx.NetworkXError,\
                  "Input is not a valid edge list"

    # numpy matrix or ndarray 
    try:
        import numpy
        if isinstance(thing,numpy.matrix) or \
               isinstance(thing,numpy.ndarray):
            try:
                return from_numpy_matrix(thing,create_using=create_using)
            except:
                raise networkx.NetworkXError,\
                  "Input is not a correct numpy matrix or array."
    except ImportError:
        warnings.warn('numpy not found, skipping conversion test.',
                      ImportWarning)

    # scipy sparse matrix - any format
    try:
        import scipy
        if hasattr(thing,"format"):
            try:
                return from_scipy_sparse_matrix(thing,create_using=create_using)
            except:
                raise networkx.NetworkXError, \
                      "Input is not a correct scipy sparse matrix type."
    except ImportError:
        warnings.warn('scipy not found, skipping conversion test.',
                      ImportWarning)


    raise networkx.NetworkXError, \
          "Input is not a known data type for conversion."

    return 

def to_dict_of_lists(G,nodelist=None):
    """Return adjacency representation of graph as a dictionary of lists

    Parameters
    ----------<commit_msg>Change name of from_whatever() to to_networkx_graph().<commit_after>"""
-------
Convert
-------

This module provides functions to convert 
NetworkX graphs to and from other formats.

The preferred way of converting data to a NetworkX graph 
is through the graph constuctor.  The constructor calls
the to_networkx_graph() function which attempts to guess the
input type and convert it automatically.

Examples
--------

Create a 10 node random graph from a numpy matrix

>>> import numpy
>>> a=numpy.reshape(numpy.random.random_integers(0,1,size=100),(10,10))
>>> D=nx.DiGraph(a) 

or equivalently

>>> D=nx.to_networkx_graph(a,create_using=nx.DiGraph()) 

Create a graph with a single edge from a dictionary of dictionaries

>>> d={0: {1: 1}} # dict-of-dicts single edge (0,1)
>>> G=nx.Graph(d)


See Also
--------
For graphviz dot formats see networkx.drawing.nx_pygraphviz
or networkx.drawing.nx_pydot.

"""
__author__ = """\n""".join(['<NAME> (<EMAIL>)',
                           '<NAME> (<EMAIL>)',
                           '<NAME>(<EMAIL>)'])
#    Copyright (C) 2006-2010 by 
#    <NAME> <<EMAIL>>
#    <NAME> <<EMAIL>>
#    <NAME> <<EMAIL>>
#    All rights reserved.
#    BSD license.


__all__ = ['to_networkx_graph','from_whatever', 
           'from_dict_of_dicts', 'to_dict_of_dicts',
           'from_dict_of_lists', 'to_dict_of_lists',
           'from_edgelist', 'to_edgelist',
           'from_numpy_matrix', 'to_numpy_matrix',
           'from_scipy_sparse_matrix', 'to_scipy_sparse_matrix']

import networkx
import warnings

def _prep_create_using(create_using):
    """Return a graph object ready to be populated.

    If create_using is None return the default (just networkx.Graph())
    If create_using.clear() works, assume it returns a graph object.
    Otherwise raise an exception because create_using is not a networkx graph.

    """
    if create_using is None:
        G=networkx.Graph()
    else:
        G=create_using
        try:
            G.clear()
        except:
            raise TypeError("Input graph is not a networkx graph type")
    return G

def to_networkx_graph(thing,create_using=None,multigraph_input=False):
    """Make a NetworkX graph from an known type.

    The preferred way to call this is automatically
    from the class constructor

    >>> d={0: {1: {'weight':1}}} # dict-of-dicts single edge (0,1)
    >>> G=nx.Graph(d)
    
    instead of the equivalent

    >>> G=nx.from_dict_of_dicts(d)

    Parameters
    ----------
    thing : a object to be converted
       Current known types are:
         any NetworkX graph
         dict-of-dicts
         dist-of-lists
         list of edges
         numpy matrix
         numpy ndarray
         scipy sparse matrix
         pygraphviz agraph

    create_using : NetworkX graph
       Use specified graph for result.  Otherwise a new graph is created.

    multigraph_input : bool (default False)
      If True and  thing is a dict_of_dicts,
      try to create a multigraph assuming dict_of_dict_of_lists.
      If thing and create_using are both multigraphs then create
      a multigraph from a multigraph.

    """
    # NX graph
    if hasattr(thing,"adj"):
        try:
            result= from_dict_of_dicts(thing.adj,\
                    create_using=create_using,\
                    multigraph_input=thing.is_multigraph())
            if hasattr(thing,'graph') and isinstance(thing.graph,dict):
                result.graph=thing.graph.copy()
            if hasattr(thing,'node') and isinstance(thing.node,dict):
                result.node=dict( (n,dd.copy()) for n,dd in thing.node.iteritems() )
            return result
        except:
            raise networkx.NetworkXError,\
                "Input is not a correct NetworkX graph."

    # pygraphviz  agraph
    if hasattr(thing,"is_strict"):
        try:
            return networkx.from_agraph(thing,create_using=create_using)
        except:
            raise networkx.NetworkXError,\
                  "Input is not a correct pygraphviz graph."

    # dict of dicts/lists
    if isinstance(thing,dict):
        try:
            return from_dict_of_dicts(thing,create_using=create_using,\
                    multigraph_input=multigraph_input)
        except:
            try:
                return from_dict_of_lists(thing,create_using=create_using)
            except:
                raise TypeError("Input is not known type.")

    # list or generator of edges
    if isinstance(thing,list) or hasattr(thing,'next'): 
        try:
            return from_edgelist(thing,create_using=create_using)
        except:
            raise networkx.NetworkXError,\
                  "Input is not a valid edge list"

    # numpy matrix or ndarray 
    try:
        import numpy
        if isinstance(thing,numpy.matrix) or \
               isinstance(thing,numpy.ndarray):
            try:
                return from_numpy_matrix(thing,create_using=create_using)
            except:
                raise networkx.NetworkXError,\
                  "Input is not a correct numpy matrix or array."
    except ImportError:
        warnings.warn('numpy not found, skipping conversion test.',
                      ImportWarning)

    # scipy sparse matrix - any format
    try:
        import scipy
        if hasattr(thing,"format"):
            try:
                return from_scipy_sparse_matrix(thing,create_using=create_using)
            except:
                raise networkx.NetworkXError, \
                      "Input is not a correct scipy sparse matrix type."
    except ImportError:
        warnings.warn('scipy not found, skipping conversion test.',
                      ImportWarning)


    raise networkx.NetworkXError, \
          "Input is not a known data type for conversion."

    return 

    

def from_whatever(thing,create_using=None,multigraph_input=False):
    """Deprecated. Use to_networkx_graph.

    See Also
    --------
    to_networkx_graph()
    """

    return to_networkx_graph(thing,
                             create_using=create_using,
                             multigraph_input=multigraph_input)

def to_dict_of_lists(G,nodelist=None):
    """Return adjacency representation of graph as a dictionary of lists

    Parameters
    ----------
{'fraction_non_alphanumeric': 0.09243697478991597, 'fraction_numerical': 0.004825692653298943, 'mean_word_length': 2.2372744411527066, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7515357', 'n_tokens_mistral': 3544, 'n_tokens_neox': 3380, 'n_words': 994}