flake8-cognitive-complexity icon indicating copy to clipboard operation
flake8-cognitive-complexity copied to clipboard

cognitive complexity calculation is incorrect

Open tjorda01 opened this issue 2 years ago • 2 comments

Computed Cognitive complexity is 12 (I believe correct) for this:

class GildedRose:
    def update_quality(self):
        for item in self.items:  # + 1
            if (
                item.name != "Aged Brie"
                and item.name != "Backstage passes to a TAFKAL80ETC concert"
             ):  # + 2
             if item.quality > 0:  # + 3
                 if item.name != "Sulfuras, Hand of Ragnaros":  # + 4
                     item.quality = item.quality - 1
            else:
                pass

However, 10 is incorrect (less than before???) for following code: Note complexity should be higher than before since code is the same with an added 'if' condition after the 'else'):

class GildedRose:
    def update_quality(self):
        for item in self.items:  # + 1
            if (
                item.name != "Aged Brie"
                and item.name != "Backstage passes to a TAFKAL80ETC concert"
             ):  # + 2
             if item.quality > 0:  # + 3
                 if item.name != "Sulfuras, Hand of Ragnaros":  # + 4
                     item.quality = item.quality - 1
            else:
                #pass
                if item.quality < 50:  # + 3
                    item.quality = item.quality

tjorda01 avatar Jan 19 '23 21:01 tjorda01

The algorithm in this plugin is implemented in https://github.com/Melevir/cognitive_complexity, you might get more attention opening an issue there

waweber avatar Jun 01 '23 16:06 waweber

When I run the functions through the complexity checker as a part of the tests, I get 16 and 15 respectively:

def test_else_complexity_ignored():
    assert get_code_snippet_compexity("""
    class GildedRose:
        def update_quality(self):                                                   # + 0 (nesting = 0)
            for item in self.items:                                                 # + 2 (1 for nesting, 1 for the loop) (nesting = 1)
                if (
                    item.name != "Aged Brie"
                    and item.name != "Backstage passes to a TAFKAL80ETC concert"
                ):                                                                  # + 4 (2 for nesting, 1 for the if, 1 for the bool operator sequence) (nesting = 2)
                    if item.quality > 0:                                            # + 4 (3 for the nesting, 1 for the if) (nesting = 3)
                        if item.name != "Sulfuras, Hand of Ragnaros":               # + 5 (4 for the nesting, 1 for the if) (nesting = 4)
                            item.quality = item.quality - 1                         # + 0 (nesting = 5)
                else:                                                               # + 3 (2 for the nesting, 1 for the else) (nesting = 2)
                    pass                                                            # + 0 (nesting = 3)
    """) == 16 # Total should be 18


def test_else_complexity_considered():
    assert get_code_snippet_compexity("""
    class GildedRose:
        def update_quality(self):                                                   # + 0 (nesting = 0)
            for item in self.items:                                                 # + 2 (1 for nesting, 1 for the loop) (nesting = 1)
                if (
                    item.name != "Aged Brie"
                    and item.name != "Backstage passes to a TAFKAL80ETC concert"
                ):                                                                  # + 4 (2 for nesting, 1 for the if, 1 for the bool operator sequence) (nesting = 2)
                    if item.quality > 0:                                            # + 4 (3 for the nesting, 1 for the if) (nesting = 3)
                        if item.name != "Sulfuras, Hand of Ragnaros":               # + 5 (4 for the nesting, 1 for the if) (nesting = 4)
                            item.quality = item.quality - 1                         # + 0 (nesting = 5)
                else:                                                               # + 3 (2 for the nesting, 1 for the else) (nesting = 2)
                    #pass
                    if item.quality < 50:                                           # + 4 (3 for the nesting, 1 for the if) (nesting = 3)
                        item.quality = item.quality
    """) == 15 # Total should be 22

Mockapapella avatar Jul 25 '23 16:07 Mockapapella