active_recall 2.0.2 → 2.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.
@@ -0,0 +1,259 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ active_recall (2.2.0)
5
+ activerecord (>= 7.0, < 9.0)
6
+ activesupport (>= 7.0, < 9.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (8.0.1)
12
+ actionpack (= 8.0.1)
13
+ activesupport (= 8.0.1)
14
+ nio4r (~> 2.0)
15
+ websocket-driver (>= 0.6.1)
16
+ zeitwerk (~> 2.6)
17
+ actionmailbox (8.0.1)
18
+ actionpack (= 8.0.1)
19
+ activejob (= 8.0.1)
20
+ activerecord (= 8.0.1)
21
+ activestorage (= 8.0.1)
22
+ activesupport (= 8.0.1)
23
+ mail (>= 2.8.0)
24
+ actionmailer (8.0.1)
25
+ actionpack (= 8.0.1)
26
+ actionview (= 8.0.1)
27
+ activejob (= 8.0.1)
28
+ activesupport (= 8.0.1)
29
+ mail (>= 2.8.0)
30
+ rails-dom-testing (~> 2.2)
31
+ actionpack (8.0.1)
32
+ actionview (= 8.0.1)
33
+ activesupport (= 8.0.1)
34
+ nokogiri (>= 1.8.5)
35
+ rack (>= 2.2.4)
36
+ rack-session (>= 1.0.1)
37
+ rack-test (>= 0.6.3)
38
+ rails-dom-testing (~> 2.2)
39
+ rails-html-sanitizer (~> 1.6)
40
+ useragent (~> 0.16)
41
+ actiontext (8.0.1)
42
+ actionpack (= 8.0.1)
43
+ activerecord (= 8.0.1)
44
+ activestorage (= 8.0.1)
45
+ activesupport (= 8.0.1)
46
+ globalid (>= 0.6.0)
47
+ nokogiri (>= 1.8.5)
48
+ actionview (8.0.1)
49
+ activesupport (= 8.0.1)
50
+ builder (~> 3.1)
51
+ erubi (~> 1.11)
52
+ rails-dom-testing (~> 2.2)
53
+ rails-html-sanitizer (~> 1.6)
54
+ activejob (8.0.1)
55
+ activesupport (= 8.0.1)
56
+ globalid (>= 0.3.6)
57
+ activemodel (8.0.1)
58
+ activesupport (= 8.0.1)
59
+ activerecord (8.0.1)
60
+ activemodel (= 8.0.1)
61
+ activesupport (= 8.0.1)
62
+ timeout (>= 0.4.0)
63
+ activestorage (8.0.1)
64
+ actionpack (= 8.0.1)
65
+ activejob (= 8.0.1)
66
+ activerecord (= 8.0.1)
67
+ activesupport (= 8.0.1)
68
+ marcel (~> 1.0)
69
+ activesupport (8.0.1)
70
+ base64
71
+ benchmark (>= 0.3)
72
+ bigdecimal
73
+ concurrent-ruby (~> 1.0, >= 1.3.1)
74
+ connection_pool (>= 2.2.5)
75
+ drb
76
+ i18n (>= 1.6, < 2)
77
+ logger (>= 1.4.2)
78
+ minitest (>= 5.1)
79
+ securerandom (>= 0.3)
80
+ tzinfo (~> 2.0, >= 2.0.5)
81
+ uri (>= 0.13.1)
82
+ appraisal (2.5.0)
83
+ bundler
84
+ rake
85
+ thor (>= 0.14.0)
86
+ ast (2.4.2)
87
+ base64 (0.2.0)
88
+ benchmark (0.4.0)
89
+ bigdecimal (3.1.9)
90
+ builder (3.3.0)
91
+ concurrent-ruby (1.3.4)
92
+ connection_pool (2.4.1)
93
+ crass (1.0.6)
94
+ date (3.4.1)
95
+ diff-lcs (1.5.1)
96
+ drb (2.2.1)
97
+ erubi (1.13.1)
98
+ globalid (1.2.1)
99
+ activesupport (>= 6.1)
100
+ i18n (1.14.6)
101
+ concurrent-ruby (~> 1.0)
102
+ io-console (0.8.0)
103
+ irb (1.14.3)
104
+ rdoc (>= 4.0.0)
105
+ reline (>= 0.4.2)
106
+ json (2.9.1)
107
+ language_server-protocol (3.17.0.3)
108
+ lint_roller (1.1.0)
109
+ logger (1.6.4)
110
+ loofah (2.23.1)
111
+ crass (~> 1.0.2)
112
+ nokogiri (>= 1.12.0)
113
+ mail (2.8.1)
114
+ mini_mime (>= 0.1.1)
115
+ net-imap
116
+ net-pop
117
+ net-smtp
118
+ marcel (1.0.4)
119
+ mini_mime (1.1.5)
120
+ minitest (5.25.4)
121
+ net-imap (0.5.4)
122
+ date
123
+ net-protocol
124
+ net-pop (0.1.2)
125
+ net-protocol
126
+ net-protocol (0.2.2)
127
+ timeout
128
+ net-smtp (0.5.0)
129
+ net-protocol
130
+ nio4r (2.7.4)
131
+ nokogiri (1.18.0-arm64-darwin)
132
+ racc (~> 1.4)
133
+ parallel (1.26.3)
134
+ parser (3.3.6.0)
135
+ ast (~> 2.4.1)
136
+ racc
137
+ psych (5.2.2)
138
+ date
139
+ stringio
140
+ racc (1.8.1)
141
+ rack (3.1.8)
142
+ rack-session (2.0.0)
143
+ rack (>= 3.0.0)
144
+ rack-test (2.2.0)
145
+ rack (>= 1.3)
146
+ rackup (2.2.1)
147
+ rack (>= 3)
148
+ rails (8.0.1)
149
+ actioncable (= 8.0.1)
150
+ actionmailbox (= 8.0.1)
151
+ actionmailer (= 8.0.1)
152
+ actionpack (= 8.0.1)
153
+ actiontext (= 8.0.1)
154
+ actionview (= 8.0.1)
155
+ activejob (= 8.0.1)
156
+ activemodel (= 8.0.1)
157
+ activerecord (= 8.0.1)
158
+ activestorage (= 8.0.1)
159
+ activesupport (= 8.0.1)
160
+ bundler (>= 1.15.0)
161
+ railties (= 8.0.1)
162
+ rails-dom-testing (2.2.0)
163
+ activesupport (>= 5.0.0)
164
+ minitest
165
+ nokogiri (>= 1.6)
166
+ rails-html-sanitizer (1.6.2)
167
+ loofah (~> 2.21)
168
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
169
+ railties (8.0.1)
170
+ actionpack (= 8.0.1)
171
+ activesupport (= 8.0.1)
172
+ irb (~> 1.13)
173
+ rackup (>= 1.0.0)
174
+ rake (>= 12.2)
175
+ thor (~> 1.0, >= 1.2.2)
176
+ zeitwerk (~> 2.6)
177
+ rainbow (3.1.1)
178
+ rake (13.2.1)
179
+ rdoc (6.10.0)
180
+ psych (>= 4.0.0)
181
+ regexp_parser (2.10.0)
182
+ reline (0.6.0)
183
+ io-console (~> 0.5)
184
+ rspec (3.13.0)
185
+ rspec-core (~> 3.13.0)
186
+ rspec-expectations (~> 3.13.0)
187
+ rspec-mocks (~> 3.13.0)
188
+ rspec-core (3.13.2)
189
+ rspec-support (~> 3.13.0)
190
+ rspec-expectations (3.13.3)
191
+ diff-lcs (>= 1.2.0, < 2.0)
192
+ rspec-support (~> 3.13.0)
193
+ rspec-mocks (3.13.2)
194
+ diff-lcs (>= 1.2.0, < 2.0)
195
+ rspec-support (~> 3.13.0)
196
+ rspec-support (3.13.2)
197
+ rubocop (1.69.2)
198
+ json (~> 2.3)
199
+ language_server-protocol (>= 3.17.0)
200
+ parallel (~> 1.10)
201
+ parser (>= 3.3.0.2)
202
+ rainbow (>= 2.2.2, < 4.0)
203
+ regexp_parser (>= 2.9.3, < 3.0)
204
+ rubocop-ast (>= 1.36.2, < 2.0)
205
+ ruby-progressbar (~> 1.7)
206
+ unicode-display_width (>= 2.4.0, < 4.0)
207
+ rubocop-ast (1.37.0)
208
+ parser (>= 3.3.1.0)
209
+ rubocop-performance (1.23.0)
210
+ rubocop (>= 1.48.1, < 2.0)
211
+ rubocop-ast (>= 1.31.1, < 2.0)
212
+ ruby-progressbar (1.13.0)
213
+ securerandom (0.4.1)
214
+ sqlite3 (2.5.0-arm64-darwin)
215
+ standard (1.43.0)
216
+ language_server-protocol (~> 3.17.0.2)
217
+ lint_roller (~> 1.0)
218
+ rubocop (~> 1.69.1)
219
+ standard-custom (~> 1.0.0)
220
+ standard-performance (~> 1.6)
221
+ standard-custom (1.0.2)
222
+ lint_roller (~> 1.0)
223
+ rubocop (~> 1.50)
224
+ standard-performance (1.6.0)
225
+ lint_roller (~> 1.1)
226
+ rubocop-performance (~> 1.23.0)
227
+ stringio (3.1.2)
228
+ thor (1.3.2)
229
+ timeout (0.4.3)
230
+ tzinfo (2.0.6)
231
+ concurrent-ruby (~> 1.0)
232
+ unicode-display_width (3.1.2)
233
+ unicode-emoji (~> 4.0, >= 4.0.4)
234
+ unicode-emoji (4.0.4)
235
+ uri (1.0.2)
236
+ useragent (0.16.11)
237
+ websocket-driver (0.7.6)
238
+ websocket-extensions (>= 0.1.0)
239
+ websocket-extensions (0.1.5)
240
+ zeitwerk (2.7.1)
241
+
242
+ PLATFORMS
243
+ arm64-darwin-23
244
+ arm64-darwin-24
245
+ arm64-darwin-25
246
+
247
+ DEPENDENCIES
248
+ active_recall!
249
+ appraisal
250
+ nokogiri (>= 1.16.2)
251
+ rails (~> 8.0)
252
+ rake (>= 12.0)
253
+ rdoc
254
+ rspec (>= 3.0)
255
+ sqlite3 (>= 2.1)
256
+ standard
257
+
258
+ BUNDLED WITH
259
+ 2.4.14
@@ -63,11 +63,10 @@ module ActiveRecall
63
63
  SEQUENCE = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765].freeze
