Programming for data science
Programming for Data Scientists: A Reproducible Learning Path
A connected SQL, Python and R core workflow with applied language extensions, built around a versioned transport-demand case study and executable review gates.
On this page
Study context
Independent learning material
This resource was prepared for study and revision. Any named institution describes the programme context; it does not imply that the institution published, endorsed or maintains this page.
This learning path starts where many introductory programming tutorials stop: with a dataset whose origin must be checked, a prediction moment that must be defined, and results that another analyst must be able to reproduce. It is written for working data scientists who already understand basic descriptive statistics, regression metrics and the difference between association and causation.
The three published core guides form one analytical handover. SQL creates and validates a feature table. Python trains a transparent demand model without using post-outcome information. R independently audits the holdout predictions and quantifies uncertainty in the difference between the candidate model and a simple baseline. Each language has a distinct responsibility; the pages are not translations of the same syntax exercise. Reviewed downstream artefacts also provide stable contracts for task-specific extensions without retraining the model or reopening its holdout.
The analytical problem
The case study predicts hourly bicycle rentals using the UCI Bike Sharing dataset. Its target, cnt, is the total number of casual and registered rentals observed in an hour. Calendar and weather fields are possible predictors.
Two design decisions control the exercise:
- The prediction is assumed to occur before rentals for the forecast hour are observed.
- Training, validation and test periods follow chronological order.
The source also contains casual and registered, and cnt = casual + registered. Those components reveal the target after the outcome has occurred. A random split or a predictor matrix containing either component could produce an attractive result while failing the intended forecasting task. The shared contract therefore prohibits casual, registered and cnt as predictors.
One dataset, three core professional roles
| Guide | Primary task | Main artefact | Question answered |
|---|---|---|---|
| SQL for Data Scientists | Ingest, profile, validate and transform | features.csv and a data-quality report | Can this table be used at the stated prediction moment? |
| Python for Data Scientists | Fit a development-only baseline and evaluate an untouched test period | model metadata, metrics and row-level predictions | Does the candidate improve on a defensible simple baseline? |
| R for Data Scientists | Recalculate metrics and resample whole days | independent audit table and bootstrap interval | Is the observed error difference stable across holdout days? |
Follow the sequence for a first reproduction. Experienced analysts may enter at any guide, but each downstream stage expects the preceding artefact and contract.
The core path remains deliberately small. Applied extensions consume its machine-readable outputs, declare their guide prerequisites and repeat the relevant analytical checks in an independent runtime.
Applied language extensions
| Guide | Required handover | Primary task | Main artefact |
|---|---|---|---|
| JavaScript and TypeScript for Data Scientists | Python predictions and R audit outputs | Validate a cross-language reporting contract and publish accessible model diagnostics | deterministic JSON and static-first HTML |
| Rust for Data Scientists | Raw dataset, dataset lock and SQL prediction-time contract | Enforce byte, schema and analytical invariants at an external-data boundary | deterministic data-quality JSON |
| C++ for Data Scientists | Python predictions and R audit outputs | Move one paired bootstrap kernel behind a validated pybind11 and NumPy boundary | deterministic native-audit JSON |
| Julia for Data Scientists | Python predictions and a committed decision-candidate snapshot | Formulate and audit a constrained synthetic monitoring plan in JuMP | deterministic decision-audit JSON and selected-hours CSV |
The JavaScript and TypeScript extension does not retrain the model or reopen selection. It recalculates the displayed holdout and grouped diagnostics, checks them against the independent R audit, and progressively enhances a complete server-generated report. The Rust extension independently rechecks the raw snapshot and prediction-time contract as a typed command-line quality gate. The C++ extension validates and snapshots typed NumPy buffers before running the paired day-block bootstrap behind a pybind11 boundary; a readable Python oracle checks every native replicate and the independent R output checks the point estimate. The Julia extension keeps regenerated forecasts as an integration check while JuMP optimises only the reviewed integer-score snapshot under explicitly synthetic constraints. None of the extensions changes the core model or treats a successful teaching run as evidence of present-day performance.
Dataset card
| Field | Recorded value |
|---|---|
| Creator | Hadi Fanaee-T |
| Repository | UCI Machine Learning Repository |
| DOI | 10.24432/C5W894 |
| Licence | CC BY 4.0 |
| Setting | Capital Bikeshare, Washington, DC |
| Observation period | 2011–2012 |
| Unit of analysis | One recorded hour |
| Checked-in rows | 17,379 |
| Repository-copy SHA-256 | b03a2d02e8c10f435c43c7f0b358b7e34a003afea53dbc37f0183f2763295133 |
| Upstream CRLF-file SHA-256 | e03de4ee4ef4dc376ac6e04bf829673c6269e8eba5c60fa121640fa2f829504f |
The UCI landing page reported 17,389 instances when checked on 15 August 2026, while the official archive’s hourly file contains 17,379 data rows. The package records that discrepancy and uses the file-observed count. It does not manufacture or infer ten records to reconcile a catalogue value.
The checked-in file uses LF line endings, which changes the byte-level digest from the upstream CRLF file. Cell values and row order are unchanged. Both digests and the original archive digest are stored in examples/programming-for-data-science/data/dataset.lock.json.
What the data can and cannot support
The dataset is useful for teaching temporal validation, count prediction, feature contracts and cross-language review. It cannot describe current demand, Sri Lankan travel, unmet trips or the causal effect of weather. It omits station capacity, bicycle availability, rebalancing, fares, network changes and several contextual influences. A model may predict recorded rentals while missing suppressed demand when no bicycle or dock was available.
Treat the 2011–2012 observations as an immutable pedagogical benchmark. Do not present the resulting coefficients as current transport evidence or policy effects.
Reproduce the complete core chain
The runnable package is under examples/programming-for-data-science/. From the repository root:
python3 -m venv examples/programming-for-data-science/.venv
examples/programming-for-data-science/.venv/bin/python -m pip install \
-r examples/programming-for-data-science/requirements.txt
examples/programming-for-data-science/.venv/bin/python \
examples/programming-for-data-science/test_all.py
Windows PowerShell uses .venv\\Scripts\\python.exe in place of .venv/bin/python. The final command deliberately fails if Rscript is missing or any tested version differs. Generated artefacts are written to examples/programming-for-data-science/artifacts/ and are not committed.
The expected checkpoints are operational contracts:
- the dataset digest, schema and 17,379-row count match;
- the target identity holds for every row;
- timestamps and source identifiers are unique;
- the feature table excludes post-outcome components;
- the temporal partitions contain 13,003 training, 2,208 validation and 2,168 test rows;
- the Python model beats the development-only hour-and-weekday baseline on test mean absolute error; and
- R independently reproduces the test metrics and returns a finite day-block bootstrap interval.
A failed assertion is evidence that the inputs, environment or method changed. Do not update the expected number merely to make a check pass. Inspect the difference, decide whether it is intentional, and document the analytical consequence.
A practical order for further work
After reproducing this baseline, improve the workflow in controlled increments:
- add a data dictionary and prediction-time availability owner for every candidate field;
- compare rolling-origin validation with the single validation window used here;
- add station capacity, availability and operational variables when a defensible source exists;
- compare count-aware and non-linear models against the transparent baseline;
- examine error by hour, working day, season and severe-weather category;
- turn machine-readable audits into accessible, static-first diagnostic reports;
- define drift thresholds and retraining ownership before deployment; and
- test transportability on a newer dataset rather than assuming it.
Each change should preserve the untouched test principle. Once the test set influences feature selection or model choice, it has become development data and a new final holdout is required.
Authorship and disclosure
These are independent study materials by Dr. Kushan Liyana Arachchige. AI assistance was used to help draft code and documentation. Dataset provenance, transformations, assertions, numerical outputs and interpretations for the core workflow received human editorial review on 15 August 2026. The C++ and Julia extensions’ clean-environment reproductions and rendered guides received review on 16 August 2026. The recorded verification establishes reproducibility for the pinned teaching workflows; it does not remove the historical-data, causal or deployment limitations stated above.