Python for Architects: Where to Start, and Where a Coin Toss Says Stop
A Tesla stock tutorial scores 0.573 ROC-AUC, close to a coin toss. What that teaches architects about Python, scikit-learn and knowing when to stop.
In August 2026 a team including Zongqian Li, Yaoyiran Li, Nigel Collier and Eugene Ie posted AutoScientist-Quant (arXiv 2608.28632). In it they wrote plainly that they had to “fix two lookahead problems” in an evaluation pipeline. That one sentence teaches more than most Python courses. Researchers with the full stack in front of them still let tomorrow leak into today, and they said so in public. PAZ has covered this before in Your backtest is lying to you. This piece starts from the other end: an architect opening Python for the first time, and the question most syllabi skip. Why learn it, where do you start, and where do you stop?
The teaching material came in through our inbox. It is the GeeksforGeeks tutorial on stock price prediction with machine learning in Python, with code revisions credited to Susobhan Akhuli. It loads eight years of Tesla OHLC data, from 1 January 2010 to 31 December 2017: 1,692 rows and 7 columns. It drops the redundant Adj Close column, builds three features (open-close, low-high and an is_quarter_end flag), splits the rows 90/10 with random_state=2022 and trains three classifiers. Then it does something rare. GeeksforGeeks’ own conclusion says the result is “no better than simply guessing with a probability of 50%”. A tutorial that ends at a coin toss and says so is a better teacher than ten that end on a rising curve.
What the numbers actually say
GeeksforGeeks reports the XGBClassifier at a training ROC-AUC of 0.964 against a validation score of 0.573. Logistic regression scores 0.519 in training and 0.544 in validation. The polynomial-kernel SVC lands at 0.472 in training and 0.447 in validation, under the coin on both. The tutorial flags the XGBoost gap as overfitting itself, which is honest. The model memorised the past and could not read the next day. Ninety-six percent in training is the render. Validation is the site.
The mechanism matters too. train_test_split shuffles rows by default, so with test_size=0.1 the 1,522 training rows and 170 validation rows come from the same eight years, all mixed together. The target uses Close.shift(-1), which is the right direction. The split still lets the model learn from Thursday and then be tested on Wednesday. Here is the trade-off: a shuffled split is fine for independent samples and misleading for anything with a calendar. With dates in the data, the score looks better than the model really is.
←TODAY: Python with pandas and scikit-learn is free, and Rhino 8’s ScriptEditor ships CPython 3, so the same language runs in Grasshopper and in the office timesheet.
→3012: The offices that lasted kept their records in plain CSV and their models humble.
Fulcrum: Learning a tool well includes learning when the honest result is “stop here”.
Why an architect should run it anyway
Swap Tesla for your office. Instead of Open, High, Low and Close you have hours per SIA 112 phase, fees per m² of floor area, and change orders per month. The moves are the same: read_csv, split a date, group by year, build a column that looks one step ahead. pandas, which Wes McKinney started in 2008, does the cleaning. scikit-learn does the modelling, and it has a quiet origin story. It began in 2007 as David Cournapeau’s Google Summer of Code project. Researchers at INRIA in France, among them Gaël Varoquaux, Fabian Pedregosa, Alexandre Gramfort and Vincent Michel, carried it into the library millions now import without a thought. Those maintainers are the reason a twelve-person Zürich studio can run a classifier at lunch.
The Tool: scikit-learn, the open-source Python machine-learning library maintained by a worldwide volunteer and institutional community. It is worth an architect’s afternoon because it puts the honest baseline (DummyClassifier) and the honest split (TimeSeriesSplit) right next to the impressive models.
Setup:
python -m venv .venv
.venv\Scripts\activate # macOS/Linux: source .venv/bin/activate
pip install pandas scikit-learn matplotlib
python -c "import sklearn, pandas; print(sklearn.__version__, pandas.__version__)"First steps:
- Export one CSV from your timesheet tool with one row per project-month: date, project, phase, hours. Load it with
pd.read_csv("hours.csv", parse_dates=["date"]).sort_values("date"). Sorting is the first line of defence. - Build a forward-looking target the same way GeeksforGeeks does:
y = (df["hours"].shift(-1) > df["hours"]).astype(int). Then drop the last row, which has no future. - Score a
DummyClassifierand aLogisticRegressionon a time-ordered split (see the Hack). If both land near 0.5, you have your answer, and it took an afternoon rather than a quarter.
Where to stop
Here is the stop point the slot asked for. Start with data you own, such as schedules exported from Archicad, timesheets, and invoice logs. Stop the moment your model cannot beat the coin on a time-ordered split. Past that point Python is not your problem. The signal simply isn’t in the columns, and more layers will only memorise better. The market, like the client, reserves the right to change its mind. Python’s real return in a Büro is the boring 80 percent: cleaning, joining and checking. PAZ Academy teaches exactly that path, from GhPython in Grasshopper to the office-data script that saves four hours a month.
Atelier: An office adopting AI will meet a colleague with a dashboard that “predicts” overruns. The defence is a written rule, not scepticism. Monday move: add one line to your BIM/IT policy saying that no in-house model informs a fee proposal unless it beats DummyClassifier on TimeSeriesSplit across all five folds.
Hack: Make the model compete against a coin, with time running in only one direction. TimeSeriesSplit always trains on the past and tests on the later block, so nothing from the future leaks in. The dummy is the floor, at a ROC-AUC of 0.5. Anything that can’t clear it clearly goes back in the drawer.
from sklearn.model_selection import TimeSeriesSplit, cross_val_score
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
cv = TimeSeriesSplit(n_splits=5) # past trains, future tests
for m in (DummyClassifier(), LogisticRegression()): print(type(m).__name__, cross_val_score(m, X, y, cv=cv, scoring="roc_auc").mean())From where I sit, the records that survived were the plain ones. A CSV a 25-year-old can open in Notepad outlived every proprietary dashboard. Keep your training data that boring.
Learn-it:
- The source tutorial: GeeksforGeeks — Stock Price Prediction using Machine Learning in Python. Run it once with the shuffled split and once with
TimeSeriesSplit, and compare. - PAZ context: Your backtest is lying to you, on lookahead, survivorship and the one
.shift(-1)that fixes them. - Personal note: before you look at a single metric, write your stop rule at the top of the notebook.
Open your timesheet export tonight, run the five Hack lines on it, and write down the number before you decide anything.
SOURCE · ↗
PAZ Kaffi · multidisciplinary editorial, led by PAZ Academy