64
64
 
65
65
  def fibonacci_number_at(index)
66
- if (0...SEQUENCE.length).cover?(index)
67
- SEQUENCE[index]
68
- else
69
- fibonacci_number_at(index - 1) + fibonacci_number_at(index - 2)
70
- end
66
+ return SEQUENCE[index] if (0...SEQUENCE.length).cover?(index)
67
+
68
+ @fibonacci_cache ||= {}
69
+ @fibonacci_cache[index] ||= fibonacci_number_at(index - 1) + fibonacci_number_at(index - 2)
71
70
  end
72
71
 
73
72
  def next_review
@@ -24,19 +24,24 @@ module ActiveRecall
24
24
  end
25
25
 
26
26
  def initialize(box:, easiness_factor:, times_right:, times_wrong:, grade:, current_time: Time.current)
27
- @box = box
27
+ @box = box # box serves as repetition number n
28
28
  @easiness_factor = easiness_factor || 2.5
29
29
  @times_right = times_right
30
30
  @times_wrong = times_wrong
31
31
  @grade = grade
32
32
  @current_time = current_time
33
- @interval = [1, box].max
33
+ @interval = case box
34
+ when 0 then 1 # First review
35
+ when 1 then 6 # Second review
36
+ else 17 # Will be overwritten for boxes > 1
37
+ end
34
38
  end
