CHAPTER 35: Running totals and missing denominators

35a: Watch the totals grow, then divide
35b: A missing ratio is not a zero cost

HOW TO RUN
Open a terminal in the extracted companion folder, the folder containing
automation, sql and visual_labs. Run:

    python visual_labs/ch35/walkthrough.py

Use python3 or py instead of python if that is the command established in
Chapter 15. No extra Python package is needed. Run it only after predicting
the displayed states. The exact output is also in expected_output.txt.

When a lab imports the automation examples, its short Path/sys.path setup
locates those existing modules relative to this file. It changes where this
Python process looks for imports; it does not change your operating-system
configuration. Preserve the extracted folder structure.

SOURCE AND MEANING
automation/data/campaigns.csv is the original fictional completed-period
fixture. The first demonstration reads it and calls the existing calculate
function. The 100/4, 100/0 and 0/4 cases are separate tiny examples, not extra
rows appended to the campaign file.

FOLLOW BEFORE YOU RUN
Make a four-column scratch table: row name, accumulated cost, accumulated
enquiries, accumulated customers. Add one campaign at a time. Compare your
three states with board 35a before reading the expected output below.

PREDICT, RUN, COMPARE
Predict what changes if newsletter enquiries increase from 8 to 10 without
changing its customers. The script performs this change on copied dictionaries
in memory. Next predict the meaning of each zero-denominator demonstration.
Run the command; compare your prediction with its labels, not only its numbers.

ONE MORE INPUT TO REASON THROUGH
Keep the original 30 enquiries and change only newsletter cost from EUR 120
to EUR 180. What are total cost and overall cost per enquiry? Work this out
before uncovering the answer.

EXPLAINED ANSWER
Cost becomes EUR 680. EUR 680 / 30 = EUR 22.67 after rounding. Customer
conversion remains 6 / 30 = 20%, because neither its numerator nor denominator
changed. This is a useful second-input check: a cost change should not alter a
customer conversion rate. You can verify with a calculator or a separate tiny
Python calculation, print(round(680 / 30, 2)).

EXPECTED OUTPUT (verified by execution)

35a: Pause after each source row
Spring search: EUR 300.00, 12 enquiries, 3 customers
Office newsletter: EUR 420.00, 20 enquiries, 5 customers
Workplace guide: EUR 620.00, 30 enquiries, 6 customers
Conversion: 20.0%
EUR per enquiry: 20.67
Change newsletter enquiries from 8 to 10:
Conversion: 18.75%
EUR per enquiry: 19.38
35b: Same rule, different denominators
100 / 4 -> 25.0
100 / 0 -> None
0 / 4 -> 0.0
Combined EUR 160 / 3 enquiries: EUR 53.33

All data in this lab are fictional teaching examples.
