mfgqc 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. mfgqc-0.1.0/LICENSE +21 -0
  2. mfgqc-0.1.0/PKG-INFO +213 -0
  3. mfgqc-0.1.0/README.md +174 -0
  4. mfgqc-0.1.0/mfgqc/__init__.py +227 -0
  5. mfgqc-0.1.0/mfgqc/_result.py +318 -0
  6. mfgqc-0.1.0/mfgqc/assumptions.py +249 -0
  7. mfgqc-0.1.0/mfgqc/attribute_agreement.py +287 -0
  8. mfgqc-0.1.0/mfgqc/capability.py +409 -0
  9. mfgqc-0.1.0/mfgqc/constants.py +114 -0
  10. mfgqc-0.1.0/mfgqc/control_charts.py +512 -0
  11. mfgqc-0.1.0/mfgqc/data.py +752 -0
  12. mfgqc-0.1.0/mfgqc/diagnostics.py +427 -0
  13. mfgqc-0.1.0/mfgqc/doe/__init__.py +31 -0
  14. mfgqc-0.1.0/mfgqc/doe/alias.py +123 -0
  15. mfgqc-0.1.0/mfgqc/doe/analysis.py +696 -0
  16. mfgqc-0.1.0/mfgqc/doe/design.py +292 -0
  17. mfgqc-0.1.0/mfgqc/doe/generate.py +71 -0
  18. mfgqc-0.1.0/mfgqc/doe/significance.py +81 -0
  19. mfgqc-0.1.0/mfgqc/doe/views.py +286 -0
  20. mfgqc-0.1.0/mfgqc/errors.py +40 -0
  21. mfgqc-0.1.0/mfgqc/gage_rr.py +475 -0
  22. mfgqc-0.1.0/mfgqc/hypothesis.py +584 -0
  23. mfgqc-0.1.0/mfgqc/ingestion.py +746 -0
  24. mfgqc-0.1.0/mfgqc/msa.py +360 -0
  25. mfgqc-0.1.0/mfgqc/multivari.py +150 -0
  26. mfgqc-0.1.0/mfgqc/nonparametric.py +159 -0
  27. mfgqc-0.1.0/mfgqc/palette.py +133 -0
  28. mfgqc-0.1.0/mfgqc/pareto_analysis.py +363 -0
  29. mfgqc-0.1.0/mfgqc/plotting.py +163 -0
  30. mfgqc-0.1.0/mfgqc/posthoc.py +259 -0
  31. mfgqc-0.1.0/mfgqc/power/__init__.py +19 -0
  32. mfgqc-0.1.0/mfgqc/power/solve.py +365 -0
  33. mfgqc-0.1.0/mfgqc/precontrol.py +170 -0
  34. mfgqc-0.1.0/mfgqc/process_sigma.py +227 -0
  35. mfgqc-0.1.0/mfgqc/registry.py +185 -0
  36. mfgqc-0.1.0/mfgqc/regression.py +871 -0
  37. mfgqc-0.1.0/mfgqc/regression_ext.py +366 -0
  38. mfgqc-0.1.0/mfgqc/reliability/__init__.py +40 -0
  39. mfgqc-0.1.0/mfgqc/reliability/availability.py +87 -0
  40. mfgqc-0.1.0/mfgqc/reliability/demonstrate.py +200 -0
  41. mfgqc-0.1.0/mfgqc/reliability/life.py +364 -0
  42. mfgqc-0.1.0/mfgqc/reliability/nonparametric.py +123 -0
  43. mfgqc-0.1.0/mfgqc/reliability/system.py +219 -0
  44. mfgqc-0.1.0/mfgqc/reliability/views.py +87 -0
  45. mfgqc-0.1.0/mfgqc/sampling.py +984 -0
  46. mfgqc-0.1.0/mfgqc/timeseries.py +639 -0
  47. mfgqc-0.1.0/mfgqc/timeseries_charts.py +391 -0
  48. mfgqc-0.1.0/mfgqc.egg-info/PKG-INFO +213 -0
  49. mfgqc-0.1.0/mfgqc.egg-info/SOURCES.txt +95 -0
  50. mfgqc-0.1.0/mfgqc.egg-info/dependency_links.txt +1 -0
  51. mfgqc-0.1.0/mfgqc.egg-info/requires.txt +14 -0
  52. mfgqc-0.1.0/mfgqc.egg-info/top_level.txt +1 -0
  53. mfgqc-0.1.0/pyproject.toml +59 -0
  54. mfgqc-0.1.0/setup.cfg +4 -0
  55. mfgqc-0.1.0/tests/test_api.py +148 -0
  56. mfgqc-0.1.0/tests/test_assumption_flags.py +90 -0
  57. mfgqc-0.1.0/tests/test_attribute_agreement.py +116 -0
  58. mfgqc-0.1.0/tests/test_attribute_charts.py +61 -0
  59. mfgqc-0.1.0/tests/test_availability.py +27 -0
  60. mfgqc-0.1.0/tests/test_capability.py +59 -0
  61. mfgqc-0.1.0/tests/test_capability_ci.py +45 -0
  62. mfgqc-0.1.0/tests/test_capability_nonnormal.py +148 -0
  63. mfgqc-0.1.0/tests/test_clean_conservative.py +109 -0
  64. mfgqc-0.1.0/tests/test_control_charts.py +37 -0
  65. mfgqc-0.1.0/tests/test_cusum_ewma.py +171 -0
  66. mfgqc-0.1.0/tests/test_demonstration.py +46 -0
  67. mfgqc-0.1.0/tests/test_diagnostics.py +208 -0
  68. mfgqc-0.1.0/tests/test_frontend_readiness.py +240 -0
  69. mfgqc-0.1.0/tests/test_gage_ci.py +44 -0
  70. mfgqc-0.1.0/tests/test_gage_rr.py +80 -0
  71. mfgqc-0.1.0/tests/test_hypothesis.py +164 -0
  72. mfgqc-0.1.0/tests/test_idiom_consistency.py +70 -0
  73. mfgqc-0.1.0/tests/test_ingestion.py +111 -0
  74. mfgqc-0.1.0/tests/test_kaplan_meier.py +50 -0
  75. mfgqc-0.1.0/tests/test_life_fit.py +120 -0
  76. mfgqc-0.1.0/tests/test_more_charts.py +107 -0
  77. mfgqc-0.1.0/tests/test_msa.py +160 -0
  78. mfgqc-0.1.0/tests/test_mtbf_bounds.py +38 -0
  79. mfgqc-0.1.0/tests/test_palette.py +53 -0
  80. mfgqc-0.1.0/tests/test_pareto_contingency.py +142 -0
  81. mfgqc-0.1.0/tests/test_plotting.py +42 -0
  82. mfgqc-0.1.0/tests/test_posthoc.py +135 -0
  83. mfgqc-0.1.0/tests/test_power.py +107 -0
  84. mfgqc-0.1.0/tests/test_process_sigma.py +84 -0
  85. mfgqc-0.1.0/tests/test_provenance.py +145 -0
  86. mfgqc-0.1.0/tests/test_published_oracles_six.py +138 -0
  87. mfgqc-0.1.0/tests/test_qcdata.py +76 -0
  88. mfgqc-0.1.0/tests/test_regression_anova.py +324 -0
  89. mfgqc-0.1.0/tests/test_regression_ext.py +120 -0
  90. mfgqc-0.1.0/tests/test_reliability_oracle.py +134 -0
  91. mfgqc-0.1.0/tests/test_reporting.py +28 -0
  92. mfgqc-0.1.0/tests/test_sampling.py +273 -0
  93. mfgqc-0.1.0/tests/test_spc_additions.py +111 -0
  94. mfgqc-0.1.0/tests/test_system.py +39 -0
  95. mfgqc-0.1.0/tests/test_timeseries.py +194 -0
  96. mfgqc-0.1.0/tests/test_timeseries_multivari.py +109 -0
  97. mfgqc-0.1.0/tests/test_z19.py +98 -0
