Reputation: 13
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
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
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
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