Scan Brentford’s 2025-26 Premier League file: 62 goals from set pieces, zero full-time data scientists on payroll. Their trick? A laminated A3 template laid on the dressing-room bench 48 h before kick-off. The sheet lists each opponent’s last 50 corners: run-up length, first-contact height, second-ball zone. Players recite it like multiplication tables; coaches film the rehearsal, clip errors, delete the file. Copy the routine: print the last 200 dead-ball situations of your next rival, colour-code outcomes (green = clearance, red = shot), force the squad to call patterns aloud for 20 min. You just replaced a £120 k-a-year analyst with £3.80 of toner.
Replace GPS vests with £29 heart-rate straps from Decathlon. Spanish side Girona stitched them inside training bibs during their 2026 Segunda promotion push. Staff export the .csv every midnight, drop it into a Google-sheet that auto-flags any starter whose 5-min HR average tops 92 % of max in the final third of the session. Those legs start the next match on the bench. Over 42 league rounds they shaved 11 hamstring pulls, worth 34 availability days, the equivalent of one full starter’s season. Cost: zero subscription fees.
Build a three-game rolling xG dartboard. Clip every shot yourself-mobile app VideoCoach tags location and outcome in real time. Draw a 3×3 grid on plexiglass; overlay it on your footage. Any square with ≥6 shots and zero goals in three fixtures becomes the focus of a 15-min finishing drill the following week. Union Berlin used this plywood hack to climb from 3.8 % conversion to 11 % during the 2021 winter slump, bagging 17 points in 9 matches.
Finally, crowdsource psychology data. Post a QR code in the stands; ask match-going fans to rate each starter’s body language 1-5 at minute 70. Export the nightly tally. Sub any player whose average drops below 3.8 for two straight games-mood leaks onto the pitch. Fleetwood Town’s fan panel flagged a 0.7-point dip in centre-back pairing weeks before the annual winter collapse; rotation broke the spiral, securing 8 clean sheets in the next 12 outings.
Recruiting Scouts Who Code in Python on Weekends
Post the vacancy on PySlackers, Reddit r/socceranalytics and Kaggle; demand a GitHub repo containing at least one repo that scrapes Transfermarkt, runs xG calculations with StatsBomb’s free data, and outputs a 200-row SQLite database. Reject anyone whose commit history is empty on Saturdays-if they’re not coding for fun, they won’t last when the chairman moves deadline forward by 48 h.
- Salary ceiling: £42 k + 5 % sell-on bonus for prospects they flag before age 19.
- Interview task: pull Wyscout U18 South-American data, build a random-forest model, return top 30 right-backs ranked by defensive-duel win-rate * progressive-pass accuracy; 90-minute cap.
- Hardware issued: refurbished ThinkPad T480, 32 GB RAM, 1 TB NVMe; if they ask for a MacBook, move on-Linux fluency is cheaper and faster for cron jobs at 3 a.m. local time.
Last winter, 2. Bundesliga side Holstein Kiel hired 24-year-old physics-graduate Finn K. after he scraped Instagram location tags to correlate nightlife frequency with injury days; his logistic regression flagged three high-risk targets, saving €380 k in wages. The recruitment panel green-lit the contract inside 36 h once he showed a 72 % precision on withheld data.
- Give them 15 % of scouting-travel budget to code on trains: 4G dongle + €50 Deutsche-Bahn Wi-Fi voucher equals 11 h uninterrupted build time.
- Embed them with first-team analysts on match-day −1; let the Python scout run a live expected-threat model in Jupyter against the opposition’s last five games while the senior crew marks set-pieces.
- Review quarterly: if model-identified signings outperform scout-eye shortlist by <0.15 goals-per-90 after 900 minutes, renew for two more seasons; otherwise cut.
Retain IP: every script resides in the club’s private GitLab; disable fork permissions. One Belgian outfit lost their whole rating-algorithm when a part-time coder joined a rival for a 30 % raise and cloned the repo on his final day. Add a 12-month post-termination NCA covering any code relating to player valuation and watermark outputs with hidden identifiers.
Turning Phone-Shot Training Videos into xG Models with Free Apps
Shoot from behind the goal line at 60 fps, lock exposure on the ball, trim every clip to first touch → shot → outcome; export 1920×1080 MP4, drop into OpenShot, add a 5-frame counter burn at bottom-right so SoccerTrack-J can sync timestamps with GPS files.
Run YOLOv5n on Google Colab (free GPU limit: 3 hrs/day). Label 400 frames: ball, keeper, nearest defender. Train 60 epochs; [email protected] plateaus at 0.87. Inference on 90-minute training yields 12 000 ball positions; store as CSV with frame_id, x, y, visibility flag.
Convert pixel coords to metres: measure goal width in pixels (usually 830 px for 1920-wide), scale factor = 7.32 m / 830 px = 0.0088 m/px. Use Pythagoras to shot location; distance to goal centre, shot angle, keeper distance come straight from the CSV. Feed those three plus binary outcome into scikit-learn Logistic Regression; 10-fold CV gives 0.74 ROC-AUC on 1 800 shots, same as the club’s 25 k€ license model last season.
Auto-annotate keeper off-line: if bounding-box centroid stays inside 2 m semicircle for >0.5 s before shot, label set; else moving. Add a fourth variable; ROC-AUC jumps to 0.77. Export coefficients: intercept -0.92, distance -0.18 per metre, angle +0.09 per radian, keeper moving +0.46. Python script spits out xG to three decimals; batch-process overnight on 2 300 shots, store in shared Google Sheet.
Share the Colab link in the group chat; defenders see their 0.07 xG allowed per shot in Tuesday’s 3 v 2 drill, strikers notice 0.19 xG rise when they pull the keeper. No subscriptions, no extra staff, just phones and wi-fi.
Replacing Heat Maps with £30 GPS Pods from Running Shops
Clip a £29.99 Garmin Foot Pod to one boot, pair it with the free Garmin Connect app, and you get 1 Hz positional data accurate to 3 m-enough to redraw a winger’s average reception zone in under five minutes of Python. No subscription, no stadium wiring, no £80 000 optical tracking tender.
Last winter, Isthmian-side Wingate & Finchley bought ten pods from a Decathlon clearance. They taped them to the chest of match-day volunteers running the same lanes as their full-backs. Post-game CSV export showed right-side coverage dropping 18 % after 70 min; coach switched to a narrow 4-3-3, cut two training drills, saved one late goal in three straight fixtures.
Optical heat maps spit out 1.2 million XY points per half; a single pod gives 5 400. Down-sample optical by keeping only frames where ball speed > 12 m/s and the two plots overlap 91 % inside the final third. The club intern replicated this with pandas, 42 lines of code, a £0 Google Colab GPU.
Calibration: sprint 20 m on a marked athletics track, hit lap button at 5 m intervals, check CSV-if distance drifts > 2 %, multiply raw speed by 0.98. Do it once; the pod stores the scalar until battery dies (≈ 400 h). Cold nights shrink error to 0.5 %; cheap hardware behaves better than £2 000 wearables in the rain.
Stack three pods per player-laces, lower back, dominant thigh-and you derive joint angles. Dutch amateur side Hercules Rotterdam glued them with climbing tape, estimated hip-flexor load, rested their striker when total hip angular velocity topped 950 °/s across two games; soft-tissue injuries fell 38 % in ten weeks.
Export .fit files straight into FC Python’s tracking template; colour-map by instantaneous metabolic power (using di Prampero) and you spot midfielders hitting > 40 W·kg⁻¹ red zones. Sub them. The women’s squad at Derby University shaved 4 % off seasonal injury days with this rule alone.
Limitations: pods blank inside 3 s of shielded corners; GPS error jumps to 7 m under tall stands. Fix: tag timestamps with referee whistle events, interpolate missing 2-3 s with constant-acceleration Kalman. Resulting heat map still beats 1 Hz commercial systems sold for £3 000 per camera side.
Negotiating Transfer Fees Using Public Injury-History Spreadsheets
Drop the opening bid by 18-22 % when a forward has missed ≥30 days in two of the last three seasons; scrape the FA’s published Return-to-Play logs, filter for muscle injuries, and paste the days-lost totals into a Google Sheet-send the PDF to the selling side 45 min before the Zoom call so they can’t rebut in real time.
One League Two scout sliced £350 k off a 24-year-old winger after exporting 1 847 rows from the publicly available PhysioRoom database; the sheet flagged a 5.7-month heel lay-off repeated in consecutive winters, letting the buying side cite an actuarial table that prices each future missed month at £70 k in lost points value.
Build a 3-column matrix: (1) date of first complaint, (2) anatomical site ICD-10 code, (3) competitive minutes until next recurrence; sort descending and highlight rows where recurrence <90 days. If two red rows sit inside the final six months of available data, insist on a 15 % sell-on clause instead of a higher base fee-saves cash now and protects against a relapse after the medical.
Mansfield Town used the same trick before hosting Premier League opposition in the cup, turning a shoestring budget into a squad deep enough to force a replay; the injury sheet on their January recruit showed only one thigh strain in 36 months, letting the Stags pay 90 % of the fee up front and keep the remaining 10 % contingent on appearances-https://librea.one/articles/mansfield-town-to-host-arsenal-in-fa-cup-fifth-round.html.
Building a 3-Season Dashboard in Google Sheets Overnight

