Decomposition: the actual job
Nobody can write a big program in one go. Engineers practice decomposition: splitting a problem into steps so small that each one is obviously codeable.
Take "compute the average of three test scores typed by a user". Decomposed:
- Read the first score and convert it to a number (lessons 1-3 and 2-3)
- Same for the second and third
- Add the three, divide by 3 (lesson 2-2), store it in a well-named variable (unit 3)
- Print the result
Every step is something you already know how to write. That is the feeling to chase: decompose until each piece is boring.
first = int(input()) second = int(input()) third = int(input()) average = (first + second + third) / 3 print(average)
Note the parentheses forcing the addition before the division, exactly the precedence rule from lesson 2-2.
The decomposed program running
Three scores on three lines, averaged.
first = int(input()) second = int(input()) third = int(input()) average = (first + second + third) / 3 print(average)
Input
10 20 30
Output
20.0Each input() call consumes one line, in order, which is why three calls read three separate scores. The order the lines are read in is the order the calls appear.
The output is 20.0 rather than 20 because / always produces a float, as lesson 2-2's operator table showed. That is the right choice for an average, since most averages are not whole numbers, and getting 20.0 here is a hint that 21.5 would work too.
The first move on a bigger problem
The best first move is to break it into small steps: ask one question, check one answer, keep a score with an accumulator, then repeat 10 times with a loop.
Decompose before writing anything. The value of doing it first is that each resulting piece turns out to be something you already own:
| step | what it uses |
|---|---|
| ask one question | print and input(), unit 1 |
| check one answer | comparison, unit 4 |
| keep a score | the accumulator pattern, lesson 5-3 |
| repeat 10 times | a for loop, lesson 5-1 |
Big programs are small pieces assembled deliberately. Nothing in that table is beyond you, and the version of this problem that feels impossible is the version where all ten questions and the scoring are one undifferentiated blob.
Notice the order the steps are in, too. Getting one question working before adding the loop means you debug one thing at a time, which is faster than debugging ten repetitions of an untested idea.
Sum and difference of two numbers
Read both numbers into variables, then use each twice.
a = int(input()) b = int(input()) print(a + b) print(a - b)
Input
8 3
Output
11 5
Reading the pieces
- Each number needs its own
int(input())line, exactly as in the average example above. - Storing them in variables is what makes using each one twice possible. Without the variables the first value would be gone by the time you needed it for the subtraction.
- The arithmetic checks out as 8 + 3 = 11 and 8 − 3 = 5.
- The order of the subtraction matters and the problem specified it.
b - awould print −5, which is a different answer to a question nobody asked.
A tip calculator
Read the bill and the percent, compute the tip, then print the tip and the total.
bill = int(input()) percent = int(input()) tip = bill * percent / 100 print(tip) print(bill + tip)
Input
50 20
Output
10.0 60.0
Reading the pieces
- Each step is one or two lines you already know: two reads, one calculation, two prints. That is decomposition doing its job.
- Dividing with
/produces a float, which is why both outputs end in.0even though the numbers are whole. - The arithmetic checks out as 50 × 20 / 100 = 10.0 and 50 + 10.0 = 60.0.
- Storing the tip in its own variable is what lets the second
printreuse it. Recomputingbill * percent / 100on the total line would work and would mean the same expression exists in two places, which is how one of them eventually gets updated and the other does not.