Bozeman CRE Market Report — Retail / Industrial / Office (For Lease)

Run Deploy Instructions

← Back to outcome

Run / Refresh Instructions — Bozeman CRE Market Report

This is a data + report deliverable. No server or build step is required to read it.

Read it

  1. Open data/market-real-estate-report.md in any Markdown viewer (or GitHub).
  2. Open data/listings.csv and data/sector-lease-averages.csv in Excel, Google Sheets, or Numbers.

Re-compute the sector averages (verification)

The averages are the arithmetic mean of asking_rate_usd_per_sf_yr for Bozeman rows with a rate. Reproduce with Python 3:

import csv
from collections import defaultdict

rows = list(csv.DictReader(open("data/listings.csv", encoding="utf-8")))
by_sector = defaultdict(list)
for r in rows:
    rate = r["asking_rate_usd_per_sf_yr"].strip()
    if rate and r["city"] == "Bozeman":
        by_sector[r["sector"]].append(float(rate))

for sector in sorted(by_sector):
    vals = by_sector[sector]
    print(f"{sector}: n={len(vals)} avg=${sum(vals)/len(vals):.2f} "
          f"min=${min(vals):.2f} max=${max(vals):.2f}")

all_vals = [v for vals in by_sector.values() for v in vals]
print(f"BLENDED: n={len(all_vals)} avg=${sum(all_vals)/len(all_vals):.2f}")

Expected output:

Industrial: n=31 avg=$14.52 min=$6.50 max=$19.00
Office: n=19 avg=$27.55 min=$18.00 max=$38.00
Retail: n=22 avg=$28.06 min=$15.00 max=$50.00
BLENDED: n=72 avg=$22.09

Refresh the data (re-pull listings)

  1. Re-open the source URLs in data/source-log.csv (LoopNet, Bozeman Real Estate Group, PropertyShark, etc.).
  2. Update asking_rate_usd_per_sf_yr, available_sf, and retrieved_at for changed rows; add/remove listings as inventory turns.
  3. Re-run the Python snippet above to recompute averages.
  4. Update the headline tables in README.md and data/market-real-estate-report.md.

Smoke test

  • listings.csv opens with one header row + listing rows; every listing_id is unique.
  • Every listing_id in listings.csv has a matching row in source-log.csv.
  • Re-computed averages match sector-lease-averages.csv and verification-report.json.