processbehavior 0.2.0__tar.gz → 0.3.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 (205) hide show
  1. {processbehavior-0.2.0 → processbehavior-0.3.0}/CHANGELOG.md +117 -1
  2. {processbehavior-0.2.0 → processbehavior-0.3.0}/CONTRIBUTING.md +7 -3
  3. {processbehavior-0.2.0 → processbehavior-0.3.0}/PKG-INFO +3 -2
  4. {processbehavior-0.2.0 → processbehavior-0.3.0}/README.md +1 -0
  5. {processbehavior-0.2.0 → processbehavior-0.3.0}/SECURITY.md +4 -4
  6. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/__init__.py +1 -1
  7. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/analysis_dataset.py +1 -1
  8. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/analysis_result.py +6 -1
  9. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/data_preparation.py +33 -1
  10. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/datasets/__init__.py +0 -10
  11. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/datasets/synthetic.py +8 -666
  12. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/derivations.py +15 -3
  13. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/exporters/excel_exporter.py +2 -92
  14. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/loss_function.py +5 -8
  15. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/plotter.py +0 -11
  16. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/residual_calculator.py +9 -8
  17. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/sds_detector.py +25 -96
  18. processbehavior-0.3.0/processbehavior/series_length.py +105 -0
  19. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/signals/config.py +5 -1
  20. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/signals/detector.py +55 -21
  21. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/signals/result.py +84 -11
  22. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/spc_constants.py +44 -0
  23. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/study.py +42 -0
  24. {processbehavior-0.2.0 → processbehavior-0.3.0}/pyproject.toml +1 -1
  25. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/conftest.py +0 -28
  26. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_derivations.py +34 -0
  27. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_documented_rule_coverage.py +30 -0
  28. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_excel_export.py +95 -0
  29. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_garbage_character_handling.py +14 -0
  30. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_loss_function.py +30 -0
  31. processbehavior-0.3.0/tests/test_na_in_factor_columns.py +96 -0
  32. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_plotting.py +84 -0
  33. processbehavior-0.3.0/tests/test_reference_integrity.py +56 -0
  34. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_residual_calculator.py +8 -8
  35. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_sds_detector.py +123 -6
  36. processbehavior-0.3.0/tests/test_series_length.py +153 -0
  37. processbehavior-0.3.0/tests/test_signal_result_surface.py +159 -0
  38. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_signals.py +76 -0
  39. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_synthetic.py +101 -0
  40. {processbehavior-0.2.0 → processbehavior-0.3.0}/.gitignore +0 -0
  41. {processbehavior-0.2.0 → processbehavior-0.3.0}/CITATION.cff +0 -0
  42. {processbehavior-0.2.0 → processbehavior-0.3.0}/CODE_OF_CONDUCT.md +0 -0
  43. {processbehavior-0.2.0 → processbehavior-0.3.0}/LICENSE +0 -0
  44. {processbehavior-0.2.0 → processbehavior-0.3.0}/examples/README.md +0 -0
  45. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/analysis.py +0 -0
  46. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/calibration.py +0 -0
  47. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/capability.py +0 -0
  48. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/datasets/data/coffee_shop_demo_long.csv +0 -0
  49. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/datasets/loaders.py +0 -0
  50. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/effects_calculator.py +0 -0
  51. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/exceptions.py +0 -0
  52. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/exporters/__init__.py +0 -0
  53. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/focused_result.py +0 -0
  54. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/formulation_spec.py +0 -0
  55. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/maximum_information.py +0 -0
  56. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/__init__.py +0 -0
  57. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/_math.py +0 -0
  58. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/capability_chart.py +0 -0
  59. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/contracts.py +0 -0
  60. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/control_chart.py +0 -0
  61. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/effects_charts.py +0 -0
  62. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/lane_boundaries.py +0 -0
  63. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/limits.py +0 -0
  64. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/maximum_information_chart.py +0 -0
  65. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/renderers.py +0 -0
  66. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/report.py +0 -0
  67. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/residuals.py +0 -0
  68. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/run_rules_viz.py +0 -0
  69. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/stats_box.py +0 -0
  70. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/themes.py +0 -0
  71. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/x_axis_layout.py +0 -0
  72. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/plotting/zones.py +0 -0
  73. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/process_behavior.py +0 -0
  74. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/py.typed +0 -0
  75. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/result_signals.py +0 -0
  76. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/result_tabular.py +0 -0
  77. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/signals/__init__.py +0 -0
  78. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/signals/detectors.py +0 -0
  79. {processbehavior-0.2.0 → processbehavior-0.3.0}/processbehavior/types.py +0 -0
  80. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/__init__.py +0 -0
  81. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/bishop_analyses/vassds1analysis.json +0 -0
  82. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/bishop_analyses/vassds2analysis.json +0 -0
  83. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/bishop_analyses/vassds3analysis.json +0 -0
  84. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/coffee_capability_full_baseline.json +0 -0
  85. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/data/FILLWEIGHTDATA_800.csv +0 -0
  86. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/data/coffee_shop_demo_long.csv +0 -0
  87. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/missing_values/X_data.parquet +0 -0
  88. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/missing_values/X_metadata.json +0 -0
  89. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/missing_values/X_statistics.json +0 -0
  90. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/missing_values/mR_data.parquet +0 -0
  91. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/missing_values/mR_metadata.json +0 -0
  92. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/missing_values/mR_statistics.json +0 -0
  93. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xbar_s/S_data.parquet +0 -0
  94. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xbar_s/S_metadata.json +0 -0
  95. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xbar_s/S_statistics.json +0 -0
  96. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xbar_s/Xbar_data.parquet +0 -0
  97. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xbar_s/Xbar_metadata.json +0 -0
  98. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xbar_s/Xbar_statistics.json +0 -0
  99. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xmr_r/X_data.parquet +0 -0
  100. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xmr_r/X_metadata.json +0 -0
  101. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xmr_r/X_statistics.json +0 -0
  102. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xmr_r/mR_data.parquet +0 -0
  103. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xmr_r/mR_metadata.json +0 -0
  104. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/paired_xmr_r/mR_statistics.json +0 -0
  105. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/pathological_ordering/X_data.parquet +0 -0
  106. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/pathological_ordering/X_metadata.json +0 -0
  107. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/pathological_ordering/X_statistics.json +0 -0
  108. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/pathological_ordering/mR_data.parquet +0 -0
  109. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/pathological_ordering/mR_metadata.json +0 -0
  110. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/pathological_ordering/mR_statistics.json +0 -0
  111. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/residual_chart/S_data.parquet +0 -0
  112. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/residual_chart/S_metadata.json +0 -0
  113. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/residual_chart/S_statistics.json +0 -0
  114. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/single_obs_strata/X_data.parquet +0 -0
  115. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/single_obs_strata/X_metadata.json +0 -0
  116. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/single_obs_strata/X_statistics.json +0 -0
  117. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/single_obs_strata/mR_data.parquet +0 -0
  118. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/single_obs_strata/mR_metadata.json +0 -0
  119. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/single_obs_strata/mR_statistics.json +0 -0
  120. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_balanced/S_data.parquet +0 -0
  121. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_balanced/S_metadata.json +0 -0
  122. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_balanced/S_statistics.json +0 -0
  123. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_balanced/Xbar_data.parquet +0 -0
  124. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_balanced/Xbar_metadata.json +0 -0
  125. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_balanced/Xbar_statistics.json +0 -0
  126. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_uneven/S_data.parquet +0 -0
  127. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_uneven/S_metadata.json +0 -0
  128. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_uneven/S_statistics.json +0 -0
  129. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_uneven/Xbar_data.parquet +0 -0
  130. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_uneven/Xbar_metadata.json +0 -0
  131. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/stratified_uneven/Xbar_statistics.json +0 -0
  132. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/unstratified_small/X_data.parquet +0 -0
  133. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/unstratified_small/X_metadata.json +0 -0
  134. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/unstratified_small/X_statistics.json +0 -0
  135. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/unstratified_small/mR_data.parquet +0 -0
  136. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/unstratified_small/mR_metadata.json +0 -0
  137. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/fixtures/golden_masters/unstratified_small/mR_statistics.json +0 -0
  138. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_analysis_bugs.py +0 -0
  139. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_analysis_dataset.py +0 -0
  140. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_analysis_golden_master.py +0 -0
  141. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_analysis_result_contract.py +0 -0
  142. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_analysis_specifications.py +0 -0
  143. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_api_reference.py +0 -0
  144. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_beyond_limits_vectorized.py +0 -0
  145. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_bin_extremes.py +0 -0
  146. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_bishop_reference.py +0 -0
  147. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_by_parameter.py +0 -0
  148. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_by_permutations.py +0 -0
  149. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_calibration.py +0 -0
  150. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_capability.py +0 -0
  151. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_capability_chart.py +0 -0
  152. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_capability_window.py +0 -0
  153. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_chart_availability.py +0 -0
  154. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_chart_column_contract.py +0 -0
  155. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_chart_parsing.py +0 -0
  156. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_control_chart_figure.py +0 -0
  157. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_data_preparation.py +0 -0
  158. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_datasets.py +0 -0
  159. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_design_state_lineage.py +0 -0
  160. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_edge_cases.py +0 -0
  161. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_effects_calculator.py +0 -0
  162. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_effects_plotting.py +0 -0
  163. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_encode_rsg_vectorized.py +0 -0
  164. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_execute_validation.py +0 -0
  165. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_focus.py +0 -0
  166. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_init_cleaning.py +0 -0
  167. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_lane_boundaries.py +0 -0
  168. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_limits_vectorized.py +0 -0
  169. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_maximum_information.py +0 -0
  170. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_notebook_ergonomics.py +0 -0
  171. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_p0_p2_regressions.py +0 -0
  172. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_performance.py +0 -0
  173. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_phased_limits.py +0 -0
  174. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_plotting_decorations.py +0 -0
  175. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_plotting_hardening.py +0 -0
  176. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_plotting_xaxis.py +0 -0
  177. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_process_behavior.py +0 -0
  178. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_recentered_mr_fix.py +0 -0
  179. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_release_gate_0_1_0_checklist.py +0 -0
  180. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_residual_aliases.py +0 -0
  181. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_residual_labels.py +0 -0
  182. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_residual_scope.py +0 -0
  183. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_resolve_by_grouping.py +0 -0
  184. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_result_signals.py +0 -0
  185. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_result_tabular.py +0 -0
  186. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_sampling_plan.py +0 -0
  187. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_sds.py +0 -0
  188. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_signal_detectors.py +0 -0
  189. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_single_detection.py +0 -0
  190. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_solo_mr_residuals.py +0 -0
  191. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_spc_constants.py +0 -0
  192. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_srp_refactor.py +0 -0
  193. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_strata_companion.py +0 -0
  194. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_strata_sufficiency.py +0 -0
  195. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_stratified_insufficiency.py +0 -0
  196. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_supports_calibration.py +0 -0
  197. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_types.py +0 -0
  198. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_validate_by_parameter.py +0 -0
  199. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_weco_integration.py +0 -0
  200. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_why_not.py +0 -0
  201. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_x_axis_layout.py +0 -0
  202. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_xbar_residual_center.py +0 -0
  203. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_xbar_s_options.py +0 -0
  204. {processbehavior-0.2.0 → processbehavior-0.3.0}/tests/test_xbar_stratified.py +0 -0
  205. {processbehavior-0.2.0 → processbehavior-0.3.0}/validation/PBTESTDATABASE_T100.csv +0 -0
