Problem 310842 · medium · Level 03 Linear Management & Searching

A Thermostat for Every Room

py-closures · nonlocal · late binding · state

A house has a heater in every room (zone), each with its own comfort band (low, high). A heater starts off. On each temperature reading it switches on if the temperature is below low, switches off if it is above high, and otherwise stays as it was (so it does not flicker on and off around one set point).

Write make_thermostats(zones), where zones maps a zone name to its (low, high) band. Return a dictionary from each zone name to a function update(temperature) that records the reading for that zone and returns the heater's state after it, "on" or "off". Every zone has its own band and its own state.

The tests use the helper run_readings(make_thermostats, zones, readings), which builds the functions once and then calls controls[zone](temperature) for each (zone, temperature) pair in order, collecting the answers. house_day(zones, n, seed) generates readings; both helpers are available with Run.

Examples

Input:  run_readings(make_thermostats, {"hall": (18, 21)},
                     [("hall", 19), ("hall", 17.5), ("hall", 20), ("hall", 21.5), ("hall", 19)])
Output: ["off", "on", "on", "off", "off"]

Input:  run_readings(make_thermostats, {"bath": (22, 24), "loft": (12, 15)},
                     [("bath", 20), ("loft", 14), ("loft", 11), ("bath", 23)])
Output: ["on", "off", "on", "on"]

Constraints

  • Up to 50 zones and 10**5 readings; low < high.
  • A temperature exactly equal to low or high changes nothing.

Goals

  • Create one closure per item, each with its own remembered settings and state
  • Change remembered state with `nonlocal`
  • Avoid closures in a loop that all see the loop's last values
Starting Python…