What’s one thing you learned? What’s still confusing?
Strings: Methods, f-strings & Text Processing
All string methods, f-string format specs, Unicode/UTF-8, bytes vs str, and regex basics.
Mini-Project: Password Strength Checker
Build a strength meter that scores a password against five rules.
Error Handling & Debugging: Don't Panic at Red Text
Read Python errors confidently, handle failures with try/except, and debug systematically.
Interactive Labs for This Track
Loop Visualizer
You're a factory robot repeating the same task on an assembly line — watch how loops automate repetitive work
List Slicing
You have a playlist of 50 songs — grab just tracks 10 through 20 with a single slice expression
Sorting Algorithms
You're organizing a library of 10,000 books — which sorting method is fastest?
Ask questions, share insights
dict.get(), and sorted by value.A program that takes a chunk of text and returns the word frequencies, sorted from most common to least common.
Text: the cat sat on the mat the cat slept
the: 3
cat: 2
sat: 1
on: 1
mat: 1
slept: 1
.split()dict.get(key, 0) + 1sorted and a key lambda.split() with no arguments breaks a string into a list of "tokens", separating on any whitespace and dropping empty strings.text = "the cat sat on the mat"
words = text.split()
print(words)
# ['the', 'cat', 'sat', 'on', 'the', 'mat']That's all you need to start counting -- a list of words.
What does " one two three ".split() return? (split with NO argument)
['one', 'two', 'three']. Calling .split() with NO argument is special: it splits on any run of whitespace, AND it automatically discards empty strings from leading/trailing whitespace. This is almost always what you want for text. Contrast with .split(" ") (explicit single space): that gives ['', '', 'one', '', 'two', ...] — empty strings everywhere. Lesson: prefer .split() over .split(" ") for natural text.What does `' hello world '.split()` return?
Loop over the words. For each word, check if it's already a key in the dict -- if yes, add one; if no, start at one.
text = "the cat sat on the mat the cat slept"
words = text.split()
counts = {}
for word in words:
if word in counts:
counts[word] += 1
else:
counts[word] = 1
print(counts)
# {'the': 3, 'cat': 2, 'sat': 1, 'on': 1, 'mat': 1, 'slept': 1}That works, but there's a slicker way -- next step.
dict.getcounts.get(word, 0) returns the current count -- or 0 if the word hasn't been seen yet. That eliminates the if/else.counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
print(counts)collections module later, you'll switch to Counter -- but dict.get(key, 0) + 1 is what every Python coder starts with.)What happens? counts = {} counts["cat"] += 1
+= operator desugars to counts["cat"] = counts["cat"] + 1 — and the right side reads counts["cat"] BEFORE assignment. Since "cat" isn't in the dict, that read raises KeyError. This is exactly why we use counts.get("cat", 0) + 1 — .get() returns the default 0 instead of crashing, making the first increment work. Alternative: from collections import defaultdict; counts = defaultdict(int) — then counts["cat"] += 1 just works.What does `counts.get('xyz', 0)` return if 'xyz' is not in counts?
sorted() with a key lambda and reverse=True.counts = {'the': 3, 'cat': 2, 'sat': 1, 'on': 1, 'mat': 1, 'slept': 1}
ranked = sorted(counts.items(), key=lambda kv: kv[1], reverse=True)
for word, count in ranked:
print(f"{word}: {count}")
# the: 3
# cat: 2
# sat: 1
# ...counts.items() returns (key, value) tuples. key=lambda kv: kv[1] tells sorted to sort by the SECOND element of each tuple -- the count. reverse=True flips it to descending.What is the FIRST element after sorting? items = [("apple", 3), ("banana", 1), ("cherry", 2)] sorted_items = sorted(items, key=lambda kv: kv[1])
key function tells sorted what to compare by — here kv[1] is the second element of each tuple (the count). So Python compares 3, 1, 2, and orders ASCENDING by default: 1, 2, 3. ('banana', 1) comes first. Without the key, sorted would compare tuples lexicographically (by first element first) and order alphabetically: apple, banana, cherry. The key= parameter is the unlock for sorting by any computed property — by length (key=len), by score (key=lambda x: x.score), or by anything else.def word_counts(text):
counts = {}
for word in text.split():
counts[word] = counts.get(word, 0) + 1
return sorted(counts.items(), key=lambda kv: kv[1], reverse=True)
for word, n in word_counts("the cat sat on the mat the cat slept"):
print(f"{word}: {n}")Five-line function. Works on any string -- a sentence, a paragraph, the contents of a file (once you learn file I/O).
Write a function `word_counts(text)` that returns a list of (word, count) tuples sorted by count descending. Make it case-insensitive ('The' and 'the' should count as the same word) and strip punctuation ('cat,' and 'cat' should count as the same word). Use only the standard library.
Input: "The cat sat. The CAT slept on the mat -- a happy cat."
cat: 3
the: 3
on: 1
mat: 1
sat: 1
slept: 1
a: 1
happy: 1def word_counts(text):
# TODO: lowercase the text
# TODO: split into words
# TODO: for each word, strip punctuation -- skip if empty
# TODO: count occurrences with dict.get
# TODO: return sorted by count descending
pass
text = "The cat sat. The CAT slept on the mat -- a happy cat."
for word, n in word_counts(text):
print(f"{word}: {n}")
Try one of these variations:
top=10 parameter so the function returns only the 10 most common words. Use list slicing on the sorted result.STOPWORDS = {"the", "a", "an", "is", ...} set. Only count words NOT in stopwords.word_counts becomes one piece of a larger text-processing pipeline.