A 3-day hands-on course: fetch real-world messy data, clean it with pandas, visualize it, and deploy a Streamlit app as a portfolio piece.
Worked Example
·
Exercises
·
Deployment Guide
Table of Contents
This is a practical EDA course built around OpenStreetMap (OSM) data — a massive, real-world, community-maintained geographic database with all the messiness that implies. There's no schema enforcement, tagging is by convention, and inconsistencies are everywhere.
Each student gets assigned a different city and works through the same pipeline:
- Fetch raw data from the Overpass API
- Explore & clean with pandas (wrong dtypes, duplicates, missing values, inconsistent tags)
- Visualize with matplotlib and plotly (bar charts, interactive maps)
- Debug intentionally broken code (read tracebacks, diagnose silent errors)
- Build a Streamlit web app that presents your analysis
- Deploy to Streamlit Community Cloud — a public URL you can put on your CV
The end result is a portfolio piece, not a notebook nobody ever opens again.
- pandas — data manipulation & cleaning
- matplotlib — static visualizations
- plotly — interactive charts & maps
- Streamlit — web app framework
- Overpass API — OpenStreetMap data access
By the end of this course you will be able to:
- Fetch structured data from a REST API and load it into a DataFrame
- Identify and fix common data quality issues (wrong dtypes, duplicates, missing values, inconsistent encoding)
- Normalize messy real-world tags into clean, analyzable columns
- Create both static and interactive visualizations to answer questions about data
- Read Python tracebacks and diagnose errors systematically
- Distinguish between exploration code (notebooks) and production code (
.pyfiles) - Deploy a data application to the web
| Time | Activity | Materials |
|---|---|---|
| Morning | Intro to OSM + Overpass API, fetch your city's data | Exercise 01 |
| Afternoon | Explore raw data, identify issues, clean & deduplicate | Exercise 02 |
By end of day: You have a clean DataFrame with proper dtypes, no duplicates, and extracted tag columns.
| Time | Activity | Materials |
|---|---|---|
| Morning | Normalize tags (cuisine, opening_hours, names) | Exercise 03 |
| Early afternoon | Visualize with matplotlib & plotly | Exercise 04 |
| Late afternoon | Debug intentionally broken code | Exercise 05 |
By end of day: You have normalized tags, publication-ready charts, and an interactive map. You can read a traceback.
| Time | Activity | Materials |
|---|---|---|
| Morning | Build your Streamlit app from notebook code | Exercise 06, app.py template |
| Afternoon | Deploy to Streamlit Community Cloud, present to class | Deployment Guide |
By end of day: You have a live web app with a public URL. That's your portfolio piece.
- Python basics — variables, loops, functions,
import. No pandas experience needed. - GitHub account — you'll fork this repo and deploy from it.
- A computer with Python 3.10+ installed.
No prior data analysis experience required. That's what this course teaches.
# Fork on GitHub first, then:
git clone https://github.com/YOUR_USERNAME/edu.eda.git
cd edu.edapip install -r requirements.txtLook up your assigned city in docs/cities.md.
jupyter notebook exercises/01_fetch_osm_data.ipynbThe worked example for Stockholm is in example/stockholm_eda.ipynb — use it as a reference, but try to solve the exercises yourself first.
edu.eda/
├── README.md ← you are here
├── requirements.txt ← Python dependencies
├── app.py ← Streamlit app template (Day 3)
│
├── example/
│ ├── stockholm_eda.ipynb ← fully worked example (teacher reference)
│ └── app_stockholm.py ← reference Streamlit app
│
├── exercises/
│ ├── 01_fetch_osm_data.ipynb ← Day 1: fetch data from Overpass API
│ ├── 02_explore_and_clean.ipynb ← Day 1: explore, clean, deduplicate
│ ├── 03_tag_normalization.ipynb ← Day 2: normalize messy OSM tags
│ ├── 04_visualization.ipynb ← Day 2: matplotlib + plotly charts & maps
│ ├── 05_debugging.ipynb ← Day 2: diagnose intentionally broken code
│ └── 06_build_streamlit_app.md ← Day 3: build & deploy instructions
│
├── docs/
│ ├── cities.md ← city assignments (one per student)
│ └── deploy.md ← Streamlit Community Cloud deployment guide
│
├── assets/ ← course logo
└── data/ ← (gitignored) your downloaded data goes here
OpenStreetMap is a free, community-maintained map of the world. Anyone can edit it. That's its strength — and the source of all the data quality issues you'll encounter:
| Problem | Example |
|---|---|
| Inconsistent tagging | amenity=restaurant vs amenity=cafe vs amenity=fast_food — no clear boundary |
| Multiple formats | Opening hours: Mo-Fr 08:00-17:00 / monday-friday 8-17 / weekdays 8am-5pm / empty |
| Multilingual names | name, name:en, name:sv, name:ar — which one to use? |
| Delimiter chaos | cuisine=italian;pizza vs cuisine=Italian vs cuisine=Pizza, Italian |
| Wrong dtypes | building:levels="3" (string) vs 3 (int), lat/lon as strings |
| Duplicates | Multiple nodes at the exact same coordinate |
| Deprecated tags | highway=unsurfaced (deprecated since 2008, still used) |
| Import artifacts | Mass imports with geometry errors, still not fully cleaned |
This is not a toy dataset — it's the real world, and that's the point.
| # | Notebook | Day | Style | Topic |
|---|---|---|---|---|
| 01 | Fetch OSM Data | 1 | Guided | Overpass API → JSON → DataFrame |
| 02 | Explore & Clean | 1 | Guided | dtypes, NaN, duplicates, column extraction |
| 03 | Tag Normalization | 2 | Semi-guided | cuisine, opening_hours, multilingual names |
| 04 | Visualization | 2 | Semi-guided | matplotlib bars + plotly interactive maps |
| 05 | Debugging | 2 | Open-ended | Read tracebacks, fix intentionally broken code |
| 06 | Build Streamlit App | 3 | Open-ended | Assemble notebook code into a deployed web app |
Progressive difficulty: exercises 01–02 are guided (fill in the blanks), 03–04 give you the problem and hints, 05–06 give you the problem and let you figure it out.
Your deployed Streamlit app should include at minimum:
- At least one filter (e.g. dropdown to select amenity type)
- An interactive map showing your city's amenities
- At least one chart answering a question about your data
- KPI metrics (total amenities, unique types, data completeness, etc.)
The public URL is your portfolio piece. Ship it.