@@ -7,6 +7,120 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2026-09-14
11
+
12
+ ### Added
13
+ - **The design report states where sigma comes from at the observed structure and
14
+ series length.** One line under ``Structure``: ``Series length: T=4. Sigma for X/mR
15
+ rests on 3 moving ranges.`` With every cell replicated it reads ``Series length: T=1.
16
+ Sigma rests on within-cell replication.`` — a single time period is a complete study.
17
+ Exposed as ``study.series_length`` (``SeriesLengthPrecision``, frozen) and
18
+ ``study.series_length_description``. The result also carries ``within_cell_df`` and,
19
+ for the moving-range case, ``mr_interval_80`` — the p10/p90 of MRbar/d2 by n = 3..30
20
+ from ``MR_SIGMA_INTERVAL_80`` (``spc_constants``), generated by
21
+ ``validation/short_series_bands.py`` (contributed by @rabujamra in #114 / #119) — for
22
+ callers who want the numbers; the report prints only the sentence. It is a fact beside
23
+ the design state, not a judgment on it: no threshold, label, or warning, and the design
24
+ state, recommended chart and analysis menu do not move with T (pinned by test). Closes
25
+ the series-length half of #114.
26
+
27
+ ### Changed
28
+ - **The R2 method for partial replication is reported as ``ma2``, not ``hybrid``.** The
29
+ docs described a per-cell hybrid for design state 3 (exact deviation where a cell has
30
+ n ≥ 2, moving average where n = 1) and said it was validated by Monte Carlo. The code
31
+ has not done that since cb037f8 (2026-03-05): with any singleton cell, R2 is Bishop's
32
+ ungrouped 2-point moving average over the full canonical sequence (Eq 13.7–13.9) for
33
+ every observation, and the 89 ADS 3 reference assertions hold against that. Only the word
34
+ survived, in six docs pages (three of which described it three different ways), the
35
+ detector's method token, the analysis-plan limitation text, two docstrings and two test
36
+ names. All now say what the code does. ``R2Method`` is ``Literal['exact', 'ma2']``;
37
+ ``SDSRegistry.get_r2_method`` returns ``'ma2'`` where it returned ``'hybrid'``;
38
+ ``get_sds_characteristics`` and ``SDSAnalysisPlan.residual_calculation_method`` use the
39
+ same two spellings in place of ``'within_cell'``, ``'moving_average'`` and ``'hybrid'``.
40
+ No arithmetic changed; none of these names is exported from the package top level.
41
+
42
+ ### Dependencies
43
+ - ``plotly>=5.18,<8`` (was ``<7``). plotly 7.0.0 (2026-08-25) was tested against the full
44
+ suite before the bound moved: its breaking changes (mapbox traces, decimal-fraction
45
+ ``rgb()`` strings, ``hsv()``, Kaleido < 1.0, figure_factory) touch nothing here. #116.
46
+
47
+ ### Fixed
48
+ - **A missing value in a factor column no longer makes a two-factor study fail.** With one
49
+ factor, rows with a blank factor value were dropped silently; with two or more, the
50
+ composite subgroup label was built before that drop and ``formulate`` raised
51
+ ``ValidationError: Cannot build RSG ... missing values in factor columns``. The same
52
+ file formulated with either factor alone and failed with both (a 85,101-row survey
53
+ file with 7,980 blank ``SURVEY QUESTION`` rows). Rows with no value in any factor
54
+ column now leave the analysis before the label is built, for any number of factors,
55
+ and the library says so with a ``ProcessBehaviorWarning`` naming the count per
56
+ factor. Response and time missing values are handled as before.
57
+ - **``evaluate`` no longer raises on a constant column.** Binning a column with no spread
58
+ (every value identical) returned the documented no-spread result for ``equal_freq`` but
59
+ raised ``ValueError: Bin edges must be unique`` from ``pd.cut`` for ``equal_width`` and
60
+ ``sd``, because their fitted edges were identical yet finite and slipped past the guard.
61
+ The derivations module promises ``evaluate`` never raises on a routine state; a constant
62
+ column is one. All three methods now return the same no-spread result, whose ``fitted``
63
+ dict also carries ``n_bins: 0``, ``edges: []`` and ``labels: []`` so callers see one
64
+ shape. Explicit ``breaks`` on a constant column still bin. Found through the app on a
65
+ single-time-point file whose TIME column was a constant.
66
+
67
+ ## [0.2.1] - 2026-09-09
68
+
69
+ ### Fixed
70
+ - **A short series no longer returns an unqualified all-clear from
71
+ ``detect_signals``.** ``SignalConfig.min_observations`` (default 20) was
72
+ unreachable: ``SignalDetector`` read a hardcoded per-rule table and never
73
+ consulted the config, so ``SignalConfig(min_observations=30)`` changed nothing.
74
+ Separately, the detector already recorded which rules it skipped for length
75
+ (``rules_skipped``, added in 0.2.0) but ``SignalResult.summary`` ignored that and
76
+ printed ``✓ No signals detected`` regardless. On a four-point X chart six of the
77
+ eight rules cannot fire, and the one that can is weakened by any trend in the
78
+ data, so the checkmark described an examination that had mostly not happened.
79
+
80
+ Now: the per-rule table is the *structural* minimum (``RULE_MIN_OBSERVATIONS``,
81
+ a rule is skipped below it, as before) and ``min_observations`` is the *advisory*
82
+ minimum. Below it the detector emits a ``ProcessBehaviorWarning`` naming both
83
+ numbers (one per chart evaluated; silence it with
84
+ ``warnings.simplefilter('ignore', ProcessBehaviorWarning)`` once a pipeline has
85
+ accounted for it) and the result is marked partial even when every runnable
86
+ rule ran.
87
+ ``SignalResult`` gains ``rules_evaluated``, ``rules_applicable``,
88
+ ``n_observations``, ``min_observations``, ``below_min_observations`` and
89
+ ``evaluation_note``; ``is_partial`` / ``evaluation_status`` now also reflect the
90
+ advisory threshold. A partial evaluation prints
91
+ ``⚠ Partial evaluation in X: 2 of 8 rules applicable at n=4 (...). No signals
92
+ from the rules evaluated.`` and the checkmark line is reserved for a complete
93
+ evaluation. Which rules run, and what they flag, is unchanged. Excel export's
94
+ Summary sheet adds evaluation status. Reported privately (GHSA-hw63-2x95-fmpv)
95
+ and in #114.
96
+ - ``SECURITY.md`` supported-versions table said 0.1.x while the prose said 0.2.x.
97
+ The table now matches the prose.
98
+
99
+ ### Removed
100
+ - **Seven never-called utilities from ``datasets.synthetic``** — ``make_edge_cases``
101
+ (unseeded, non-deterministic), ``compare_sds_characteristics`` (its docstring
102
+ table was factually wrong), ``validate_sds_detection`` (vacuous: it compared
103
+ ``observed_sds`` to the very value it was handed, so it always returned True),
104
+ ``generate_test_suite``, ``get_sds_info`` + ``print_sds_summary`` (a second,
105
+ drifting copy of ``SDSRegistry`` metadata), and ``make_large_dataset``. Zero
106
+ callers existed anywhere in the package, tests, docs, or examples.
107
+ - ``SDSRegistry.print_all_analysis_plans`` and ``SDSRegistry.get_capability_matrix``
108
+ (same finding: no callers).
109
+ - Dead branches: the Excel exporter's ``_write_stratified_summary_tab`` (unreachable
110
+ since stratified charts moved to the single-entry ``strata`` payload) and its
111
+ Series/scalar effects arms; the plotter's legacy underscore-name stratification
112
+ arm and unused ``_get_data_legend_name``; the ``Study`` arm of the loss
113
+ function's ``_coerce_ads`` (``assess_loss`` takes an ``AnalysisDataSet``).
114
+
115
+ ### CI / Infrastructure
116
+ - **The Bishop validation gate now bites.** ``validation/e2e_bishop_report.py``
117
+ exits nonzero when any of its 280 assertions diverge from the reference values
118
+ (previously it only rendered PASS/FAIL into the report), the publish workflow
119
+ runs the same gate before any release, the four reference artifacts are
120
+ SHA-256-pinned by ``tests/test_reference_integrity.py`` and check out
121
+ byte-exact on every platform, and CODEOWNERS routes any change to the gate's
122
+ inputs through the maintainer.
123
+
10
124
  ## [0.2.0] - 2026-08-31