mfgqc-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brantner Solutions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
mfgqc-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: mfgqc
3
+ Version: 0.1.0
4
+ Summary: Auditable SPC, capability, and gage R&R for manufacturing: statistical guardrails, hash-chained provenance, canonical QC charts.
5
+ Author: Brantner Solutions
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://mfgqc.brantnersolutions.com
8
+ Project-URL: Documentation, https://mfgqc.brantnersolutions.com
9
+ Project-URL: Repository, https://github.com/cjbrant/mfgQC
10
+ Project-URL: Issues, https://github.com/cjbrant/mfgQC/issues
11
+ Keywords: spc,statistical-process-control,capability,cpk,gage-rr,msa,six-sigma,manufacturing,control-charts,doe,design-of-experiments,reliability,acceptance-sampling,quality-control
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Manufacturing
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: numpy>=1.23
27
+ Requires-Dist: pandas>=1.5
28
+ Requires-Dist: scipy>=1.9
29
+ Requires-Dist: matplotlib>=3.6
30
+ Requires-Dist: statsmodels>=0.13
31
+ Requires-Dist: scikit-learn>=1.1
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest>=7; extra == "test"
34
+ Provides-Extra: docs
35
+ Requires-Dist: mkdocs-material>=9.5; extra == "docs"
36
+ Requires-Dist: mkdocstrings[python]>=0.25; extra == "docs"
37
+ Requires-Dist: mkdocs-material[imaging]>=9.5; extra == "docs"
38
+ Dynamic: license-file
39
+
40
+ # mfgQC
41
+
42
+ [![PyPI version](https://img.shields.io/pypi/v/mfgqc.svg)](https://pypi.org/project/mfgqc/)
43
+ [![Python versions](https://img.shields.io/pypi/pyversions/mfgqc.svg)](https://pypi.org/project/mfgqc/)
44
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
45
+ [![tests](https://github.com/cjbrant/mfgQC/actions/workflows/tests.yml/badge.svg)](https://github.com/cjbrant/mfgQC/actions/workflows/tests.yml)
46
+ [![docs](https://img.shields.io/badge/docs-mfgqc.brantnersolutions.com-0a7d5a.svg)](https://mfgqc.brantnersolutions.com)
47
+
48
+ **Auditable SPC, capability, and gage R&R for manufacturing** — by
49
+ [Brantner Solutions](https://brantnersolutions.com).
50
+ Full documentation: **[mfgqc.brantnersolutions.com](https://mfgqc.brantnersolutions.com)**.
51
+
52
+ Quality-control analysis for manufacturing practitioners, not statisticians or
53
+ programmers. Three pillars:
54
+
55
+ 1. **Statistical guardrails.** Every analysis checks its own assumptions and
56
+ reports the outcome. It warns and recommends; it never silently switches
57
+ methods. Auto-correction is opt-in.
58
+ 2. **Practitioner-oriented.** You bring domain knowledge; mfgQC brings the
59
+ statistics, data handling, and canonical charts. Errors say what's missing
60
+ and why.
61
+ 3. **Auditable by construction.** `QCData` and result objects are immutable and
62
+ carry a structured, propagating provenance history, so the full lineage from
63
+ raw data to final number can be reconstructed.
64
+
65
+ ## Install
66
+
67
+ ```bash
68
+ pip install mfgqc
69
+ ```
70
+
71
+ For development (editable install with test extras):
72
+
73
+ ```bash
74
+ pip install -e ".[test]"
75
+ ```
76
+
77
+ Requires Python 3.10+. Core dependencies are NumPy, pandas, SciPy, Matplotlib,
78
+ statsmodels, and scikit-learn.
79
+
80
+ ## Use
81
+
82
+ The idiom is always the same: `load` a frame, attach metadata with `.spec()` /
83
+ `.roles()`, then call an analysis. Every result has `.report()` (text),
84
+ `.summary()` (a flat dict), `.to_dict()` (full structured payload), and `.view()`
85
+ (the canonical chart).
86
+
87
+ ```python
88
+ import pandas as pd, mfgqc
89
+
90
+ qc = (mfgqc.load(df, measure="width", subgroup="lot", subgroup_size=5)
91
+ .spec(lower=1.0, upper=2.0, target=1.5))
92
+
93
+ print(qc.capability()) # Cp/Cpk (within-sigma) + Pp/Ppk (overall) + assumption report
94
+ print(qc.control_chart()) # inferred chart, run-rules violations
95
+ print(qc.gage_rr()) # ANOVA gage R&R (needs part/operator/replicate roles)
96
+
97
+ fig = qc.capability().view(save="capability.png") # canonical chart (matplotlib Figure)
98
+ ```
99
+
100
+ To load a CSV, read it with pandas first: `mfgqc.load(pd.read_csv(path), measure=...)`.
101
+
102
+ ## Provenance & auditability
103
+
104
+ This is mfgQC's reason to exist over `qcc` or Minitab: the lineage from raw data to
105
+ final number is recorded, immutable, and verifiable — not asserted in a doc.
106
+
107
+ **What is recorded.** Every step that derives a number appends a structured
108
+ provenance entry: ingest, spec/role binding, each transform (e.g. Box-Cox),
109
+ subgroup aggregation, the sigma method chosen, and each assumption check. The
110
+ chain is reconstructable end to end:
111
+
112
+ ```python
113
+ qc = mfgqc.load(df, measure="y").spec(lower=0.1, upper=8)
114
+ cap = qc.transform("boxcox").capability()
115
+
116
+ [s["operation"] for s in cap.lineage()]
117
+ # ['load', 'spec', 'transform', 'capability', 'assumption:normality']
118
+ ```
119
+
120
+ **Immutability guarantee (append-only by construction).** `QCData` and every
121
+ result are frozen dataclasses; the history is an immutable tuple of frozen steps,
122
+ so it cannot be reordered, inserted into, or edited in place. The ingest boundary
123
+ defensive-copies the input frame, `.frame` hands back a copy, and `.values()` is
124
+ read-only — so nothing a caller does to what mfgQC returns can reach back and
125
+ change a recorded result.
126
+
127
+ **Tamper-evidence (hash-chained and verifiable).** Each step folds into a
128
+ running SHA-256, exposed as `provenance_digest()` and stamped into `to_dict()`.
129
+ Capture the digest when you record a number, and re-check it later:
130
+
131
+ ```python
132
+ digest = cap.provenance_digest() # store alongside the reported Cpk
133
+ cap.verify_provenance(digest) # True; flips to False if any step was edited
134
+ ```
135
+
136
+ **The limit, stated honestly.** The digest is a content hash, not a cryptographic
137
+ signature: code running in the same process could edit a step *and* recompute the
138
+ digest. It defends against accidental corruption and post-hoc edits to a stored
139
+ result, not against an adversary who controls the interpreter. One boundary is
140
+ explicit: once you extract the matplotlib `Figure` from `.view()`, edits to that
141
+ Figure are outside the lineage.
142
+
143
+ ## Modules
144
+
145
+ - **Capability** — Cp/Cpk (within-subgroup sigma) vs Pp/Ppk (overall sigma), Cpm,
146
+ each with confidence intervals (small-n point estimates are overconfident; the
147
+ interval is reported so you see it); normal plus Box-Cox / Clements / Johnson
148
+ non-normal methods.
149
+ - **Control charts** — I-MR, Xbar-R, Xbar-S, p/np/c/u, EWMA, CUSUM, short-run;
150
+ Nelson and Western Electric run rules.
151
+ - **Measurement systems analysis** — ANOVA gage R&R, bias, linearity, stability,
152
+ attribute agreement (Cohen/Fleiss/weighted kappa).
153
+ - **Hypothesis testing** — assumption-routing two-sample / one-sample / variance /
154
+ proportion tests, one-way ANOVA, post-hoc (Tukey/Games-Howell/Dunn/Dunnett),
155
+ non-parametrics (Mood's median, repeated measures).
156
+ - **Regression & DOE** — OLS, model selection, logistic, non-linear least squares,
157
+ Box-Cox; full and fractional factorial design generation and effect analysis
158
+ (Lenth for unreplicated designs) with alias structure.
159
+ - **Sample size & power** — t-test, ANOVA, proportion, and variance, via the
160
+ noncentral distributions.
161
+ - **Attributes & reliability** — DPMO/sigma level, life-distribution fitting with
162
+ censoring, Kaplan-Meier, system reliability, bearing life (ISO 281), MTBF,
163
+ availability, demonstration tests.
164
+ - **Acceptance sampling** — single attribute plans, OC curves, ANSI/ASQ Z1.4 and
165
+ Z1.9.
166
+
167
+ ## Method choices
168
+
169
+ The choices a practitioner needs to trust the number are explicit, not hidden:
170
+
171
+ - **Control-chart inference.** `control_chart()` with no `kind=` picks the
172
+ variables chart from the subgroup size: size 1 → I-MR (individuals + moving
173
+ range), size 2–10 → X̄-R, size > 10 → X̄-S. Pass `kind=` to override; attribute
174
+ charts (`p`/`np`/`c`/`u`) are always explicit.
175
+ - **Within-subgroup sigma (Cp/Cpk).** Equal subgroups use R̄/d₂; individuals use
176
+ MR̄/d₂; unequal subgroup sizes use the pooled within-subgroup standard
177
+ deviation. Pp/Ppk always use the overall standard deviation. The estimator
178
+ actually used is reported in the capability result (`sigma_used`, e.g.
179
+ `"within (R-bar/d2)"`).
180
+
181
+ ## Building on mfgQC
182
+
183
+ mfgQC is built to be driven programmatically (e.g. by a report builder or UI):
184
+
185
+ - `mfgqc.list_analyses()` / `mfgqc.ANALYSES` — machine-readable catalog of every
186
+ analysis and its required inputs.
187
+ - `result.to_dict()` — full JSON-serializable payload (fields, assumption checks,
188
+ provenance); `result.summary()` is the flat form.
189
+ - `result.view(save="chart.png")` — headless chart rendering to PNG/SVG.
190
+ - `mfgqc.MissingPrerequisiteError` — specific, catchable error naming what an
191
+ analysis still needs.
192
+
193
+ ## Documentation
194
+
195
+ Full user guide and reference (with the formula, assumptions, and source standard
196
+ each method is pinned to) live at
197
+ **[mfgqc.brantnersolutions.com](https://mfgqc.brantnersolutions.com)**.
198
+
199
+ ## Tests
200
+
201
+ The suite has two layers. Regression tests pin mfgQC to its build oracles
202
+ (Montgomery; AIAG MSA 4th ed.; Lawson, *Design and Analysis of Experiments with
203
+ R*). A separate `tests/correctness/` suite pins each analysis to an **independent**
204
+ source it was not built against (the NIST/SEMATECH e-Handbook and StRD certified
205
+ datasets, the R `qcc`/`SixSigma` packages, and scipy/statsmodels computed in-test).
206
+
207
+ ```bash
208
+ pytest
209
+ ```
210
+
211
+ ---
212
+
213
+ © Brantner Solutions · [brantnersolutions.com](https://brantnersolutions.com) · MIT License
mfgqc-0.1.0/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # mfgQC
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/mfgqc.svg)](https://pypi.org/project/mfgqc/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/mfgqc.svg)](https://pypi.org/project/mfgqc/)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+ [![tests](https://github.com/cjbrant/mfgQC/actions/workflows/tests.yml/badge.svg)](https://github.com/cjbrant/mfgQC/actions/workflows/tests.yml)
7
+ [![docs](https://img.shields.io/badge/docs-mfgqc.brantnersolutions.com-0a7d5a.svg)](https://mfgqc.brantnersolutions.com)
8
+
9
+ **Auditable SPC, capability, and gage R&R for manufacturing** — by
10
+ [Brantner Solutions](https://brantnersolutions.com).
11
+ Full documentation: **[mfgqc.brantnersolutions.com](https://mfgqc.brantnersolutions.com)**.
12
+
13
+ Quality-control analysis for manufacturing practitioners, not statisticians or
14
+ programmers. Three pillars:
15
+
16
+ 1. **Statistical guardrails.** Every analysis checks its own assumptions and
17
+ reports the outcome. It warns and recommends; it never silently switches
18
+ methods. Auto-correction is opt-in.
19
+ 2. **Practitioner-oriented.** You bring domain knowledge; mfgQC brings the
20
+ statistics, data handling, and canonical charts. Errors say what's missing
21
+ and why.
22
+ 3. **Auditable by construction.** `QCData` and result objects are immutable and
23
+ carry a structured, propagating provenance history, so the full lineage from
24
+ raw data to final number can be reconstructed.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install mfgqc
30
+ ```
31
+
32
+ For development (editable install with test extras):
33
+
34
+ ```bash
35
+ pip install -e ".[test]"
36
+ ```
37
+
38
+ Requires Python 3.10+. Core dependencies are NumPy, pandas, SciPy, Matplotlib,
39
+ statsmodels, and scikit-learn.
40
+
41
+ ## Use
42
+
43
+ The idiom is always the same: `load` a frame, attach metadata with `.spec()` /
44
+ `.roles()`, then call an analysis. Every result has `.report()` (text),
45
+ `.summary()` (a flat dict), `.to_dict()` (full structured payload), and `.view()`
46
+ (the canonical chart).
47
+
48
+ ```python
49
+ import pandas as pd, mfgqc
50
+
51
+ qc = (mfgqc.load(df, measure="width", subgroup="lot", subgroup_size=5)
52
+ .spec(lower=1.0, upper=2.0, target=1.5))
53
+
54
+ print(qc.capability()) # Cp/Cpk (within-sigma) + Pp/Ppk (overall) + assumption report
55
+ print(qc.control_chart()) # inferred chart, run-rules violations
56
+ print(qc.gage_rr()) # ANOVA gage R&R (needs part/operator/replicate roles)
57
+
58
+ fig = qc.capability().view(save="capability.png") # canonical chart (matplotlib Figure)
59
+ ```
60
+
61
+ To load a CSV, read it with pandas first: `mfgqc.load(pd.read_csv(path), measure=...)`.
62
+
63
+ ## Provenance & auditability
64
+
65
+ This is mfgQC's reason to exist over `qcc` or Minitab: the lineage from raw data to
66
+ final number is recorded, immutable, and verifiable — not asserted in a doc.
67
+
68
+ **What is recorded.** Every step that derives a number appends a structured
69
+ provenance entry: ingest, spec/role binding, each transform (e.g. Box-Cox),
70
+ subgroup aggregation, the sigma method chosen, and each assumption check. The
71
+ chain is reconstructable end to end:
72
+
73
+ ```python
74
+ qc = mfgqc.load(df, measure="y").spec(lower=0.1, upper=8)
75
+ cap = qc.transform("boxcox").capability()
76
+
77
+ [s["operation"] for s in cap.lineage()]
78
+ # ['load', 'spec', 'transform', 'capability', 'assumption:normality']
79
+ ```
80
+
81
+ **Immutability guarantee (append-only by construction).** `QCData` and every
82
+ result are frozen dataclasses; the history is an immutable tuple of frozen steps,
83
+ so it cannot be reordered, inserted into, or edited in place. The ingest boundary
84
+ defensive-copies the input frame, `.frame` hands back a copy, and `.values()` is
85
+ read-only — so nothing a caller does to what mfgQC returns can reach back and
86
+ change a recorded result.
87
+
88
+ **Tamper-evidence (hash-chained and verifiable).** Each step folds into a
89
+ running SHA-256, exposed as `provenance_digest()` and stamped into `to_dict()`.
90
+ Capture the digest when you record a number, and re-check it later:
91
+
92
+ ```python
93
+ digest = cap.provenance_digest() # store alongside the reported Cpk
94
+ cap.verify_provenance(digest) # True; flips to False if any step was edited
95
+ ```
96
+
97
+ **The limit, stated honestly.** The digest is a content hash, not a cryptographic
98
+ signature: code running in the same process could edit a step *and* recompute the
99
+ digest. It defends against accidental corruption and post-hoc edits to a stored
100
+ result, not against an adversary who controls the interpreter. One boundary is
101
+ explicit: once you extract the matplotlib `Figure` from `.view()`, edits to that
102
+ Figure are outside the lineage.
103
+
104
+ ## Modules
105
+
106
+ - **Capability** — Cp/Cpk (within-subgroup sigma) vs Pp/Ppk (overall sigma), Cpm,
107
+ each with confidence intervals (small-n point estimates are overconfident; the
108
+ interval is reported so you see it); normal plus Box-Cox / Clements / Johnson
109
+ non-normal methods.
110
+ - **Control charts** — I-MR, Xbar-R, Xbar-S, p/np/c/u, EWMA, CUSUM, short-run;
111
+ Nelson and Western Electric run rules.
112
+ - **Measurement systems analysis** — ANOVA gage R&R, bias, linearity, stability,
113
+ attribute agreement (Cohen/Fleiss/weighted kappa).
114
+ - **Hypothesis testing** — assumption-routing two-sample / one-sample / variance /
115
+ proportion tests, one-way ANOVA, post-hoc (Tukey/Games-Howell/Dunn/Dunnett),
116
+ non-parametrics (Mood's median, repeated measures).
117
+ - **Regression & DOE** — OLS, model selection, logistic, non-linear least squares,
118
+ Box-Cox; full and fractional factorial design generation and effect analysis
119
+ (Lenth for unreplicated designs) with alias structure.
120
+ - **Sample size & power** — t-test, ANOVA, proportion, and variance, via the
121
+ noncentral distributions.
122
+ - **Attributes & reliability** — DPMO/sigma level, life-distribution fitting with
123
+ censoring, Kaplan-Meier, system reliability, bearing life (ISO 281), MTBF,
124
+ availability, demonstration tests.
125
+ - **Acceptance sampling** — single attribute plans, OC curves, ANSI/ASQ Z1.4 and
126
+ Z1.9.
127
+
128
+ ## Method choices
129
+
130
+ The choices a practitioner needs to trust the number are explicit, not hidden:
131
+
132
+ - **Control-chart inference.** `control_chart()` with no `kind=` picks the
133
+ variables chart from the subgroup size: size 1 → I-MR (individuals + moving
134
+ range), size 2–10 → X̄-R, size > 10 → X̄-S. Pass `kind=` to override; attribute
135
+ charts (`p`/`np`/`c`/`u`) are always explicit.
136
+ - **Within-subgroup sigma (Cp/Cpk).** Equal subgroups use R̄/d₂; individuals use
137
+ MR̄/d₂; unequal subgroup sizes use the pooled within-subgroup standard
138
+ deviation. Pp/Ppk always use the overall standard deviation. The estimator
139
+ actually used is reported in the capability result (`sigma_used`, e.g.
140
+ `"within (R-bar/d2)"`).
141
+
142
+ ## Building on mfgQC
143
+
144
+ mfgQC is built to be driven programmatically (e.g. by a report builder or UI):
145
+
146
+ - `mfgqc.list_analyses()` / `mfgqc.ANALYSES` — machine-readable catalog of every
147
+ analysis and its required inputs.
148
+ - `result.to_dict()` — full JSON-serializable payload (fields, assumption checks,
149
+ provenance); `result.summary()` is the flat form.
150
+ - `result.view(save="chart.png")` — headless chart rendering to PNG/SVG.
151
+ - `mfgqc.MissingPrerequisiteError` — specific, catchable error naming what an
152
+ analysis still needs.
153
+
154
+ ## Documentation
155
+
156
+ Full user guide and reference (with the formula, assumptions, and source standard
157
+ each method is pinned to) live at
158
+ **[mfgqc.brantnersolutions.com](https://mfgqc.brantnersolutions.com)**.
159
+
160
+ ## Tests
161
+
162
+ The suite has two layers. Regression tests pin mfgQC to its build oracles
163
+ (Montgomery; AIAG MSA 4th ed.; Lawson, *Design and Analysis of Experiments with
164
+ R*). A separate `tests/correctness/` suite pins each analysis to an **independent**
165
+ source it was not built against (the NIST/SEMATECH e-Handbook and StRD certified
166
+ datasets, the R `qcc`/`SixSigma` packages, and scipy/statsmodels computed in-test).
167
+
168
+ ```bash
169
+ pytest
170
+ ```
171
+
172
+ ---
173
+
174
+ © Brantner Solutions · [brantnersolutions.com](https://brantnersolutions.com) · MIT License
@@ -0,0 +1,227 @@
1
+ """mfgQC - quality-control analysis for manufacturing practitioners.
2
+
3
+ Three design pillars: statistical guardrails (every analysis checks and reports
4
+ its own assumptions, never silently switching methods), practitioner-oriented
5
+ (legible errors, no statistics/programming background assumed), and auditable by
6
+ construction (immutable data and results carrying a structured, propagating
7
+ provenance history).
8
+
9
+ Quick start (fluent idiom: verb -> object -> methods)
10
+ -----------------------------------------------------
11
+ >>> import pandas as pd, mfgqc
12
+ >>> clean_df = mfgqc.clean(raw, [mfgqc.fix_names(), mfgqc.coerce_numeric(["width"])])
13
+ >>> data = mfgqc.load(clean_df, measure="width", subgroup="batch").spec(lower=1.0, upper=2.0)
14
+ >>> mfgqc.overview(data) # role/spec-aware diagnostic
15
+ >>> cap = data.capability() # uses the attached spec
16
+ >>> cc = data.control_chart()
17
+ >>> grr = data.gage_rr()
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from .assumptions import AssumptionCheck
23
+ from .capability import CapabilityResult
24
+ from .control_charts import ControlChartResult, Violation
25
+ from .data import (
26
+ Crossed,
27
+ QCData,
28
+ QCMeta,
29
+ Step,
30
+ Subgroups,
31
+ from_wide,
32
+ load,
33
+ )
34
+ from .gage_rr import GageRRResult
35
+ from .hypothesis import (
36
+ HypothesisResult,
37
+ test_anova,
38
+ test_mean,
39
+ test_means,
40
+ test_paired,
41
+ test_proportion,
42
+ test_proportions,
43
+ test_variance,
44
+ )
45
+ from .ingestion import (
46
+ Overview,
47
+ clean,
48
+ clean_report,
49
+ coerce_numeric,
50
+ drop,
51
+ drop_constant,
52
+ drop_duplicates,
53
+ fix_names,
54
+ normalize_case,
55
+ overview,
56
+ parse_dates,
57
+ recode_empty,
58
+ recode_missing,
59
+ rename,
60
+ select,
61
+ standard_tidy,
62
+ )
63
+ from .msa import BiasResult, LinearityResult, StabilityResult
64
+ from .palette import set_theme
65
+ from .pareto_analysis import ContingencyResult, ParetoResult, contingency, pareto, test_independence
66
+ from .regression import (
67
+ AnovaResult,
68
+ CorrelationResult,
69
+ RegressionResult,
70
+ correlation,
71
+ )
72
+ from .sampling import (
73
+ AOQResult,
74
+ LotDisposition,
75
+ OCCurveResult,
76
+ SamplingPlan,
77
+ Z19Disposition,
78
+ Z19Plan,
79
+ find_plan,
80
+ sampling_plan,
81
+ z14_plan,
82
+ z19_plan,
83
+ )
84
+ from .timeseries_charts import CUSUMResult, EWMAResult
85
+ from . import doe as design
86
+ from .doe import DOEResult, Design, LenthResult
87
+ from . import power
88
+ from .power import PowerResult
89
+ from .process_sigma import ProcessSigmaResult, compute as process_sigma
90
+ from .attribute_agreement import AttributeAgreementResult
91
+ from .posthoc import PosthocResult
92
+ from .nonparametric import test_medians, test_repeated
93
+ from .precontrol import PrecontrolResult
94
+ from .regression_ext import LogisticResult, NonlinearResult
95
+ from .timeseries import TimeSeriesResult
96
+ from .multivari import MultivariResult
97
+ from . import reliability
98
+ from .reliability.availability import availability
99
+ from .reliability import (
100
+ LifeFitResult,
101
+ KaplanMeierResult,
102
+ SystemReliabilityResult,
103
+ BearingLifeResult,
104
+ AvailabilityResult,
105
+ MTBFResult,
106
+ DemonstrationResult,
107
+ )
108
+ from .errors import MissingPrerequisiteError, PyQCError
109
+ from .registry import ANALYSES, ANALYSES_BY_NAME, Analysis, list_analyses
110
+
111
+ __version__ = "0.1.0"
112
+
113
+ __all__ = [
114
+ # fluent entry points
115
+ "load",
116
+ "from_wide",
117
+ "overview",
118
+ "clean",
119
+ "clean_report",
120
+ # data model
121
+ "QCData",
122
+ "QCMeta",
123
+ "Step",
124
+ "Subgroups",
125
+ "Crossed",
126
+ "Overview",
127
+ "AssumptionCheck",
128
+ # cleaning tasks
129
+ "fix_names",
130
+ "coerce_numeric",
131
+ "parse_dates",
132
+ "recode_missing",
133
+ "recode_empty",
134
+ "drop_constant",
135
+ "drop_duplicates",
136
+ "select",
137
+ "drop",
138
+ "rename",
139
+ "normalize_case",
140
+ "standard_tidy",
141
+ # results
142
+ "CapabilityResult",
143
+ "ControlChartResult",
144
+ "Violation",
145
+ "GageRRResult",
146
+ "HypothesisResult",
147
+ "BiasResult",
148
+ "LinearityResult",
149
+ "StabilityResult",
150
+ "RegressionResult",
151
+ "AnovaResult",
152
+ "CorrelationResult",
153
+ "ParetoResult",
154
+ "ContingencyResult",
155
+ "EWMAResult",
156
+ "CUSUMResult",
157
+ # hypothesis tests
158
+ "test_mean",
159
+ "test_means",
160
+ "test_paired",
161
+ "test_anova",
162
+ "test_variance",
163
+ "test_proportion",
164
+ "test_proportions",
165
+ # regression / ANOVA / correlation
166
+ "correlation",
167
+ # Pareto + contingency
168
+ "pareto",
169
+ "contingency",
170
+ "test_independence",
171
+ # acceptance sampling
172
+ "sampling_plan",
173
+ "find_plan",
174
+ "set_theme",
175
+ "z14_plan",
176
+ "z19_plan",
177
+ "SamplingPlan",
178
+ "OCCurveResult",
179
+ "AOQResult",
180
+ "LotDisposition",
181
+ "Z19Plan",
182
+ "Z19Disposition",
183
+ # design of experiments
184
+ "design",
185
+ "DOEResult",
186
+ "Design",
187
+ "LenthResult",
188
+ # sample size & power
189
+ "power",
190
+ "PowerResult",
191
+ # attributes capability
192
+ "process_sigma",
193
+ "ProcessSigmaResult",
194
+ # attribute agreement (kappa)
195
+ "AttributeAgreementResult",
196
+ # multiple comparisons & nonparametrics
197
+ "PosthocResult",
198
+ "test_medians",
199
+ "test_repeated",
200
+ # SPC additions
201
+ "PrecontrolResult",
202
+ # regression additions
203
+ "LogisticResult",
204
+ "NonlinearResult",
205
+ # time-series & multi-vari
206
+ "TimeSeriesResult",
207
+ "MultivariResult",
208
+ # reliability & maintainability
209
+ "reliability",
210
+ "availability",
211
+ "LifeFitResult",
212
+ "KaplanMeierResult",
213
+ "SystemReliabilityResult",
214
+ "BearingLifeResult",
215
+ "AvailabilityResult",
216
+ "MTBFResult",
217
+ "DemonstrationResult",
218
+ # errors
219
+ "PyQCError",
220
+ "MissingPrerequisiteError",
221
+ # analysis registry (for frontends)
222
+ "ANALYSES",
223
+ "ANALYSES_BY_NAME",
224
+ "Analysis",
225
+ "list_analyses",
226
+ "__version__",
227
+ ]