Text Analyzer in Python
Beginner · Text and words · about 45 minutes to build · 116 lines
Paste a paragraph and get its word count, sentence count, longest word, most used words and reading time.
The program
Press Run and answer its questions in the box that appears under the code.
Open it in the full editor to save it, share it and keep building.
Sample run
What the program printed, and what was typed (in yellow).
Text analyzer Paste or type your text. Press Enter on an empty line to finish. > Python was created by Guido van Rossum and first released in 1991. Today Python is used for websites, data science, games and teaching. > Why do so many beginners start with Python? It reads almost like English, so beginners can focus on ideas. Many schools teach Python, and many games are written in it. > Text report -------------------------------- Characters 303 Characters (no spaces) 251 Words 53 Unique words 41 Sentences 5 Words per sentence 10.6 Average word length 4.6 -------------------------------- Longest word: beginners (9 letters) Reading time: about 16 seconds Most used words (leaving out small words like "the"): python 4 **** many 3 *** games 2 ** beginners 2 ** Analyze another text? (y/n) y Paste or type your text. Press Enter on an empty line to finish. > There are no words to analyze. Analyze another text? (y/n) n Goodbye.
How it is built
1. Reading several lines
input() reads one line at a time, so the program keeps reading until the user enters an empty line, then joins the lines with spaces.
def read_paragraph(): """Read lines until an empty line and return them as one text.""" print("Paste or type your text. Press Enter on an empty line to finish.") lines = [] while True: line = input("> ") if not line.strip(): break lines.append(line.strip()) return " ".join(lines)
2. Finding the words
The pattern matches runs of letters and digits with an optional apostrophe part, so don't stays one word and punctuation is left out. Lower-casing first means Python and python count as the same word.
def find_words(text): """Return the words in the text, lowercase, keeping words like don't.""" return re.findall(r"[a-z0-9]+(?:'[a-z]+)?", text.lower())
3. Counting sentences
re.split() cuts the text at every full stop, question mark or exclamation mark. Empty pieces, like the one after the last full stop, are not counted.
def count_sentences(text): """Count sentences by splitting at full stops, ? and exclamation marks.""" pieces = re.split(r"[.?!]+", text) return sum(1 for piece in pieces if piece.strip())
4. Reading time
At 200 words a minute, each word takes 0.3 seconds. divmod() splits the total into whole minutes and the seconds left over.
def reading_time(word_count): """Turn a word count into a friendly reading time.""" seconds = round(word_count / WORDS_PER_MINUTE * 60) if seconds < 10: return "a few seconds" if seconds < 60: return f"about {seconds} seconds" minutes, seconds = divmod(seconds, 60) extra = f" {seconds} s" if seconds else "" return f"about {minutes} min{extra}"
5. The most used words
Counter counts every word that is not in STOP_WORDS, and most_common() returns the top ones. Each count is drawn as a bar of stars.
def print_common_words(words): """Print the words used more than once, leaving out small words.""" counts = Counter(word for word in words if word not in STOP_WORDS) top = counts.most_common(TOP_WORDS) repeated = [(word, n) for word, n in top if n > 1] print('\nMost used words (leaving out small words like "the"):') if not repeated: print(" No word appears more than once.") for word, count in repeated: print(f" {word:<14}{count:>3} {'*' * count}")
6. The report
max(words, key=len) finds the longest word and len(set(words)) counts the different words. Widths like :<22 and :>10 in the f-strings line the labels and numbers up in columns.
def analyze(text): """Print a report of counts, averages and the most common words.""" words = find_words(text) if not words: print("There are no words to analyze.") return longest = max(words, key=len) average = sum(len(word) for word in words) / len(words) sentences = count_sentences(text) print("\nText report") print("-" * 32) print(f"{'Characters':<22}{len(text):>10}") print(f"{'Characters (no spaces)':<22}{len(text.replace(' ', '')):>10}") print(f"{'Words':<22}{len(words):>10}") print(f"{'Unique words':<22}{len(set(words)):>10}") print(f"{'Sentences':<22}{sentences:>10}") print(f"{'Words per sentence':<22}{len(words) / max(sentences, 1):>10.1f}") print(f"{'Average word length':<22}{average:>10.1f}") print("-" * 32) print(f"Longest word: {longest} ({len(longest)} letters)") print(f"Reading time: {reading_time(len(words))}") print_common_words(words)
Make it bigger
- Add a readability score such as Flesch reading ease, which uses words per sentence and syllables per word.
- Read the text from a .txt file instead of typing it.
- Show the most common letters as well as the most common words.
- Compare two texts and list the words they share.
What it practises
- re.findall and re.split
- collections.Counter
- sets for unique words
- lining up columns with f-strings