Text-file programs
Part of the free LogicWiz Python course, Module 8: Files. The examples and practice run in the app.
One question is almost certain in your board paper: "Write a function to read a text file and count..." There are only a handful of patterns behind all of them. Learn these and that question is free marks.
You'll learn to
- Use the three shapes of a text-file program: whole text, words, lines
- Count vowels, consonants, uppercase and lowercase letters in a file
- Display words separated by `#`, and count or select specific words and lines
- Copy selected lines (for example, lines without "a") into a new file
Learn
Three shapes cover almost every question
Every text-file program is: open with with, read, loop, count or print. Only the loop changes:
| Question asks about | Read with | Loop over |
|---|---|---|
| characters (vowels, uppercase) | f.read() |
each character |
words (count "the", # between words) |
f.read().split() or line.split() |
each word |
| lines (starting with T, without "a") | for line in f |
each line |
Pick the shape first; the rest is a counter and an if.
Words separated by #
with open("story.txt") as f:
for line in f:
words = line.split()
print("#".join(words))
The CBSE classic: "read a text file line by line and display each word separated by a #". split() with no argument splits on any run of spaces and also drops the \n. Many marking schemes print word + "#" for every word instead; both show you can split lines into words.
Vowels, consonants, upper and lower case
v = c = up = low = 0
with open("story.txt") as f:
text = f.read()
for ch in text:
if ch.isalpha():
if ch.lower() in "aeiou":
v += 1
else:
c += 1
if ch.isupper():
up += 1
else:
low += 1
print("Vowels:", v, "Consonants:", c)
print("Upper:", up, "Lower:", low)
isalpha() skips spaces, dots and newlines, so they are counted as neither vowel nor consonant. ch.lower() makes "A" and "a" both count as vowels.
Counting one word
count = 0
with open("story.txt") as f:
for word in f.read().split():
if word.strip(".,!?").lower() == "the":
count += 1
print("'the' appears", count, "times")
Two cleanups make it right: strip(".,!?") so "chai." matches "chai", and lower() so "The" matches "the". Board questions ask this for "the", "Me"/"My", or "He"/"She".
Lines starting with T
count = 0
with open("story.txt") as f:
for line in f:
if line.startswith("T"):
count += 1
print("Lines starting with T:", count)
Step through and watch line take each line of the file in turn. startswith is safer than line[0], which fails on an empty string.
Copy lines that do not contain "a"
with open("story.txt") as src, open("no_a.txt", "w") as dst:
for line in src:
if "a" not in line:
dst.write(line)
with open("no_a.txt") as f:
print(f.read())
One with can open two files. Each kept line already has its \n, so write it as it is. Open the output file once, outside the loop.
Four slips cost marks here: split(" ") makes empty "words" when there are two spaces (use split()); punctuation sticks to words ("chai." is not "chai"); case ("The" is not "the"); and opening the output file with "w" inside the loop, which wipes it on every line.
CBSE practical-file and board programs on text files: display words separated by #; count vowels, consonants, uppercase and lowercase; count "Me" and "My" (or "the"); display lines starting with a letter; display words shorter than 4 characters; copy lines not containing "a" to another file. Write them as functions (def count_vowels():), since that is how the paper asks.
In one line
Text-file programs: read, then loop over characters, words (split()) or lines; strip punctuation and lowercase before comparing; open the output file once.