forgetful 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|