Exercise 2: Finding an Input Where the Two Thick Clients Agree — Possible Solution ==================================================================== A SEARCH ACROSS SEVERAL INPUTS ------------------------------ Running both this chapter's own mobile_client_calculate_total() and web_client_calculate_total() across a range of items_total values (all for a loyalty member) found: items_total=50: mobile=45.0, web=45.0, agree=True items_total=80: mobile=72.0, web=72.0, agree=True items_total=90: mobile=81.0, web=81.0, agree=True items_total=95: mobile=85.5, web=85.5, agree=True items_total=100: mobile=90.0, web=90.0, agree=True items_total=101: mobile=90.9, web=86.4, agree=False items_total=120: mobile=103.0, web=103.5, agree=False items_total=90 is a clean example: both clients return 81.0. WHY THE BUG DOESN'T SHOW UP FOR THIS INPUT ------------------------------ Both functions share one conditional branch: "if total > 100, subtract $5." At items_total=90, the loyalty discount alone (90 * 0.90 = 81) never pushes the running total above 100 - so the $5-off branch is simply never entered by EITHER client, regardless of which order the two rules are checked in. With only one of the two rules ever actually firing, there's no ordering for the two clients to disagree about - the mobile and web implementations only diverge when BOTH rules are live at once, which requires the discounted total to cross the $100 threshold specifically because of which rule ran first. THE GENERAL PATTERN THIS REVEALS ------------------------------ This chapter's own $120 example (mobile=103.0, web=103.5) worked specifically because 120 is high enough that the order the two rules run in changes whether the $5-off condition (total > 100) is still true by the time it's checked. Every value at or below 100 sidesteps the bug entirely; every value comfortably above 100 (verified at 101, 105, 110, 111, 120, 150, 200) triggers it. This means the two thick clients agree on MOST small orders and disagree on most larger ones - a bug that's easy to miss in casual testing with small example orders, and easy to hit in production once a real customer places a large one. WHY THIS WORKS AS AN ANSWER ------------------------------ A genuinely agreeing input is found and verified directly rather than assumed to exist, and the explanation for why it agrees is traced to the specific conditional structure shared by both functions, rather than treating it as a coincidence.