Projects
Things I have built outside the posts — research pipelines, working software, and tools I needed and could not find.
The posts on this site are arguments. These are artifacts: code that someone other than me runs, or was built to be handed over. Each one links to its source.
Where a project produced a result, the result is stated here rather than implied — including where the answer was less clean than I wanted.
Research and modelling
Messi vs Ronaldo — the weighted case
An R Shiny dashboard that compares the two on difficulty-adjusted scoring rather than raw totals. Opponent Elo, venue, competition stage and away status are compressed into one difficulty score by a single global FAMD, and goals are weighted by it. The denominator is every valid minute — 2,201 appearances and 181,081 minutes, with all 1,063 scoreless appearances kept in, which is where most comparisons quietly cheat.
The result is the reason the project is worth reading. On the weighted index per 90 the gap is +0.0953 in Messi’s favour (0.1337 against 0.0384), and a seeded 10,000-resample match bootstrap puts 96% of resampled differences above zero — but the 95% percentile interval is [−0.0120, +0.1999], which crosses it. The dashboard reports both numbers side by side and refuses to print a significance verdict or a winner badge. Cohen’s d is +0.090.
It is a fixed 2002–2026 research snapshot, not a live feed of career totals, and the limitations section says so in seven bullets. Runs from a precomputed bundle rather than scraping at startup; the container is pinned by digest and runs non-root.
Bayesian Change-Point Detection in Nigerian Rainfall
A hierarchical Bayesian change-point analysis of 74 years of precipitation (1950–2023) across nine meteorological stations in Nigeria’s three climate zones, written for an IEEE conference paper. PyMC and NUTS, with partial pooling of change-point timing across zones through shared hyperpriors and a non-centered parameterisation.
The finding worth stating: the transitions are coherent but asynchronous — Sahel breaks in 1958, Guinea Savanna in 2016, Coastal in 2015, with the hierarchical group estimate at 1989. The Coastal 94% HDI spans 1996–2022, which is wide enough to be honest about how little that zone’s timing is pinned down. The no-change-point null is decisively rejected in every zone by PSIS-LOO.
Priors are weakly informative and each one is justified in a table in the README. Pre-computed MCMC traces ship with the repository, so the figures can be regenerated without re-running the sampler — the same instinct as _freeze on this site.
Soccer: Bayesian World Cup prediction
Europe versus South America, worked as a causal problem before a predictive one. Currently at stage one: the causal DAG, the implied conditional independencies, and an explicit identification statement, with latent team strength modelled as an unobserved node.
Early and incomplete — the DAG and its validation exist, the model does not yet. It is here because the ordering is the point: the identification argument is written down before anything is fitted.
Software built for someone else to use
ATBU Academic Planning Portal
A desktop application managing 223 professor records for the Director of Academic Planning at Abubakar Tafawa Balewa University. Python and Flet over SQLite, packaged as a Windows executable for a non-technical user.
The part that mattered was the export: the National Universities Commission requires a specific Excel layout for professor-list updates, and producing it by hand for accreditation is where the errors were coming from. The app generates it directly, and imports the three-section Excel format the university already used. Editing is password-protected with bcrypt, and the database backs up in one click.
PRP Command Center
A single-file, zero-dependency operations dashboard covering 20 local government areas and 212 wards in Bauchi State, with real GRID3 geography rendered as inline SVG.
The constraint drove the design: no network requests at all, so it works on a laptop in a room with no connection, which is the room it was built for. Ward status is derived from the clock rather than fetched.
Kaduna Solar Lead Gen
A Streamlit app that pulls real business locations from OpenStreetMap and turns them into qualified solar-installation leads with a generated pitch per prospect.
Tools
Silman endgame Anki deck
A generator that turns Jeremy Silman’s Complete Endgame Course into 3,214 Anki flashcards, graded from beginner to expert so the deck can be studied in the rating-band order the book is organised around. Written because I wanted to drill the endgames and typing them by hand was not going to happen.
This website
The source of everything you are reading, execution cache included. Posts run in R or Python, one engine per post, and every published result is frozen at publication so a package upgrade cannot silently change a figure years later.
More work — including client and consultancy material that is not open source — is in my portfolio folder, and anything public is on GitHub.