Reproducible AI Data Analysis Project: Test the Result

A reproducible AI data analysis project should let another person inspect your input, run your code and check your answer. A polished chart alone cannot do that. This beginner Python project provides a small, inspectable example: six synthetic rows become four usable records, with a known mean of 105 seconds.

We ran the code, tested five selected cases and repeated the calculation with two local Python interpreters. You can download the input, answer key, transformation log and source code. The exercise uses invented teaching data, not records about real researchers, students or employers.

Why build a reproducible AI data analysis project now?

Anthropic’s 5 November research report examines 207,049 scientific sessions from its consumer plans. Observations cover 2 August–30 September 2026. Its main sample includes 128,914 Chat/Cowork sessions and 78,135 Claude Code sessions. Sessions are not unique scientists or successful discoveries.

Anthropic main sample: 128,914 Chat or Cowork scientific sessions and 78,135 Claude Code scientific sessions, totaling 207,049; observations 2 August to 30 September 2026, not unique people.
The source’s unit is a classified session. A person may contribute multiple sessions, so these counts cannot establish a scientist headcount.

Data analysis accounts for 33.7% of Chat/Cowork scientific sessions and 48.1% of Claude Code scientific sessions. The comparison figure, 27.6%, describes modeled researcher time using SciNet. These denominators differ. The 14.4 percentage-point difference between the two product shares is arithmetic, not a productivity gain or time saved.

Data analysis shares: 33.7 percent of Chat or Cowork scientific sessions, 48.1 percent of Claude Code scientific sessions and 27.6 percent of modeled researcher time; denominators differ.
Read each denominator before comparing bars. The source does not turn these three percentages into a causal productivity estimate.

The report also includes a separate survey of 528 scientists drawn from selected grant applicants in the US and Canada. Its selection and life/health emphasis limit generalization. Read the full primary report for classification and modeling methods.

For a learner, this context suggests a useful project question: can a reader trace your result back to its input? It does not establish employer demand, a hiring advantage or an employment guarantee. Our project below is original teaching work, separate from Anthropic’s data.

The fixture: six rows with a known answer

Start with an immutable CSV containing three fields. Keep the original file unchanged and record its SHA-256 hash. The hash identifies these exact bytes; it does not prove that data are true.

FieldMeaningRule
record_idSynthetic record identifierRequired; conflicting repeated IDs cause rejection
durationInvented task durationFinite, nonnegative number; missing values are logged and excluded
unitDuration unitOnly s or min; convert minutes to seconds

The six input rows contain A01 at 120 seconds, A02 at 2 minutes twice, A03 with a missing duration, A04 at 90 seconds and A05 at 1.5 minutes. Therefore, the duplicate and the missing value are visible before analysis begins.

Our rules remove only an exact duplicate record with the same ID, duration and unit. They reject a repeated ID with conflicting values. This distinction matters: silently keeping the last conflicting row would hide an unresolved data problem.

Original synthetic fixture row accounting: six input rows, one duplicate excluded, one missing duration excluded and four retained records.
Six minus one minus one equals four retained records. These counts describe a chosen teaching fixture, not a real-world data-quality rate.

The retained durations are 120, 120, 90 and 90 seconds. Their sum is 420 seconds, and 420 divided by four gives 105 seconds. Two retained minute values are converted to seconds. The transformation log records each input row’s treatment, including exclusions.

Run the Python project locally

Download the code pack linked below and extract it into an empty directory. Review scripts/pipeline.py before running it. The script uses Python’s standard library and requires no paid API, account credentials or external dataset.

From the extracted project directory, run: python3 scripts/pipeline.py –input data/analysis-teaching-fixture.csv –output-dir output/run.

Next, run the selected checks: python3 scripts/pipeline.py –input data/analysis-teaching-fixture.csv –output-dir output/tests –self-test.

