forgetful 0.0.4
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.
- data/Manifest +10 -0
- data/README +51 -0
- data/bin/forgetful +75 -0
- data/examples/katakana_romanji.csv +71 -0
- data/examples/romanji_katakana.csv +71 -0
- data/forgetful.gemspec +34 -0
- data/lib/csv_ext/reminder.rb +24 -0
- data/lib/forgetful.rb +7 -0
- data/lib/reminder.rb +45 -0
- data/test/test_forgetful.rb +0 -0
- metadata +83 -0
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
A minimal command-line app implementing the SuperMemo 2 algorithm.
|
3
|
+
|
4
|
+
The SuperMemo algorithm is designed to refresh your memory at
|
5
|
+
intervals based on how well you remembered something.
|
6
|
+
|
7
|
+
Put question-answer pairs in a file. Everyday, feed the file to forgetful and
|
8
|
+
it will quiz you on what you need to remember today. Based on your
|
9
|
+
self-evaluation, forgetful will reschedule at an appropriate time in the
|
10
|
+
future.
|
11
|
+
|
12
|
+
Usage:
|
13
|
+
|
14
|
+
forgetful filename.csv [more filenames]
|
15
|
+
|
16
|
+
Format:
|
17
|
+
|
18
|
+
A CSV file to contain your questions and answers, in the following format:
|
19
|
+
|
20
|
+
question,answer
|
21
|
+
|
22
|
+
Flow:
|
23
|
+
|
24
|
+
1. shows question (press enter)
|
25
|
+
2. shows answer
|
26
|
+
3. asks for self-evaluation (type number, and enter)
|
27
|
+
4. repeats for all questions
|
28
|
+
5. repeats for questions that scored less than 4
|
29
|
+
|
30
|
+
Self-evaluation:
|
31
|
+
|
32
|
+
5 - perfect response
|
33
|
+
4 - correct response after a hesitation
|
34
|
+
3 - correct response recalled with serious difficulty
|
35
|
+
2 - incorrect response; where the correct one seemed easy to recall
|
36
|
+
1 - incorrect response; the correct one remembered
|
37
|
+
0 - complete blackout.
|
38
|
+
|
39
|
+
WARNING:
|
40
|
+
|
41
|
+
Statistics are written back to the input file. This is a feature. Put your CSV
|
42
|
+
files under source control to keep a history.
|
43
|
+
|
44
|
+
Enjoy!
|
45
|
+
|
46
|
+
############################################################
|
47
|
+
|
48
|
+
The article that sparked my interest: http://www.wired.com/medtech/health/magazine/16-05/ff_wozniak
|
49
|
+
|
50
|
+
The algorithm itself: http://www.supermemo.com/english/ol/sm2.htm
|
51
|
+
|
data/bin/forgetful
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$VERBOSE = true
|
3
|
+
|
4
|
+
############################################################
|
5
|
+
|
6
|
+
require "#{File.dirname(__FILE__)}/../lib/forgetful"
|
7
|
+
|
8
|
+
############################################################
|
9
|
+
|
10
|
+
def ask(prompt, validate_re=//)
|
11
|
+
while true
|
12
|
+
print prompt
|
13
|
+
answer = readline.chomp
|
14
|
+
|
15
|
+
return answer.to_i if answer =~ validate_re
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#-------------------------------------------------
|
20
|
+
|
21
|
+
def ask_grade(prompt)
|
22
|
+
ask(prompt, /\A[0-5]\Z/)
|
23
|
+
end
|
24
|
+
|
25
|
+
#-------------------------------------------------
|
26
|
+
|
27
|
+
def ask_about(reminder, i, n)
|
28
|
+
ask("#{i}/#{n}. Q: #{reminder.question}")
|
29
|
+
puts " A: #{reminder.answer}"
|
30
|
+
q = ask_grade(" ? ")
|
31
|
+
puts
|
32
|
+
return q
|
33
|
+
end
|
34
|
+
|
35
|
+
#-------------------------------------------------
|
36
|
+
|
37
|
+
def quiz(reminders)
|
38
|
+
i = 0
|
39
|
+
reminders.collect do |reminder|
|
40
|
+
i += 1
|
41
|
+
reminder.next(ask_about(reminder, i, reminders.size))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
############################################################
|
46
|
+
|
47
|
+
def process_file(filename)
|
48
|
+
#--------------------- quiz ----------------------
|
49
|
+
reminders = Reminder.load_csv(filename)
|
50
|
+
|
51
|
+
dues, not_dues = reminders.partition {|reminder| reminder.execute_on <= Date.today}
|
52
|
+
|
53
|
+
puts "### QUIZ: #{filename}"
|
54
|
+
gradeds = quiz(dues.sort_by { rand })
|
55
|
+
|
56
|
+
Reminder.save_csv(filename, (gradeds + not_dues).sort)
|
57
|
+
|
58
|
+
#-------------------- review ---------------------
|
59
|
+
faileds = gradeds.select {|reminder| reminder.review? }
|
60
|
+
until faileds.empty?
|
61
|
+
puts "# REVIEW: #{filename}"
|
62
|
+
gradeds = quiz(faileds.sort_by { rand }) # review
|
63
|
+
faileds = gradeds.select {|reminder| reminder.review? }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
############################################################
|
68
|
+
|
69
|
+
filenames = ARGV.dup
|
70
|
+
ARGV.clear
|
71
|
+
|
72
|
+
filenames.each do |filename|
|
73
|
+
process_file filename
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
ア,a
|
2
|
+
バ,ba
|
3
|
+
ベ,be
|
4
|
+
ビ,bi
|
5
|
+
ボ,bo
|
6
|
+
ブ,bu
|
7
|
+
チ,chi
|
8
|
+
ダ,da
|
9
|
+
デ,de
|
10
|
+
ヂ,di (ji)
|
11
|
+
ド,do
|
12
|
+
ヅ,du (zu)
|
13
|
+
エ,e
|
14
|
+
フ,fu
|
15
|
+
ガ,ga
|
16
|
+
ゲ,ge
|
17
|
+
ギ,gi
|
18
|
+
ゴ,go
|
19
|
+
グ,gu
|
20
|
+
ハ,ha
|
21
|
+
ヘ,he
|
22
|
+
ヒ,hi
|
23
|
+
ホ,ho
|
24
|
+
イ,i
|
25
|
+
ジ,ji
|
26
|
+
カ,ka
|
27
|
+
ケ,ke
|
28
|
+
キ,ki
|
29
|
+
コ,ko
|
30
|
+
ク,ku
|
31
|
+
マ,ma
|
32
|
+
メ,me
|
33
|
+
ミ,mi
|
34
|
+
モ,mo
|
35
|
+
ム,mu
|
36
|
+
ン,n
|
37
|
+
ナ,na
|
38
|
+
ネ,ne
|
39
|
+
ニ,ni
|
40
|
+
ノ,no
|
41
|
+
ヌ,nu
|
42
|
+
オ,o
|
43
|
+
パ,pa
|
44
|
+
ペ,pe
|
45
|
+
ピ,pi
|
46
|
+
ポ,po
|
47
|
+
プ,pu
|
48
|
+
ラ,ra
|
49
|
+
レ,re
|
50
|
+
リ,ri
|
51
|
+
ロ,ro
|
52
|
+
ル,ru
|
53
|
+
サ,sa
|
54
|
+
セ,se
|
55
|
+
シ,shi
|
56
|
+
ソ,so
|
57
|
+
ス,su
|
58
|
+
タ,ta
|
59
|
+
テ,te
|
60
|
+
ト,to
|
61
|
+
ツ,tsu
|
62
|
+
ウ,u
|
63
|
+
ワ,wa
|
64
|
+
ヲ,wo
|
65
|
+
ヤ,ya
|
66
|
+
ヨ,yo
|
67
|
+
ユ,yu
|
68
|
+
ザ,za
|
69
|
+
ゼ,ze
|
70
|
+
ゾ,zo
|
71
|
+
ズ,zu
|
@@ -0,0 +1,71 @@
|
|
1
|
+
a,ア
|
2
|
+
ba,バ
|
3
|
+
be,ベ
|
4
|
+
bi,ビ
|
5
|
+
bo,ボ
|
6
|
+
bu,ブ
|
7
|
+
chi,チ
|
8
|
+
da,ダ
|
9
|
+
de,デ
|
10
|
+
di (ji),ヂ
|
11
|
+
do,ド
|
12
|
+
du (zu),ヅ
|
13
|
+
e,エ
|
14
|
+
fu,フ
|
15
|
+
ga,ガ
|
16
|
+
ge,ゲ
|
17
|
+
gi,ギ
|
18
|
+
go,ゴ
|
19
|
+
gu,グ
|
20
|
+
ha,ハ
|
21
|
+
he,ヘ
|
22
|
+
hi,ヒ
|
23
|
+
ho,ホ
|
24
|
+
i,イ
|
25
|
+
ji,ジ
|
26
|
+
ka,カ
|
27
|
+
ke,ケ
|
28
|
+
ki,キ
|
29
|
+
ko,コ
|
30
|
+
ku,ク
|
31
|
+
ma,マ
|
32
|
+
me,メ
|
33
|
+
mi,ミ
|
34
|
+
mo,モ
|
35
|
+
mu,ム
|
36
|
+
na,ナ
|
37
|
+
ne,ネ
|
38
|
+
ni,ニ
|
39
|
+
no,ノ
|
40
|
+
nu,ヌ
|
41
|
+
n,ン
|
42
|
+
o,オ
|
43
|
+
pa,パ
|
44
|
+
pe,ペ
|
45
|
+
pi,ピ
|
46
|
+
po,ポ
|
47
|
+
pu,プ
|
48
|
+
ra,ラ
|
49
|
+
re,レ
|
50
|
+
ri,リ
|
51
|
+
ro,ロ
|
52
|
+
ru,ル
|
53
|
+
sa,サ
|
54
|
+
se,セ
|
55
|
+
shi,シ
|
56
|
+
so,ソ
|
57
|
+
su,ス
|
58
|
+
ta,タ
|
59
|
+
te,テ
|
60
|
+
to,ト
|
61
|
+
tsu,ツ
|
62
|
+
u,ウ
|
63
|
+
wa,ワ
|
64
|
+
wo,ヲ
|
65
|
+
ya,ヤ
|
66
|
+
yo,ヨ
|
67
|
+
yu,ユ
|
68
|
+
za,ザ
|
69
|
+
ze,ゼ
|
70
|
+
zo,ゾ
|
71
|
+
zu,ズ
|
data/forgetful.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{forgetful}
|
3
|
+
s.version = "0.0.4"
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["Jonathan Palardy"]
|
7
|
+
s.date = %q{2008-11-12}
|
8
|
+
s.default_executable = %q{forgetful}
|
9
|
+
s.description = %q{A minimal command-line implementation of the SuperMemo 2 algorithm.}
|
10
|
+
s.email = %q{jonathan.palardy@gmail.com}
|
11
|
+
s.executables = ["forgetful"]
|
12
|
+
s.extra_rdoc_files = ["bin/forgetful", "lib/csv_ext/reminder.rb", "lib/forgetful.rb", "lib/reminder.rb", "README"]
|
13
|
+
s.files = ["bin/forgetful", "examples/katakana_romanji.csv", "examples/romanji_katakana.csv", "forgetful.gemspec", "lib/csv_ext/reminder.rb", "lib/forgetful.rb", "lib/reminder.rb", "Manifest", "README", "test/test_forgetful.rb"]
|
14
|
+
s.homepage = %q{http://github.com/jpalardy/forgetful}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Forgetful", "--main", "README"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{forgetful}
|
18
|
+
s.rubygems_version = %q{1.2.0}
|
19
|
+
s.summary = %q{A minimal command-line implementation of the SuperMemo 2 algorithm.}
|
20
|
+
s.test_files = ["test/test_forgetful.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 2
|
25
|
+
|
26
|
+
if current_version >= 3 then
|
27
|
+
s.add_runtime_dependency(%q<fastercsv>, [">= 0", "= 1.4"])
|
28
|
+
else
|
29
|
+
s.add_dependency(%q<fastercsv>, [">= 0", "= 1.4"])
|
30
|
+
end
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<fastercsv>, [">= 0", "= 1.4"])
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'fastercsv'
|
4
|
+
|
5
|
+
class Reminder
|
6
|
+
|
7
|
+
def self.load_csv(filename)
|
8
|
+
identity = lambda {|x| x}
|
9
|
+
|
10
|
+
FasterCSV.read(filename, :converters => [identity, identity, :integer, :integer, :date, :float, :integer]).collect do |list|
|
11
|
+
self.new(*list)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.save_csv(filename, reminders)
|
16
|
+
FasterCSV.open(filename, "w") do |csv|
|
17
|
+
reminders.each do |reminder|
|
18
|
+
csv << reminder.to_a
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
data/lib/forgetful.rb
ADDED
data/lib/reminder.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
class Reminder
|
3
|
+
attr_reader :question, :answer, :i, :interval, :execute_on, :ef, :q
|
4
|
+
|
5
|
+
def initialize(question, answer, i=0, interval=0, execute_on=Date.today, ef=2.5, q=nil)
|
6
|
+
@question = question
|
7
|
+
@answer = answer
|
8
|
+
@i = i
|
9
|
+
@interval = interval
|
10
|
+
@execute_on = execute_on
|
11
|
+
@ef = ef
|
12
|
+
@q = q
|
13
|
+
end
|
14
|
+
|
15
|
+
def next(q)
|
16
|
+
if q < 3
|
17
|
+
i = 0
|
18
|
+
interval = 1
|
19
|
+
else
|
20
|
+
i = self.i + 1
|
21
|
+
interval = {0 => 1, 1 => 6}.fetch(self.i, self.interval * self.ef).round
|
22
|
+
end
|
23
|
+
|
24
|
+
execute_on = Date.today + interval
|
25
|
+
|
26
|
+
ef = self.ef + (0.1 - (5-q) * (0.08 + (5-q) * 0.02))
|
27
|
+
ef = [ef, 1.3].max
|
28
|
+
|
29
|
+
Reminder.new(self.question, self.answer, i, interval, execute_on, ef, q)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_a
|
33
|
+
[self.question, self.answer, self.i, self.interval, self.execute_on, self.ef, self.q]
|
34
|
+
end
|
35
|
+
|
36
|
+
def <=>(other)
|
37
|
+
self.to_a <=> other.to_a
|
38
|
+
end
|
39
|
+
|
40
|
+
def review?
|
41
|
+
q < 4
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
File without changes
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: forgetful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Palardy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-12 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: fastercsv
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
- - "="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: "1.4"
|
27
|
+
version:
|
28
|
+
description: A minimal command-line implementation of the SuperMemo 2 algorithm.
|
29
|
+
email: jonathan.palardy@gmail.com
|
30
|
+
executables:
|
31
|
+
- forgetful
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files:
|
35
|
+
- bin/forgetful
|
36
|
+
- lib/csv_ext/reminder.rb
|
37
|
+
- lib/forgetful.rb
|
38
|
+
- lib/reminder.rb
|
39
|
+
- README
|
40
|
+
files:
|
41
|
+
- bin/forgetful
|
42
|
+
- examples/katakana_romanji.csv
|
43
|
+
- examples/romanji_katakana.csv
|
44
|
+
- forgetful.gemspec
|
45
|
+
- lib/csv_ext/reminder.rb
|
46
|
+
- lib/forgetful.rb
|
47
|
+
- lib/reminder.rb
|
48
|
+
- Manifest
|
49
|
+
- README
|
50
|
+
- test/test_forgetful.rb
|
51
|
+
has_rdoc: false
|
52
|
+
homepage: http://github.com/jpalardy/forgetful
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --line-numbers
|
56
|
+
- --inline-source
|
57
|
+
- --title
|
58
|
+
- Forgetful
|
59
|
+
- --main
|
60
|
+
- README
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "1.2"
|
74
|
+
version:
|
75
|
+
requirements: []
|
76
|
+
|
77
|
+
rubyforge_project: forgetful
|
78
|
+
rubygems_version: 1.2.0
|
79
|
+
signing_key:
|
80
|
+
specification_version: 2
|
81
|
+
summary: A minimal command-line implementation of the SuperMemo 2 algorithm.
|
82
|
+
test_files:
|
83
|
+
- test/test_forgetful.rb
|