stat_power 0.1.0.alpha.2 → 0.1.0.alpha.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1c655045d40fab84f807e1092e00ab08829ff0d9066f1081c14e9a75d411d52
4
- data.tar.gz: bd2eff9c48b33c0512ce887eb704b674c2a6b8f511b65733a6c230de82f7617a
3
+ metadata.gz: 2c69ef6117ff1e0bf73f795f855383722810e4e0153d33fe65e5baf803c6554b
4
+ data.tar.gz: 68e88eb27fff0e23651c8ae4f9a954eb14718703287b9aaf596b251dd0d742af
5
5
  SHA512:
6
- metadata.gz: 1f941dc407c89a7f931511b9355a0495924d0edaf09c6b599190fa39a80668224330513072c1f7cfd2f7b05dbb39d01a0bd405ef1fe1d6a7132aaf06b57cc3d7
7
- data.tar.gz: eddde39e8855abf2e9df24160968f28b8ba52884b6d4d3bcf954bd0c1231740ee99e7d67007ff05f50b15b6a80728ff8a41abc2b948a38e97c6b4519bff69a06
6
+ metadata.gz: d8882a7378d4e07735877624fdb21ac512b9e54f5bb42a0342374fcd18e922e85b36710fe9e05fcf92a8b2a5abea3711198bc3df678a7d5796735581bfa9b108
7
+ data.tar.gz: b5f799b202dc11cc3a7b0290a2d90ff1061771f43cc021e7626e6c256213ff95a8a597f09f5034ec9b1e7f9b070aef0ef8f940fec7734b52263f589349ac86d8
data/CHANGELOG.md CHANGED
@@ -4,6 +4,42 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.1.0.alpha.3 - 2026-09-20
8
+
9
+ ### Added
10
+
11
+ - Contribution guide, code of conduct, and security policy
12
+ - Issue templates, including a dedicated numerical-discrepancy report
13
+ - Pull request template requiring independent numerical validation
14
+ - `CODEOWNERS` and Dependabot configuration for Bundler and GitHub Actions
15
+ - CodeQL analysis workflow
16
+ - `bin/setup` and `bin/console` developer scripts
17
+ - `rake verify` task running every check that CI runs
18
+ - Steep type checking of `lib/` against `sig/`, now enforced in CI
19
+ - SimpleCov line and branch coverage with an enforced minimum
20
+ - `.gitattributes`, `.editorconfig`, and `.ruby-version` for reproducible
21
+ formatting and tooling across platforms
22
+
23
+ ### Changed
24
+
25
+ - CI now runs lint, type check, and coverage as dedicated jobs, declares
26
+ least-privilege permissions, and cancels superseded runs
27
+ - RuboCop runs with `NewCops: enable`
28
+ - Gem metadata now includes a contact address, bug tracker, and versioned
29
+ source URI; maintainer-only files are no longer packaged
30
+
31
+ ### Fixed
32
+
33
+ - **`sig/stat_power.rbs` shipped in 0.1.0.alpha.2 was not valid RBS.** The
34
+ block signature for `PowerCurve.generate` used an unparenthesized union
35
+ return type, so any consumer feeding the packaged signatures to `rbs` or
36
+ Steep hit a parse error at line 282. Runtime behaviour was unaffected;
37
+ 0.1.0.alpha.1 was not affected, because it predates `PowerCurve`. `rbs
38
+ validate` accepts the malformed form, which is why it reached a release;
39
+ `steep check` now runs in CI and in the release gate.
40
+ - `EffectSize::ChiSquare.association` computed column marginals by mutating an
41
+ accumulator array; it now uses `transpose`
42
+
7
43
  ## 0.1.0.alpha.2 - 2026-09-20
8
44
 
9
45
  ### Added
data/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # stat_power
2
2
 