35
39
 
36
40
  def score
37
41
  raise "Grade must be between 0-5!" unless GRADES.include?(@grade)
38
- update_easiness_factor
39
- update_repetition_and_interval
42
+ old_ef = @easiness_factor
43
+ update_easiness_factor if @grade >= 3
44
+ update_repetition_and_interval(old_ef)
40
45
 
41
46
  {
42
47
  box: @box,
@@ -51,13 +56,14 @@ module ActiveRecall
51
56
  private
52
57
 
53
58
  GRADES = [
54
- 5, # Perfect response. The learner recalls the information without hesitation.
55
- 4, # Correct response after a hesitation. The learner recalls the information but with some difficulty.
56
- 3, # Correct response recalled with serious difficulty. The learner struggles but eventually recalls the information.
57
- 2, # Incorrect response, but the learner was very close to the correct answer. This might involve recalling some of the information correctly but not all of it.
58
- 1, # Incorrect response, but the learner feels they should have remembered it. This is typically used when the learner has a sense of familiarity with the material but fails to recall it correctly.
59
- 0 # Complete blackout. The learner does not recall the information at all.
59
+ 5, # Perfect response
60
+ 4, # Correct response after a hesitation
61
+ 3, # Correct response recalled with serious difficulty
62
+ 2, # Incorrect response, but close
63
+ 1, # Incorrect response with familiarity
64
+ 0 # Complete blackout
60
65
  ].freeze
66
+
61
67
  REQUIRED_ATTRIBUTES = [
62
68
  :box,
63
69
  :easiness_factor,
@@ -71,22 +77,23 @@ module ActiveRecall
71
77
  @easiness_factor = [@easiness_factor, MIN_EASINESS_FACTOR].max
72
78
  end
73
79
 
74
- def update_repetition_and_interval
80
+ def update_repetition_and_interval(old_ef)
75
81
  if @grade >= 3
76
- @box += 1
77
- @times_right += 1
78
- @interval = case @box
79
- when 1
82
+ @interval = if @box == 0
80
83
  1
81
- when 2
84
+ elsif @box == 1
82
85
  6
83
86
  else
84
- (@interval || 1) * @easiness_factor
87
+ # Apply exponential scaling based on the box number
88
+ (6 * (old_ef**(@box - 1))).round
85
89
  end
90
+
91
+ @box += 1
92
+ @times_right += 1
86
93
  else
87
94
  @box = 0
88
- @times_wrong += 1
89
95
  @interval = 1
96
+ @times_wrong += 1
90
97
  end
91
98
  end
92
99
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecall
4
- VERSION = "2.0.2"
4
+ VERSION = "2.2.0"
5
5
  end
data/standard.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  fix: true
2
2
  parallel: true
3
- ruby_version: 3.0
3
+ ruby_version: 3.2
data/tmp/.gitkeep ADDED
File without changes
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_recall
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Gravina
8
8
  - Jayson Virissimo
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2024-04-29 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: appraisal
@@ -31,20 +30,20 @@ dependencies:
31
30
  requirements:
32
31
  - - ">="
33
32
  - !ruby/object:Gem::Version
34
- version: '6.0'
35
- - - "<="
33
+ version: '7.0'
34
+ - - "<"
36
35
  - !ruby/object:Gem::Version
37
- version: '7.2'
36
+ version: '9.0'
38
37
  type: :development
39
38
  prerelease: false
40
39
  version_requirements: !ruby/object:Gem::Requirement
41
40
  requirements:
42
41
  - - ">="
43
42
  - !ruby/object:Gem::Version
44
- version: '6.0'
45
- - - "<="
43
+ version: '7.0'
44
+ - - "<"
46
45
  - !ruby/object:Gem::Version
47
- version: '7.2'
46
+ version: '9.0'
48
47
  - !ruby/object:Gem::Dependency
49
48
  name: rake
50
49
  requirement: !ruby/object:Gem::Requirement
@@ -91,16 +90,16 @@ dependencies:
91
90
  name: sqlite3
92
91
  requirement: !ruby/object:Gem::Requirement
93
92
  requirements:
94
- - - ">="
93
+ - - "~>"
95
94
  - !ruby/object:Gem::Version
96
- version: '0'
95
+ version: '2.1'
97
96
  type: :development
98
97
  prerelease: false
99
98
  version_requirements: !ruby/object:Gem::Requirement
100
99
  requirements:
101
- - - ">="
100
+ - - "~>"
102
101
  - !ruby/object:Gem::Version
103
- version: '0'
102
+ version: '2.1'
104
103
  - !ruby/object:Gem::Dependency
105
104
  name: standard
106
105
  requirement: !ruby/object:Gem::Requirement
@@ -121,40 +120,40 @@ dependencies:
121
120
  requirements:
122
121
  - - ">="
123
122
  - !ruby/object:Gem::Version
124
- version: '6.0'
125
- - - "<="
123
+ version: '7.0'
124
+ - - "<"
126
125
  - !ruby/object:Gem::Version
127
- version: '7.2'
126
+ version: '9.0'
128
127
  type: :runtime
129
128
  prerelease: false
130
129
  version_requirements: !ruby/object:Gem::Requirement
131
130
  requirements:
132
131
  - - ">="
133
132
  - !ruby/object:Gem::Version
134
- version: '6.0'
135
- - - "<="
133
+ version: '7.0'
134
+ - - "<"
136
135
  - !ruby/object:Gem::Version
137
- version: '7.2'
136
+ version: '9.0'
138
137
  - !ruby/object:Gem::Dependency
139
138
  name: activesupport
140
139
  requirement: !ruby/object:Gem::Requirement
141
140
  requirements:
142
141
  - - ">="
143
142
  - !ruby/object:Gem::Version
144
- version: '6.0'
145
- - - "<="
143
+ version: '7.0'
144
+ - - "<"
146
145
  - !ruby/object:Gem::Version
147
- version: '7.2'
146
+ version: '9.0'
148
147
  type: :runtime
149
148
  prerelease: false
150
149
  version_requirements: !ruby/object:Gem::Requirement
151
150
  requirements:
152
151
  - - ">="
153
152
  - !ruby/object:Gem::Version
154
- version: '6.0'
155
- - - "<="
153
+ version: '7.0'
154
+ - - "<"
156
155
  - !ruby/object:Gem::Version
157
- version: '7.2'
156
+ version: '9.0'
158
157
  description: A spaced-repetition system to be used with ActiveRecord models
159
158
  email:
160
159
  - robert.gravina@gmail.com
@@ -168,6 +167,7 @@ files:
168
167
  - ".rspec"
169
168
  - ".tool-versions"
170
169
  - Appraisals
170
+ - CLAUDE.md
171
171
  - Gemfile
172
172
  - Gemfile.lock
173
173
  - LICENSE
@@ -175,17 +175,16 @@ files:
175
175
  - Rakefile
176
176
  - active_recall.gemspec
177
177
  - bin/console
178
+ - bin/flatten
178
179
  - bin/lint
179
180
  - bin/setup
180
181
  - bin/spec
181
- - gemfiles/rails_6_0.gemfile
182
- - gemfiles/rails_6_0.gemfile.lock
183
- - gemfiles/rails_6_1.gemfile
184
- - gemfiles/rails_6_1.gemfile.lock
185
182
  - gemfiles/rails_7_0.gemfile
186
183
  - gemfiles/rails_7_0.gemfile.lock
187
184
  - gemfiles/rails_7_1.gemfile
188
185
  - gemfiles/rails_7_1.gemfile.lock
186
+ - gemfiles/rails_8_0.gemfile
187
+ - gemfiles/rails_8_0.gemfile.lock
189
188
  - lib/active_recall.rb
190
189
  - lib/active_recall/algorithms/fibonacci_sequence.rb
191
190
  - lib/active_recall/algorithms/leitner_system.rb
@@ -204,12 +203,12 @@ files:
204
203
  - lib/generators/active_recall/templates/create_active_recall_tables.rb
205
204
  - lib/generators/active_recall/templates/migrate_okubo_to_active_recall.rb
206
205
  - standard.yml
206
+ - tmp/.gitkeep
207
207
  homepage: https://github.com/jaysonvirissimo/active_recall
208
208
  licenses:
209
209
  - MIT
210
210
  metadata:
211
211
  allowed_push_host: https://rubygems.org/
212
- post_install_message:
213
212
  rdoc_options: []
214
213
  require_paths:
215
214
  - lib
@@ -217,15 +216,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
216
  requirements:
218
217
  - - ">="
219
218
  - !ruby/object:Gem::Version
220
- version: '3.0'
219
+ version: '3.2'
221
220
  required_rubygems_version: !ruby/object:Gem::Requirement
222
221
  requirements:
223
222
  - - ">="
224
223
  - !ruby/object:Gem::Version
225
224
  version: '0'
226
225
  requirements: []
227
- rubygems_version: 3.5.3
228
- signing_key:
226
+ rubygems_version: 3.6.9
229
227
  specification_version: 4
230
228
  summary: A spaced-repetition system
231
229
  test_files: []