Unit 05 · lesson

Build an Automated System Monitor

Core path: 35 minutes

This is the first week where the program starts to feel less like a worksheet and more like a small system.

You will collect data for several devices, evaluate each one, keep totals across repeated runs, and then let the user decide whether to run another scan.

That means several ideas are active at the same time: input, conversion, conditions, for, while, counters, and accumulators. If the program gets confusing, do not stare at all of it. Trace one loop at a time.

Scan a known number of devices

Start with:

device_count = int(input("How many devices will you check? "))

for device_number in range(1, device_count + 1):
    print(f"Checking device {device_number}")

Why device_count + 1?

Because the stop value in range() is excluded. If the user enters 3, we want the loop variable to become 1, 2, and 3.

Inside the loop, collect:

device_name = input("Device name: ")
battery = int(input("Battery percentage: "))
temperature = float(input("Temperature: "))

Then classify each device:

battery <= 10      → CRITICAL BATTERY
temperature >= 80  → OVERHEATING
otherwise          → NORMAL

Decide which rule gets priority if both battery and temperature are dangerous.

Count warnings across iterations

Before the loop:

warning_count = 0

When a warning occurs:

warning_count += 1

This variable has a different job from device_name or battery. It keeps information across iterations.

After the loop:

print(f"Warnings detected: {warning_count}")

Accumulate battery values

Before the loop:

total_battery = 0

Inside:

total_battery += battery

After all devices are processed:

average_battery = total_battery / device_count

Run a small case you can verify by hand. If the battery values are 50, 70, and 90, the average should be 70.

Do not trust a formatted number just because it looks professional.

Produce the report

Aim for output like:

=== REPORT ===
Devices checked: 3
Warnings detected: 2
Average battery: 56.7%

The report is the visible result. The interesting part is the state that had to survive the loop to produce it.

Add an outer loop

Now ask:

again = input("Run another scan? yes/no: ").lower()

Wrap the scan process in a while loop so the user can run multiple batches.

This creates two levels of repetition:

WHILE another batch is requested
    FOR each device in this batch
        collect data
        evaluate device
        update totals
    print batch report
    ask whether to scan again

Read that structure slowly. The for loop answers how many devices are in this batch? The while loop answers do we know how many batches the user will run?

Break the stop condition intentionally

Run or inspect:

scan_again = "yes"

while scan_again == "yes":
    print("Scanning...")

Nothing inside the loop changes scan_again.

So the condition that was true before iteration 1 is still true after iteration 1, iteration 2, iteration 5000...

That is the mechanism behind the infinite loop.

Repair it by updating the state that controls termination.

Keep a loop debugging record

For at least one bug, record:

### Loop failure
What did I observe?
What condition controlled repetition?
What value did that condition depend on?
Did that value change?
What one change repaired the loop?

Success evidence

Your final monitor should show:

  • a for loop over a user-selected device count;
  • at least two branch conditions;
  • a warning counter;
  • a battery accumulator and average;
  • a while loop for repeated scans;
  • one deliberately created infinite-loop explanation; and
  • one iteration trace you can explain without running the program.

Automation is not "the computer does it for me." It is you define the repetition precisely enough that the computer can repeat it without you.