import%20marimo%0A%0A__generated_with%20%3D%20%220.23.9%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%20How%20many%20St.%20Petersburg%20houses%20meet%20our%20purchase%20criteria%3F%0A%0A%20%20%20%20Built%20to%20put%20a%20real%20number%20behind%20an%20essay%20line%20%E2%80%94%20*%22to%20minimize%20our%20risk%20we%0A%20%20%20%20limited%20our%20scope%2C%20which%20reduced%20our%20viable%20options%20significantly.%22*%0A%0A%20%20%20%20**The%20five%20criteria%3A**%0A%0A%20%20%20%201.%20**Block%20%2F%20masonry%20construction**%20(not%20frame)%20%E2%80%94%20lower%20insurance%2C%20storm-resilient%0A%20%20%20%202.%20**Non-flood%20zone**%20%E2%80%94%20FEMA%20Zone%20X%20only%20(hard%20disqualifier%20per%20project%20domain%20rules)%0A%20%20%20%203.%20**Slab-on-grade%20foundation**%20%E2%80%94%20footing-based%2C%20not%20piers%2Fpiles%0A%20%20%20%204.%20**%E2%89%A5%2020%20ft%20above%20sea%20level**%20%E2%80%94%20storm-surge%20margin%0A%20%20%20%205.%20**Evacuation%20zone%20NON-EVAC%20or%20E**%20%E2%80%94%20zone%20E%20is%20the%20lowest-risk%2C%20last-to-clear%0A%20%20%20%20%20%20%20evac%20zone%3B%20zones%20A%E2%80%93D%20excluded%0A%0A%20%20%20%20**Universe.**%20The%20%60parcels%60%20table%20is%20already%20filtered%20to%20single-family%20residential%0A%20%20%20%20(FL%20DOR%20use%20code%20%6001%60)%2C%20so%20%22houses%22%20needs%20no%20extra%20filter.%20We%20scope%20to%0A%20%20%20%20%60municipality%20%3D%20'ST%20PETERSBURG'%60.%0A%0A%20%20%20%20**Data%20sources%20%26%20decisions%20(flagged%20pre-data%20unless%20noted)%3A**%0A%0A%20%20%20%20-%20*Construction*%20%E2%86%92%20%60parcels.construction_type%60%3B%20**block**%20%3D%20CB%2Fmasonry%2Freinforced%0A%20%20%20%20%20%20concrete%20families%2C%20**frame**%20excluded.%0A%20%20%20%20-%20*Flood%20%2F%20evac*%20%E2%86%92%20%60parcels.flood_zone%60%20(%60X%60)%20and%20%60parcels.evac_zone%60%20(%60NON%20EVAC%60%0A%20%20%20%20%20%20or%20%60E%60%3B%20zones%20A%E2%80%93D%20excluded).%0A%20%20%20%20-%20*Slab*%20%E2%86%92%20joined%20from%20raw%20%60RP_BUILDING.csv%60%20%60FOUNDATION%60.%20**Decision%20(pre-data)%3A**%0A%20%20%20%20%20%20slab%20%3D%20footing-based%20foundations%20(%60Continuous%20Footing%20Poured%60%2C%20%60Continuous%0A%20%20%20%20%20%20Footing%60%2C%20%60Spread%2FMono%20Footing%60)%3B%20piers%2Fpiles%20%3D%20elevated%2C%20excluded.%20Blank%0A%20%20%20%20%20%20foundations%20are%20*not*%20counted%20as%20slab%20(conservative).%0A%20%20%20%20-%20*Elevation*%20%E2%86%92%20sampled%20from%20the%20USGS%203DEP%201%2F3-arc-second%20DEM%20(NAVD88%2C%20~10%20m)%0A%20%20%20%20%20%20at%20each%20parcel's%20lat%2Flon.%20Ground%20elevation%2C%20not%20finished-floor.%0A%0A%20%20%20%20**Headline%20(post-data)%3A**%20**~22%2C400%20of%2082%2C686%20houses%20(27.1%25)%20%E2%80%94%20about%20one%20in%0A%20%20%20%20four.**%20Relaxing%20the%20bar%20from%20the%20original%2030%20ft%20%2F%20non-evac-only%20to%20**20%20ft%20%2F%0A%20%20%20%20(non-evac%20or%20zone%20E)**%20adds%20~7%2C070%20houses%20(15%2C337%20%E2%86%92%2022%2C403)%2C%20*all*%20of%20them%20in%20the%0A%20%20%20%20newly-admitted%2020%E2%80%9330%20ft%20band%3A%20~5%2C460%20zone-E%20houses%20plus%20~1%2C600%20low%20non-evac%20houses.%0A%20%20%20%20At%20%E2%89%A5%2030%20ft%20the%20field%20is%20still%20entirely%20non-evac%2C%20so%20the%20two%20relaxations%20act%20only%20on%0A%20%20%20%20lower%20ground.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%20%20%20%20from%20urllib.request%20import%20urlopen%0A%0A%20%20%20%20import%20altair%20as%20alt%0A%20%20%20%20import%20duckdb%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20rasterio%0A%0A%20%20%20%20return%20Path%2C%20alt%2C%20duckdb%2C%20mo%2C%20np%2C%20pd%2C%20rasterio%2C%20urlopen%0A%0A%0A%40app.cell%0Adef%20_(Path%2C%20duckdb)%3A%0A%20%20%20%20def%20_find_root()%20-%3E%20Path%3A%0A%20%20%20%20%20%20%20%20for%20d%20in%20%5BPath.cwd()%2C%20*Path.cwd().parents%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(d%20%2F%20%22analytics.db%22).exists()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20d%0A%20%20%20%20%20%20%20%20raise%20FileNotFoundError(%22analytics.db%20not%20found%20walking%20up%20from%20cwd%22)%0A%0A%20%20%20%20ROOT%20%3D%20_find_root()%0A%20%20%20%20conn%20%3D%20duckdb.connect(str(ROOT%20%2F%20%22analytics.db%22)%2C%20read_only%3DTrue)%20%20%23%20read-only%3A%20project%20convention%0A%20%20%20%20return%20ROOT%2C%20conn%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20%23%20---%20criteria%20definitions%20(pre-data%20decisions%3B%20single%20source%20of%20truth)%20---%0A%20%20%20%20BLOCK%20%3D%20(%0A%20%20%20%20%20%20%20%20%22CB%20STUCCO%2FCB%20RECLAD%22%2C%0A%20%20%20%20%20%20%20%20%22CONCRETE%20BLOCK%22%2C%0A%20%20%20%20%20%20%20%20%22MASONRY%22%2C%0A%20%20%20%20%20%20%20%20%22REINFORCED%20CONCRETE%22%2C%0A%20%20%20%20%20%20%20%20%22MASONRY%20BRICK%22%2C%0A%20%20%20%20%20%20%20%20%22MASONRY%20STONE%22%2C%0A%20%20%20%20)%0A%20%20%20%20SLAB%20%3D%20(%0A%20%20%20%20%20%20%20%20%22Continuous%20Footing%20Poured%22%2C%0A%20%20%20%20%20%20%20%20%22Continuous%20Footing%22%2C%0A%20%20%20%20%20%20%20%20%22Spread%2FMono%20Footing%22%2C%0A%20%20%20%20)%0A%20%20%20%20EVAC%20%3D%20(%22NON%20EVAC%22%2C%20%22E%22)%20%20%23%20acceptable%20evac%20zones%3A%20out%20of%20evac%2C%20plus%20zone%20E%20(lowest%20risk)%0A%20%20%20%20ELEV_FT%20%3D%2020.0%20%20%23%20hard%20storm-surge%20threshold%2C%20feet%20above%20sea%20level%20(NAVD88)%0A%0A%20%20%20%20def%20_sql_list(vals)%3A%0A%20%20%20%20%20%20%20%20return%20%22(%22%20%2B%20%22%2C%22.join(%22'%22%20%2B%20v%20%2B%20%22'%22%20for%20v%20in%20vals)%20%2B%20%22)%22%0A%0A%20%20%20%20BLOCK_SQL%2C%20SLAB_SQL%2C%20EVAC_SQL%20%3D%20_sql_list(BLOCK)%2C%20_sql_list(SLAB)%2C%20_sql_list(EVAC)%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22**Block%20set%3A**%20%7Blen(BLOCK)%7D%20construction%20types%20%26nbsp%3B%C2%B7%26nbsp%3B%20%22%0A%20%20%20%20%20%20%20%20f%22**Slab%20set%3A**%20%7Blen(SLAB)%7D%20footing%20types%20%26nbsp%3B%C2%B7%26nbsp%3B%20%22%0A%20%20%20%20%20%20%20%20f%22**Evac%20OK%3A**%20%7B'%2C%20'.join(EVAC)%7D%20%26nbsp%3B%C2%B7%26nbsp%3B%20%22%0A%20%20%20%20%20%20%20%20f%22**Elevation%20cut%3A**%20%E2%89%A5%20%7BELEV_FT%3A.0f%7D%20ft%22%0A%20%20%20%20)%0A%20%20%20%20return%20BLOCK_SQL%2C%20ELEV_FT%2C%20EVAC_SQL%2C%20SLAB_SQL%0A%0A%0A%40app.cell%0Adef%20_(ROOT%2C%20mo%2C%20urlopen)%3A%0A%20%20%20%20%23%20USGS%203DEP%201%2F3%20arc-second%20tile%20covering%20Tampa%20Bay%20%2F%20St.%20Pete%20(NAVD88%20meters).%0A%20%20%20%20%23%20Regenerable%2C%20~300%20MB%20%E2%86%92%20gitignored%20under%20data%2Fdem%2F.%20Auto-download%20if%20missing.%0A%20%20%20%20DEM_PATH%20%3D%20ROOT%20%2F%20%22data%22%20%2F%20%22dem%22%20%2F%20%22USGS_13_n28w083.tif%22%0A%20%20%20%20DEM_URL%20%3D%20(%0A%20%20%20%20%20%20%20%20%22https%3A%2F%2Fprd-tnm.s3.amazonaws.com%2FStagedProducts%2FElevation%2F13%2FTIFF%2F%22%0A%20%20%20%20%20%20%20%20%22current%2Fn28w083%2FUSGS_13_n28w083.tif%22%0A%20%20%20%20)%0A%20%20%20%20if%20not%20DEM_PATH.exists()%3A%0A%20%20%20%20%20%20%20%20DEM_PATH.parent.mkdir(parents%3DTrue%2C%20exist_ok%3DTrue)%0A%20%20%20%20%20%20%20%20with%20urlopen(DEM_URL)%20as%20r%2C%20open(DEM_PATH%2C%20%22wb%22)%20as%20f%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20f.write(r.read())%0A%20%20%20%20dem_status%20%3D%20mo.md(f%22DEM%20tile%20ready%3A%20%60%7BDEM_PATH.relative_to(ROOT)%7D%60%22)%0A%20%20%20%20dem_status%0A%20%20%20%20return%20(DEM_PATH%2C)%0A%0A%0A%40app.cell%0Adef%20_(ROOT%2C%20conn)%3A%0A%20%20%20%20%23%20Foundation%20per%20parcel%20from%20raw%20RP_BUILDING.csv%2C%20joined%20on%20STRAP%20%3D%3D%20parcel_id.%0A%20%20%20%20%23%20One%20building%20per%20parcel%3A%20prefer%20a%20non-blank%20foundation%2C%20then%20lowest%20building%20number.%0A%20%20%20%20_raw%20%3D%20(ROOT%20%2F%20%22data%22%20%2F%20%22raw%22%20%2F%20%22RP_BUILDING.csv%22).as_posix()%0A%20%20%20%20conn.execute(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20CREATE%20OR%20REPLACE%20TEMP%20VIEW%20building_foundation%20AS%0A%20%20%20%20%20%20%20%20SELECT%20pid%2C%20found%20FROM%20(%0A%20%20%20%20%20%20%20%20%20%20SELECT%20STRAP%20AS%20pid%2C%20FOUNDATION%20AS%20found%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ROW_NUMBER()%20OVER%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PARTITION%20BY%20STRAP%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ORDER%20BY%20CASE%20WHEN%20FOUNDATION%20IS%20NULL%20OR%20FOUNDATION%20%3D%20''%20THEN%201%20ELSE%200%20END%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20TRY_CAST(BUILDING_NUMBER%20AS%20INT)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%20AS%20rn%0A%20%20%20%20%20%20%20%20%20%20FROM%20read_csv_auto('%7B_raw%7D'%2C%20header%3Dtrue%2C%20all_varchar%3Dtrue)%0A%20%20%20%20%20%20%20%20)%20WHERE%20rn%20%3D%201%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20The%20elevation%20landscape%20(before%20any%20filter)%0A%0A%20%20%20%20Before%20applying%20a%20single%20criterion%2C%20here%20is%20where%20*all*%20of%20St.%20Petersburg's%0A%20%20%20%20single-family%20housing%20sits%20on%20the%20ground%20%E2%80%94%20DEM%20elevation%20sampled%20at%20every%20parcel%2C%0A%20%20%20%20no%20construction%20%2F%20flood%20%2F%20evac%20%2F%20slab%20filter.%20The%20two%20dashed%20lines%20are%20the%20storm-surge%0A%20%20%20%20bars%3A%20the%20**20%20ft**%20rule%20used%20here%20and%20the%20original%20**30%20ft**%20bar.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(DEM_PATH%2C%20ELEV_FT%2C%20conn%2C%20np%2C%20pd%2C%20rasterio)%3A%0A%20%20%20%20%23%20Citywide%20elevation%20landscape%3A%20DEM%20ground%20elevation%20for%20ALL%20St-Pete%20SFR%20parcels%2C%0A%20%20%20%20%23%20no%20criteria%20filter%20(~82.7k%20point%20samples).%20Drop%20nodata%20%2F%20open-water%20cells%2C%20then%0A%20%20%20%20%23%20pre-aggregate%20into%202%20ft%20bins%20so%20the%20chart%20embeds%20~30%20rows%2C%20not%2082k%20(altair's%20limit).%0A%20%20%20%20_rows%20%3D%20conn.execute(%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20SELECT%20latitude%2C%20longitude%20FROM%20parcels%0A%20%20%20%20%20%20%20%20WHERE%20municipality%20%3D%20'ST%20PETERSBURG'%0A%20%20%20%20%20%20%20%20%20%20AND%20latitude%20IS%20NOT%20NULL%20AND%20longitude%20IS%20NOT%20NULL%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20).fetchall()%0A%20%20%20%20_lons%20%3D%20%5Bfloat(r%5B1%5D)%20for%20r%20in%20_rows%5D%0A%20%20%20%20_lats%20%3D%20%5Bfloat(r%5B0%5D)%20for%20r%20in%20_rows%5D%0A%20%20%20%20with%20rasterio.open(DEM_PATH)%20as%20_ds%3A%0A%20%20%20%20%20%20%20%20_feet%20%3D%20np.array(%5Bv%5B0%5D%20for%20v%20in%20_ds.sample(zip(_lons%2C%20_lats))%5D%2C%20float)%20*%203.28084%0A%20%20%20%20_feet%20%3D%20_feet%5Bnp.isfinite(_feet)%20%26%20(_feet%20%3E%20-50)%20%26%20(_feet%20%3C%20500)%5D%0A%0A%20%20%20%20_step%20%3D%202.0%0A%20%20%20%20_lo%20%3D%20np.floor(_feet.min()%20%2F%20_step)%20*%20_step%0A%20%20%20%20_hi%20%3D%20np.ceil(_feet.max()%20%2F%20_step)%20*%20_step%0A%20%20%20%20_edges%20%3D%20np.arange(_lo%2C%20_hi%20%2B%20_step%2C%20_step)%0A%20%20%20%20_counts%2C%20_%20%3D%20np.histogram(_feet%2C%20bins%3D_edges)%0A%20%20%20%20elev_hist%20%3D%20pd.DataFrame(%0A%20%20%20%20%20%20%20%20%7B%22bin_lo%22%3A%20_edges%5B%3A-1%5D%2C%20%22bin_hi%22%3A%20_edges%5B1%3A%5D%2C%20%22parcels%22%3A%20_counts%7D%0A%20%20%20%20)%0A%20%20%20%20elev_stats%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22n%22%3A%20int(_feet.size)%2C%0A%20%20%20%20%20%20%20%20%22median%22%3A%20float(np.median(_feet))%2C%0A%20%20%20%20%20%20%20%20%22below_new%22%3A%20float(100%20*%20(_feet%20%3C%20ELEV_FT).mean())%2C%0A%20%20%20%20%20%20%20%20%22below_old%22%3A%20float(100%20*%20(_feet%20%3C%2030).mean())%2C%0A%20%20%20%20%7D%0A%20%20%20%20return%20elev_hist%2C%20elev_stats%0A%0A%0A%40app.cell%0Adef%20_(ELEV_FT%2C%20alt%2C%20elev_hist%2C%20elev_stats%2C%20mo%2C%20pd)%3A%0A%20%20%20%20_hist%20%3D%20(%0A%20%20%20%20%20%20%20%20alt.Chart(elev_hist)%0A%20%20%20%20%20%20%20%20.mark_bar(color%3D%22%239ecae1%22%2C%20stroke%3D%22white%22%2C%20strokeWidth%3D0.3)%0A%20%20%20%20%20%20%20%20.encode(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dalt.X(%22bin_lo%3AQ%22%2C%20title%3D%22Ground%20elevation%20(ft%2C%20NAVD88)%22%2C%20scale%3Dalt.Scale(zero%3DFalse))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x2%3D%22bin_hi%3AQ%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dalt.Y(%22parcels%3AQ%22%2C%20title%3D%22St-Pete%20SFR%20parcels%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20tooltip%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alt.Tooltip(%22bin_lo%3AQ%22%2C%20title%3D%22from%20ft%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alt.Tooltip(%22bin_hi%3AQ%22%2C%20title%3D%22to%20ft%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alt.Tooltip(%22parcels%3AQ%22%2C%20title%3D%22parcels%22%2C%20format%3D%22%2C%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20_rule_new%20%3D%20(%0A%20%20%20%20%20%20%20%20alt.Chart(pd.DataFrame(%7B%22ft%22%3A%20%5BELEV_FT%5D%7D))%0A%20%20%20%20%20%20%20%20.mark_rule(color%3D%22%23e45756%22%2C%20size%3D2%2C%20strokeDash%3D%5B6%2C%204%5D)%0A%20%20%20%20%20%20%20%20.encode(x%3D%22ft%3AQ%22)%0A%20%20%20%20)%0A%20%20%20%20_rule_old%20%3D%20(%0A%20%20%20%20%20%20%20%20alt.Chart(pd.DataFrame(%7B%22ft%22%3A%20%5B30.0%5D%7D))%0A%20%20%20%20%20%20%20%20.mark_rule(color%3D%22%23f58518%22%2C%20size%3D2%2C%20strokeDash%3D%5B2%2C%202%5D)%0A%20%20%20%20%20%20%20%20.encode(x%3D%22ft%3AQ%22)%0A%20%20%20%20)%0A%20%20%20%20elev_chart%20%3D%20(_hist%20%2B%20_rule_new%20%2B%20_rule_old).properties(%0A%20%20%20%20%20%20%20%20width%3D640%2C%0A%20%20%20%20%20%20%20%20height%3D300%2C%0A%20%20%20%20%20%20%20%20title%3Df%22St.%20Petersburg%20ground%20elevation%20%E2%80%94%20all%20%7Belev_stats%5B'n'%5D%3A%2C%7D%20single-family%20parcels%22%2C%0A%20%20%20%20)%0A%20%20%20%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22**Median%20%7Belev_stats%5B'median'%5D%3A.0f%7D%20ft.**%20Red%20dashed%20%3D%20%7BELEV_FT%3A.0f%7D%20ft%20bar%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22(**%7Belev_stats%5B'below_new'%5D%3A.0f%7D%25**%20of%20the%20city%20sits%20below%20it)%3B%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22orange%20dashed%20%3D%20old%2030%20ft%20bar%20(**%7Belev_stats%5B'below_old'%5D%3A.0f%7D%25**%20below).%22%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20elev_chart%2C%0A%20%20%20%20%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20The%20shape%20is%20the%20whole%20point%3A%20St.%20Pete%20is%20**bimodal**%20%E2%80%94%20a%20large%20low%20cluster%20around%0A%20%20%20%205%E2%80%9310%20ft%20(the%20coastal%2Fpeninsular%20flats)%20and%20a%20second%20mass%20up%20around%2045%E2%80%9352%20ft%20(the%0A%20%20%20%20inland%20ridge).%20The%20median%20parcel%20sits%20right%20at%20**~19%20ft**%2C%20essentially%20on%20top%20of%20the%0A%20%20%20%2020%20ft%20bar%2C%20which%20is%20why%20dropping%20from%2030%20ft%20to%2020%20ft%20matters%20so%20much%3A%20~64%25%20of%20the%0A%20%20%20%20city's%20ground%20is%20below%2030%20ft%20but%20only%20~52%25%20is%20below%2020%20ft%2C%20so%20the%20move%20frees%20the%0A%20%20%20%2012-point%20slice%20living%20in%20that%2020%E2%80%9330%20ft%20band.%20The%20criteria%20funnel%20below%20then%20layers%0A%20%20%20%20construction%2C%20flood%20zone%2C%20evac%2C%20and%20slab%20on%20top%20of%20this%20terrain.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20BLOCK_SQL%2C%0A%20%20%20%20DEM_PATH%2C%0A%20%20%20%20ELEV_FT%2C%0A%20%20%20%20EVAC_SQL%2C%0A%20%20%20%20SLAB_SQL%2C%0A%20%20%20%20conn%2C%0A%20%20%20%20np%2C%0A%20%20%20%20pd%2C%0A%20%20%20%20rasterio%2C%0A)%3A%0A%20%20%20%20def%20cascade(zip_filter%3A%20str%20%7C%20None)%20-%3E%20dict%3A%0A%20%20%20%20%20%20%20%20%22%22%22Sequential%20survivor%20counts%20for%20one%20zip%20(or%20citywide%20if%20None).%22%22%22%0A%20%20%20%20%20%20%20%20where_zip%20%3D%20f%22AND%20p.zip%20%3D%20'%7Bzip_filter%7D'%22%20if%20zip_filter%20else%20%22%22%0A%0A%20%20%20%20%20%20%20%20def%20n(extra%3A%20str)%20-%3E%20int%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20conn.execute(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22SELECT%20COUNT(*)%20FROM%20parcels%20p%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22WHERE%20p.municipality%20%3D%20'ST%20PETERSBURG'%20%7Bwhere_zip%7D%20%7Bextra%7D%22%0A%20%20%20%20%20%20%20%20%20%20%20%20).fetchone()%5B0%5D%0A%0A%20%20%20%20%20%20%20%20sfr%20%3D%20n(%22%22)%0A%20%20%20%20%20%20%20%20block%20%3D%20n(f%22AND%20p.construction_type%20IN%20%7BBLOCK_SQL%7D%22)%0A%20%20%20%20%20%20%20%20zonex%20%3D%20n(f%22AND%20p.construction_type%20IN%20%7BBLOCK_SQL%7D%20AND%20p.flood_zone%20%3D%20'X'%22)%0A%20%20%20%20%20%20%20%20evac_ok%20%3D%20n(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22AND%20p.construction_type%20IN%20%7BBLOCK_SQL%7D%20AND%20p.flood_zone%20%3D%20'X'%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22AND%20p.evac_zone%20IN%20%7BEVAC_SQL%7D%22%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20slab%20survivors%20%2B%20coordinates%20for%20elevation%20sampling%0A%20%20%20%20%20%20%20%20coords%20%3D%20conn.execute(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20SELECT%20p.latitude%2C%20p.longitude%0A%20%20%20%20%20%20%20%20%20%20%20%20FROM%20parcels%20p%0A%20%20%20%20%20%20%20%20%20%20%20%20LEFT%20JOIN%20building_foundation%20b%20ON%20p.parcel_id%20%3D%20b.pid%0A%20%20%20%20%20%20%20%20%20%20%20%20WHERE%20p.municipality%20%3D%20'ST%20PETERSBURG'%20%7Bwhere_zip%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20AND%20p.construction_type%20IN%20%7BBLOCK_SQL%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20AND%20p.flood_zone%20%3D%20'X'%20AND%20p.evac_zone%20IN%20%7BEVAC_SQL%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20AND%20b.found%20IN%20%7BSLAB_SQL%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20).fetchall()%0A%20%20%20%20%20%20%20%20slab%20%3D%20len(coords)%0A%0A%20%20%20%20%20%20%20%20if%20slab%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20lons%20%3D%20%5Bfloat(c%5B1%5D)%20for%20c%20in%20coords%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20lats%20%3D%20%5Bfloat(c%5B0%5D)%20for%20c%20in%20coords%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20with%20rasterio.open(DEM_PATH)%20as%20ds%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feet%20%3D%20np.array(%5Bv%5B0%5D%20for%20v%20in%20ds.sample(zip(lons%2C%20lats))%5D%2C%20float)%20*%203.28084%0A%20%20%20%20%20%20%20%20%20%20%20%20ge30%20%3D%20int(np.nansum(feet%20%3E%3D%20ELEV_FT))%0A%20%20%20%20%20%20%20%20%20%20%20%20med%20%3D%20float(np.nanmedian(feet))%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ge30%2C%20med%20%3D%200%2C%20float(%22nan%22)%0A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22all_sfr%22%3A%20sfr%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22block%22%3A%20block%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%2B%20Zone%20X%22%3A%20zonex%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%2B%20evac%20NON%2FE%22%3A%20evac_ok%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%2B%20slab%22%3A%20slab%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22%2B%20%3E%3D%7BELEV_FT%3A.0f%7Dft%20(final)%22%3A%20ge30%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22median_elev_ft%22%3A%20round(med%2C%201)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22final_pct_of_sfr%22%3A%20round(100%20*%20ge30%20%2F%20sfr%2C%201)%20if%20sfr%20else%200.0%2C%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20funnel%20%3D%20pd.DataFrame(%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22CITYWIDE%22%3A%20cascade(None)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%2233710%20(west)%22%3A%20cascade(%2233710%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%2233713%20(ridge)%22%3A%20cascade(%2233713%22)%2C%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20)%0A%20%20%20%20funnel%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Reading%20the%20funnel%0A%0A%20%20%20%20**Citywide%3A**%20~22%2C400%20houses%20survive%20all%20criteria%20%E2%80%94%20**27.1%25**%2C%20about%201%20in%203.7.%0A%20%20%20%20The%20two%20heaviest%20cuts%20are%20still%20construction%20(block)%20and%20flood%20zone%3B%20with%20the%20bar%20at%0A%20%20%20%2020%20ft%20and%20zone%20E%20admitted%2C%20the%20evac%20and%20elevation%20steps%20now%20bind%20only%20modestly%0A%20%20%20%20(block%20construction%20here%20is%20~96%25%20slab).%0A%0A%20%20%20%20**The%20two%20focus%20zips%20diverge%20sharply%3A**%0A%0A%20%20%20%20-%20**33713%20(Disston%20Heights%20ridge)**%20%E2%80%94%20**~58%25**%20of%20its%20houses%20qualify%2C%20essentially%0A%20%20%20%20%20%20unchanged%20from%20the%20old%2030%20ft%20%2F%20non-evac-only%20bar.%20Every%20block%20house%20is%20already%0A%20%20%20%20%20%20Zone%20X%20*and*%20non-evac%2C%20and%20median%20survivor%20elevation%20is%20**51.5%20ft**%2C%20so%20the%0A%20%20%20%20%20%20relaxations%20free%20nothing%20here.%20High%2C%20dry%2C%20inland%20by%20design.%0A%20%20%20%20-%20**33710%20(west)**%20%E2%80%94%20now%20**~43%25**%2C%20up%20sharply%20from%20~9%25%20under%20the%20old%20bar.%20Admitting%0A%20%20%20%20%20%20zone%20E%20keeps%20most%20of%20the%20field%20through%20the%20evac%20step%20(9%2C045%20%E2%86%92%207%2C289)%20where%0A%20%20%20%20%20%20non-evac-only%20had%20cut%20it%20to%20~1%2C900%3B%20the%20**20%20ft%20rule%20is%20now%20the%20binding%20constraint**%0A%20%20%20%20%20%20%E2%80%94%20median%20survivor%20elevation%20is%20just%20**21.3%20ft**%2C%20so%20it%20still%20trims%20~1%2C940%20of%20the%0A%20%20%20%20%20%20slab%20survivors.%20Lower%20and%20closer%20to%20Boca%20Ciega%20Bay.%0A%0A%20%20%20%20So%20%22limiting%20our%20scope%22%20still%20bites%20unevenly%3A%20on%20the%20ridge%20the%20criteria%20are%20almost%0A%20%20%20%20free%2C%20while%20on%20the%20west%20side%20the%20relaxed%20bar%20now%20keeps%20~4%20in%2010%20houses%20(vs%20~1%20in%2010%0A%20%20%20%20before).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20BLOCK_SQL%2C%0A%20%20%20%20DEM_PATH%2C%0A%20%20%20%20ELEV_FT%2C%0A%20%20%20%20EVAC_SQL%2C%0A%20%20%20%20SLAB_SQL%2C%0A%20%20%20%20conn%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20np%2C%0A%20%20%20%20rasterio%2C%0A)%3A%0A%20%20%20%20%23%20Verify%20(post-data)%3A%20decompose%20what%20the%20two%20relaxations%20(30-%3E20%20ft%2C%20%2Bzone%20E)%20buy.%0A%20%20%20%20%23%20All%20final%20survivors%20%3D%20block%2Fslab%2FZone-X%2C%20evac%20in%20(NON%20EVAC%2C%20E)%2C%20elevation%20%3E%3D%2020%20ft.%0A%20%20%20%20_rows%20%3D%20conn.execute(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20SELECT%20p.latitude%2C%20p.longitude%2C%20p.evac_zone%0A%20%20%20%20%20%20%20%20FROM%20parcels%20p%0A%20%20%20%20%20%20%20%20LEFT%20JOIN%20building_foundation%20b%20ON%20p.parcel_id%20%3D%20b.pid%0A%20%20%20%20%20%20%20%20WHERE%20p.municipality%20%3D%20'ST%20PETERSBURG'%0A%20%20%20%20%20%20%20%20%20%20AND%20p.construction_type%20IN%20%7BBLOCK_SQL%7D%0A%20%20%20%20%20%20%20%20%20%20AND%20p.flood_zone%20%3D%20'X'%20AND%20p.evac_zone%20IN%20%7BEVAC_SQL%7D%0A%20%20%20%20%20%20%20%20%20%20AND%20b.found%20IN%20%7BSLAB_SQL%7D%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20).fetchall()%0A%20%20%20%20_lons%20%3D%20%5Bfloat(r%5B1%5D)%20for%20r%20in%20_rows%5D%0A%20%20%20%20_lats%20%3D%20%5Bfloat(r%5B0%5D)%20for%20r%20in%20_rows%5D%0A%20%20%20%20_evac%20%3D%20np.array(%5Br%5B2%5D%20for%20r%20in%20_rows%5D)%0A%20%20%20%20with%20rasterio.open(DEM_PATH)%20as%20_ds%3A%0A%20%20%20%20%20%20%20%20_feet%20%3D%20np.array(%5Bv%5B0%5D%20for%20v%20in%20_ds.sample(zip(_lons%2C%20_lats))%5D%2C%20float)%20*%203.28084%0A%20%20%20%20_final%20%3D%20_feet%20%3E%3D%20ELEV_FT%0A%20%20%20%20_n_final%20%3D%20int(_final.sum())%0A%20%20%20%20_zone_e%20%3D%20int((_final%20%26%20(_evac%20%3D%3D%20%22E%22)).sum())%0A%20%20%20%20_band%20%3D%20int((_final%20%26%20(_feet%20%3C%2030)).sum())%20%20%23%2020-30%20ft%2C%20admitted%20only%20by%20the%20relaxation%0A%20%20%20%20_ge30%20%3D%20int((_final%20%26%20(_feet%20%3E%3D%2030)).sum())%20%20%23%20would%20survive%20the%20old%2030%20ft%20bar%20too%0A%20%20%20%20_ge30_evac%20%3D%20int((_final%20%26%20(_feet%20%3E%3D%2030)%20%26%20(_evac%20!%3D%20%22NON%20EVAC%22)).sum())%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22**Relaxation%20decomposition%3A**%20%7B_n_final%3A%2C%7D%20final%20survivors.%20%22%0A%20%20%20%20%20%20%20%20f%22**%7B_ge30%3A%2C%7D**%20sit%20at%20%E2%89%A5%2030%20ft%20(the%20old%20bar)%2C%20and%20**%7B_ge30_evac%7D**%20of%20those%20are%20in%20an%20%22%0A%20%20%20%20%20%20%20%20f%22evac%20zone%20%E2%80%94%20so%20above%2030%20ft%20the%20field%20is%20still%20entirely%20non-evac.%20The%20other%20%22%0A%20%20%20%20%20%20%20%20f%22**%7B_band%3A%2C%7D**%20are%20newly%20admitted%2C%20all%20in%20the%2020%E2%80%9330%20ft%20band%2C%20of%20which%20%22%0A%20%20%20%20%20%20%20%20f%22**%7B_zone_e%3A%2C%7D**%20are%20zone%20E.%20%22%0A%20%20%20%20%20%20%20%20%2B%20(%22%E2%9C%85%20Both%20relaxations%20act%20only%20on%20lower%20ground.%22%0A%20%20%20%20%20%20%20%20%20%20%20if%20_ge30_evac%20%3D%3D%200%20else%20%22%E2%9A%A0%EF%B8%8F%20Evac%20zones%20now%20appear%20above%2030%20ft%20%E2%80%94%20review.%22)%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%23%20Caveats%20(for%20honest%20prose)%0A%0A%20%20%20%20-%20**Slab**%20uses%20footing%20type%20as%20a%20proxy%20(no%20literal%20%22slab%22%20field%20exists).%20645%0A%20%20%20%20%20%20citywide%20survivors%20had%20a%20blank%20foundation%20and%20were%20excluded%3B%20counting%20them%20as%0A%20%20%20%20%20%20slab%20raises%20the%20final%20figure%20to%20~22%2C400%E2%80%9323%2C050.%0A%20%20%20%20-%20**Elevation**%20is%20DEM%20ground%20elevation%20(~10%20m%20grid)%2C%20not%20finished-floor%20%2F%20elevation%0A%20%20%20%20%20%20certificate.%20Adequate%20for%20a%2020%20ft%20threshold%3B%20all%20sampled%20points%20hit%20valid%20cells.%0A%20%20%20%20-%20**Block%20construction%20is%20~96%25%20slab**%20in%20this%20market%2C%20so%20%22block%20on%20slab%22%20is%20nearly%0A%20%20%20%20%20%20one%20criterion%2C%20not%20two.%0A%20%20%20%20-%20Read-only%20against%20%60analytics.db%60%3B%20foundation%20from%20raw%20%60RP_BUILDING.csv%60%3B%20elevation%0A%20%20%20%20%20%20from%20a%20one-time%20USGS%20DEM%20download%20(%60data%2Fdem%2F%60%2C%20gitignored).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
1d3dbbac28a765cf9d01c1339693ef2e