11
125
 
12
126
  ### Removed
@@ -755,7 +869,9 @@ and may change between minor versions until 1.0.
755
869
  - `natsort >= 8.0`
756
870
  - `plotly >= 5.18, < 7`
757
871
 
758
- [Unreleased]: https://github.com/cnicholas/processbehavior/compare/v0.2.0...HEAD
872
+ [Unreleased]: https://github.com/cnicholas/processbehavior/compare/v0.3.0...HEAD
873
+ [0.3.0]: https://github.com/cnicholas/processbehavior/compare/v0.2.1...v0.3.0
874
+ [0.2.1]: https://github.com/cnicholas/processbehavior/compare/v0.2.0...v0.2.1
759
875
  [0.2.0]: https://github.com/cnicholas/processbehavior/compare/v0.1.1...v0.2.0
760
876
  [0.1.1]: https://github.com/cnicholas/processbehavior/compare/v0.1.0...v0.1.1
761
877
  [0.1.0]: https://github.com/cnicholas/processbehavior/releases/tag/v0.1.0
@@ -164,8 +164,12 @@ Releases are published to PyPI by the `Publish` workflow on tag push.
164
164
  in `CHANGELOG.md` and update the compare links at the bottom.
165
165
  3. Bump the version in `processbehavior/__init__.py` (`__version__`).
166
166
  `pyproject.toml` reads it via `[tool.hatch.version]`.
167
- 4. Commit with subject `Release vX.Y.Z`, push to `main`.
168
- 5. Tag and push:
167
+ 4. Run `python validation/e2e_bishop_report.py` and commit the regenerated
168
+ `docs/reference/validation.md`. Its header carries the version string, and
169
+ the publish workflow fails if the committed page has drifted from what the
170
+ validator writes.
171
+ 5. Commit with subject `Release vX.Y.Z`, push to `main`.
172
+ 6. Tag and push:
169
173
  ```bash
170
174
  git tag -s vX.Y.Z -m "Release vX.Y.Z"
171
175
  git push origin vX.Y.Z
@@ -173,7 +177,7 @@ Releases are published to PyPI by the `Publish` workflow on tag push.
173
177
  The tag push triggers `.github/workflows/publish.yml`, which builds,
174
178
  verifies with `twine check`, and uploads to PyPI via OIDC trusted
175
179
  publishing — no API tokens.
176
- 6. Verify the release on https://pypi.org/project/processbehavior/ and run
180
+ 7. Verify the release on https://pypi.org/project/processbehavior/ and run
177
181
  `pip install processbehavior==X.Y.Z` in a fresh venv to confirm the
178
182
  README quickstart still runs end-to-end.
179
183
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: processbehavior
3
- Version: 0.2.0
3
+ Version: 0.3.0
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'
@@ -86,6 +86,7 @@ Description-Content-Type: text/markdown
86
86
  [![PyPI version](https://img.shields.io/pypi/v/processbehavior.svg)](https://pypi.org/project/processbehavior/)
87
87
  [![Python versions](https://img.shields.io/pypi/pyversions/processbehavior.svg)](https://pypi.org/project/processbehavior/)
88
88
  [![CI](https://github.com/cnicholas/processbehavior/actions/workflows/ci.yml/badge.svg)](https://github.com/cnicholas/processbehavior/actions/workflows/ci.yml)
89
+ [![codecov](https://codecov.io/gh/cnicholas/processbehavior/graph/badge.svg)](https://codecov.io/gh/cnicholas/processbehavior)
89
90
  [![License](https://img.shields.io/pypi/l/processbehavior.svg)](https://github.com/cnicholas/processbehavior/blob/main/LICENSE)
90
91
 
91
92
  A Python library for **Process Behavior Analysis** following Thomas A. Bishop's Variance Analysis System (VAS) methodology.
@@ -3,6 +3,7 @@
3
3
  [![PyPI version](https://img.shields.io/pypi/v/processbehavior.svg)](https://pypi.org/project/processbehavior/)
4
4
  [![Python versions](https://img.shields.io/pypi/pyversions/processbehavior.svg)](https://pypi.org/project/processbehavior/)
5
5
  [![CI](https://github.com/cnicholas/processbehavior/actions/workflows/ci.yml/badge.svg)](https://github.com/cnicholas/processbehavior/actions/workflows/ci.yml)
6
+ [![codecov](https://codecov.io/gh/cnicholas/processbehavior/graph/badge.svg)](https://codecov.io/gh/cnicholas/processbehavior)
6
7
  [![License](https://img.shields.io/pypi/l/processbehavior.svg)](https://github.com/cnicholas/processbehavior/blob/main/LICENSE)
7
8
 
8
9
  A Python library for **Process Behavior Analysis** following Thomas A. Bishop's Variance Analysis System (VAS) methodology.
@@ -2,13 +2,13 @@
2
2
 
3
3
  ## Supported versions
4
4
 
5
- processbehavior is in **alpha** (0.1.x). Only the most recent 0.1.x release
6
- receives security fixes. 0.2.x is the supported line; 0.1.x is not patched.
5
+ processbehavior is in **alpha**. Only the most recent 0.2.x release receives
6
+ security fixes; 0.1.x is not patched.
7
7
 
8
8
  | Version | Supported |
9
9
  | ------- | ------------------ |
10
- | 0.1.x | :white_check_mark: |
11
- | < 0.1 | :x: |
10
+ | 0.2.x | :white_check_mark: |
11
+ | < 0.2 | :x: |
12
12
 
13
13
  ## Reporting a vulnerability
14
14
 
@@ -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.0'
50
+ __version__ = '0.3.0'
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:
@@ -1029,11 +1029,16 @@ class AnalysisResult:
1029
1029
  >>> from processbehavior.signals import SignalConfig
1030
1030
  >>> config = SignalConfig(
1031
1031
  ... enabled_rules=['rule_1', 'rule_2'],
1032
- ... min_observations=30,
1032
+ ... min_observations=30, # below 30 points the result is marked partial
1033
1033
  ... ignore_first_n=5
1034
1034
  ... )
1035
1035
  >>> signals = result.detect_signals(config=config)
1036
1036
 
1037
+ A short series never returns an unqualified all-clear: when rules were
1038
+ skipped for length, or the series is below ``min_observations``,
1039
+ ``signals.is_partial`` is True and ``signals.summary`` says which rules
1040
+ were evaluated.
1041
+
1037
1042
  Access violations:
1038
1043
 
1039
1044
  >>> signals.by_rule['rule_2'] # Rule 2 violations
@@ -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').
@@ -6,18 +6,13 @@ from __future__ import annotations
6
6
 
7
7
  from .loaders import load_coffee_shop
8
8
  from .synthetic import (
9
- compare_sds_characteristics,
10
- generate_test_suite,
11
- get_sds_info,
12
9
  make_design,
13
- make_edge_cases,
14
10
  make_sds1,
15
11
  make_sds2,
16
12
  make_sds3,
17
13
  make_sds4,
18
14
  make_sds5,
19
15
  make_sds6,
20
- print_sds_summary,
21
16
  )
22
17
 
23
18
  __all__ = [
@@ -28,10 +23,5 @@ __all__ = [
28
23
  'make_sds5',
29
24
  'make_sds6',
30
25
  'make_design',
31
- 'make_edge_cases',
32
26
  'load_coffee_shop',
33
- 'compare_sds_characteristics',
34
- 'generate_test_suite',
35
- 'get_sds_info',
36
- 'print_sds_summary',
37
27
  ]