Greeting Formatter Class

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
Amazon

Problem

You're building a small text-cleanup utility as a class. Implement MessageFormatter with a method sort_by_case(text) that returns text regrouped so every lowercase letter comes first, then every uppercase letter, then everything else (digits, spaces, punctuation), with each character keeping the position it had within its own group. Also expose a top-level sort_by_case(text) that builds a MessageFormatter, runs the method, and returns the string; that driver is the graded entry point.

First impressions are formatted carefully.

Example 1

Input:

text = "hElLo"

Output:

"hloEL"

Example 2

Input:

text = "PyThOn"

Output:

"yhnPTO"

Worked solution and explanation

What this really is

Strip the 'formatter' costume and this is a stable three-way partition: lowercase, uppercase, everything else, with each character holding the position it had inside its own group. Anyone can bucket the characters. The tell is whether you keep them STABLE. Reach for a sort keyed on case and you scramble the within-group order the problem quietly demands, and it is just as easy to let the digits and spaces disappear into a letter bucket. The class-and-driver shape is the second half: the object does the work, but a plain top-level sort_by_case(text) is what gets graded, so the callable surface has to delegate cleanly.


Break it down

Step 1: Walk the text once

Make three empty lists and iterate the characters of text a single time. Appending as you go keeps each character in the order it appeared, which is exactly the stability the result needs.

Step 2: Classify each character

For each character, ask islower() first, then isupper(); anything that answers no to both (digits, spaces, punctuation) falls through to the third list. The order of the checks does not matter as long as non-letters have a home.

Step 3: Concatenate in case order

Join the three lists and concatenate them lowercase, then uppercase, then the rest. Building the strings once at the end with join avoids repeated string concatenation inside the loop.

Step 4: Expose the driver

The class does the work, but the grader calls the top-level sort_by_case(text). Have it construct a MessageFormatter, call its sort_by_case(text), and return the string, so the object design stays behind a plain callable surface.


The solution

Class with a stable three-way partition, exposed via a top-level driver
class MessageFormatter:
    def sort_by_case(self, text):
        lower = []
        upper = []
        other = []
        for char in text:
            if char.islower():
                lower.append(char)
            elif char.isupper():
                upper.append(char)
            else:
                other.append(char)
        return ''.join(lower) + ''.join(upper) + ''.join(other)


def sort_by_case(text):
    return MessageFormatter().sort_by_case(text)

Common follow-up questions