A "should I ride today?" black ice prediction tool for Vancouver cyclists. Takes weather forecast data, runs it through a rule-based risk model, and emails a morning risk assessment (Safe / Caution / Dangerous).
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtScrape Reddit for historical ice reports (do once — hits the API):
python3 -m src.scraper.reddit scrapeTo re-run just the relevance filter on already-scraped data (fast, no network):
python3 -m src.scraper.reddit filterCollect historical weather data from Environment Canada (takes a while):
python3 -m src.weather.env_canadaBuild labeled dataset by propagating ice labels across cold spells:
python3 -m src.labeler.propagateRun the rule-based model against the labeled dataset:
python3 -m src.validateGet today's prediction (requires SMTP env vars for email):
python3 -m src.mainpytest| Variable | Description |
|---|---|
SMTP_HOST |
SMTP server hostname |
SMTP_PORT |
SMTP port (default: 587) |
SMTP_USER |
SMTP username/email |
SMTP_PASS |
SMTP password or app password |
NOTIFY_EMAIL |
Email address to send predictions to |
- Install the gcloud CLI and authenticate
- Deploy:
gcloud functions deploy predict-ice \
--runtime python311 \
--trigger-http \
--entry-point predict_ice \
--source . \
--set-secrets 'SMTP_HOST=smtp-host:latest,SMTP_PORT=smtp-port:latest,SMTP_USER=smtp-user:latest,SMTP_PASS=smtp-pass:latest,NOTIFY_EMAIL=notify-email:latest'- Set up Cloud Scheduler to trigger at 5:00 AM PST daily:
gcloud scheduler jobs create http black-ice-daily \
--schedule "0 5 * * *" \
--time-zone "America/Vancouver" \
--uri "FUNCTION_URL" \
--http-method POSTSee findings.md for detailed methodology, results, and limitations.
src/
├── scraper/reddit.py # Arctic Shift API — historical Reddit ice reports
├── weather/
│ ├── env_canada.py # Environment Canada historical hourly data
│ └── forecast.py # Current conditions fetcher
├── labeler/propagate.py # Label propagation across cold spells
├── model/rules.py # Rule-based prediction (temp, humidity, dew point, wind, precip)
├── notify/email.py # SMTP email notifications
├── validate.py # Model validation against labeled data
└── main.py # Entry point + Cloud Function handler