diff --git a/docs/snippets/weather/station-search/filter_by_climate_zone.py b/docs/snippets/weather/station-search/filter_by_climate_zone.py index 62075af..7f5ad96 100644 --- a/docs/snippets/weather/station-search/filter_by_climate_zone.py +++ b/docs/snippets/weather/station-search/filter_by_climate_zone.py @@ -4,14 +4,25 @@ index: StationIndex = ... # type: ignore[assignment] # --8<-- [start:example] -# Each WeatherStation carries its ASHRAE HOF climate zone. -zone_4a = [s for s in index.stations if s.ashrae_climate_zone.startswith("4A")] +# Ask for a zone by its code. The code is parsed out of the label rather than +# read off the front of it, which matters: 2,162 of the 69,638 bundled records +# are labelled "7A - ASHRAE Climate Zone could not be determined" or "8A - ...", +# and neither 7A nor 8A is an ASHRAE zone, since zones 7 and 8 carry no suffix. +zone_4a = index.filter(climate_zone="4A") print(f"Zone 4A stations: {len(zone_4a)}") -# Combine with country/state via the existing filter() to narrow further: -us_zone_5 = [s for s in index.filter(country="USA") if s.ashrae_climate_zone.startswith("5")] +# Combine with the other keys, which all narrow together. +seattle_area = index.filter(climate_zone="4C", country="USA", state="WA") +print(f"Zone 4C in Washington: {len(seattle_area)}") -# Pick the warmest design dry-bulb in a given zone: -hottest = max(us_zone_5, key=lambda s: s.cooling_design_db_c) +# The stations whose zone upstream could not determine are reachable, and only +# this way: no climate_zone value returns them. Asking for them is a separate +# question because the zone key's domain is already every real code, so a +# reserved string could not be told apart from one. +undetermined = index.filter(climate_zone_determined=False) +print(f"Zone not determined upstream: {len(undetermined)}") + +# Pick the warmest design dry-bulb in a zone. +hottest = max(index.filter(climate_zone="5A", country="USA"), key=lambda s: s.cooling_design_db_c) print(f"{hottest.display_name}: {hottest.cooling_design_db_c} °C / {hottest.cooling_design_db_f:.1f} °F") # --8<-- [end:example] diff --git a/docs/weather/station-search.md b/docs/weather/station-search.md index 0f6d8fc..9ec8ce8 100644 --- a/docs/weather/station-search.md +++ b/docs/weather/station-search.md @@ -112,7 +112,8 @@ Combine `geocode()` with `nearest()` for address-based search: !!! tip "Climate-zone-aware search" Each `WeatherStation` carries its ASHRAE HOF climate zone, design - dry-bulb temperatures, HDD18, and CDD10. See + dry-bulb temperatures, HDD18, and CDD10. Filter on the zone with the + index's own key rather than on the label text: see [Filter by Climate Zone](#filter-by-climate-zone) below. ## Filter by Country @@ -151,11 +152,36 @@ design conditions from a neighbouring WMO station; otherwise it is ## Filter by Climate Zone -Filter stations by ASHRAE climate zone using a plain list comprehension: +Ask the index for a zone by its code. -```python ---8<-- "docs/snippets/weather/station-search/filter_by_climate_zone.py:example" -``` +=== "Python" + + ```python + --8<-- "docs/snippets/weather/station-search/filter_by_climate_zone.py:example" + ``` + +=== "TypeScript" + + ```ts + --8<-- "docs/snippets/js/weather/station-search/filter_by_climate_zone.ts:example" + ``` + +!!! warning "The label is not a code, and matching its first token invents two zones" + + 2,162 of the 69,638 bundled records are labelled + `7A - ASHRAE Climate Zone could not be determined` or `8A - ...`. Neither 7A + nor 8A is an ASHRAE zone: zones 7 and 8 carry no moisture suffix. Reading the + code off the front of the label therefore produces twenty-one zones where + there are nineteen, and files 3.1% of the index under two that do not exist. + + The zone key matches a parsed code with those records excluded, so it returns + nothing for `7A`. They stay reachable through the separate key for records + whose zone was not determined, and every station is returned by exactly one of + the two. + + A related trap, for anyone writing the parse by hand: the suffix is `[ABC]`, + not `[AB]`. Dropping C loses 3C, 4C and 5C, which is 1,653 marine-zone + stations, leaves sixteen zones where there are nineteen, and raises nothing. ## Listing Countries