Counting Programs
The commonest string question in any paper is a counting question, and they are all the same program: a counter above the loop, a test inside it, a print() after. What changes is only the test — so once you can write one of these, you can write all of them.
1Program 1 — count the vowels and the consonants
Ask for a sentence and report how many vowels and how many consonants it contains. Spaces, digits and punctuation are neither.
- a sentence
- look at each character in turn
- ignore anything that is not a letter
- sort the letters into vowel or consonant
- the two counts
# count the vowels and the consonants in a sentence
sentence = input('Enter a sentence: ')
vowels = 0
consonants = 0
for ch in sentence:
if ch.isalpha():
if ch.lower() in 'aeiou':
vowels = vowels + 1
else:
consonants = consonants + 1
print('Vowels:', vowels)
print('Consonants:', consonants)Enter a sentence: LambdaLab teaches Python 3 Vowels: 7 Consonants: 15
if ch.isalpha():The outer question: is this a letter at all? Without it, the space, the digit and anything else would fall into the else and be counted as consonants — which is the single commonest fault in this program.
if ch.lower() in 'aeiou':The inner question, asked only of letters. lower() means one test covers 'A' and 'a'; the string 'aeiou' is being used as a list of five things to check against, which is what in does.
vowels = vowels + 1Twelve spaces of indentation — inside the inner if, inside the outer if, inside the loop. Each level is four, and the level is what decides which question a line belongs to.
isalpha(), the count is wrong and looks right. Drop that outer if and the sentence above reports 19 consonants — the 15 real ones plus three spaces and a digit. Nothing errors. The only way to catch it is to count a short sentence by hand and compare.2Program 2 — sort every character into a bucket
Count the capitals, the small letters, the digits, the spaces and everything else in a line of text.
# sort every character of a sentence into one of five buckets
sentence = input('Enter a sentence: ')
upper = 0
lower = 0
digits = 0
spaces = 0
others = 0
for ch in sentence:
if ch.isupper():
upper = upper + 1
elif ch.islower():
lower = lower + 1
elif ch.isdigit():
digits = digits + 1
elif ch == ' ':
spaces = spaces + 1
else:
others = others + 1
print('Capitals:', upper)
print('Small letters:', lower)
print('Digits:', digits)
print('Spaces:', spaces)
print('Anything else:', others)Enter a sentence: CBSE Class 11 - Python! Capitals: 6 Small letters: 9 Digits: 2 Spaces: 4 Anything else: 2
if…elif…else ladder, not five separate ifs. Every character belongs in exactly one bucket, and a ladder stops at the first true rung — so nothing can be counted twice. Five separate ifs would work here too, only because the tests happen not to overlap; the ladder says one of these out loud, and the else guarantees nothing is dropped.Check the total if you want to be sure: 6 + 9 + 2 + 4 + 2 = 23, and len('CBSE Class 11 - Python!') is 23. Every character landed somewhere, which is what the else is for.
3Program 3 — how many times does one character appear?
Ask for a sentence and a character, and count how often that character occurs — without using count().
# count how many times one character appears, without using count()
sentence = input('Enter a sentence: ')
wanted = input('Which character? ')
count = 0
for ch in sentence:
if ch == wanted:
count = count + 1
print(wanted, 'appears', count, 'times')Enter a sentence: mississippi Which character? s s appears 4 times
sentence.count(wanted). Know both. The method is what you would write in real code; the loop is what the question is testing, and it is the one that keeps working when the rule gets fussier — “count the vowels” has no method, and neither has “count the capitals that come after a space”.4Program 4 — count the words
Count the words in a sentence. Two ways: by counting the gaps, and by letting Python do the splitting.
# count the words by counting the gaps between them
sentence = 'the quick brown fox jumps'
words = 1
for ch in sentence:
if ch == ' ':
words = words + 1
print('Words:', words)
print('Words, using split():', len(sentence.split()))Words: 5 Words, using split(): 5
Five words have four gaps between them, which is why the counter starts at 1 and not 0 — it is counting the gaps and then counting the last word separately, in advance.
split() has none of those problems, because it splits on runs of whitespace and drops the empties — which is exactly the sort of detail a hand-written loop is expected to get wrong.Words: 5 Words, using split(): 3
5Program 5 — how many of each character?
Report how many times every character appears, not just one.
One counter per character is impossible to write in advance — you do not know which characters will turn up. A dictionary is the answer: the character is the key, the tally is the value, and keys are created as they are met.
# how many times does each character appear?
word = 'banana'
counts = {}
for ch in word:
counts[ch] = counts.get(ch, 0) + 1
print(counts){'b': 1, 'a': 3, 'n': 2}counts = {}An empty dictionary, made before the loop — the same 'collector above the loop' idea, with a dictionary instead of a number.
counts[ch] = counts.get(ch, 0) + 1get(ch, 0) asks for the tally so far and answers 0 when the character has never been seen. Writing counts[ch] with a key that does not exist yet creates it, so the first sighting stores 1.
counts[ch] + 1 would raise KeyError. The first time a character turns up it has no entry, and asking for a key that is not there is an error, not a zero. That is the whole reason get() is here, and it is why the dictionary lesson makes such a point of the difference between d[k] and d.get(k, 0).The keys come out in the order the characters were first seen — b, then a, then n — because that is the order Python keeps a dictionary in. Not alphabetical, and not by size.
6Recap
Started above the loop, raised inside it, printed after. Five buckets means five names, all set to 0 before the loop begins.
isalpha() first, then vowel-or-consonant. Skip the filter and every space and digit falls into the else.
if…elif…else stops at the first true rung, and the else catches whatever the earlier tests did not.
counts.get(ch, 0) + 1 — the key is the character, and get() supplies the 0 that a missing key would otherwise refuse.
- 1
Count the digits in a sentence and add them up at the same time.
Hint · Two collectors, one
if ch.isdigit(), andint(ch)for the total. - 2
Count how many words in a sentence begin with a capital letter.
Hint · Loop over
sentence.split()and testw[0].isupper(). - 3
Count the vowels, but stop counting as soon as you have found five.
Hint · A
breakinside theif, once the counter reaches 5. - 4
Count how many characters of a sentence are not letters, digits or spaces.
Hint · The five-bucket program with three buckets thrown away — or one
ifwith threeandednots. - 5
Report which vowel appears most often in a word, using the frequency dictionary.
Hint · Build the dictionary first, then loop over
'aeiou'and comparecounts.get(v, 0).
A vowel/consonant counter drops the if ch.isalpha() test. What happens to 'Hi 7!'?
Why does counts[ch] = counts.get(ch, 0) + 1 use get() rather than counts[ch] + 1?
The gap-counting word counter is given 'the quick fox ' — two spaces in the middle and one at the end. What does it report?