1 The Problem
We want a timer: the user gives a number of seconds, and the program counts down — 5, 4, 3, 2, 1 — then announces “Time’s up!”. It teaches how a program can wait, and how to count down rather than up.
2 How to Think About It
The plan, before any code:
3 The Build — explained part by part
Here is the complete timer. Each line is explained below.
import time
# Ask how many seconds to count down from.
seconds = int(input("Count down from how many seconds? "))
# Count from 'seconds' down to 1.
while seconds > 0:
print(seconds)
time.sleep(1) # pause the program for one real second
seconds = seconds - 1
print("Time's up!")
seconds = int(input(...)) — read how many seconds and turn it into a number.
while seconds > 0: — keep repeating as long as there is time left. The moment
seconds hits 0, the loop stops.print(seconds) — show the current number.
time.sleep(1) — the new idea: pause the whole program for one real second. This is what makes it feel like a real countdown.
seconds = seconds - 1 — take one off the counter, so next time around the number is smaller. Without this line, the loop would run forever.
seconds = seconds - 1 — the number never shrinks, so the loop runs forever.while seconds >= 0 — this shows 0 too, then says time is up.> 0 so it stops at 1 and the “time's up” message is the zero moment.time.sleep(1) outside the loop — then it waits once, not each second.sleep inside the loop so it pauses every step.4 Test & Prove Each Part
We do not want tests that actually wait (that would be slow), so we test the countdown logic — the sequence of numbers produced — separately from the waiting.
def countdown_sequence(seconds):
"""Return the list of numbers shown, without any waiting."""
numbers = []
while seconds > 0:
numbers.append(seconds)
seconds = seconds - 1
return numbers
def test_counts_from_five():
"""From 5 we get 5, 4, 3, 2, 1."""
assert countdown_sequence(5) == [5, 4, 3, 2, 1]
def test_counts_from_one():
"""From 1 we get just [1]."""
assert countdown_sequence(1) == [1]
def test_ends_at_one():
"""The last number is always 1, never 0."""
assert countdown_sequence(10)[-1] == 1
Run with pytest -v. Notice we separated the logic (the sequence of numbers) from the waiting so tests run instantly. Separating “what to do” from “slow side-effects” is a professional habit.
5 The Interface
What it expects
Count down from how many seconds? 3What it returns
3
2
1
Time's up!6 Run It & Automate It
python3 timer.pyEnter a number and watch it count down in real time.
Jenkins runs the tests automatically — each line explained below.
Count down from how many seconds? 3
3
2
1
Time's up!time.sleep(1) is missing or in the wrong place — it must be inside the loop.seconds = seconds - 1 inside the loop.// Jenkinsfile — automated tests on every change.
pipeline {
agent any
stages {
stage('Get the code') { steps { checkout scm } } // download the code
stage('Install') { steps { sh 'python3 -m venv venv && . venv/bin/activate && pip install pytest' } } // test tool
stage('Test') { steps { sh '. venv/bin/activate && pytest -v' } } // run every test
}
post {
success { echo 'All tests passed.' }
failure { echo 'A test failed — look above.' }
}
}
- Minutes and seconds. Show 1:30 instead of 90. (Teaches: division and remainder.)
- A beep at the end. Print a row of stars or ring the terminal bell. (Teaches: output tricks.)
- Count up too. Offer a stopwatch mode. (Teaches: a second branch.)