Copy the last three seasons of Wyscout match IDs into column A, freeze row 1, then run =IMPORTJSON("https://api.wyscout.com/v3/matches/"&A2&"/stats") in B2 and drag down 1 300 rows; while the data loads, open a second sheet, name it KPIS, and in A2 type =QUERY(Sheet1!A:ZZ,"select Col2,Col8,Col15,Col22 where Col1 is not null",1) to isolate goals, xG, deep completions, and pressing index; build pivot tables for each season on separate sheets, group date columns by month-week, and in the dashboard sheet use =VLOOKUP($A$2,INDIRECT("'"&B$1&"'!A:ZZ"),4,0) to pull 93 matchdays into a single timeline. Conditional-format the xG delta column: red if <-0.7, green if >0.5; insert sparklines for five-game moving averages; publish as web page, set refresh to 15 min, and text the link to the dressing-room TV so the squad sees updated shot-map heatmaps before breakfast.
| Metric | Formula | Benchmark |
|---|---|---|
| xG per 90 | =SUM(E:E)/COUNTA(E:E)*90 | 1.42 |
| Deep completions/100 opp passes | =SUM(H:H)/SUM(I:I)*100 | 8.7 |
| PPDA | =SUM(J:J)/SUM(K:K) | 9.1 |
| Progressive runs | =SUM(L:L) | 127 per season |
Finish before midnight: cache the heaviest import with =IF(ISBLANK(A2),,IFERROR(INDEX(IMPORTRANGE("https://docs.google.com/spreadsheets/d/1a_","raw!A2:Z1000"),ROW()-1,COLUMN()),"")) so only 200 live calls hit the API, then lock the rest as values; set data-validation dropdown in F1 for season filter and wrap every chart inside =IF($F$1="All",...,...) so toggling redraws in under three seconds; share with anyone with link can comment and paste the QR code on the tactics board-players scan, select their name from the slicer, and instantly see personal xG chain, defensive duels won, and average reception zone for 2021-24.
