piouser09
piouser09

Reputation: 13

What to do and what to think about when reducing the if/else part of my python code?

So, i have a bunch of words in a list called words that i want to compute some statistics on. I have grouped them into a dictionary but i want to reduce the if/else block of code so that it has less repetition. What do i have to think about and what do i do to reduce that? Thanks!

Summary stats of words into its respective groups.

for word in words:
    if len(word) <= 3:
        num_vowels = 0
        for ch in word:
            if ch in 'aeiou':
                num_vowels = num_vowels + 1
        if num_vowels == 0:
            get_stats('short','no_vowels')
        elif 1 <= num_vowels <= 2:
            get_stats('short','few_vowels')
        else:
            get_stats('short','many_vowels')
     elif 4 <= len(word) <= 7:
        num_vowels = 0
        for ch in word:
            if ch in 'aeiou':
                num_vowels = num_vowels + 1
        if num_vowels == 0:
            get_stats('medium','no_vowels')
        elif 1 <= num_vowels <= 2:
            get_stats('medium','few_vowels')
        else:
            get_stats('medium','many_vowels')
    else:
        num_vowels = 0
        for ch in word:
            if ch in 'aeiou':
                num_vowels = num_vowels + 1
        if num_vowels == 0:
            get_stats('long','no_vowels')
        elif 1 <= num_vowels <= 2:
            get_stats('long','few_vowels')
        else:
            get_stats('long','many_vowels')

Upvotes: 0

Views: 51

Answers (3)

Woody1193
Woody1193

Reputation: 8010

Your issue is primarily one of separability. Individually, your if-else blocks are okay but they become a problem because you've embedded them one inside the other, which you don't have to do and probably should avoid:

def get_description(num_words):
    if (num_words < 4):
        return 'short'
    elif (num_words < 8):
        return 'medium'
    else:
        return 'long'

def get_vowels_description(num_words):
    if (num_words == 0):
        return 'no_vowels'
    elif (num_words < 3):
        return 'few_vowels'
    else:
        return 'many_vowels'

Now, with these function definitions, you can build out your main call in a much more readable fashion:

for word in words:
    num_vowels = sum( [1 for c in list(word) if c in 'aeiou'] )
    return get_stats(get_description(len(word)), get_vowels_description(num_vowels))

As you can see, this is much more manageable and will let you test each piece separately so you can be sure that they all work. In fact, a rule of thumb you should follow is that, when you see code that looks the same as other code except for a difference of input, then it's time to split it out into a function/method. At any rate, I hope this helps.

Upvotes: 1

jarcobi889
jarcobi889

Reputation: 845

Might help break up the monotony, you could break things up and calculate them separately.

for word in words:
    # Move your vowel counting to the top of the for-loop so you aren't re-counting every if statement
    num_vowels = 0
    vowels = 'aeiou'
    for character in word:
        if character in vowels:
            num_vowels += 1

    # Determine your vowel qualifier only once in once place
    if num_vowels == 0:
        vowel_qualifier = 'no_vowels' 
    elif 1 <= num_vowels <= 2:
        vowel_qualifier = 'few_vowels'
    else:
        vowel_qualifier = 'many_vowels'

    # Determine your length qualifier only once too
    if len(word) <= 3:
        length_qualifier = 'short'
     elif 4 <= len(word) <= 7:
        length_qualifier = 'medium'
    else:
        length_qualifier = 'long'

    # Finally, get stats based on the qualifiers above
    get_stats(length_qualifier, vowel_qualifier)

Upvotes: 0

Ricardo Branco
Ricardo Branco

Reputation: 6079

This code has no repetition. Also, I removed some redundant comparations and the counting of vowels:

for word in words:
    if len(word) <= 3:
        description = "short"
    elif len(word) <= 7:
        description = "medium"
    else:
        description = "long"
    num_vowels = sum(word.count(c) for c in 'aeiou')
    if num_vowels == 0:
        get_stats(description, 'no_vowels')
    elif num_vowels <= 2:
        get_stats(description, 'few_vowels')
    else:
        get_stats(description, 'many_vowels')

Upvotes: 3

Related Questions