Back to work
New Product0-to-1Adoption

USC Student Housing Matcher

A Flask web app I built solo that fetches live listings from 11 USC-area property managers, scores them against a student's preferences, and returns ranked matches with a reason for each. Used by 10 classmates to find housing they booked.

View Live DemoView CodeHosted on a free tier; may take a moment to wake up.

Overview

Finding housing near USC means checking a dozen scattered property-manager sites by hand, each in a different format, with no way to compare across them. I hit this myself as a new student, and when a close friend ran into the same wall this year, I built the tool I wish I'd had.

What It Does

A student answers eight questions: budget, unit type, room and bathroom privacy, size, distance from campus, move-in date, and pets. The app has already loaded current listings from 11 area property managers, scores each against those answers, and returns a ranked top ten with address, rent, distance from USC, and a plain-English reason for each match. Listings with incomplete data are shown separately as an unscored list rather than guessed at.

How It Works

Live fetching from 11 AppFolio property-manager sites via BeautifulSoup, around 725 scored listings, geocoded against USC using OpenStreetMap with a committed cache. A deterministic weighted scoring model applies hard filters for budget, distance, and pets, with documented heuristics for fields no source exposes. Exact-size matches form their own tier, so a larger cheaper unit cannot out-rank the studio someone actually wants.

My Role

Solo build. I designed the scoring model, wrote the scrapers and geocoding pipeline, built the Flask app and UI, and deployed it end to end.

The Hard Problems

Two bugs were worth the fight. First, a production concurrency issue where the background load thread started in gunicorn's master process instead of the worker, so form submissions failed while the logs falsely reported the data was ready. The fix was moving the load into gunicorn's post_fork hook so it runs inside the worker that actually serves traffic. Second, a scoring-normalization bug where penalizing suspiciously cheap listings accidentally floated them higher, because removing a low factor raised the normalized average. The fix was keeping the price factor in the denominator as a real zero-weighted penalty instead of removing it.

Results & Recommendations

Used by 10 classmates to find housing near campus, several of whom scheduled bookings on places the tool surfaced.

Next Steps

Move the static-snapshot sources to live fetching, persist loaded state to eliminate the cold-start delay on restart, and add an extraction layer for property sites that don't expose clean feeds.