philiprehberger-ring_buffer 0.1.5 → 0.2.0

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: f38ecf9b42695830add96e0218d665eb4f258d8b4765827d244b147dfa10827f
4
- data.tar.gz: a6b0ee06470c7283b5503cb5fac563cf6b5a6a27cfaca8371c856218608f4d66
3
+ metadata.gz: c769e36a185afb7b7b200d7fc7d29822c067460b135f64f32ca5157164f070fc
4
+ data.tar.gz: 40ce5c2dc5f27dc4aab0ebf8fe376e5e971c31acac25cb47248c7b212eadeeed
5
5
  SHA512:
6
- metadata.gz: 90759da53fd6a5aa40d1b1b9393944f81e9d47779d84c021223a810becafc4e72b3410c3a8d1ada1419a3bfdb08e2192524af6b02d4c9a09e77cd97c2246ff1f
7
- data.tar.gz: 7f7f091815c8d02ac0cf863dd99887241c2898ca2bd7df5e0f0a3a45f1d94d0d8561827ca4c2fbaa5bdde2ad7c5be4ba13f1abcc7f31b2c9deb2c643bfc2f2cb
6
+ metadata.gz: a9a1dc2bdbbe335dccf1607aea535bbf7baf21e5b1bcbcd3e4d05f49a84f0a13f927abdc1086b70d3019c13e6ed495105a25e1145f73550135851ef2b05a0c7a
7
+ data.tar.gz: 873932dfa685d64a5ceaa0d677241ffa821a917ced571dbbf5b97a737d53fcc85024ce28f6d01004b2045737bae0f1325a62f72607a6261bf8b6335a76b24716
data/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.0] - 2026-04-03
11
+
12
+ ### Added
13
+ - Index-based access via `[]` with positive and negative indices
14
+ - `first` method for accessing oldest elements
15
+ - `clear` method to reset buffer state
16
+ - Statistical methods: `variance`, `stddev`, `median`
17
+
18
+ ## [0.1.6] - 2026-03-31
19
+
20
+ ### Added
21
+ - Add GitHub issue templates, dependabot config, and PR template
22
+
10
23
  ## [0.1.5] - 2026-03-31
11
24
 
12
25
  ### Changed
data/README.md CHANGED
@@ -38,24 +38,51 @@ buf.to_a # => [2, 3, 4]
38
38
  buf.full? # => true
39
39
  ```
40
40
 
41
- ### Statistics
41
+ ### Index Access
42
42
 
43
43
  ```ruby
44
- buf = Philiprehberger::RingBuffer.new(100)
44
+ buf = Philiprehberger::RingBuffer.new(5)
45
45
  [10, 20, 30].each { |v| buf.push(v) }
46
46
 
47
- buf.average # => 20.0
48
- buf.sum # => 60
49
- buf.min # => 10
50
- buf.max # => 30
47
+ buf[0] # => 10 (oldest)
48
+ buf[-1] # => 30 (newest)
49
+ buf[99] # => nil (out of bounds)
51
50
  ```
52
51
 
53
- ### Last N Elements
52
+ ### First / Last Elements
54
53
 
55
54
  ```ruby
56
55
  buf = Philiprehberger::RingBuffer.new(10)
57
56
  (1..10).each { |v| buf.push(v) }
58
- buf.last(3) # => [8, 9, 10]
57
+
58
+ buf.first # => 1
59
+ buf.first(3) # => [1, 2, 3]
60
+ buf.last(3) # => [8, 9, 10]
61
+ ```
62
+
63
+ ### Clear
64
+
65
+ ```ruby
66
+ buf = Philiprehberger::RingBuffer.new(5)
67
+ [1, 2, 3].each { |v| buf.push(v) }
68
+ buf.clear
69
+ buf.size # => 0
70
+ buf.empty? # => true
71
+ ```
72
+
73
+ ### Statistics
74
+
75
+ ```ruby
76
+ buf = Philiprehberger::RingBuffer.new(100)
77
+ [10, 20, 30].each { |v| buf.push(v) }
78
+
79
+ buf.average # => 20.0
80
+ buf.sum # => 60
81
+ buf.min # => 10
82
+ buf.max # => 30
83
+ buf.variance # => 66.66666666666667
84
+ buf.stddev # => 8.16496580927726
85
+ buf.median # => 20.0
59
86
  ```
60
87
 
61
88
  ### Enumerable
@@ -73,15 +100,21 @@ buf.select(&:odd?) # => [1, 3]
73
100
  |--------|-------------|
74
101
  | `RingBuffer.new(capacity)` | Create a buffer with fixed capacity |
75
102
  | `#push(value)` | Add a value, overwriting oldest if full |
