Inspiration

An aerospace contractor 3D-prints Ti-6Al-4V brackets by laser powder bed fusion, and the brackets keep failing the client's strength tests. The shop already logs chamber oxygen, powder-room humidity and powder reuse, but nobody relates them to part strength, so trouble shows up only when parts fail. We built the screen a quality engineer opens the day a build's witness tensile coupons come back from the lab.

What it does

Upload one row per tested witness coupon: a build ID and the ultimate tensile strength (MPa); the per-build logs are optional. The tool answers with one action (RELEASE, HOLD, INVESTIGATE, COLLECT MORE DATA, IMPROVE or CHECK DATA) plus the evidence:

  • Stability: X-bar and S control charts with limits from a 20-build baseline (sigma_short pooled within builds), read with the course's 8 tests for special causes (defaults: tests 1-4 on X-bar, test 1 on S).
  • Capability: one-sided Cpk and Ppk against the client minimum (default 895 MPa, the ASTM F2924 minimum for Ti-6Al-4V), with 95% intervals and one-sided lower bounds. The process counts as capable only when Cpk's lower bound clears the required 1.33 over a 20-build baseline.
  • Failures: expected coupons below spec (normal model) next to the observed count, with a Shapiro-Wilk check and a Q-Q plot.
  • Drivers: a regression of build means on the logged factors (HC3 robust errors) that names what to fix first, and says plainly that it shows association, not proof.

Every tab has a "how to read this" note, and the Method tab shows every formula.

How we built it

  • qc.py is a plain, tested Python statistics library with no web code; app.py is a thin Shiny for Python dashboard that only calls qc.assess(), so every number on screen traces to one function.
  • Deployed to the course Posit Connect by GitHub Actions (committed manifest, health check, logged-out check), plus a static Shinylive mirror on GitHub Pages that runs Python in the browser.
  • Three seeded, simulated datasets with a codebook: a stable printer (RELEASE), a dehumidifier failure after build 20 (HOLD; first alarm at build 22; humidity -1.82 MPa per %RH), and a new printer with messy lab data (IMPROVE).

Challenges we ran into

  • False alarms. With all 8 tests on both charts, about 46% of perfectly stable 25-build histories trip at least one test (we simulated it). We kept tests 1-4 on X-bar and test 1 on S as defaults, and HOLD looks only at patterns still active at the newest build.
  • Stability can't be proven from four builds. A confidence bound on Cpk assumes stability, so RELEASE also needs a 20-build baseline of builds with replicate coupons.
  • Messy lab data. Missing results, short builds and single-coupon builds are handled and reported, never imputed.

Accomplishments that we're proud of

  • 53 automated tests: a hand-worked known answer (Cpk 2.0742, 95% lower bound 1.4587), the course's own examples, Anscombe's quartet for the regression, a planted signal for each of the 8 tests, and degenerate cases (constant data never yields an infinite Cpk).
  • Our 8 tests match the course's spc_tests_from() on 500 random charts with zero mismatches, and a separate stats-reviewer agent re-derived every number; all of its findings were fixed.
  • On the humidity dataset the tool tells the drift story the way the course teaches it: Cpk 1.43 but Ppk 0.88.

What we learned

  • sigma_short versus sigma_total is the whole difference between capability and performance.
  • Every extra run rule costs false alarms, so measure the cost before choosing defaults.
  • Statistics first, styling last: verify against known answers before building any UI.

What's next

  • A Phase I workflow that excludes builds with explained special causes and freezes the limits.
  • Multi-printer comparison (ANOVA), and a designed-experiment template to confirm the humidity driver before changing the process.

Built With

Share this project:

Updates

Submission history