forgetful 0.3.0 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  gem.email = "jonathan.palardy@gmail.com"
11
11
  gem.homepage = "http://github.com/jpalardy/forgetful"
12
12
  gem.authors = ["Jonathan Palardy"]
13
- gem.add_development_dependency "rspec", ">= 1.2.9"
13
+ gem.add_development_dependency "rspec", "= 1.2.9"
14
14
  end
15
15
  Jeweler::GemcutterTasks.new
16
16
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.3
data/bin/forgetful CHANGED
@@ -1,55 +1,58 @@
1
+ #!/usr/bin/env ruby
1
2
 
2
3
  require "forgetful"
3
4
  require "forgetful/cli"
4
- require 'getoptlong'
5
+ require 'optparse'
5
6
 
6
7
  #-------------------------------------------------
7
8
 
8
- def usage(status=0)
9
- $stderr.puts <<-END
10
- Usage: #{File.basename($0)} [options] filename(s)
9
+ def parse(args)
10
+ options = { :filenames => [],
11
+ :verbose => false,
12
+ :action => :quiz }
11
13
 
12
- --help, -h Show this message
13
- --touch, -t Validate filename(s) and write back in full CSV format
14
- --version Show version information
15
- END
14
+ args.options do |arg|
15
+ arg.banner = "Usage: forgetful [OPTION]... [FILE]..."
16
+ arg.separator ""
17
+ arg.separator "Specific options:"
16
18
 
17
- exit status
18
- end
19
+ arg.on( '-t', '--touch', "Validate filename(s) and write back in full CSV format") do
20
+ options[:action] = :touch
21
+ end
22
+
23
+ arg.separator ""
24
+ arg.separator "Common options:"
25
+
26
+ arg.on( '-v', '--verbose', "Show more information") do
27
+ options[:verbose] = true
28
+ end
19
29
 
20
- def parse_argv
21
- result = { :filenames => [],
22
- :action => :quiz }
23
-
24
- opts = GetoptLong.new(['--help', '-h', GetoptLong::NO_ARGUMENT],
25
- ['--touch', '-t', GetoptLong::NO_ARGUMENT],
26
- ['--version', GetoptLong::NO_ARGUMENT])
27
-
28
- opts.each do |opt, arg|
29
- case opt
30
- when '--help'
31
- usage
32
- when '--touch'
33
- result[:action] = :touch
34
- when '--version'
30
+ arg.on( '--version', "Show version") do
35
31
  puts File.read(File.join(File.dirname(__FILE__), "..", "VERSION"))
36
- exit 0
32
+ exit
33
+ end
34
+
35
+ arg.on_tail('-h', '--help', "Show this message") do
36
+ puts arg
37
+ exit
37
38
  end
39
+
40
+ arg.parse!
38
41
  end
39
42
 
40
- result[:filenames] = ARGV.dup
41
- ARGV.clear
43
+ options[:filenames] = args.dup
44
+ args.clear
42
45
 
43
- result
46
+ options
44
47
  end
45
48
 
46
49
  #-------------------------------------------------
47
50
 
48
- options = parse_argv
51
+ options = parse(ARGV)
49
52
 
50
53
  begin
51
54
  options[:filenames].each do |filename|
52
- ReminderFile.new(filename).send(options[:action])
55
+ ReminderFile.new(filename, options[:verbose]).send(options[:action])
53
56
  end
54
57
  rescue Interrupt
55
58
  puts
data/lib/forgetful/cli.rb CHANGED
@@ -1,16 +1,18 @@
1
1
 
2
2
  class ReminderFile
3
- attr_reader :filename
3
+ attr_reader :filename, :verbose
4
4
 
5
- def initialize(filename)
5
+ def initialize(filename, verbose=false)
6
6
  @filename = filename
7
+ @verbose = verbose
7
8
  end
8
9
 
9
10
  def reminders
10
11
  @reminders ||= Reminder.read_csv(filename)
11
12
  end
12
13
 
13
- def reminders=(reminders)
14
+ def write(reminders)
15
+ raise "Writing back a different number of reminders than read from file (#{reminders.size} != #{@reminders.size})" if reminders.size != @reminders.size
14
16
  Reminder.write_csv(filename, reminders.sort)
