| layout | default |
|---|---|
| title | Problem-Solving Guide |
| parent | Practice and Projects |
| nav_order | 1 |
| permalink | /practice/problem-solving-guide/ |
Intermediate problems ask two questions: “Does the code work?” and “Is the design easy to change, test, and operate?” Solve correctness first and improve the design second.
Rewrite the problem in one sentence. List the input, output, rules, and anything still unknown.
Write at least three cases:
- one normal case;
- one boundary case, such as empty input;
- one invalid or failure case.
Write small numbered steps before code. Decide which responsibility belongs in each function or class and which data structure makes the rule clear.
Build the smallest working version. Run each planned case. Test behavior rather than internal line-by-line details.
Improve names, remove repetition, separate dependencies, and measure performance only when input size makes it relevant.
Input:
orders = [
{"customer": "Asha", "total": 120},
{"customer": "Ben", "total": 80},
{"customer": "Asha", "total": 50},
]Expected shape:
{
"Asha": [120, 50],
"Ben": [80],
}Plan:
- Start with an empty dictionary.
- Read one order at a time.
- Create the customer's list if it does not exist.
- Append the total.
- Return the dictionary.
Only after this works should you decide whether defaultdict, a dataclass, validation, or a database is useful.
Before finishing, ask:
- Can names reveal the intent without comments?
- Does each function have one clear responsibility?
- Is external I/O separated from business rules?
- Can a test replace the network, clock, or database?
- What happens for empty, malformed, duplicated, slow, or very large input?
- Are errors useful to the caller without exposing secrets?
- Is added complexity solving a real problem?
Do not guess from code length. Identify the operation repeated as input grows, create realistic data, and measure the whole task. A generator may save memory but can be slower or harder to reuse; concurrency adds coordination cost; a database index speeds some reads but costs storage and write work. Record the trade-off you chose.
Problem:
Input:
Output:
Rules:
Normal example:
Boundary example:
Failure example:
Plan:
Dependencies:
Tests:
Complexity or performance concern:
What I would improve next: