processbehavior 0.2.1__tar.gz → 0.3.1__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 (206) hide show
  1. {processbehavior-0.2.1 → processbehavior-0.3.1}/CHANGELOG.md +94 -1
  2. {processbehavior-0.2.1 → processbehavior-0.3.1}/PKG-INFO +2 -2
  3. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/__init__.py +1 -1
  4. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/analysis_dataset.py +1 -1
  5. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/data_preparation.py +33 -1
  6. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/datasets/synthetic.py +2 -2
  7. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/derivations.py +214 -83
  8. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/residual_calculator.py +9 -8
  9. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/sds_detector.py +24 -22
  10. processbehavior-0.3.1/processbehavior/series_length.py +105 -0
  11. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/spc_constants.py +44 -0
  12. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/study.py +42 -0
  13. {processbehavior-0.2.1 → processbehavior-0.3.1}/pyproject.toml +1 -1
  14. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_derivations.py +34 -0
  15. processbehavior-0.3.1/tests/test_derivations_robustness.py +315 -0
  16. processbehavior-0.3.1/tests/test_na_in_factor_columns.py +96 -0
  17. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_residual_calculator.py +8 -8
  18. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_sds_detector.py +34 -6
  19. processbehavior-0.3.1/tests/test_series_length.py +153 -0
  20. {processbehavior-0.2.1 → processbehavior-0.3.1}/.gitignore +0 -0
  21. {processbehavior-0.2.1 → processbehavior-0.3.1}/CITATION.cff +0 -0
  22. {processbehavior-0.2.1 → processbehavior-0.3.1}/CODE_OF_CONDUCT.md +0 -0
  23. {processbehavior-0.2.1 → processbehavior-0.3.1}/CONTRIBUTING.md +0 -0
  24. {processbehavior-0.2.1 → processbehavior-0.3.1}/LICENSE +0 -0
  25. {processbehavior-0.2.1 → processbehavior-0.3.1}/README.md +0 -0
  26. {processbehavior-0.2.1 → processbehavior-0.3.1}/SECURITY.md +0 -0
  27. {processbehavior-0.2.1 → processbehavior-0.3.1}/examples/README.md +0 -0
  28. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/analysis.py +0 -0
  29. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/analysis_result.py +0 -0
  30. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/calibration.py +0 -0
  31. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/capability.py +0 -0
  32. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/datasets/__init__.py +0 -0
  33. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/datasets/data/coffee_shop_demo_long.csv +0 -0
  34. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/datasets/loaders.py +0 -0
  35. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/effects_calculator.py +0 -0
  36. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/exceptions.py +0 -0
  37. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/exporters/__init__.py +0 -0
  38. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/exporters/excel_exporter.py +0 -0
  39. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/focused_result.py +0 -0
  40. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/formulation_spec.py +0 -0
  41. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/loss_function.py +0 -0
  42. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/maximum_information.py +0 -0
  43. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/__init__.py +0 -0
  44. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/_math.py +0 -0
  45. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/capability_chart.py +0 -0
  46. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/contracts.py +0 -0
  47. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/control_chart.py +0 -0
  48. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/effects_charts.py +0 -0
  49. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/lane_boundaries.py +0 -0
  50. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/limits.py +0 -0
  51. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/maximum_information_chart.py +0 -0
  52. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/plotter.py +0 -0
  53. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/renderers.py +0 -0
  54. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/report.py +0 -0
  55. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/residuals.py +0 -0
  56. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/run_rules_viz.py +0 -0
  57. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/stats_box.py +0 -0
  58. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/themes.py +0 -0
  59. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/x_axis_layout.py +0 -0
  60. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/plotting/zones.py +0 -0
  61. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/process_behavior.py +0 -0
  62. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/py.typed +0 -0
  63. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/result_signals.py +0 -0
  64. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/result_tabular.py +0 -0
  65. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/signals/__init__.py +0 -0
  66. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/signals/config.py +0 -0
  67. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/signals/detector.py +0 -0
  68. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/signals/detectors.py +0 -0
  69. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/signals/result.py +0 -0
  70. {processbehavior-0.2.1 → processbehavior-0.3.1}/processbehavior/types.py +0 -0
  71. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/__init__.py +0 -0
  72. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/conftest.py +0 -0
  73. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/bishop_analyses/vassds1analysis.json +0 -0
  74. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/bishop_analyses/vassds2analysis.json +0 -0
  75. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/bishop_analyses/vassds3analysis.json +0 -0
  76. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/coffee_capability_full_baseline.json +0 -0
  77. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/data/FILLWEIGHTDATA_800.csv +0 -0
  78. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/data/coffee_shop_demo_long.csv +0 -0
  79. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/missing_values/X_data.parquet +0 -0
  80. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/missing_values/X_metadata.json +0 -0
  81. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/missing_values/X_statistics.json +0 -0
  82. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/missing_values/mR_data.parquet +0 -0
  83. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/missing_values/mR_metadata.json +0 -0
  84. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/missing_values/mR_statistics.json +0 -0
  85. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xbar_s/S_data.parquet +0 -0
  86. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xbar_s/S_metadata.json +0 -0
  87. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xbar_s/S_statistics.json +0 -0
  88. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xbar_s/Xbar_data.parquet +0 -0
  89. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xbar_s/Xbar_metadata.json +0 -0
  90. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xbar_s/Xbar_statistics.json +0 -0
  91. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xmr_r/X_data.parquet +0 -0
  92. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xmr_r/X_metadata.json +0 -0
  93. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xmr_r/X_statistics.json +0 -0
  94. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xmr_r/mR_data.parquet +0 -0
  95. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xmr_r/mR_metadata.json +0 -0
  96. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/paired_xmr_r/mR_statistics.json +0 -0
  97. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/pathological_ordering/X_data.parquet +0 -0
  98. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/pathological_ordering/X_metadata.json +0 -0
  99. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/pathological_ordering/X_statistics.json +0 -0
  100. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/pathological_ordering/mR_data.parquet +0 -0
  101. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/pathological_ordering/mR_metadata.json +0 -0
  102. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/pathological_ordering/mR_statistics.json +0 -0
  103. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/residual_chart/S_data.parquet +0 -0
  104. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/residual_chart/S_metadata.json +0 -0
  105. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/residual_chart/S_statistics.json +0 -0
  106. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/single_obs_strata/X_data.parquet +0 -0
  107. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/single_obs_strata/X_metadata.json +0 -0
  108. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/single_obs_strata/X_statistics.json +0 -0
  109. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/single_obs_strata/mR_data.parquet +0 -0
  110. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/single_obs_strata/mR_metadata.json +0 -0
  111. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/single_obs_strata/mR_statistics.json +0 -0
  112. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_balanced/S_data.parquet +0 -0
  113. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_balanced/S_metadata.json +0 -0
  114. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_balanced/S_statistics.json +0 -0
  115. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_balanced/Xbar_data.parquet +0 -0
  116. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_balanced/Xbar_metadata.json +0 -0
  117. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_balanced/Xbar_statistics.json +0 -0
  118. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_uneven/S_data.parquet +0 -0
  119. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_uneven/S_metadata.json +0 -0
  120. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_uneven/S_statistics.json +0 -0
  121. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_uneven/Xbar_data.parquet +0 -0
  122. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_uneven/Xbar_metadata.json +0 -0
  123. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/stratified_uneven/Xbar_statistics.json +0 -0
  124. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/unstratified_small/X_data.parquet +0 -0
  125. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/unstratified_small/X_metadata.json +0 -0
  126. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/unstratified_small/X_statistics.json +0 -0
  127. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/unstratified_small/mR_data.parquet +0 -0
  128. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/unstratified_small/mR_metadata.json +0 -0
  129. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/fixtures/golden_masters/unstratified_small/mR_statistics.json +0 -0
  130. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_analysis_bugs.py +0 -0
  131. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_analysis_dataset.py +0 -0
  132. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_analysis_golden_master.py +0 -0
  133. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_analysis_result_contract.py +0 -0
  134. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_analysis_specifications.py +0 -0
  135. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_api_reference.py +0 -0
  136. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_beyond_limits_vectorized.py +0 -0
  137. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_bin_extremes.py +0 -0
  138. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_bishop_reference.py +0 -0
  139. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_by_parameter.py +0 -0
  140. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_by_permutations.py +0 -0
  141. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_calibration.py +0 -0
  142. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_capability.py +0 -0
  143. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_capability_chart.py +0 -0
  144. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_capability_window.py +0 -0
  145. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_chart_availability.py +0 -0
  146. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_chart_column_contract.py +0 -0
  147. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_chart_parsing.py +0 -0
  148. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_control_chart_figure.py +0 -0
  149. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_data_preparation.py +0 -0
  150. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_datasets.py +0 -0
  151. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_design_state_lineage.py +0 -0
  152. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_documented_rule_coverage.py +0 -0
  153. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_edge_cases.py +0 -0
  154. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_effects_calculator.py +0 -0
  155. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_effects_plotting.py +0 -0
  156. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_encode_rsg_vectorized.py +0 -0
  157. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_excel_export.py +0 -0
  158. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_execute_validation.py +0 -0
  159. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_focus.py +0 -0
  160. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_garbage_character_handling.py +0 -0
  161. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_init_cleaning.py +0 -0
  162. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_lane_boundaries.py +0 -0
  163. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_limits_vectorized.py +0 -0
  164. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_loss_function.py +0 -0
  165. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_maximum_information.py +0 -0
  166. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_notebook_ergonomics.py +0 -0
  167. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_p0_p2_regressions.py +0 -0
  168. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_performance.py +0 -0
  169. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_phased_limits.py +0 -0
  170. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_plotting.py +0 -0
  171. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_plotting_decorations.py +0 -0
  172. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_plotting_hardening.py +0 -0
  173. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_plotting_xaxis.py +0 -0
  174. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_process_behavior.py +0 -0
  175. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_recentered_mr_fix.py +0 -0
  176. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_reference_integrity.py +0 -0
  177. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_release_gate_0_1_0_checklist.py +0 -0
  178. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_residual_aliases.py +0 -0
  179. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_residual_labels.py +0 -0
  180. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_residual_scope.py +0 -0
  181. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_resolve_by_grouping.py +0 -0
  182. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_result_signals.py +0 -0
  183. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_result_tabular.py +0 -0
  184. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_sampling_plan.py +0 -0
  185. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_sds.py +0 -0
  186. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_signal_detectors.py +0 -0
  187. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_signal_result_surface.py +0 -0
  188. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_signals.py +0 -0
  189. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_single_detection.py +0 -0
  190. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_solo_mr_residuals.py +0 -0
  191. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_spc_constants.py +0 -0
  192. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_srp_refactor.py +0 -0
  193. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_strata_companion.py +0 -0
  194. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_strata_sufficiency.py +0 -0
  195. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_stratified_insufficiency.py +0 -0
  196. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_supports_calibration.py +0 -0
  197. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_synthetic.py +0 -0
  198. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_types.py +0 -0
  199. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_validate_by_parameter.py +0 -0
  200. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_weco_integration.py +0 -0
  201. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_why_not.py +0 -0
  202. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_x_axis_layout.py +0 -0
  203. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_xbar_residual_center.py +0 -0
  204. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_xbar_s_options.py +0 -0
  205. {processbehavior-0.2.1 → processbehavior-0.3.1}/tests/test_xbar_stratified.py +0 -0
  206. {processbehavior-0.2.1 → processbehavior-0.3.1}/validation/PBTESTDATABASE_T100.csv +0 -0
