Activity 2-9

Syllable Counter


In this lab, you will be creating a syllable counter to count the number of syllables in any given word. The syllable counter works by counting vowels according to the following rules:

  1. A vowel counts as one syllable.
  2. However, a sequence of adjacent vowels (a, e, i, o, u, y) is only one syllable.
  3. If the word ends with the vowel e, it does not count as a separate syllable.
  4. If the algorithm yields a total syllable count of zero, change the syllable count to one.

We have provided stencil code here that includes a dictionary of syllable counts. A dictionary is a data structure that contains key-value pairs separated by commas. In this case, the keys are the actual words, and the values are the number of syllables in those words.

Task 1

Write a function definition count_syllables(word) that simply returns the number 0. We'll fill it out shortly.

In your main() function, you will be iterating through every key-value pair, checking if your predicted syllable count from your function returns for each word matches the correct number of syllables. Each key is a word, and each value indicates how many syllables that word actually contains.

You can iterate through a dictionary using a for loop:

for word, true_count in word_syllable_counts.items():
	my_count =  count_syllables(word)
    	if true_count != my_count:
        	print("{}\tTrue: {}\tComputed: {}".format(word, true_count, my_count))

The for loop iterates through each key-value pair in the dictionary.

Inside the for loop, the code will count the number of syllables in each word by calling a count_syllables(word) function that you will soon fill in.

The if statement here will check if your syllable count is incorrect for a word compared to the actual syllable count. If so, it will print out the word, the number of actual syllables, and the number of syllables your function predicted.

Test your dictionary iteration code to make sure it works before moving on to Task 2.

Task 2

For your count_syllables syllables function, here is some code to get you started:

count = 0
for char in word:
    if is_vowel(char):
        count += 1

Here, we start by initializing a count variable to 0. Then we use a for loop to iterate through every character in a word. If a character is a vowel, we increment the count by 1.

Write the function is_vowel(char) to return True or False if a particular character is in the set of vowel characters: {'a','e','i','o','u','y'}.

Now you will modify this for loop in order to take into account the fact that a vowel does not always indicate another syllable. Look at the rules listed near the start of this handout.

You won't be able to iterate through every character in the word anymore, but will instead be iterating through every index in the word, using the range() function, beginning at 0 and stopping at the length of the word. The reason behind this is that you will need to check if the previous letter is a vowel, and you can't get the previous letter without an index. Modify the for char in word: line to use the index instead. It should take the form for (2) in (1) where:

  1. The input iterable: the range you want to iterate over. You can use the form range(stop), where stop is one more than the last index.
  2. The temporary iteration variable. Choose a useful name that's descriptive of its type.

Unfortunately this means that we no longer have a variable char for the character we are currently evaluating. Define a variable current_character using the variable word and the temporary iteration variable you defined in your for loop

Test your code again at this point. Some of the words in the dictionary won't be printed because this simple counter will already compute the correct answer. For the words that do print out, ensure that the 'computed' count matches the number of vowels in the word

Task 3

In accordance with rule 2, you will need to check if the character before current_character is a vowel. If the current character is a vowel and the previous character is also vowel, then those two letters are still part of the same syllable so we should not increment the syllable count again. Inside your if statement, create a variable previous_character and check that it is not a vowel before count is incremented. Inside your for loop, you should now have a nested if statement. The first if statement checking if the current character is a vowel, and the second if statement checking if the previous character is not a vowel.

In a for loop, accessing the index before or after the current index is potentially dangerous because if the index is 0, the index before it will be -1 and we don't want to compare the first letter to the last letter. Likewise, accessing the next index is a problem when our index is already the last item. Python will throw an index out of bounds exception. Therefore, when accessing either the item before the current item or the item after, you should check that we are not at the limits. So, just before your definition of previous_character check that the current index is not 0. If it is 0, the count should just be increment, otherwise we are safe to create our previous_character variable.

Run your code and check what words don't pass. If your code is correct so far, besides the word "cwtch", the words "receive", "abdicate", and "message" should also not be passing your test. At this stage, your program should predict that they have one more syllable than they actually do. Do you know why? If you're unsure, check rule 3 above.

Task 4

We won't count the syllable if the character is an 'e' and it is the last letter in the word. Inside the if statement that checks if the previous character is not a vowel, include another if statement. This if statement should increment the count if the current index is not the last item and it should also increment the count if the last letter is not an 'e' (convince yourself we already know it's a vowel).

Test your program again, there should only be two words remaining: 'he' and 'cwtch'. Our program up until now successfully predicted the syllables in 'he', but it was an unfortunate victim of our 'e' rule. Therefore, you will need to check if your algorithm yields a syllable count of zero. If so, change the syllable count to one, to satisfy rule 4.

Run your program to check that your code is counting the number of syllables correctly.

Once you're done, please check off your lab with a TA or share your file with by midnight, 3/21.