I have to make a program that asks the user for a String and then counts and prints the number of vowels in the String. The vowels that count are a, e, i, o, u, y, and the uppercase versions of these. For example, the input "ebony and ivory" would print 7. I also can't use any built-in string functions for this problem.
This is what I have so far:
userString = str(input("Please enter a string:"))
numVowels = 0
n=0
a=0
e=0
i=0
o=0
u=0
y=0
while (ord(userString[n]) != 0 or ord(userString[n+1])!=0):
if (userString[n] == 'a' or userString[n]=='A'):
a += 1
numVowels += 1
elif (userString[n] == 'e' or userString[n]=='E'):
e += 1
numVowels += 1
elif (userString[n] == 'i' or userString[n]=='I'):
i += 1
numVowels += 1
elif (userString[n] == 'o' or userString[n]=='O'):
o += 1
numVowels += 1
elif (userString[n] == 'u' or userString[n]=='U'):
u += 1
numVowels += 1
elif (userString[n] == 'y' or userString[n]=='Y'):
y += 1
numVowels += 1
n+=1
print("There are", numVowels, "vowels. There are", a, "A's", e, "E's", i, "I's", o, "O's", u, "U's, and", y, "Y's, including both uppercase and lowercase versions.")
However I keep getting the error:
IndexError: string index out of range
I am using Python 3.
First, you don't need to look at userString[n+1]. Trying to do so when n is already the last index is the first thing that triggers that error message.
Second, even if you remove that test, your loop will still not terminate when it should, because the nul character it's looking for at the end of the string is an implementation detail in the runtime of the C code that comprises the Python interpreter. From Python itself, that character is inaccessible, so ord(userString[n]) will never be 0 for any n unless you explicitly put a "\0" in the string at the Python level. Failing that, the loop will sail past the end of the string and trigger the same IndexError when you try to access userString[n] with n equal to the length of the string.
There are better ways to loop through a string in Python, but the simplest fix for your code is to change the while condition to this:
while n < len(userString):
If len counts as a "built-in string function", which is debatable, then you should just loop over the string in a more typical Pythonic way:
for ch in userString:
if (ch == 'a' or ch=='A'):
a += 1
numVowels += 1
...
There are improvements that can be made to the conditional code that checks for vowels as well (as in mbaytas's answer), but that wasn't your question.
In Python, you can iterate over a string, like you would over a list.
Exploiting this functionality, and using a list to store the vowels, you can use something along the lines of the following code to achieve the functionality you want:
inputString = "This is our input string."
vowels = ["A", "E", "I", "O", "U", "Y", "a", "e", "i", "o", "u", "y"]
vowelCount = 0
for character in inputString:
if (character in vowels):
vowelCount += 1
print vowelCount
I see that your code in the question makes use of conditionals and loops, but not lists. If you'd like to avoid using lists for some reason (e.g. not covered in class yet), you can do the following:
inputString = "This is our input string."
vowelCount = 0
for character in inputString:
if (character == 'A' or
character == 'E' or
character == 'I' or
character == 'O' or
character == 'U' or
character == 'Y' or
character == 'a' or
character == 'e' or
character == 'i' or
character == 'o' or
character == 'u' or
character == 'y'):
vowelCount += 1
print vowelCount
You can also modify the code above using elif statements instead of or logic to break down the occurrence of each vowel.
If you'd like to avoid using the for ... in ... functionality and stick to the while loop, consider the following:
vowelCount = 0
index = 0
while (index < len(inputString)):
if (inputString[index] in vowels):
vowelCount += 1
index += 1
Python offers many features that make solving problems like this a joy. Dictionary comprehensions, list comprehensions, etc.:
vowels = {v: 1 for v in 'aeiouyAEIOUY'}
def num_vowels(input_string):
return sum(vowels.get(character, 0) for character in input_string)
print(num_vowels(str(input("Please enter a string:")))
It's always a good approach to implement the general case first and derive your special case from that. I assumed that you can are "allowed" to use a dict. I avoided built-in methods of str for this.
def count_chars(s, chars):
cdict = {i:0 for i in chars}
for c in s:
try:
cdict[c] += 1
except KeyError:
pass
return cdict
def count_vowels(s):
chars = ['a','e','i','o','u', 'y', 'A', 'E', 'I', 'O', 'U', 'Y']
vowels = count_chars(s, chars=chars)
return vowels, sum(vowels.values())
# test it
tally, total = count_vowels(str(input()))
print(tally, total)
I will give it a try too :)
code below individual vowel and sum that up for total vowels count
input_string = str(input("Please enter a string: "))
vowel = [['a','A'], ['e','E'], ['i','I'], ['o','O'], ['u','U'], ['y','Y']]
vc = [0] * 6 # individual vowel count
for ch in input_string:
for i,v in enumerate(vowel):
if ch in v:
vc[i] += 1
total = sum(vc)
print("There are", total, "vowels.")
print("There are {0} A's {1} E's {2} I's {3} O's {4} U's, and {5} Y's, including both uppercase and lowercase versions.".format(*vc))
Related
I'm pretty new to python and I'm having trouble with my
if then else statements and I only get is "no repeating vowels" which mean my rep_vowel is still returning 0
so the program rules are as follows.
if no vowel appears next to itself (e.g. hello), then print:
no vowel repeats
if exactly one vowel is repeated in sequence at least once (e.g. committee) then print a message that indicates which vowel repeats:
only vowel e repeats
if more than one vowel repeats (e.g. green door) then print:
more than one vowel repeats
ignore upper case - lower case differences: assume all the input is always lowercase
answer = input("Enter a string: ")
rep_vowel = 0
i = 0
length_Answer = len(answer)
next_string = 1
curChar = answer[0+rep_vowel]
for i in range(0,length_Answer):
if answer[0 + i] in ["a","e","i","o","u"]:
i =+ 1
next_string = answer[0+i+i]
if next_string == answer:
rep_vowel =+ 1
if rep_vowel == 0:
print("no repeating vowles")
elif rep_vowel > 1:
print("more than 1 repeating vowels")
else:
print ("the letter "+ str(curChar) +" repeats")
You have a few mistakes so i'll try to address several of them:
You do a lot of [0 + something] indexing, which is useless, since 0 + something always equals to something, so yo should just do indexing with [something]
Changing the value of i with i += 1 is bad because you are already increasing it as part of the loop
All you have to do to find a match is simply match the current letter to the next one, if both are the same and they are also vowels, you've found a match.
You are initializing unnecessary variables such as i = 0 only to have them overridden in the next lines
Adding all of those together:
answer = input("Enter a string: ")
vowels = "aeiou"
repeats = [] # this list will hold all repeats of vowels
for i in range(len(answer) - 1): # i'll explain the -1 part at the end
if answer[i] in vowels and answer[i] == answer[i + 1]:
repeats.append(answer[i])
if len(repeats) == 0:
print("no repeating vowles")
elif len(repeats) > 1:
print("more than 1 repeating vowels")
else:
print("the letter " + repeats[0] + " repeats")
This still doesn't take every possible input into account, but it should get you started on a final solution (or perhaps that's enough). For example, input of teest will give the correct result but the input of teeest doesn't (depends on your definition of correct).
About the len(answer-1) range, that's only to make sure we don't go out of bounds when doing answer[i + 1], so we're stopping on the next to last letter instead.
Firstly, you have to indent your code.
to say if (condition) then do print('hello') you write it this way:
if condition:
print('hello')
Secondly, you are using i =+ 1 which is the same as i=1
I think you meant i +=1 which is i = i+1
Finally, I suggest this code:
answer = input("Enter a string: ")
vowel_repeated_count = 0
length_Answer = len(answer)
i=0
while (i <length_Answer-1):
#we check if it's a vowel
if answer[i] in ["a","e","i","o","u"]:
#we check if it's followed by the same vowel
if answer[i+1] == answer[i]:
#increment the vowel_repeated_count
vowel_repeated_count +=1
#we save the vowel for the display
vowel = answer[i]
#we skip the other same repeated vowels
#example: abceeed, we skip the third e
while (answer[i] == vowel and i < length_Answer-1):
i +=1
#we add this incrementation because we're in a while loop
i +=1
if vowel_repeated_count == 0:
print("no repeating vowles")
elif vowel_repeated_count == 1:
print("the letter "+ str(vowel) +" repeats")
else:
print ("more than 1 repeating vowels")
You have some logical errors. It's time consuming to edit that. You can try this, I have modified your code. Hope it will work for you. I have commented beside every important line.
answer = input("Enter a string: ")
is_found = {} #a dictionary that will hold information about how many times a vowel found,initially all are 0
is_found["a"]=0
is_found["e"] = 0
is_found['i']=0
is_found['o']=0
is_found['u']=0
vowels =["a","e","i","o","u"]
for i in range(0,len(answer)):
if answer[i] in vowels:
is_found[answer[i]] = is_found[answer[i]]+1 # if a vowel found then increase its counter
repeated=0 #let 0 repeated vowel
previously_repeated=False #to trace whether there is a previously repeated character found
curChar=None
for key,value in is_found.items(): #iterate over dictionary
if previously_repeated and value>1: #if a vowel found and previously we have another repeated vowel.
repeated=2
elif previously_repeated==False and value>1: # we don't have previously repeated vowel but current vowel is repeated
curChar=key
previously_repeated=True
repeated=1
if repeated== 0:
print("no repeating vowles")
elif repeated> 1:
print("more than 1 repeating vowels")
else:
print ("the letter "+ str(curChar) +" repeats")
There is no need to increment your counter i. In your for loop, it will increment itself each time it goes through the for loop. Also, you need a variable to keep track of how many times the vowel repeats.
answer = input("Enter a string: ")
rep_vowel = 0
length_Answer = len(answer)
vowelList=["a","e","i","o","u"]
vowelRepeated = []
#this will go from i=0 to length_Answer-1
for i in range(length_Answer):
if (answer[i] in vowelList) and (answer[i+1] in vowelList):
if (answer[i] == answer[i+1]):
vowelRepeated.append(answer[i])
repVowel += 1
if rep_vowel==0:
print("no repeating vowels")
elif rep_vowel==1:
print("only one vowel repeated:")
print(vowelRepeated)
else:
print("multiple vowels repeated:")
print(vowelRepeated)
for such counting, I will prefer to use a dictionary to keep the counting number. Your code has been modified for your reference
answer = input("Enter a string: ")
length_Answer = len(answer)
count = dict()
for i in range(length_Answer):
if answer[i] in ["a","e","i","o","u"]:
if answer[i+1] == answer[i]:
if answer[i] in count:
count[answer[i]] += 1
else:
count[answer[i]] = 1
rep_vowel = len(count)
if rep_vowel == 0:
print("no repeating vowles")
elif rep_vowel > 1:
print("more than 1 repeating vowels")
else:
for k in count:
vowel = k
print("the letter " + vowel + " repeats")
You have a few issues with your solution :
1) You never use curChar, i'm guessing you wanted to enter the next_string value into it after the '==' statement.
2) You compare your next_string to answer, this will always be a false statement.
3) Also no need to use [0+i], [i] is good enough
Basically what you want to do is this flow :
1) Read current char
2) Compare to next char
3) If equal put into a different variable
4) If happens again raise a flag
Optional solution :
vowel_list = ["a","e","i","o","u"]
recuring_vowel_boolean_list = [answer[index]==answer[index+1] and answer[index] in vowel_list for index in range(len(answer)-1)]
if not any(recuring_vowel_boolean_list ):
print("no repeating vowels")
elif (recuring_vowel_boolean_list.count(True) > 1):
print("More then 1 repeating vowels")
else:
print("The letter {} repeats".format(answer[recuring_vowel_boolean_list.index(True)]))
I've currently solving a MIT undergrad problem in Python 3.5.
The goal is to write a Python script counting and printing the number of vowels in a string containing only lower-case letters without using a function wrapper or even a function definition (stated in the assignment, weird ?).
def vowels_count(s):
i=0
counter = 0
while(s[i] != " "):
if s[i] == "a" or s[i] == "e" or s[i] == "i" or s[i] == "o" or s[i] == "u":
counter += 1
i = i + 1
return(counter)
I have two problems:
1/ first of, my own code using a while do structure meets a problem with the use of the index navigating from the first character to the last one. The debugger says: index out of range
2/ finally, if I have to comply with the MIT instructions, I would not be able to do anything in a single-line code without defining a function.
Thanks for your support
Why is this version not correct on the string index i ?
def vowels_count_1(s):
i = 0
counter = 0
while(s[i] != ""):
if s[i] == "a" or s[i] == "e" or s[i] == "i" or s[i] == "o" or s[i] == "u":
counter += 1
i += 1
print("Number of vowels: " + str(counter))
You can use the condition of i being less than the length of your string to break out of the while loop. I also recommend the easier approach of just checking if the letter at s[i] is in a string composed of vowels:
def vowels_count(s):
i = 0
counter = 0
while i < len(s):
if s[i] in 'aeiou':
counter += 1
i += 1
return counter
If you wanted to do this in one line, you could use the length of a list comprehension:
counter = len([c for c in s if c in 'aeiou'])
As you learn more and more you'll be able to count the vowels in one line using sum and a generation expression.
You could fix your loop while i < len(s), i.e. up to the length of the string, but much better is just to iterate over the sequence of characters we call "string".
for ch in s:
if ch == 'a' or ...
No indices needed. No i.
If you have learned the in operator already, you could simplify the test.
Without a function probably means this:
s = "the string"
# your code here
print("vowel count:", counter)
But I'm not sure ...
Here is an one line solution:
reduce(lambda t, c : (t + 1) if c in 'aeiou' else t, s.lower(), 0)
I am required to input a string, calculate the number of vowels in that string, and then calculate the most and least occurring vowels. When the string contains no vowels at all, a message should print saying "no vowels were entered". Where there are vowels which occur the same number of times (e.g. if a and e both occur twice ), these vowels should both appear as being most or least occurring. However, if some vowels are in the string but not all, then the ones which do not appear in the sting should be ignored (rather than printing "a=0"). I think the counting part at the start is correct to an extent, but not quite. As for the most/least occurrences, I don't even know where to begin. Any help would be appreciated!
myString = str(input("Please type a sentence: ").lower())
count = [0, 0, 0, 0, 0]
for vowel in myString:
if vowel == "a" :
count[0]=count[0]+1
if vowel == "e" :
count[1]=count[1]+1
if vowel == "i" :
count[2]=count[2]+1
if vowel == "o" :
count[3]=count[3]+1
if vowel == "u" :
count[4]=count[4]+1
while count[0] > 0:
print ("acount :",count[0])
break
while count[1] > 0:
print ("ecount :",count[1])
break
while count[2] > 0:
print ("icount :",count[2])
break
while count[3] > 0:
print ("ocount :",count[3])
break
while count[4] > 0:
print ("ucount :",count[4])
break
else:
if count[0] == 0 and count[1] == 0 and count[2] == 0 and count[3] == 0 and count[4] == 0:
print ("No vowels were found")
from collections import Counter
d = Counter(input("Enter Sentence:"))
print sorted("aeiou",key=lambda x:d.get(x,0))
seems like a much easier way to do it ...
Well, you've got a list, count, with 5 counts in it. How do you find out which count is the highest? Just call max on it:
>>> count = [7, 1, 3, 10, 2]
>>> max(count)
10
Now that you know the max is 10, how do you know which letters have counts of 10?
>>> max_count = max(count)
>>> for i, n in enumerate(count):
... if n == max_count:
... # use i the same way you use it above
You should be able to figure out how to do the minimum count as well.
But there's one extra problem for minimum count: it sounds like you want the minimum that's not 0, not the absolute minimum. I'd write it like this:
>>> min_count = min(x for x in count if x>0)
… or, maybe more compactly:
>>> min_count = min(filter(bool, count))
But I'm guessing you don't understand comprehensions yet. In which case, you'll need to explicitly loop over the values, keeping track of the minimum value(s) that aren't 0. This implementation of max should help guide you in the right direction:
def my_max(iterable):
max_value = None
for value in iterable:
if max_value is None or value > max_value:
max_value = value
return max_value
All that being said, this is one of many cases where using the right data structure makes the job a lot easier. For example, if you used a dictionary instead of a list, you could replace the whole first half of your code with this:
count = dict.from_keys('aeiou', 0)
for vowel in myString:
if vowel in 'aeiou':
count[vowel] += 1
Using a defaultdict or a Counter makes it even easier; then you don't need to explicitly initialize the counts to 0.
count=[0,0,0,0,0]
myString = str(input("Please type a sentence: ").lower())
for x in mystring:
flag = 'aeiou'.find(x)
if flag>=0:
count[flag] +=1
print max(count)
here find function will try to find the 'x' from aeiou if found return position of 'x` else return -1. so in flag i will get the position else -1
I tried to run this program, but for some reason the string gets changed only to lowercase. The vowels don't turn to lowercase. Any ideas on why?
Thanks!
def changeCaps(string):
i = 0
while i < len(string):
if string[i] == 'a' or string[i] == 'e' or string[i] == 'i' or string[i] == 'o' or string[i] =='u':
print(string[i].upper())
i = i + 1
else:
print(string[i].lower())
i = i + 1
changeCaps("AlbErT")
What doubleo said in his two comments is correct: because the A and E in AlbErt are already capitalized, they aren't equal to lowercase a and e, and as such, they are made to be lowercase along with all the consonants. if you ware wanting to change the case of any letter typed, that would require a different routine. Something more along these lines:
def changeCaps(string):
i = 0
while i < len(string):
if string[i].islower():
print(string[i].upper())
i = i + 1
else:
print(string[i].lower())
i = i + 1
changeCaps("AlbErT")
This will result in any uppercase letters becoming lowercase and any lowercase letters becoming uppercase, and whether or not it is a vowel or consonant will have nothing to do with it.
Also, why not use a for loop instead? This will work just as well, and take up fewer lines of code:
def changeCaps(string):
for i in range(len(string)):
if string[i].islower():
print(string[i].upper())
else:
print(string[i].lower())
changeCaps("AlbErT")
Okay, so it only saves two lines, but it makes more sense to use a for loop in my opinion. Either way, the resultant output would be:
aLBeRt
On a final note, as Anton pointed out, you don't even really need a numeric pointer, just go over the string.
def changeCaps(string):
for c in string:
if c.islower():
print(c.upper())
else:
print(c.lower())
changeCaps("AlbErT")
(Thanks, Anton!)
This is a module in my program:
def runVowels():
# explains what this program does
print "This program will count how many vowels and consonants are"
print "in a string."
# get the string to be analyzed from user
stringToCount = input("Please enter a string: ")
# convert string to all lowercase letters
stringToCount.lower()
# sets the index count to it's first number
index = 0
# a set of lowercase vowels each element will be tested against
vowelSet = set(['a','e','i','o','u'])
# sets the vowel count to 0
vowels = 0
# sets the consonant count to 0
consonants = 0
# sets the loop to run as many times as there are characters
# in the string
while index < len(stringToCount):
# if an element in the string is in the vowels
if stringToCount[index] in vowels:
# then add 1 to the vowel count
vowels += 1
index += 1
# otherwise, add 1 to the consonant count
elif stringToCount[index] != vowels:
consonants += 1
index += 1
# any other entry is invalid
else:
print "Your entry should only include letters."
getSelection()
# prints results
print "In your string, there are:"
print " " + str(vowels) + " vowels"
print " " + str(consonants) + " consonants"
# runs the main menu again
getSelection()
However, when I test this program, I get this error:
line 28, in runVowels
stringToCount = input("Please enter a string: ")
File "<string>", line 1
PupEman dABest
^
SyntaxError: unexpected EOF while parsing
I tried adding a + 1 to the "while index < len(stringToCount)" but that didn't help either. I'm pretty new to python and I don't really understand what's wrong with my code. Any help would be appreciated.
I researched this error, all I found out was that EOF stands for end of file. This didn't help at all with resolving my problem. Also, I understand that sometimes the error isn't necessarily where python says the error is, so I double-checked my code and nothing seemed wrong in my eyes. Am I doing this the round-about way by creating a set to test the string elements against? Is there a simpler way to test if string elements are in a set?
Question resolved. Thank you to all!
Looks like you're using Python 2. Use raw_input(...) instead of input(...). The input() function will evaluate what you have typed as a Python expression, which is the reason you've got a SyntaxError.
As suggested use raw_input. Also you don't need to do this:
while index < len(stringToCount):
# if an element in the string is in the vowels
if stringToCount[index] in vowels:
# then add 1 to the vowel count
vowels += 1
index += 1
# otherwise, add 1 to the consonant count
elif stringToCount[index] != vowels:
consonants += 1
index += 1
# any other entry is invalid
else:
print "Your entry should only include letters."
getSelection()
Strings in Python are iterable, so you can just do something like this:
for character in stringToCount:
if character in vowelSet : # Careful with variable names, one is a list and one an integer, same for consonants.
vowels += 1
elif character in consonantsSet: # Need this, if something is not in vowels it could be a number.
consonants += 1
else:
print "Your entry should only include letters."
This should do just fine. Using a while is not necessary here, and very non-Pythonic imho. Use the advantage of using a nice language like Python when you can to make your life easier ;)
You can count the vowels like so:
>>> st='Testing string against a set of vowels - Python'
>>> sum(1 for c in st if c.lower() in 'aeiou')
12
You can do something similar for consonants:
>>> sum(1 for c in st if c.lower() in 'bcdfghjklmnpqrstvwxyz')
26
Also,
if stringToCount[index] in vowels:
should read
if stringToCount[index] in vowelSet:
Here's another way you could solve the same thing:
def count_vowels_consonants(s):
return (sum(1 for c in s if c.lower() in "aeiou"),
sum(1 for c in s if c.lower() in "bcdfghjklmnpqrstvwxyz"))
To wit:
>>> count_vowels_consonants("aeiou aeiou yyy")
(10, 3)
>>> count_vowels_consonants("hello there")
(4, 6)
Python truly is grand.
The errors in your file run as follows (plus some suggestions):
stringToCount = input("Please enter a string: ")
This should be raw_input if you want what the user typed in as a string.
stringToCount.lower()
The .lower() method returns a new string with its letters lowered. It doesn't modify the original:
>>> a = "HELLO"
>>> a.lower()
"hello"
>>> a
"HELLO"
vowelSet = set(['a','e','i','o','u'])
Here you could just as easily do:
vowelSet = set("aeiou")
Note you also don't strictly need a set but it is indeed more efficient in general.
# sets the vowel count to 0
vowels = 0
# sets the consonant count to 0
consonants = 0
Please, you don't need comments for such simple statements.
index = 0
while index < len(stringToCount):
You usually don't need to use a while loop like this in python. Note that all you use index for is to get the corresponding character in stringToCount. Should instead be:
for c in stringToCount:
Now instead of:
if stringToCount[index] in vowels:
vowels += 1
index += 1
You just do:
if c in vowels:
vowels += 1
elif stringToCount[index] != vowels:
consonants += 1
index += 1
# any other entry is invalid
Not quite right. You're checking that a character doesn't equal a set. Maybe you meant:
elif c not in vowels:
consonants += 1
But then there'd be no else case... Got to fix your logic here.
print "In your string, there are:"
print " " + str(vowels) + " vowels"
print " " + str(consonants) + " consonants"
The above is more pythonically written as:
print "In your string, there are: %s vowels %s consonants" % (
vowels, consonants)
# runs the main menu again
getSelection()
Not sure why you're calling that there - why not call getSelection() from whatever calls runVowel()?
Hope that helped! Enjoy learning this great language.
Bah, all that code is so slow ;). Clearly the fastest solution is:
slen = len(StringToCount)
vowels = slen - len(StringToCount.translate(None, 'aeiou'))
consonants = slen - vowels
...note that I don't claim it's the clearest... just the fastest :)