The first command writes cleaned-results.csv, transformation-log.csv, a simple SVG result chart and a run manifest. The manifest records the command, Python version, input hash, rules, output hashes and summary values. The second command exercises the five cases described below.

If your interpreter is named python rather than python3, use that executable instead. We tested Python 3.10.10 and 3.9.6 on the same computer. We have not tested every operating system or Python release. Check your manifest rather than assuming your environment matches ours.

Tech Consulting Tailored to Your Coding Journey

Get expert guidance in coding with a personalized consultation. Receive unique, actionable insights delivered in 1-3 business days.

Get Started

If you are setting up an environment first, see our guide to updating pip in existing virtual environments. Keep environment maintenance separate from changing the fixture’s analysis rules.

Five tests: rejection can be the correct outcome

A check should compare an observed outcome with an expectation declared beforehand. Otherwise, code that quietly accepts bad input can look successful merely because it did not crash.

Selected caseExpected outcomeObserved outcome
Clean four-record fixtureAcceptAccepted
Six-row fixture with declared exclusionsAccept and log exclusionsAccepted with log
Unsupported duration unitRejectRejected
Conflicting repeated record IDRejectRejected
Negative durationRejectRejected

All five selected expectations matched. Three cases deliberately reject input; they are successful checks of rejection behavior. Do not relabel them as three failures or describe five selected checks as a general accuracy rate.

Five selected Python validation cases: two accepted as expected and three rejected as expected; all five match their predeclared outcomes.
These are selected local tests, not a population estimate, comprehensive security assessment or guarantee that no other bug exists.

To extend the project, add an empty-file case, a missing identifier and an infinite numeric value. Declare the expected behavior first. Then retain the actual output, including an unexpected failure, rather than adjusting the expected answer to make the check green.

Our GitHub token audit guide also explains why a portfolio should avoid real credentials. This project needs none: synthetic data are sufficient to demonstrate validation and provenance.

The result: 105 seconds, with a bounded claim

Four retained synthetic records: A01 and A02 at 120 seconds each, A04 and A05 at 90 seconds each; mean 105 seconds and total 420 seconds.
This is the fixture’s known answer. It measures no real person, job, organization or scientific research session.

We ran the pipeline under Python 3.10.10, then reran the raw fixture under Python 3.9.6 in a fresh local process. The cleaned-results CSV, transformation-log CSV and SVG chart had identical bytes across those two runs. The downloadable reproduction manifest records the hashes and versions.

However, this remains one-machine testing. It is not independent replication by a second person or a second computer. We did not call a Claude API, test Claude’s scientific accuracy or use Anthropic’s underlying session records.

A useful next step is to ask someone else to extract the pack and run the documented command without your help. Record their environment, actual result and any missing instruction. Until that happens, describe the work as locally rerun rather than independently reproduced.

Result-to-input audit trail connects the immutable six-row input, declared cleaning rules, four retained outputs and bounded 105-second mean; the manifest links input, code, command and result hashes.
Use this audit trail to explain where the number came from. Each connection should point to a retained file or documented rule, not merely an attractive diagram.

Download the inspectable project

The original synthetic fixture and our teaching tables are available for reuse under CC0. Our pipeline code is supplied under the MIT license in the pack. These permissions do not relicense Anthropic’s report or its underlying data.

Download the Python source and project pack (ZIP). Extract it before running the commands; do not run commands inside the archive preview.

What a reviewer should be able to establish

A reviewer should be able to identify the original input, explain every excluded row, reproduce the known arithmetic and distinguish tested behavior from untested claims. They should also find a clear license, executable instructions and a candid limitations note.

That makes a reproducible AI data analysis project more useful than a screenshot with an unexplained number. Its value is the inspectable chain between data, rules and result. Keep that chain small enough to review, then extend it with evidence.

Research and execution checked 7 November 2026. Primary report published 5 November; source observation window 2 August–30 September. The six-row exercise is synthetic, and all project findings above refer only to the retained local runs.