3
+ [![CI](https://github.com/DiogoRibeiro7/stat_power/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/DiogoRibeiro7/stat_power/actions/workflows/ci.yml)
4
+ [![RubyGems](https://img.shields.io/gem/v/stat_power?include_prereleases)](https://rubygems.org/gems/stat_power)
5
+ [![Gem Downloads](https://img.shields.io/gem/dt/stat_power)](https://rubygems.org/gems/stat_power)
6
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.2-CC342D?logo=ruby&logoColor=white)](https://www.ruby-lang.org/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+
3
9
  Native Ruby statistical power analysis and sample-size determination.
4
10
 
5
11
  > **Alpha release:** `stat_power` is under active development. The public API
@@ -17,13 +23,13 @@ gem install stat_power --prerelease
17
23
  or pin the exact alpha:
18
24
 
19
25
  ```bash
20
- gem install stat_power -v 0.1.0.alpha.2
26
+ gem install stat_power -v 0.1.0.alpha.3
21
27
  ```
22
28
 
23
29
  With Bundler:
24
30
 
25
31
  ```ruby
26
- gem "stat_power", "0.1.0.alpha.2"
32
+ gem "stat_power", "0.1.0.alpha.3"
27
33
  ```
28
34
 
29
35
  ## Status
@@ -112,29 +118,39 @@ freeze candidate.
112
118
 
113
119
  ## Development
114
120
 
115
- Install dependencies:
121
+ Set up the checkout:
116
122
 
117
123
  ```bash
118
- bundle install
124
+ bin/setup
119
125
  ```
120
126
 
121
- Run the test suite:
127
+ Open a console with the library loaded:
122
128
 
123
129
  ```bash
124
- bundle exec rspec
130
+ bin/console
125
131
  ```
126
132
 
127
- Run lint and signature validation:
133
+ Run everything CI runs:
128
134
 
129
135
  ```bash
130
- bundle exec rubocop
131
- bundle exec rbs validate
136
+ bundle exec rake verify
132
137
  ```
133
138
 
134
- Validate that the library loads:
139
+ That is the same as running each check individually:
135
140
 
136
141
  ```bash
137
- ruby -Ilib -e 'require "stat_power"'
142
+ bundle exec rspec # specs
143
+ bundle exec rubocop # lint
144
+ bundle exec rbs validate # signature syntax
145
+ bundle exec steep check # lib/ type checked against sig/
146
+ ```
147
+
148
+ Measure test coverage. Instrumentation roughly doubles the runtime, so it is
149
+ opt-in; CI enforces a minimum in a dedicated job.
150
+
151
+ ```bash
152
+ COVERAGE=1 bundle exec rspec
153
+ open coverage/index.html
138
154
  ```
139
155
 
140
156
  Build the gem locally:
@@ -143,6 +159,29 @@ Build the gem locally:
143
159
  gem build stat_power.gemspec
144
160
  ```
145
161
 
162
+ ## Contributing
163
+
164
+ Contributions are welcome. Because this is a numerical library, the bar is
165
+ reproducibility: every statistical result must be justified by a published
166
+ formula or an independently generated reference value.
167
+
168
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow, the shape a new
169
+ power-analysis family is expected to take, and how to supply reference values.
170
+
171
+ Participation is governed by the [Code of Conduct](CODE_OF_CONDUCT.md).
172
+
173
+ ### Found a wrong number?
174
+
175
+ If `stat_power` disagrees with `pwr`, R, G*Power or a textbook, that is the
176
+ highest-priority class of bug here. Open an issue using the **Numerical
177
+ discrepancy** template.
178
+
179
+ ## Security
180
+
181
+ See [SECURITY.md](SECURITY.md) for supported versions and how to report a
182
+ vulnerability privately. A numerically incorrect result is a bug, not a
183
+ vulnerability; report those as ordinary issues.
184
+
146
185
  ## Mathematical conventions
147
186
 
148
187
  See [docs/mathematical_conventions.md](docs/mathematical_conventions.md).
@@ -98,7 +98,7 @@ module StatPower
98
98
  break if mixture_converged?(weight_sum, lower_weight, upper_weight)
99
99
  end
100
100
 
101
- [[total, 0.0].max, 1.0].min
101
+ total.clamp(0.0, 1.0)
102
102
  end
103
103
  private_class_method :poisson_mixture
104
104
 
@@ -110,7 +110,7 @@ module StatPower
110
110
  break if mixture_converged?(weight_sum, lower_weight, upper_weight)
111
111
  end
112
112
 
113
- [[total, 0.0].max, 1.0].min
113
+ total.clamp(0.0, 1.0)
114
114
  end
115
115
  private_class_method :poisson_beta_mixture
116
116
 
@@ -48,7 +48,7 @@ module StatPower
48
48
  )
49
49
  end
50
50
 
51
- [[result, 0.0].max, 1.0].min
51
+ result.clamp(0.0, 1.0)
52
52
  end
53
53
 
54
54
  # Survival function P(T > x).
@@ -45,14 +45,7 @@ module StatPower
45
45
  def association(probabilities:)
46
46
  table = probability_table!(probabilities)
47
47
  row_totals = table.map(&:sum)
48
- column_count = table.first.length
49
- column_totals = Array.new(column_count, 0.0)
50
-
51
- table.each do |row|
52
- row.each_with_index do |value, column|
53
- column_totals[column] += value
54
- end
55
- end
48
+ column_totals = table.transpose.map(&:sum)
56
49
 
57
50
  if row_totals.any?(&:zero?) || column_totals.any?(&:zero?)
58
51
  raise StatPower::DomainError,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StatPower
4
- VERSION = "0.1.0.alpha.2"
4
+ VERSION = "0.1.0.alpha.3"
5
5
  end
data/sig/stat_power.rbs CHANGED
@@ -279,7 +279,7 @@ module StatPower
279
279
  module PowerCurve
280
280
  def self.generate: (
281
281
  sample_sizes: Enumerable[Numeric]
282
- ) { (Float) -> Numeric | PowerResult | UnequalPowerResult | AnovaResult | F2Result | ChiSquareResult } -> Array[PowerCurvePoint]
282
+ ) { (Float) -> (Numeric | PowerResult | UnequalPowerResult | AnovaResult | F2Result | ChiSquareResult) } -> Array[PowerCurvePoint]
283
283
  end
284
284
 
285
285
  module SpecialFunctions
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stat_power
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha.2
4
+ version: 0.1.0.alpha.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Diogo Ribeiro
@@ -13,6 +13,7 @@ dependencies: []
13
13
  description: Native Ruby tools for statistical power analysis, sample-size determination,
14
14
  effect-size calculations, and inverse power problems.
15
15
  email:
16
+ - dfr@esmad.ipp.pt
16
17
  executables: []
17
18
  extensions: []
18
19
  extra_rdoc_files: []
@@ -20,7 +21,6 @@ files:
20
21
  - CHANGELOG.md
21
22
  - LICENSE
22
23
  - README.md
23
- - RELEASING.md
24
24
  - ROADMAP.md
25
25
  - docs/mathematical_conventions.md
26
26
  - docs/pwr_parity.md
@@ -63,7 +63,9 @@ homepage: https://github.com/DiogoRibeiro7/stat_power
63
63
  licenses:
64
64
  - MIT
65
65
  metadata:
66
- source_code_uri: https://github.com/DiogoRibeiro7/stat_power
66
+ homepage_uri: https://github.com/DiogoRibeiro7/stat_power
67
+ source_code_uri: https://github.com/DiogoRibeiro7/stat_power/tree/v0.1.0.alpha.3
68
+ bug_tracker_uri: https://github.com/DiogoRibeiro7/stat_power/issues
67
69
  changelog_uri: https://github.com/DiogoRibeiro7/stat_power/blob/main/CHANGELOG.md
68
70
  documentation_uri: https://github.com/DiogoRibeiro7/stat_power#readme
69
71
  rubygems_mfa_required: 'true'
@@ -80,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
82
  requirements:
81
83
  - - ">="
82
84
  - !ruby/object:Gem::Version
83
- version: '0'
85
+ version: '3.4'
84
86
  requirements: []
85
87
  rubygems_version: 3.5.22
86
88
  signing_key:
data/RELEASING.md DELETED
@@ -1,113 +0,0 @@
1
- # Releasing stat_power
2
-
3
- This project uses prerelease versions until the public API is ready to stabilize.
4
-
5
- ## RubyGems trusted publishing
6
-
7
- RubyGems Trusted Publishing allows GitHub Actions to publish without storing a
8
- long-lived RubyGems API key.
9
-
10
- The trusted publisher for `stat_power` must match:
11
-
12
- - Gem name: `stat_power`
13
- - Repository owner: `DiogoRibeiro7`
14
- - Repository name: `stat_power`
15
- - Workflow filename: `release.yml`
16
- - Environment: `release`
17
-
18
- The workflow is stored at `.github/workflows/release.yml`.
19
-
20
- ## Alpha release checklist
21
-
22
- 1. Ensure all CI jobs are green on `main`.
23
- 2. Confirm `lib/stat_power/version.rb` contains the intended version.
24
- 3. Move the release entries in `CHANGELOG.md` out of `Unreleased`.
25
- 4. Build the gem locally:
26
-
27
- ```bash
28
- gem build stat_power.gemspec
29
- ```
30
-
31
- 5. Inspect the built package:
32
-
33
- ```bash
34
- gem specification stat_power-*.gem name version files --yaml
35
- ```
36
-
37
- 6. Install the built gem into a clean location:
38
-
39
- ```bash
40
- GEM_HOME="$(mktemp -d)" gem install stat_power-*.gem --no-document
41
- ```
42
-
43
- 7. Run a smoke test against the installed package:
44
-
45
- ```bash
46
- ruby -e 'require "stat_power"; puts StatPower::VERSION'
47
- ```
48
-
49
- 8. Confirm the RubyGems trusted publisher still matches
50
- `.github/workflows/release.yml` and the `release` environment.
51
-
52
- 9. Create and push the release tag. For the current release:
53
-
54
- ```bash
55
- VERSION=0.1.0.alpha.2
56
- git checkout main
57
- git pull --ff-only
58
- git tag "v${VERSION}"
59
- git push origin "v${VERSION}"
60
- ```
61
-
62
- Pushing the tag triggers the release workflow. It validates that:
63
-
64
- - the tag matches `StatPower::VERSION`
65
- - the tagged commit is contained in `main`
66
- - the test suite passes
67
- - RuboCop passes
68
- - RBS signatures validate
69
- - the gem builds successfully
70
-
71
- The workflow requests short-lived RubyGems credentials through OIDC, pushes the
72
- already-built gem artifact with `gem push`, and creates a GitHub Release.
73
- Prerelease versions are marked as prereleases on GitHub automatically.
74
-
75
- ## Retrying a failed release
76
-
77
- If a release tag already exists but the workflow fails before RubyGems accepts
78
- the gem, do not create a new version merely to retry the same artifact.
79
-
80
- 1. Open **Actions → Release gem**.
81
- 2. Choose **Run workflow**.
82
- 3. Enter the existing tag, for example `v0.1.0.alpha.2`.
83
- 4. Run the workflow from `main`.
84
-
85
- The manual dispatch checks out the existing tag and publishes that exact
86
- artifact while using the latest release workflow definition from `main`.
87
-
88
- Once a version appears on RubyGems.org, it is immutable and must not be reused.
89
-
90
- ## After publishing
91
-
92
- Verify the public installation path:
93
-
94
- ```bash
95
- gem install stat_power --prerelease
96
- ```
97
-
98
- Then confirm:
99
-
100
- ```bash
101
- ruby -e 'require "stat_power"; puts StatPower::VERSION'
102
- ```
103
-
104
- For the current release the expected output is:
105
-
106
- ```text
107
- 0.1.0.alpha.2
108
- ```
109
-
110
- ## Failed releases after publication
111
-
112
- Once a version exists on RubyGems.org, do not overwrite or reuse that version.
113
- Increment the prerelease version and create a new tag.