What This Dog Actually Costs
This is a submission for Weekend Challenge: Dog Days Edition What I Built What This Dog Actually Costs estimates the lifetime cost of owning a dog by breed, and shows it as a probability distribution instead of a single number. Every "cost of a dog" article gives you one figure. "About $30,000 over its life." That number is useless the moment you look at a real dog. Breeds are wildly different, and the cost is not fixed. It is a gamble. Most owners pay in a normal range. Some get hit with a $6,000 hip surgery or a cancer bill in year eight. A single average hides the entire risk. So I built a tool that shows the shape of the bet before you take it. Pick a breed and you see the median, the typical range, and the expensive tail nobody budgets for. It runs on a Monte Carlo simulation of 10,000 dog-lifetimes per breed, 300,000 simulated lives in total, computed in Snowflake SQL. Four things it does: The distribution. The full spread of outcomes for a breed, with the tail past $40,000 shaded red so you can see how likely a very expensive dog really is. Roll a life. A button that pulls one random simulated dog out of Snowflake and narrates its whole life: which conditions hit, at what age, and the running total. Abstract odds become one dog's story. A scenario lab. Two sliders, deductible and coinsurance, that make Snowflake re-run the numbers live to answer "is insurance worth it for this breed?" There is an adopt-versus-buy toggle too. A leaderboard. All 30 breeds ranked by cost, tail risk, or cost per year. Demo 🎥 Video walkthrough: And to try it yourself on streamlit 🔗 Live App - mutina.streamlit.app The surprise the simulation kept handing me: the safe, popular choice is the expensive one. All figures are uninsured, pay-as-you-go, in US dollars. The two most popular family dogs in America are also the priciest to own. A Labrador Retriever runs a median of about $32,700 over its life, and a Golden Retriever about $32,650. The Golden has the fattest tail of any breed I modeled: nearly 1 in 5 tops $40,000, driven mostly by cancer. A Great Dane looks like the scary one, but it is not the villain. It costs the most per year to run, about $3,400, yet lives only ~9 years, so its lifetime median lands mid-pack near $30,300. A short life is not a cheap one, but a long healthy one with cancer risk costs even more. A French Bulldog sits at a median of about $22,500, with a typical range of $15,000 to $32,000. The three-lives view makes the spread concrete: a lucky one costs about $13,900, a median one $22,500, a nightmare one $35,200. A Border Collie lives long yet stays predictable: a median around $24,000 and only about a 3% chance of topping $40,000. Nearly half of Cavalier King Charles Spaniels develop mitral valve disease. You can watch that single condition bend the whole distribution. The affordability test is the blunt one. At $75/month saved and a $1,500 emergency fund, there is a 74% chance a French Bulldog hands you a year you can't cover. Its median worst year is about $5,150. Raise the fund and watch the number fall. The distribution, not a single number. Everything past $40,000 is shaded red. Same breed, three real simulated dogs: $23,410, $32,710, and $44,626. Move a slider and Snowflake re-runs all 10,000 lives, then hands you a verdict. Code lewisawe / Dog-Days What This Dog Actually Costs Estimate the lifetime cost of owning a dog by breed, shown as a probability distribution instead of a single number. The estimates come from a Monte Carlo simulation of thousands of dog-lifetimes run in Snowflake SQL. Built for the DEV Weekend Challenge: Dog Days Edition. How it works Three input tables (breeds, health conditions, breed-condition risk) are loaded into Snowflake from CSV. sql/03_simulation.sql simulates 10,000 dog-lifetimes per breed. Each simulated dog draws its own lifespan, accrues care costs each year (senior years weighted higher), and rolls the dice on the health conditions its breed is prone to. The Streamlit app reads the result tables and shows the cost distribution, the headline numbers, and the top cost drivers per breed. It also narrates individual simulated lives (three percentile lives plus a random "roll a life"), stress-tests a budget against every dog's worst year, and runs a… View on GitHub The pieces: data/: the dataset (30 breeds, 16 conditions, breed-specific risk), plus SOURCES.md documenting every assumption. sql/01_schema.sql, 02_load.sql, 03_simulation.sql: the schema and data load, then the Monte Carlo simulation. load_data.py runs the whole pipeline against a fresh Snowflake trial in one command. streamlit_app.py: the app. It runs as a Streamlit-in-Snowflake app on the active session, or locally against your account, with no code changes. How I Built It The data. 30 popular breeds, 16 health conditions, and the breed-specific lifetime probability of each. Lifespans lean on the Royal Veterinary College's VetCompass 2024 life tables. Treatment and care costs use US insurer claims data and vet ranges (hip dysplasia treatment averages around $5,200, for example). Every figure is a documented, honest planning estimate, not a quote. Snowflake is the engine, not just storage. The interesting work is the simulation, and it runs in SQL. GENERATOR fans each breed out into 10,000 rows. NORMAL and UNIFORM draw each dog's lifespan and roll its disease risks year by year. PERCENTILE_CONT collapses 300,000 simulated dog-lives into medians and tails. It builds in a few seconds on an XS warehouse. The core: -- one row per simulated dog: draw a lifespan around the breed median CREATE OR REPLACE TABLE sim_dogs AS SELECT b.breed_name, ROW_NUMBER() OVER (PARTITION BY b.breed_name ORDER BY RANDOM()) AS sim_id, GREATEST(1, LEAST(20, ROUND(b.lifespan_median + b.lifespan_sd * NORMAL(0, 1, RANDOM())))) AS lifespan_years, (b.annual_food + b.annual_routine_vet + b.annual_preventatives) AS annual_baseline, b.puppy_setup, b.purchase_price FROM breeds b CROSS JOIN TABLE(GENERATOR(ROWCOUNT => 10000)) g; One gotcha worth flagging: Snowflake's NORMAL(mean, stddev, gen) needs mean and stddev to be constants. You cannot pass columns. The fix is to draw a standard normal and scale it yourself: median + sd * NORMAL(0, 1, RANDOM()). Two modeling choices worth stating. Routine care is age-weighted: the last up to three years of a dog's life cost 40% more, since senior dogs need more vet visits and medication. And the headline number is deliberately uninsured, pay-as-you-go. Insurance isn't baked into the base cost (that would double-count premiums against out-of-pocket bills). Instead it lives in the scenario tab as an explicit choice. The scenario lab uses Snowflake live. The insurance question is not precomputed. When you move the deductible or coinsurance slider, the app fires a parameterized query that recomputes uninsured versus insured cost across all 10,000 lives and returns two fresh distributions plus a verdict. The answer changes by breed: for a high-risk breed insurance shrinks the tail and pays for itself; for a low-risk one the premiums outrun the payouts. Trust the SQL by reimplementing it. I wrote a pure-Python mirror of the model and a DuckDB mirror, then confirmed all three land on the same medians. When an independent reimplementation agrees, the warehouse math is sound. The affordability panel stress-tests your budget against every simulated dog's worst year. The app is Streamlit, reading the result tables. It detects its environment: inside Snowflake it uses the active Snowpark session, and locally it uses the Python connector. Prize Categories Best Use of Snowflake. Snowflake is the compute engine. The Monte Carlo simulation, the percentile math, and the live insurance scenarios all run as SQL in the warehouse. The app connects to Snowflake for every view. It runs either as a Streamlit-in-Snowflake app on the active session, or on Streamlit Cloud against a dedicated read-only Snowflake user with a warehouse credit cap. Every breed ranked. The Labrador and the other popular family dogs sit at the top.
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to