103
+ | `#[](index)` | Access by index (0 = oldest, -1 = newest) |
76
104
  | `#to_a` | Convert to array (oldest first) |
77
105
  | `#size` | Number of elements in the buffer |
78
106
  | `#full?` | Whether the buffer is at capacity |
79
107
  | `#empty?` | Whether the buffer has no elements |
108
+ | `#first(n)` | First n elements (oldest) |
109
+ | `#last(n)` | Last n elements (most recent) |
110
+ | `#clear` | Remove all elements, reset state |
80
111
  | `#average` | Average of numeric elements |
81
112
  | `#sum` | Sum of numeric elements |
82
113
  | `#min` | Minimum element |
83
114
  | `#max` | Maximum element |
84
- | `#last(n)` | Last n elements (most recent) |
115
+ | `#variance` | Population variance |
116
+ | `#stddev` | Population standard deviation |
117
+ | `#median` | Median value |
85
118
 
86
119
  ## Development
87
120
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  class RingBuffer
5
- VERSION = '0.1.5'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
@@ -113,6 +113,73 @@ module Philiprehberger
113
113
  arr.last(n)
114
114
  end
115
115
 
116
+ # Access element by index (0 = oldest, -1 = newest)
117
+ #
118
+ # @param index [Integer]
119
+ # @return [Object, nil]
120
+ def [](index)
121
+ arr = to_a
122
+ return nil if arr.empty?
123
+ return nil if index >= arr.length || index < -arr.length
124
+
125
+ arr[index]
126
+ end
127
+
128
+ # Return the oldest n elements
129
+ #
130
+ # @param n [Integer] number of elements (default 1)
131
+ # @return [Object, Array]
132
+ def first(n = 1)
133
+ arr = to_a
134
+ return arr.first if n == 1
135
+
136
+ arr.first(n)
137
+ end
138
+
139
+ # Remove all elements and reset internal state
140
+ #
141
+ # @return [self]
142
+ def clear
143
+ @buffer = Array.new(@capacity)
144
+ @head = 0
145
+ @count = 0
146
+ self
147
+ end
148
+
149
+ # Population variance of numeric elements
150
+ #
151
+ # @return [Float]
152
+ def variance
153
+ return 0.0 if @count <= 1
154
+
155
+ avg = average
156
+ arr = to_a
157
+ arr.sum { |v| (v - avg)**2 } / arr.length.to_f
158
+ end
159
+
160
+ # Population standard deviation of numeric elements
161
+ #
162
+ # @return [Float]
163
+ def stddev
164
+ Math.sqrt(variance)
165
+ end
166
+
167
+ # Median value of numeric elements
168
+ #
169
+ # @return [Float, nil]
170
+ def median
171
+ return nil if empty?
172
+
173
+ sorted = to_a.sort
174
+ mid = sorted.length / 2
175
+
176
+ if sorted.length.odd?
177
+ sorted[mid].to_f
178
+ else
179
+ (sorted[mid - 1] + sorted[mid]) / 2.0
180
+ end
181
+ end
182
+
116
183
  # Iterate over elements (oldest first)
117
184
  #
118
185
  # @yield [element]
metadata CHANGED
@@ -1,18 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-ring_buffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-31 00:00:00.000000000 Z
11
+ date: 2026-04-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Fixed-capacity ring buffer that overwrites oldest entries on overflow,
14
- with built-in statistics (average, sum, min, max), last-n retrieval, and Enumerable
15
- support.
14
+ with index access, built-in statistics (average, sum, min, max, variance, stddev,
15
+ median), first/last-n retrieval, and Enumerable support.
16
16
  email:
17
17
  - me@philiprehberger.com
18
18
  executables: []
@@ -24,11 +24,11 @@ files:
24
24
  - README.md
25
25
  - lib/philiprehberger/ring_buffer.rb
26
26
  - lib/philiprehberger/ring_buffer/version.rb
27
- homepage: https://github.com/philiprehberger/rb-ring-buffer
27
+ homepage: https://philiprehberger.com/open-source-packages/ruby/philiprehberger-ring_buffer
28
28
  licenses:
29
29
  - MIT
30
30
  metadata:
31
- homepage_uri: https://github.com/philiprehberger/rb-ring-buffer
31
+ homepage_uri: https://philiprehberger.com/open-source-packages/ruby/philiprehberger-ring_buffer
32
32
  source_code_uri: https://github.com/philiprehberger/rb-ring-buffer
33
33
  changelog_uri: https://github.com/philiprehberger/rb-ring-buffer/blob/main/CHANGELOG.md
34
34
  bug_tracker_uri: https://github.com/philiprehberger/rb-ring-buffer/issues