Breaking Problems into Steps
Beginners often look at a problem, open the editor and start typing, hoping the code will somehow work out. It rarely does. Experienced programmers spend most of their time before typing: understanding the problem and breaking it into small pieces, each of which is easy to solve. This is called decomposition.
In this lesson you will learn a six-step method for any programming problem, and use it on a real one: splitting a trip's expenses fairly among friends.
A six-step method
- Understand the problem. What goes in (the inputs)? What should come out (the outputs)? Ask questions until you can say both clearly.
- Work one example by hand. Use pen and paper and real numbers. If you cannot solve it by hand, you cannot tell a computer how to.
- Break it into smaller problems. Each piece should be small enough that you can see how to code it.
- Write the plan in pseudocode or a flowchart.
- Code one piece at a time and test it before moving to the next.
- Check unusual cases, such as zero, empty lists or numbers that do not divide evenly.
Step 1: understand the problem
Four friends went on a weekend trip to Jaipur. Different people paid for different things. They want to split the total cost equally and know who owes money and who should get money back.
- Input: each person's name and how much they paid.
- Output: for each person, either "gets back ₹X" or "owes ₹X".
Step 2: work an example by hand
| Person | Paid for | Amount paid |
|---|---|---|
| Aarav | Hotel | ₹4,200 |
| Priya | Food | ₹1,800 |
| Rohan | Nothing | ₹0 |
| Meera | Fort tickets | ₹1,000 |
Total spent: 4200 + 1800 + 0 + 1000 = ₹7,000. Fair share: 7000 ÷ 4 = ₹1,750 each.
- Aarav paid 4200, which is 2450 more than his share: he gets back ₹2,450.
- Priya paid 1800, which is 50 more: she gets back ₹50.
- Rohan paid 0, which is 1750 less: he owes ₹1,750.
- Meera paid 1000, which is 750 less: she owes ₹750.
Check: the money owed (1750 + 750 = 2500) equals the money to give back (2450 + 50 = 2500). The hand calculation is correct, and you now have test answers for your program.
Step 3: break it into smaller problems
Looking at what you did by hand, there are three separate jobs:
- Add up what everyone paid.
- Divide by the number of people to get the share.
- For each person, compare what they paid with the share and print the result.
Step 4: write the plan
SET total TO sum of all amounts paid
SET share TO total / number of people
FOR EACH person
SET difference TO amount paid - share
IF difference > 0 THEN
PRINT name, "gets back", difference
ELSE IF difference < 0 THEN
PRINT name, "owes", -difference
ELSE
PRINT name, "is settled"
END IF
END FORStep 5: code and test one piece at a time
Start with piece 1 only, and test it against the hand answer of 7000:
payments = [["Aarav", 4200], ["Priya", 1800], ["Rohan", 0], ["Meera", 1000]]
def total_paid(payments):
total = 0
for name, amount in payments:
total += amount
return total
print(total_paid(payments))7000
It matches, so move on. for name, amount in payments takes each small list such as ["Aarav", 4200] and unpacks its two items into name and amount. Now add the share and the comparison:
payments = [["Aarav", 4200], ["Priya", 1800], ["Rohan", 0], ["Meera", 1000]]
def total_paid(payments):
total = 0
for name, amount in payments:
total += amount
return total
def settle(payments):
total = total_paid(payments)
share = total / len(payments)
print(f"Total ₹{total}, share ₹{share:.0f} each")
for name, amount in payments:
difference = amount - share
if difference > 0:
print(f"{name} gets back ₹{difference:.0f}")
elif difference < 0:
print(f"{name} owes ₹{-difference:.0f}")
else:
print(f"{name} is settled")
settle(payments)Total ₹7000, share ₹1750 each Aarav gets back ₹2450 Priya gets back ₹50 Rohan owes ₹1750 Meera owes ₹750
Every line matches the hand calculation. Here is the same solution in JavaScript, built from the same plan:
const payments = [["Aarav", 4200], ["Priya", 1800], ["Rohan", 0], ["Meera", 1000]];
function totalPaid(payments) {
let total = 0;
for (const [name, amount] of payments) {
total += amount;
}
return total;
}
function settle(payments) {
const total = totalPaid(payments);
const share = total / payments.length;
console.log(`Total ₹${total}, share ₹${share} each`);
for (const [name, amount] of payments) {
const difference = amount - share;
if (difference > 0) {
console.log(`${name} gets back ₹${difference}`);
} else if (difference < 0) {
console.log(`${name} owes ₹${-difference}`);
} else {
console.log(`${name} is settled`);
}
}
}
settle(payments);Total ₹7000, share ₹1750 each Aarav gets back ₹2450 Priya gets back ₹50 Rohan owes ₹1750 Meera owes ₹750
Step 6: check unusual cases
Good programmers ask "what could break this?" Try these by changing the data:
- The total does not divide evenly. With three friends and ₹1,000, the share is 333.33... Formatting with
:.0frounds it, so the amounts may not add up exactly. A real app would work in paise or give the extra rupee to one person. - An empty list.
len(payments)is 0, and dividing by zero crashes the Python version. You could checkif not payments:at the start and print a message. - Everyone paid the same. Every person should be "settled". Test it.
You do not have to handle every case on day one, but you should know they exist.
Common mistakes
- Coding before understanding. If you cannot state the inputs and outputs in one sentence each, go back to step 1.
- Writing the whole program, then testing. When fifty new lines fail, the bug could be anywhere. Test each piece as you add it.
- Testing only with easy numbers. Also try zero, one item, equal values and numbers that do not divide evenly.
- One giant block of code. Split it into functions, each doing one job, so each part can be tested on its own.
Key points
- Decomposition means breaking a big problem into small problems that are easy to solve.
- Start by naming the inputs and outputs, then solve one example by hand.
- The hand-worked example gives you the test answers for your program.
- Write a plan, then code one piece at a time and test each piece before moving on.
- Functions are a natural way to hold each small piece.
- Always ask which unusual inputs could break your program.
Exercise
A college needs 75% attendance. There were 24 classes. Use the six steps to write a program that prints each student's attendance percentage (one decimal place) and then a list of the students below 75%. Data: Aarav attended 18, Isha 22, Kabir 15, Ananya 24. Work out the answers by hand first, then write a function attendance_percent(attended, total) and use it.
Show solution
By hand: Aarav 18/24 = 75.0%, Isha 91.7%, Kabir 62.5%, Ananya 100.0%. Only Kabir is below 75%.
TOTAL_CLASSES = 24
records = [["Aarav", 18], ["Isha", 22], ["Kabir", 15], ["Ananya", 24]]
def attendance_percent(attended, total):
return attended / total * 100
shortage = []
for name, attended in records:
pct = attendance_percent(attended, TOTAL_CLASSES)
print(f"{name}: {pct:.1f}%")
if pct < 75:
shortage.append(name)
print("Below 75%:", shortage)Aarav: 75.0% Isha: 91.7% Kabir: 62.5% Ananya: 100.0% Below 75%: ['Kabir']
The program reuses the hand-worked answers as a test. Aarav at exactly 75% is not in the shortage list, because the check is < 75, which matches the rule "75% is needed".
Quick Quiz
1. What is decomposition?
Small pieces are easier to plan, code and test than one big problem.
2. Why work an example by hand before coding?
If you can solve it by hand, you can describe the steps, and you know what output to expect.
3. What should you do after coding the first small piece of a program?
Testing each piece as you go keeps bugs small and easy to find.
4. In the trip example, what happens with an empty list of payments?
len(payments) is 0, so total / len(payments) divides by zero; check for an empty list first.
Learn Intro to Programming with a mentor
Free lessons get you started. Our Python Programming training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
