String Methods: split, find, startswith
The split method provides another approach: splitting the address at @ produces parts, and the second part is the domain.
Try it: Counting Words with a Dictionary
The py4e histogram pattern: split each line into words, count them with counts[word] = counts.get(word, 0) + 1, then find the most common word with a max loop or by sorting (count, word) tuples in reverse.
How it works
- Optionally remove punctuation with str.translate and lower-case the line, then split() it into words.
- For each word: counts.get(word, 0) returns the current count or 0 for a new word; store it plus one (or the if word not in counts form).
- A dict remembers insertion order: a word's position is fixed the first time it is seen.
- Max loop: keep the word whose count is strictly larger than the best so far (the first word wins a tie).
- Or build [(count, word) …], sort with reverse=True (ties ordered by the word, reversed) and slice [:N].
Default run (25 steps): Start with an empty dict. The text has 3 lines. … [:3] keeps the top 3: [(5, 'the'), (2, 'sat'), (2, 'on')].
Simplified: Printable-ASCII text up to 320 characters, 8 lines and 60 words, typed in the lab instead of read from a file or URL.
Loading the simulation…
From Mail Log to Evidence
A mail log may contain thousands of messages. Looking at the raw lines makes it difficult to answer questions such as which sender emailed most often or which organization sent the most mail. A histogram turns those repeated values into a dictionary: each unique value becomes a key, and its frequency becomes the associated value.
The central analytical choice is the key you count. A full email address groups messages by individual sender. A domain groups messages by organization. The same raw messages can therefore produce different results when the analysis becomes more or less granular.
Building the Email Histogram
To count messages from each full email address, process one address at a time and use the address as the dictionary key. The pattern counts[key] = counts.get(key, 0) + 1 handles both cases: a key that has not appeared before starts at zero, while an existing key receives one more count. Repeating this operation makes all messages from the same sender accumulate under one dictionary key.
Counting Repeated Senders
Count these sender addresses: ana@example.com, lee@example.com, ana@example.com, sam@school.org.
- 1First address
ana@example.com is not yet a key, so its count becomes 1.
- 2Second address
lee@example.com is new, so its count becomes 1.
- 3Third address
ana@example.com already has a count of 1, so it becomes 2.
- 4Fourth address
sam@school.org is new, so its count becomes 1.
The histogram is ana@example.com: 2, lee@example.com: 1, and sam@school.org: 1.
Separating Username and Domain
An email address contains a username part before the @ character and a domain part after it. The find method locates the position of @. Once that position is known, slicing from the position after @ selects the domain. The split method provides another approach: splitting the address at @ produces parts, and the second part is the domain.
Selecting the Maximum Sender
After building the histogram, finding the most prolific sender requires a maximum loop. Keep two pieces of state: the key for the current best sender and the value for that sender's current highest count. For each dictionary entry, compare its count with the current maximum. When the new count is higher, replace both tracked values.
largest_sender = None
largest_count = 0
for sender in counts:
if counts[sender] > largest_count:
largest_sender = sender
largest_count = counts[sender]- 1Begin with no selected sender and a current maximum of zero.
- 2Read one sender from the dictionary.
- 3If that sender's count is greater than the current maximum, save the sender and its count.
- 4Continue through the dictionary. At the end, the saved pair represents the highest frequency found.
largest_senderstores the key associated with the highest count found so far.largest_countstores the highest count found so far.- Each dictionary key is examined.
- A larger count replaces both pieces of maximum-tracking state.
largest_sender: ana@example.com
largest_count: 2Changing the Counting Granularity
Counting full addresses answers an individual-sender question. To ask which organizations send the most mail, extract each address's domain first and use that domain as the histogram key. Messages from different usernames then accumulate together when their domains match.
| Histogram key | Question answered | Grouping effect |
|---|---|---|
| Full email address | Which individual sender sent the most messages? | Different usernames remain separate. |
| Domain | Which organization or domain sent the most messages? | Addresses sharing a domain are combined. |
The key determines the granularity of the analysis.
Checking Message Prefixes
The startswith method can identify lines or messages whose text begins with a required prefix. This is useful when processing a log and selecting only lines that begin with a particular marker before extracting or counting their contents.
Mistakes in Histogram Analysis
Common mistake Using the full email address when the question asks for organization-level results.
What it looks likeCounting ana@example.com and lee@example.com as unrelated keys.
Why it failsThe two senders have different full addresses, but their shared domain should be combined for a domain histogram.
Do this insteadExtract the domain with email.split("@")[1] and use that domain as the dictionary key.
Common mistake Updating a histogram without handling a key's first appearance.
What it looks likecounts[email] = counts[email] + 1Why it failsA new email address does not yet have a dictionary value.
Do this insteadUse counts[email] = counts.get(email, 0) + 1.Common mistake Tracking only the largest count during the maximum loop.
What it looks likeSaving largest_count but not the sender key.
Why it failsThe count tells you the frequency, but not which dictionary entry produced it.
Do this insteadTrack both the current maximum key and its value.
Common mistake Treating find's result as the domain itself.
What it looks likeUsing email.find("@") as though it returned example.com.Why it failsfind locates the position of @. It does not extract the text after that position.
Do this insteadSlice from the position after @, or use email.split("@")[1].
Common mistake Using startswith to find a prefix anywhere in a line.
What it looks likeExpecting line.startswith("From:") to match text that appears later.
Why it failsThe method checks whether the string begins with the specified prefix.
Do this insteadUse startswith only when the required text must occur at the beginning.
Practice the Transformation
Suppose the messages come from ana@example.com, lee@example.com, ana@example.com, pat@school.org, and lee@example.com. Determine the full-address histogram, identify the sender with the highest count, and then determine the domain histogram.
Hints
- Use each full email address as the first histogram key.
- For the domain histogram, split each address at @ and use the second part.
- For the maximum, compare each dictionary count while tracking both the sender and the count.
- 1A strong solution produces a full-address histogram with ana@example.com counted twice, lee@example.com counted twice, and pat@school.org counted once. The maximum loop identifies a tie between ana@example.com and lee@example.com at two messages; the exact selected sender depends on how the loop handles equal counts. The domain histogram combines the first two addresses under example.com for a total of four messages, while school.org has one.
Key Takeaways
- A histogram stores frequencies in a dictionary: unique values are keys and occurrence counts are values.
- Use counts[key] =
counts.get(key, 0)+ 1 to update a histogram for new and existing keys. - Use a maximum loop that tracks both the highest count and the key associated with it.
- find locates the @ separator, while
split("@")[1] directly extracts the domain. - Changing the key from a full email address to a domain changes the analysis from individual senders to organizations.