@@ -7,6 +7,97 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.1] - 2026-09-14
11
+
12
+ ### Fixed
13
+ - **Derived variables: ``evaluate`` and ``validate`` now keep their never-raises promise.**
14
+ An adversarial pass (36,000 fuzzed evaluations) found four ways to make them raise from
15
+ pandas: ±inf in the source column (``equal_freq`` / ``equal_width``: "bins must increase
16
+ monotonically"), range labels that collide at six significant digits on a tiny range or a
17
+ near-constant ``sd`` fit ("labels must be unique"), duplicate or null explicit
18
+ ``bin_labels``, and a string ``shift`` / ``exponent`` reaching numpy. Now: ±inf leaves the
19
+ bin fit, becomes NaN, and is counted in ``n_invalid`` with a message; range labels gain
20
+ precision until distinct (numbered bins as the last resort, with a message); explicit
21
+ labels must be non-empty, null-free and unique; ``shift``, ``exponent`` and ``breaks`` must
22
+ be finite numbers; ``on_invalid`` must be ``'error'`` or ``'na'``; ``n`` must be a positive
23
+ integer (numpy integers accepted, booleans rejected) — all at construction, as
24
+ ``ValidationError``. A datetime or categorical source now evaluates to an all-NA result
25
+ with a message instead of transforming nanoseconds or category codes. A permanent seeded
26
+ fuzz test guards the contract.
27
+
28
+ ### Changed
29
+ - **Every non-finite transform result is a domain violation.** ``log``/``sqrt`` of ``inf``,
30
+ ``square`` overflow and ``inverse`` of a denormal used to return ``inf`` with
31
+ ``n_invalid=0`` (only ``power`` overflow was flagged); all are now violations, so
32
+ ``on_invalid`` applies and an ``inf`` can no longer reach the limits. A z-score of a
33
+ constant (or single-value) column is now a violation for every value rather than a silent
34
+ all-NaN column, so ``on_invalid='error'`` names the derivation at ``formulate``.
35
+ ``arcsin`` on values in (1, 100] adds the hint "if these are percentages, divide by 100".
36
+ Requesting more equal-frequency / equal-width bins than there are distinct values now fits
37
+ one bin per distinct value and says so. ``'ordinal'`` labels above five bins say they fell
38
+ back to numbered bins. ``to_dict`` converts numpy scalars and arrays (it was documented
39
+ JSON-safe but was not); ``from_dict`` decodes the ``Infinity``/``NaN`` tags only under
40
+ numeric keys, so a bin labelled ``"NaN"`` stays a string; a missing ``id`` is a
41
+ ``ValidationError``, not a ``KeyError``. Finite inputs with distinct labels produce
42
+ byte-identical edges, labels and values.
43
+
44
+ ## [0.3.0] - 2026-09-14
45
+
46
+ ### Added
47
+ - **The design report states where sigma comes from at the observed structure and
48
+ series length.** One line under ``Structure``: ``Series length: T=4. Sigma for X/mR
49
+ rests on 3 moving ranges.`` With every cell replicated it reads ``Series length: T=1.
50
+ Sigma rests on within-cell replication.`` — a single time period is a complete study.
51
+ Exposed as ``study.series_length`` (``SeriesLengthPrecision``, frozen) and
52
+ ``study.series_length_description``. The result also carries ``within_cell_df`` and,
53
+ for the moving-range case, ``mr_interval_80`` — the p10/p90 of MRbar/d2 by n = 3..30
54
+ from ``MR_SIGMA_INTERVAL_80`` (``spc_constants``), generated by
55
+ ``validation/short_series_bands.py`` (contributed by @rabujamra in #114 / #119) — for
56
+ callers who want the numbers; the report prints only the sentence. It is a fact beside
57
+ the design state, not a judgment on it: no threshold, label, or warning, and the design
58
+ state, recommended chart and analysis menu do not move with T (pinned by test). Closes
59
+ the series-length half of #114.
60
+
61
+ ### Changed
62
+ - **The R2 method for partial replication is reported as ``ma2``, not ``hybrid``.** The
63
+ docs described a per-cell hybrid for design state 3 (exact deviation where a cell has
64
+ n ≥ 2, moving average where n = 1) and said it was validated by Monte Carlo. The code
65
+ has not done that since cb037f8 (2026-03-05): with any singleton cell, R2 is Bishop's
66
+ ungrouped 2-point moving average over the full canonical sequence (Eq 13.7–13.9) for
67
+ every observation, and the 89 ADS 3 reference assertions hold against that. Only the word
68
+ survived, in six docs pages (three of which described it three different ways), the
69
+ detector's method token, the analysis-plan limitation text, two docstrings and two test
70
+ names. All now say what the code does. ``R2Method`` is ``Literal['exact', 'ma2']``;
71
+ ``SDSRegistry.get_r2_method`` returns ``'ma2'`` where it returned ``'hybrid'``;
72
+ ``get_sds_characteristics`` and ``SDSAnalysisPlan.residual_calculation_method`` use the
73
+ same two spellings in place of ``'within_cell'``, ``'moving_average'`` and ``'hybrid'``.
74
+ No arithmetic changed; none of these names is exported from the package top level.
75
+
76
+ ### Dependencies
77
+ - ``plotly>=5.18,<8`` (was ``<7``). plotly 7.0.0 (2026-08-25) was tested against the full
78
+ suite before the bound moved: its breaking changes (mapbox traces, decimal-fraction
79
+ ``rgb()`` strings, ``hsv()``, Kaleido < 1.0, figure_factory) touch nothing here. #116.
80
+
81
+ ### Fixed
82
+ - **A missing value in a factor column no longer makes a two-factor study fail.** With one
83
+ factor, rows with a blank factor value were dropped silently; with two or more, the
84
+ composite subgroup label was built before that drop and ``formulate`` raised
85
+ ``ValidationError: Cannot build RSG ... missing values in factor columns``. The same
86
+ file formulated with either factor alone and failed with both (a 85,101-row survey
87
+ file with 7,980 blank ``SURVEY QUESTION`` rows). Rows with no value in any factor
88
+ column now leave the analysis before the label is built, for any number of factors,
89
+ and the library says so with a ``ProcessBehaviorWarning`` naming the count per
90
+ factor. Response and time missing values are handled as before.
91
+ - **``evaluate`` no longer raises on a constant column.** Binning a column with no spread
92
+ (every value identical) returned the documented no-spread result for ``equal_freq`` but
93
+ raised ``ValueError: Bin edges must be unique`` from ``pd.cut`` for ``equal_width`` and
94
+ ``sd``, because their fitted edges were identical yet finite and slipped past the guard.
95
+ The derivations module promises ``evaluate`` never raises on a routine state; a constant
96
+ column is one. All three methods now return the same no-spread result, whose ``fitted``
97
+ dict also carries ``n_bins: 0``, ``edges: []`` and ``labels: []`` so callers see one
98
+ shape. Explicit ``breaks`` on a constant column still bin. Found through the app on a
99
+ single-time-point file whose TIME column was a constant.
100
+
10
101
  ## [0.2.1] - 2026-09-09
11
102
 
12
103
  ### Fixed
@@ -812,7 +903,9 @@ and may change between minor versions until 1.0.
812
903
  - `natsort >= 8.0`
813
904
  - `plotly >= 5.18, < 7`
814
905
 
815
- [Unreleased]: https://github.com/cnicholas/processbehavior/compare/v0.2.1...HEAD
906
+ [Unreleased]: https://github.com/cnicholas/processbehavior/compare/v0.3.1...HEAD
907
+ [0.3.1]: https://github.com/cnicholas/processbehavior/compare/v0.3.0...v0.3.1
908
+ [0.3.0]: https://github.com/cnicholas/processbehavior/compare/v0.2.1...v0.3.0
816
909
  [0.2.1]: https://github.com/cnicholas/processbehavior/compare/v0.2.0...v0.2.1
817
910
  [0.2.0]: https://github.com/cnicholas/processbehavior/compare/v0.1.1...v0.2.0
818
911
  [0.1.1]: https://github.com/cnicholas/processbehavior/compare/v0.1.0...v0.1.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: processbehavior
3
- Version: 0.2.1
3
+ Version: 0.3.1
4
4
  Summary: Python-native Process Behavior & Control Charts (spec-driven SPC with tidy outputs)
5
5
  Project-URL: Homepage, https://github.com/cnicholas/processbehavior
6
6
  Project-URL: Repository, https://github.com/cnicholas/processbehavior
@@ -28,7 +28,7 @@ Requires-Python: >=3.10
28
28
  Requires-Dist: natsort>=8.0.0
29
29
  Requires-Dist: numpy>=1.23
30
30
  Requires-Dist: pandas<3,>=2.0
31
- Requires-Dist: plotly<7,>=5.18
31
+ Requires-Dist: plotly<8,>=5.18
32
32
  Requires-Dist: typing-extensions>=4.0; python_version < '3.11'
33
33
  Provides-Extra: dev
34
34
  Requires-Dist: filelock>=3.20.3; extra == 'dev'
@@ -47,7 +47,7 @@ its ``.sds`` field. Internally some modules still use the legacy "SDS"
47
47
  prefix (e.g. ``sds_detector.py``); the model itself is three-state.
48
48
  """
49
49
 
50
- __version__ = '0.2.1'
50
+ __version__ = '0.3.1'
51
51
 
52
52
  # Result object
53
53
  from processbehavior.analysis_result import AnalysisResult
@@ -183,7 +183,7 @@ class AnalysisDataSet:
183
183
  - n_cell_min: minimum observations per cell
184
184
  - n_cell_max: maximum observations per cell
185
185
  - K_obs: number of unique factor levels observed
186
- - r2_method: 'exact', 'ma2', or 'hybrid'
186
+ - r2_method: 'exact' or 'ma2'
187
187
  Returns None if structure stats haven't been computed.
188
188
  """
189
189
  if self._structure_stats is None:
@@ -16,6 +16,7 @@ Follows the Pythonic Hadley philosophy:
16
16
  from __future__ import annotations
17
17
 
18
18
  import logging
19
+ import warnings
19
20
  from functools import reduce
20
21
  from typing import TYPE_CHECKING
21
22
 
@@ -24,7 +25,7 @@ import pandas as pd
24
25
  from natsort import natsorted
25
26
  from pandas.api.types import is_numeric_dtype
26
27
 
27
- from .exceptions import ColumnNotFoundError, FactorNotFoundError, ValidationError
28
+ from .exceptions import ColumnNotFoundError, FactorNotFoundError, ProcessBehaviorWarning, ValidationError
28
29
 
29
30
  if TYPE_CHECKING:
30
31
  from .formulation_spec import FormulationSpec
@@ -281,6 +282,13 @@ class DataPreparation:
281
282
 
282
283
  # Add composite grouping variable if needed
283
284
  if spec.has_grouping:
285
+ # A row with no value in a factor column belongs to no cell, so it leaves the
286
+ # analysis here — for one factor or many. The single-factor path used to drop
287
+ # such rows silently via the rsg dropna below; the multi-factor path raised
288
+ # from _add_composite_column before reaching it, so the same file formulated
289
+ # with one factor and failed with two (Tom's survey file, 7,980 blank
290
+ # SURVEY QUESTION rows). Both paths now drop first and say so.
291
+ out = self._drop_rows_missing_factor_values(out, spec)
284
292
  out = self._add_grouping_column(out, spec)
285
293
 
286
294
  # Drop rows with missing values in analysis-critical columns BEFORE
@@ -533,6 +541,30 @@ class DataPreparation:
533
541
  # Private Helper Methods
534
542
  # ========================================================================
535
543
 
544
+ def _drop_rows_missing_factor_values(self, df: pd.DataFrame, spec: FormulationSpec) -> pd.DataFrame:
545
+ """
546
+ Drop rows with a missing value in any factor column, and report it.
547
+
548
+ Reported as a ``ProcessBehaviorWarning`` (the house style for "the
549
+ library changed your data on your behalf"), naming the count per
550
+ factor, so an analyst sees that 7,980 rows left the study rather than
551
+ discovering a smaller N later.
552
+ """
553
+ factor_cols = spec.rsg_vars_list
554
+ missing = df[factor_cols].isna()
555
+ if not missing.any().any():
556
+ return df
557
+ per_col = {col: int(n) for col, n in missing.sum().items() if n}
558
+ n_rows = int(missing.any(axis=1).sum())
559
+ warnings.warn(
560
+ f'Dropped {n_rows:,} of {len(df):,} rows with no value in a factor column: '
561
+ + ', '.join(f'{col} ({n:,} missing)' for col, n in per_col.items())
562
+ + '. A row with no factor value belongs to no cell, so it is excluded from the analysis.',
563
+ ProcessBehaviorWarning,
564
+ stacklevel=6,
565
+ )
566
+ return df.loc[~missing.any(axis=1)]
567
+
536
568
  def _add_grouping_column(self, df: pd.DataFrame, spec: FormulationSpec) -> pd.DataFrame:
537
569
  """
538
570
  Add composite grouping column (e.g., 'lane_head').
@@ -416,13 +416,13 @@ def make_sds3( # noqa: C901
416
416
  Characteristics:
417
417
  ---------------
418
418
  - Some cells have n=1, others have n≥2
419
- - Requires hybrid R2 estimation
419
+ - Mixed cell sizes: R2 by MA2 across the full sequence
420
420
  - Reflects real-world data collection reality
421
421
  - Most challenging to analyze correctly
422
422
 
423
423
  Use Cases:
424
424
  ---------
425
- - Testing hybrid variance estimation algorithms
425
+ - Testing R2 selection with mixed cell sizes
426
426
  - Demonstrating real-world data structures
427
427
  - Validating robustness to missing data
428
428
  - Development of SDS detection logic