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
fix the off by one issues #6
Conversation
+1 code looks good too. |
Just noticed you sent this. I have #7 which resolves this and other issues. I changed the calculation but in a more obvious way. The issue is that the number of decisions is off by one, not the formula which you're changing. |
@sigmavirus24 : I noticed that as well, and updated my branch as such. The dot-graph of the trivial function is much more sensible now ( f1->stmt1 rather than f1->f1) as a bonus. The --minimum-threshold option for dot graphing was also of by one as a consequence. |
updated the diff |
@@ -286,7 +286,7 @@ def main(argv): | |||
help="output a graphviz dot file", action="store_true") | |||
opar.add_option("-m", "--min", dest="threshold", | |||
help="minimum complexity for output", type="int", | |||
default=2) | |||
default=0) |
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.
Why should this be 0?
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.
By default, I want to see a graph of everything.
Previously it was 2 when the minimum was in fact 2 due to bugs.
I've made 0 mean "literally everything", so that I can still graph things out when I've introduced bugs.
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.
What about not making the graph utility rely on the threshold?
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.
The only purpose of the minimum threshold is to limit the output for dot mode.
I believe you're confusing this with flake8's -m/--maximum-threshold, which is unrelated.
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.
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.
As you like, but my perception of the original intent was to cull very large outputs, and you'd lose that ability.
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.
Then why not set the default to 1 and force your own use of this to always use 0.
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 thought the intent was to show everything by default, and the original
author simply hadn't considered (with good reason) negative complexities.
A default of 1 would behave quite similarly, but hide bugs from the output,
which is not a good practice.
On Fri, Apr 18, 2014 at 2:43 PM, Ian Cordasco notifications@github.comwrote:
In mccabe.py:
@@ -286,7 +286,7 @@ def main(argv):
help="output a graphviz dot file", action="store_true")
opar.add_option("-m", "--min", dest="threshold",
help="minimum complexity for output", type="int",
default=2)
default=0)
Then why not set the default to 1 and force your own use of this to always
use 0.—
Reply to this email directly or view it on GitHubhttps://github.com//pull/6/files#r11788170
.
Buck Golemon
Cell: (408) 202-3901
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.
The problem with a default of 0 is that when used to actually determine the complexity of a file or piece of code (when not using the graph functionality) you will everything printed to the screen.
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.
As you like, this was meant to be a minor improvement.
The 2 was obviously a holdover from buggier days.
:)
FYI @bukzor I really want to merge this so if you can address that one concern and rebase it, I'd ❤︎ it. :) |
This was the previous behavior as well; the smallest complexity a function could have was 2, and functions with a complexity of 2 were printed. |
I've updated the diff as you want. |
@@ -67,6 +67,8 @@ def __init__(self, name, entity, lineno): | |||
|
|||
def connect(self, n1, n2): | |||
self.nodes[n1].append(n2) | |||
# Ensure that the destination node is always counted. | |||
self.nodes[n2] |
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 is a no-op?!
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.
It causes an entry to be created in a defaultdict.
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.
Ah, I see :)
However, "explicit is better than implicit", so self.nodes[n2] = list()
is IMO much better.
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.
@bukzor it's perfectly obvious to those who understand what self.nodes
is. Do not feel pressured to do more than is necessary
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 change duplicates what was done by @sigmavirus24 on a previous commit in def complexity(self):
.
I proposed in the comment https://github.com/flintwork/mccabe/pull/7/files#diff-c8e207640776e7218af4cd9951eb2fceL84 to adjust slightly the computation to highlight the fact that it is num_nodes
which was wrong, not num_edges
.
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.
However, "explicit is better than implicit", so self.nodes[n2] = list() is IMO much better.
@schlamar That has different behavior. We're not guaranteed that n2 has no successors.
The explicit version of this line would be:
if n2 not in self.nodes[n2]: self.nodes[n2] = self.nodes.default_factory()
Which is, of course, the behavior of defaultdict.__getitem__
, except with worse performance.
If you still like this better than it is currently written, I will change it.
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.
@bukzor what you wrote is fine. Anyone who has read the code will understand the expected behaviour.
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.
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.
While that may be true (or may not; it's certainly not obvious), it doesn't change the truth of my assertion:
If a tree has more than one leaf node, #6 will be correct while #7 will not.
It's certainly not impossible that the tree will have more than one leaf after future changes.
This leads me to say that #6 is more correct.
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.
Anyone who has read the code will understand the expected behaviour.
It was not obvious for me (with years of Python experience) and I've never seen this before. So an additional comment like "ensure the key is in the defaultdict" wouldn't harm anyone, right? :)
@bukzor this is still not in a mergable state. Were you planning on rebasing? |
Rebased and passed CI. |
@@ -3,3 +3,5 @@ | |||
*.py[cod] | |||
.tox | |||
dist | |||
# silly vim. | |||
.*.sw[a-z] |
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.
you can use your global gitignore for such files :)
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 agree with @schlamar about this. Please revert this addition.
Rebased again. |
All issues resolved I think. |
Thanks for the reminder @bukzor. I'll take another look at this tonight. |
Sorry that it took so long to merge this @bukzor Thanks for the contribution |
cool! Let me know when we should see an improved behavior from flake8. |
Resolves #5