This session finishes off loops (patterns, nested loops, loop control) and then dives properly into strings.
Current population is 10000 and it grows 10% every year. We want the population at the end of each of the last 10 years, so we walk backwards. Going back one year undoes a 10% increase, which means dividing by 1.1.
curr_pop = 10000
for i in range(10, 0, -1): # counts 10, 9, 8, ... down to 1
print(i, curr_pop)
curr_pop = curr_pop / 1.1 # step one year into the past
Output (decimals get long, shown rounded):
10 10000
9 9090.91
8 8264.46
7 7513.15
6 6830.13
5 6209.21
4 5644.74
3 5131.58
2 4665.07
1 4240.98
We print first, then divide. So year 10 shows the full 10000, and each earlier year is a bit smaller.
Add up 1/1! + 2/2! + 3/3! + ... for n terms. Instead of recomputing the factorial every time, we grow it step by step.
n = int(input('enter n'))
result = 0
fact = 1
for i in range(1, n+1):
fact = fact * i # fact becomes i! one step at a time
result = result + i/fact
print(result)
If you enter 5:
2.708333333333333
Tiny bit of trivia: each term i/i! is the same as 1/(i-1)!, so this sum slowly creeps towards the number e (about 2.718) as n grows.
A loop inside a loop. For every single value of the outer loop, the inner loop runs all the way through.
for i in range(1, 5):
for j in range(1, 5):
print(i, j)
Output (every pair, 4 x 4 = 16 lines):
1 1
1 2
1 3
1 4
2 1
2 2
...
4 4
Patterns are the classic use of nested loops. Outer loop → rows, inner loop → what to print on each row.