Problem Solving: Beginner
Stripe's engineering culture is famous for its focus on algorithmic problem-solving because every major product at the company - payments, billing, fraud detection, and tax calculation - was built by engineers who learned to decompose complex problems into small, solvable steps before writing a single line of code. The ability to look at a hard problem and see a structured sequence of simpler problems is what separates engineers who ship at scale from those who get stuck. Every Stripe engineer started exactly where you are now, practicing the skill of translating a real-world problem into a clear algorithm. This lesson builds exactly that foundation.
Breaking Problems into Steps
Turn word problems into code steps
Example: Calculating a Tip
The Power of Pseudocode
- FOR each number in the list
- IF number is even
- add it to the sum
- PRINT the sum
- for num in numbers:
- if num % 2 == 0:
- total += num
- print(total)
> A loop adds up numbers [10, 20, 30] into a running total. Pick the right assignment operator to accumulate the sum step by step.
total = 0 for num in [10, 20, 30]: total num print(total)
Input/Output Analysis
Map inputs to outputs before coding
Finding the Largest Value
Testing with Examples
> This find_largest function initializes largest to 0, so it fails when all numbers in the list are negative. It returns 0 instead of the actual largest value.
Returns 0 instead of -1 for a list of negative numbers
Analyzing inputs and outputs before writing code reveals hidden assumptions. The fix here -- initializing largest to numbers[0] rather than 0 -- only becomes obvious when you test with negative inputs.
Tracing Code Manually
Trace any loop by hand on paper
The Variable Table Method
This code swaps the values of x and y without using a temporary variable. Tracing reveals how it works.
Tracing Loops
> A loop runs four times with i going from 0 to 3, combining each value into a running total. Pick an arithmetic operator and trace what the final result will be.
total = 0 for i in range(4): total = total i print(total)
Pattern Recognition
Pick the right pattern for any loop
The Accumulator Pattern
- Need a single total, count, or combined result? Use the accumulator pattern
- Need to know IF something exists in a collection? Use the search pattern with early return
- Need a subset of items that match a rule? Use the filter pattern with an empty list and append
- Not sure yet? Start with the simplest approach, then refactor once you see the shape of the answer
The Search Pattern
The Filter Pattern
> This filter loop uses != 0 instead of == 0 in the modulo check, so it keeps odd numbers instead of even ones.
Prints [1, 3, 5] instead of [2, 4, 6]
Testing Simple Cases
Catch bugs with edge case tests
Start Simple
Edge Cases Matter
> This average calculator divides by len(numbers) without checking for an empty list first, causing a ZeroDivisionError when no numbers are provided.
ZeroDivisionError: division by zero when the list is empty
> You are a junior data analyst at Accenture working through your first real-world client data cleaning task. You must systematically debug errors in a messy CSV dataset to deliver a clean, validated output file by end of week.
KeyError exceptions all share the same missing column name, targeting the root cause in one fix.Think before you code
- Category
- Python
- Difficulty
- beginner
- Duration
- 20 minutes
- Challenges
- 0 hands-on challenges
Topics covered: Breaking Problems into Steps, Input/Output Analysis, Tracing Code Manually, Pattern Recognition, Testing Simple Cases
Lesson Sections
- Breaking Problems into Steps (concepts: pyFuncDef)
Every complex problem is just a collection of simple problems. The key skill is decomposition: breaking a big problem into smaller, manageable pieces that you can solve one at a time. Example: Calculating a Tip Problem: Write a program that calculates the tip for a restaurant bill. Before writing any code, let's break this down: Now each step is simple enough to code directly: Notice how the code directly mirrors our steps. This is no accident. When you plan well, the code practically writes its
- Input/Output Analysis (concepts: pyFuncDef)
Before solving any problem, you must understand two things: What data goes IN (inputs) and what data comes OUT (outputs). Everything else is just the transformation between them. Finding the Largest Value Problem: Given a list of numbers, find the largest one. With this analysis, writing the code becomes straightforward: Testing with Examples Always create concrete examples before coding. Work through them by hand to verify your understanding. Problem: Reverse a string. These examples help you u
- Tracing Code Manually (concepts: pyWhileLoops)
Code tracing means executing code in your head (or on paper) exactly as a computer would, step by step. This skill is essential for debugging and understanding how code works. The Variable Table Method Create a table tracking the value of each variable after every line executes. Let's trace this code: Tracing Loops Loops require tracking values across multiple iterations. Trace this code that calculates the sum of digits: Manual tracing builds the mental model you need to debug. When code does n
- Pattern Recognition (concepts: pyForBasic)
Most programming problems follow common patterns. Once you recognize a pattern, you can apply a known solution approach. This is why experienced programmers solve problems faster; they've seen similar patterns before. The Accumulator Pattern This pattern builds up a result by processing items one at a time. You start with an initial value and update it in a loop. These three patterns cover the vast majority of beginner problems. Recognizing which one applies is often the hardest part, so here is
- Testing Simple Cases (concepts: pyTesting)
Before testing complex inputs, always verify your code works with simple cases. If it fails on easy inputs, it will definitely fail on hard ones. Start Simple When testing a function that processes lists, try these in order: Example: Testing a function that finds the maximum: Edge Cases Matter Edge cases are inputs at the boundaries of what's valid. They're where bugs most commonly hide. Handling edge cases is not optional. It separates working code from production-ready code. The consequences o