15
17
  end
16
18
 
@@ -20,30 +22,37 @@ class ReminderFile
20
22
  # 3. sort the rows
21
23
  def touch
22
24
  puts "### TOUCH: #{filename}"
23
- self.reminders = reminders
25
+ write(reminders)
24
26
  end
25
27
 
26
28
  def quiz
27
29
  puts "### QUIZ: #{filename}"
28
30
  dues, not_dues = reminders.partition { |reminder| reminder.due_on <= Date.today }
29
- gradeds = quiz_map(dues.sort_by { rand })
31
+ gradeds, ungradeds = quiz_map(dues.sort_by { rand })
30
32
 
31
- self.reminders = gradeds + not_dues
33
+ write(gradeds + ungradeds + not_dues)
32
34
 
33
35
  faileds = gradeds.select { |reminder| reminder.review? }
34
- until faileds.empty?
36
+ until faileds.empty? || ungradeds.any?
35
37
  puts "### REVIEW: #{filename}"
36
- gradeds = quiz_map(faileds.sort_by { rand })
38
+ gradeds, ungradeds = quiz_map(faileds.sort_by { rand })
37
39
  faileds = gradeds.select { |reminder| reminder.review? }
38
40
  end
39
41
  end
40
42
 
41
43
  private
42
44
  def quiz_map(reminders)
43
- reminders.zip(1..reminders.length).map do |reminder, i|
44
- q = ask(reminder, i, reminders.size)
45
- reminder.next(q)
45
+ gradeds = []
46
+ ungradeds = reminders.dup
47
+
48
+ reminders.each_with_index do |reminder, i|
49
+ q = ask(reminder, i+1, reminders.size)
50
+ gradeds << ungradeds.shift.next(q)
46
51
  end
52
+ rescue EOFError
53
+ # tolerate Ctrl-D, skips the rest of the quiz
54
+ ensure
55
+ return gradeds, ungradeds
47
56
  end
48
57
 
49
58
  def ask(reminder, i, n)
@@ -54,6 +63,7 @@ class ReminderFile
54
63
  readline
55
64
 
56
65
  puts padding + "A: #{reminder.answer}"
66
+ puts padding + " %.2f -> %s" % [reminder.ef, reminder.history.join] if verbose
57
67
 
58
68
  while true
59
69
  print padding + "? "
@@ -8,6 +8,10 @@ class Reminder
8
8
  @history = history.dup.freeze
9
9
  end
10
10
 
11
+ def ef
12
+ SuperMemo::traverse(history)[0]
13
+ end
14
+
11
15
  def next(q)
12
16
  new_history = history + [q]
13
17
  Reminder.new(question, answer, SuperMemo::next_date(Date.today, new_history), new_history)
@@ -16,6 +16,10 @@ describe "reminder" do
16
16
  it "should be valid" do
17
17
  @reminder.to_a.should == [@question, @answer, Date.today, []]
18
18
  end
19
+
20
+ it "should have an ef of 2.5" do
21
+ @reminder.ef.should be_close(2.5, 0.0001)
22
+ end
19
23
  end
20
24
 
21
25
  describe "with full constructor" do
@@ -33,6 +37,10 @@ describe "reminder" do
33
37
  @reminder.history.push(5)
34
38
  }.should raise_error(error_type, "can't modify frozen array")
35
39
  end
40
+
41
+ it "should have an ef of 2.8 (based on history)" do
42
+ @reminder.ef.should be_close(2.8, 0.0001)
43
+ end
36
44
  end
37
45
 
38
46
  describe "next" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 0
9
- version: 0.3.0
8
+ - 3
9
+ version: 0.3.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jonathan Palardy
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-22 00:00:00 -04:00
17
+ date: 2010-11-05 00:00:00 -04:00
18
18
  default_executable: forgetful
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -23,7 +23,7 @@ dependencies:
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
25
25
  requirements:
26
- - - ">="
26
+ - - "="
27
27
  - !ruby/object:Gem::Version
28
28
  segments:
29
29
  - 1