New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
updated functions in core.py
#7027
Conversation
The functions now raise for a multigraph, but they still don't raise when self-loops are present. (except for Also note that this changes the previous behavior -- before this, a MultiGraph object with no multi-edges worked. So, if we decide to do it this way, we'll need to deprecate that behavior for two minor version releases. That means we can't use the The wording in the doc_strings does not align with NetworkX terminology either. It talks about parallel edges instead of multiedges, for example. sigh Seems like |
@dschult , In the recent 3 commits, I have made the following changes :
The Thank you :) |
I think your example for parallel edges does give the correct paths, but not the correct edge id because you need a As for the optional |
@dschult I've updated the docs according to the code. I added another exception in the Thank you :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make all appropriate errors NetworkXNotImplemented
(e.g. by changing line 581). But in all the functions, we can make it raise that exception for self-loops and for multigraph and/or directed.
The history is that NetworkXError
used to be the only exception type with messages determining what the problem is. We shifted to multiple exception types later and have only incrementally been updating exceptions. This seems like a good time to do that. It also simplifies the Raises
section.
Also, I think we should not mention that the code could work for multigraphs if the core_number is provided. While a carefully constructed dic for core_number might let the code give an answer, there is no well-defined core number for multigraphs and so the returned answer would not make sense. The core_number
input is supposed to be created by core_number and that doesn't allow multigraphs. So, let's just return to the raises comment that the function is not defined for graphs with self loops or parallel edges
. (with directed in there too when appropriate).
The wording involving dict
s and the meaning of the key and value was carefully chosen to be short and hopefully consistent with the following syntax:
... a dict keyed by <some description of the key> to <some description of the value>
e.g.: A dict keyed by node to its core number.
The import
statements in each example should be removed. All examples in NetworkX assume that import networkx as nx
has been done before the example is used.
I like the vertex
-> node
changes and the examples seem good! :}
Thanks
networkx/algorithms/core.py
Outdated
NetworkXError | ||
The onion decomposition is not implemented for graphs with self loops | ||
or parallel edges or for directed graphs. | ||
The onion decomposition is not implemented for graphs with self loops. | ||
NetworkXNotImplemented | ||
If `G` is a Multigraph or Directed graph. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make both of these errors NetworkXNotImplemented
(line 581).
The other functions can be handled similarly. The history is that NetworkXError
used to be the only exception type with messages determining what the problem is. We shifted to multiple exception types later and have only incrementally been updating exceptions. This seems like a good time to do that.
@dschult thank you for the review. I've made the suggested changes. Please let me know if this looks good to you. I think we should add Thank you :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we combine the two reasons for nx.NetworkXNotImplemented
since the type of the error is the same? Something like:
The k-core is not implemented for graphs with self-loops or for multigraphs.
I will ask that you not use capital letters for Multigraph
and Directed graph
so they don't get confused with the classes (which has capital letters to start each part of the name). Capitals at the start of the sentence are fine. Otherwise lets pretend that multigraph is a real word and use lowercase. :) Pretty nit-picky... but it's good to be nit-picky sometimes. :}
For the calls of the exceptions, can we use the prefix nx.
instead of the special import at the top? This might change other code, but it is arguably more clear and avoids an import at the top. There is a simmilar issue/question about whether to import not_implemented_for
specially at the top, or use nx.utils.not_implemented_for(...
in every call. I prefer the latter because if you forget where the function is from, you don't have to scroll to the top to find out. It says where it is from. Both forms show up a lot in networkx for sure. And I'm not sure if there is universal agreement on this issue. :}
Thanks for these changes!
@dschult thank you for the review. I've made the suggested changes. Please let me know if this looks good to you :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm approving this -- looks good.
Just as I say that, I notice that you used .nodes()
in the examples to create the NodeView. That is probably preferred to be the attribute (though the method formulation is available for backward compatibility). So, just .nodes
is perhaps more aligned with .nodes
and .edges
being attributes. I'm Ok with leaving it this way too.
I think this is ready for another pair of eyes! :}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and applied the "parallel edges" -> "multigraph" feedback to the other remaining instances in the docstrings.
Let's make all appropriate errors NetworkXNotImplemented (e.g. by changing line 581). But in all the functions, we can make it raise that exception for self-loops and for multigraph and/or directed.
One unfortunate consequence of changing the exception type is that this will break folks who are explicitly catching NetworkXError
exceptions in try-except statements. If NetworkXNotImplementedError
inherited from NetworkXError
I don't think this would be an issue, but that's not currently the case.
This is a very minor API break as a result of the cleanup, so I'm not inclined to have it be a blocker - I just wanted to make sure others are aware of the behavior change!
Everything else LGTM so I'll approve but let someone else merge after seeing this comment!
@rossbar , but we can pass multigraph objects in the import networkx as nx
G = nx.Graph()
G.add_edges_from([(1, 2),(2, 3)])
cn = nx.core_number(G)
G = nx.MultiGraph(G)
print(nx.k_shell(G, k=1, core_number = cn))
# output : MultiGraph with 3 nodes and 2 edges So, there won't be any Also, earlier @dschult suggested to keep it
So that's why I suggested maybe we should consider adding
Thank you :) |
The issue doesn't have to do with the multigraph instances, but rather with the changing exception type itself. Here's a concrete example; the following code will run fine in networkx 3.2: >>> import networkx as nx
>>> G = nx.complete_graph(5)
>>> G.add_edge(1, 1)
>>> try:
... nx.core_number(G)
... except nx.NetworkXError:
... print("Caught it")
Caught it However, because this PR changes the exception type from >>> try:
... nx.core_number(G)
... except nx.NetworkXError:
... print("Caught it")
Traceback (most recent call last)
...
NetworkXNotImplemented: Input graph has self loops which is not permitted; Consider using G.remove_edges_from(nx.selfloop_edges(G)). In practice, this means that any user code which is catching exceptions related to the Just to restate my opinion from above though: I'm willing to try sneaking this breaking change in, since IMO it is likely to affect only a relatively small number of users (i.e. those explicitly catching exceptions from |
@rossbar I was able to understand your point on the effects of changing Thank you :) |
I think this looks good as it is right now. It is true that people can get the wrong results if they submit a The term :) |
core.py
OK... Thanks for this! |
* added examples in core.py * updated core.py docs * added test_k_truss_self_loop * small bug fix in test_k_truss_self_loop * updated core.py * updated core.py file * inline implementation for decorators and exceptions and modified sections * changed .nodes() to .nodes * Replace parallel edges with multigraph in docstrings. --------- Co-authored-by: Ross Barnowski <rossbar@berkeley.edu>
core_number(G)
andk_core(G, k)
algorithms.Added@not_implemented_for("multigraph")
tok_core()
,k_shell()
,k_crust()
andk_corona()