Python Tutorial
Python Project: Word Counter
Count characters, words, and lines in a block of text, then list the most common words.
What you are building
You analyse a paragraph stored as one string. The program counts characters, words, and lines. Then it builds a dictionary of word frequencies and prints the most common words first.
Use the Python editor at /try. Do not open the HTML, C, or C++ editors for this page. The paragraph is hardcoded, so Run never waits for a file or for input().
Skills used
lenon a string for character countsplitlinesfor lines,splitfor words- A dict that maps each word to a count
str.lowerand a small strip of punctuation so Python and python count as one wordsortedwith a key to rank counts
Count characters, words, and lines
len(text) counts every character, including spaces and newline marks. Words are the piecessplit() returns. Lines are the pieces splitlines() returns. Those three numbers answer different questions, so print all three.
Example
text = """Python is easy to read.
Python is also easy to write.
Read the text. Write more Python."""
print("Characters:", len(text))
print("Lines:", len(text.splitlines()))
print("Words:", len(text.split()))split() with no argument splits on any whitespace. Two spaces do not create an empty word.split(" ") would, so prefer the no-argument form for this project.
Tally words with a dict
Walk the word list. Normalize each token: lowercase it, then strip punctuation from both ends. Use the cleaned token as a dict key. counts.get(word, 0) + 1 starts a new key at 1 and increments an old one.
Example
words = ["Python", "is", "easy.", "Python"]
counts = {}
for raw in words:
word = raw.strip(".,!?").lower()
if not word:
continue
counts[word] = counts.get(word, 0) + 1
print(counts)dict.get(key, 0) returns 0 when the word is new. That saves a separateif word in counts branch. Empty strings after stripping should be skipped, or a lone period would become a fake word.
Complete program
The full script prints the three totals, then a ranked table of the most common words. Copy it into/try and Run. You should see python at the top of the ranking.
Example
text = """Python is easy to read.
Python is also easy to write.
Read the text. Write more Python."""
chars = len(text)
lines = text.splitlines()
raw_words = text.split()
counts = {}
for raw in raw_words:
word = raw.strip(".,!?;:\"'").lower()
if not word:
continue
counts[word] = counts.get(word, 0) + 1
ranked = sorted(counts.items(), key=lambda item: item[1], reverse=True)
print("Word counter")
print("------------")
print("Characters:", chars)
print("Lines:", len(lines))
print("Words:", len(raw_words))
print("Unique words:", len(counts))
print()
print("Most common")
print("word count")
for word, n in ranked[:8]:
print(f"{word:10} {n:5}")| Word | Count in the demo paragraph |
|---|---|
| python | 3 |
| is | 2 |
| easy | 2 |
| to | 2 |
| read / write | 2 each, after punctuation is stripped |
read. and Read become read. That is why the table talks about stripped punctuation. If the ranking looks wrong, print raw_words first and check the tokens.
Common mistakes
- Using
len(text.split("\n"))on a string with no trailing newline and mixing that up withsplitlines(). Prefersplitlines(). - Sorting the dict itself. Dicts remember insertion order, not count. Sort
counts.items(). - Sorting without
reverse=True. Then the rare words appear first. - Forgetting
.lower(). Then Python and python are two keys. - Counting characters with
len(text.split()). That is the word count again, not the character count.
How to extend / Practice tasks
Keep the same paragraph at first so you can compare against the table above.
- Ignore a small stop list such as
["is", "to", "the"]. Skip those keys when you fill the dict and print the new top words. - Print only words that appear more than once. Filter
rankedwith a list comprehension before the loop. - Replace the paragraph with two sentences of your own and confirm that characters, words, and lines all change, not just the ranking.
📘 Real-World Deep Dive
A word-frequency counter is the "hello world" of text processing — tokenise, normalise, count, rank. The same four steps power search indexing, spam filters, and the bag-of-words features behind classic NLP.
What to build
Count how often each word appears in a block of text, case-insensitively and ignoring punctuation, then show the top few.
Real-Life Example
import re
from collections import Counter
text = "The cat sat. The cat ran! The DOG slept."
words = re.findall(r"[a-z]+", text.lower()) # normalise + tokenise
counts = Counter(words)
for word, n in counts.most_common(3):
print(f"{word:6} {n}")Counter + most_common turns "rank words by frequency" into two lines instead of a manual dict-and-sort.
Expected Output
the 3
cat 2
sat 1Common mistakes
- Splitting on spaces only leaves punctuation stuck to words ("cat." vs "cat") — normalise with a regex or
str.translatefirst. - Forgetting
.lower()counts "The" and "the" separately, skewing every total. - Loading a huge file with
.read()holds it all in RAM; iterate line by line and update the Counter incrementally for big inputs.
🚀 Performance & Best Practices
Counteris implemented in C and faster than a hand-rolled dict loop, and.most_common(k)uses a heap so it doesn't fully sort.- A
re.findalltokeniser is both shorter and more correct than chained.replace()calls. - To ignore common words ("the", "a"), subtract a stop-word set before counting.
🧪 Try It Yourself
- Read the text from a file passed on the command line.
- Filter out a set of stop words before counting and see how the top list changes.
- Report the number of distinct words and the total word count alongside the ranking.