'Counting the number of unique vowels in a string
I have the following task:
Import the
sysmodule and create a function with a string parameter that will print the number of unique vowels in the string regardless of whether it is uppercase or lowercase.
For example:
Test 1: The argument swEet should print 1
Test 2: The argument “Aaa aeeE” should print 2
Test 3: The argument "eiOuayOI j_#Ra" should print 5
I have the following code:
import sys
def count_vowels(args):
vowels = set()
for arg in args:
for char in arg:
if char.lower() in 'aeiou':
vowels.add(char)
return len(vowels)
print(count_vowels(sys.argv[1:]))
Test case 1 is the only test that prints the expected output. The other two test cases, Test 2 and Test 3, do not print the correct expected result. Test 2 prints 5 rather the expected output of 4 and Test 3 prints 6 instead of the expected output of 5.
Solution 1:[1]
I think you're overcomplicating things. To get the number of unique vowels, you can lowercase the entire string, then call set() on the lowercased string to get a set of unique letters. You can then check whether each vowel is in this set. If it is, it appears in the text, otherwise it doesn't:
def count_vowels(text):
letters = set(text.lower())
count = 0
for vowel in 'aeiou':
if vowel in letters:
count += 1
return count
print(count_vowels("Aaa aeeE")) # Prints 2
print(count_vowels("eiOuayOI j_#Ra")) # Prints 5
If you prefer a one-liner, you can do this:
def count_vowels(text):
return sum(1 for vowel in 'aeiou' if vowel in set(text.lower()))
or this (as suggested by psmears):
def count_vowels(text):
return len(set(text.lower()) & set('aeiou'))
Solution 2:[2]
You are still mixing upper/lower casing, see other answers.
There is a lot shorter version for this
def count_vowels(word):
# all letters you are interested in
allowed = frozenset("aeiou")
# get the len of the intersection between allowed and lower cased word
return len(allowed.intersection( word.lower()))
tests = [("swEet",1), ("Aaa aeeE", 2),("eiOuayOI j_#Ra", 5)]
for t in tests:
print(t[0], "is", count_vowels(t[0]), "should be", t[1])
Output:
swEet is 1 should be 1
Aaa aeeE is 2 should be 2
eiOuayOI j_#Ra is 5 should be 5
This uses (frozen)set.intersection - and returns its length. frozenset is just a non-mutable version of set.
Solution 3:[3]
Change vowels.add(char) to vowels.add(char.lower())
Solution 4:[4]
The other answers and comments explain the problem well, you should use a variable to count the occurrences of each vowel. Here's a short solution using list comprehension instead of a for loop:
def count_vowels(args: str):
args = set(args.lower())
return sum([vowel in args for vowel in 'aeiou'])
You can even go as far as to make it a lambda function:
count_vowels = lambda args: sum([vowel in set(args.lower()) for vowel in 'aeiou'])
Solution 5:[5]
You should also transform the char you append to the vowels set() to .lower(), since now it's adding the vowel as is, so the set can contain both o and O:
vowels.add(char.lower())
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Patrick Artner |
| Solution 3 | rstr1112 |
| Solution 4 | Ronan Howard |
| Solution 5 | Jeremy Caney |
