The Letter Tally

An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.

Domain
Python
Difficulty
easy
Seniority
L3
Asked in
Nintendo

Problem

We're tallying how often each character shows up in the free-text fields coming off a data feed. Implement a CharCounter class built from a string text, plus a top-level char_counter_demo(text) that constructs it and returns its get_counts(): one [char, count] pair per distinct character, sorted by character. Only alphanumeric characters count, spaces and punctuation don't, and case matters, so 'A' and 'a' are separate entries.

Each character in the string has a count to answer for.

Example 1

Input:

text = "hello world"

Output:

[["d",1],["e",1],["h",1],["l",3],["o",2],["r",1],["w",1]]

Example 2

Input:

text = "Aa Bb! a."

Output:

[["A",1],["B",1],["a",2],["b",1]]

Worked solution and explanation

What this problem really is

Underneath the class wrapper, this is a filtered frequency table: the constructor walks text once and accumulates counts, and get_counts hands back a sorted view. The skill is deciding exactly which characters earn a row, and keying each row on the character exactly as it appeared. The trap that sinks people is the filter: reach for isalpha() and every digit silently disappears, because digits are alphanumeric too. The second trap is case: lowercase on the way in and 'A' and 'a' collapse, so 'aAaA' comes back as one row of 4 instead of two rows of 2.


Break down the requirements

Step 1: Accumulate counts in __init__, filtering as you go

Walk the string once in the constructor. Skip anything that fails isalnum() (spaces, punctuation) and bump a per-character counter for the rest. Do not lowercase: case is part of the identity here.

Step 2: Have get_counts return sorted [char, count] pairs

Sort the distinct characters with plain sorted(). That is codepoint order, which naturally puts every uppercase letter ahead of every lowercase one, so 'B' lands before 'a'. Emit each character with its count as a two-element pair.

Step 3: Wire the class to a top-level driver

The grader calls one top-level function, so char_counter_demo(text) builds CharCounter(text) and returns its get_counts() result. It is a thin driver, nothing more.


The solution

Class with filtered frequency counting plus a driver
class CharCounter:
    def __init__(self, text: str):
        self.freq = {}
        for ch in text:
            if not ch.isalnum():
                continue
            if ch in self.freq:
                self.freq[ch] += 1
            else:
                self.freq[ch] = 1

    def get_counts(self) -> list:
        result = []
        for key in sorted(self.freq.keys()):
            result.append([key, self.freq[key]])
        return result


def char_counter_demo(text: str) -> list:
    counter = CharCounter(text)
    return counter.get_counts()
`isalnum()` (correct)
Keeps letters AND digits, so 'b3a3b' tallies the 3s. Spaces and punctuation drop out.
`isalpha()` (silent bug)
Keeps only letters, so every digit vanishes with no error. 'b3a3b' loses its 3s and nobody notices until a count is wrong.

Common follow-up questions