Labs
Three sandboxes you can use right here
Real results from my projects, in your browser. Each sandbox keeps its settings in the page address, so Copy link to this view shares exactly what you see.
Content moderation: where to draw the line
From the content moderation classifier case study.
Sandbox · threshold
Move the line: what happens when you flag more, or less?
Real results, not a simulation: the published DistilBERT model's scores for 180,488 held-out test comments (8.0% toxic), saved for every threshold from 0.02 to 0.98. Nothing runs a model in your browser. Source: Kaggle notebook and the threshold sweep that re-scored the same test set.
Ask the EU Digital Services Act: keyword vs vector search
From the Ask the DSA case study.
Sandbox · keyword vs vector
Same question, two ways of searching the law
Precomputed, clearly labelled: the top 3 articles that keyword search (BM25) and vector search (the all-MiniLM-L6-v2 embedding model) returned for each of the 25 test questions. Keyword search had the right article in its top 3 for 17 of 25 questions, vector search for 21. Nothing is searched live here. Text: EUR-Lex, © European Union. Not legal advice. Source: code and evaluation.
Dublin bikes: query the pipeline's tables
From the Dublin bikes data pipeline case study.
Sandbox · SQL console
Query the pipeline's tables in your browser
A read-only DuckDB database runs in your browser over a small sample of the published tables: every station from 16 Oct to 26 Oct 2026, 27140 station-hours. Opening it downloads DuckDB (about 10 MB, once) from jsDelivr. Full tables: Hugging Face dataset.
Tables and columns
fct_station_hour: station_id, hour_utc, snapshots, avg_bikes, min_bikes, max_bikes, avg_free_docks, share_empty, share_full, share_rentingdim_station: station_id, station_name, address, lat, lon, capacitydim_hour: hour_utc, hour_local, local_date, local_hour, weekday, is_weekend, temperature_c, rainfall_mm, wind_kmh, humidity_pct, weather_description
Example queries (they leave out STATION118, a placeholder station with no data, and one station listed with 0 docks):
select s.station_name, round(avg(f.share_empty) * 100, 1) as pct_time_empty, s.capacity
from fct_station_hour f join dim_station s using (station_id)
where s.capacity > 0 and s.station_name <> 'STATION118'
group by all order by pct_time_empty desc limit 10
select h.local_hour, h.is_weekend, round(avg(f.avg_bikes), 1) as avg_bikes_per_station
from fct_station_hour f join dim_hour h using (hour_utc) join dim_station s using (station_id)
where s.capacity > 0 and s.station_name <> 'STATION118'
group by all order by h.is_weekend, h.local_hour
select case when h.rainfall_mm > 0 then 'raining' else 'dry' end as weather,
count(*) as station_hours,
round(avg(1 - f.avg_bikes / s.capacity) * 100, 1) as pct_docks_without_bike
from fct_station_hour f
join dim_hour h using (hour_utc) join dim_station s using (station_id)
where s.capacity > 0 and s.station_name <> 'STATION118' and h.rainfall_mm is not null and h.local_hour between 7 and 21
group by all