Module: ThinkingLobster

Defined in:
lib/thinking_lobster.rb

Overview

Provides a way of intelligently scheduling review times for learning items stored in a MongoDB database.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(collection) ⇒ Object

Includes a set of fields and support methods into the base class. Mongoid must be included in the base class. Setup Mongoid before setting up this library.

Examples

class FlashCard
  include Mongoid::Document
  include ThinkingLobster
  field :question
  field :answer
end


20
21
22
23
24
25
26
27
# File 'lib/thinking_lobster.rb', line 20

def self.included(collection)
  collection.send :field, :times_reviewed,  type: Integer, default: 0
  collection.send :field, :winning_streak,  type: Integer, default: 0
  collection.send :field, :losing_streak,   type: Integer, default: 0
  collection.send :field, :review_due_at,   type: Time,    default: ->{Time.now}
  collection.send :field, :previous_review, type: Time
  collection.send :include, Mongoid::Timestamps
end

Instance Method Details

#mark_correct!(current_time = Time.now) ⇒ Object

Marks the item correct and increases the item’s review intervals accordingly. Takes no action if review takes place before the scheduled review time.

Example:

flash_card = SomeDocument.new
flash_card.mark_correct! # => #<SomeItem:0x123>

Paramters:

  • (Time) current_time - Time object by which review times are set. This parameter is almost always left to its default value (Time.now) but may be changed for testing or special use cases.

Returns an instance of the base class



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/thinking_lobster.rb', line 56

def mark_correct!(current_time = Time.now)
  return self if self.too_soon?(current_time)
  increment_wins
  if time_since_review(current_time) < @@config[:cutoff]
    new_item_correct(current_time)
  else
    old_item_correct(current_time)
  end
  self.save
  self
end

#mark_incorrect!(current_time = Time.now) ⇒ Object

Marks the item incorrect and shortens the review interval.

Example:

flash_card = SomeDocument.new
flash_card.mark_incorrect! # => #<SomeItem:0x123>

Parameters:

  • (Time) current_time - Time object by which review times are set. Defaults to Time.now . This parameter is typically left to its default value but may be changed for testing or special use cases.

Returns an instance of the base class.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/thinking_lobster.rb', line 78

def mark_incorrect!(current_time = Time.now)
  increment_losses
  if time_since_review(current_time) < @@config[:cutoff]
    #the Review time after a new item's failure is Time.now
    new_item_incorrect(current_time)
  else
    old_item_incorrect(current_time)
  end
  self.save
  self
end

#previous_review?Boolean

Indicates if the item has a previous review recorded (which would indicate wether it is a newly added item).

Example:

flash_card = SomeDocument.new
flash_card.previous_review?
# => false

No parameters

Returns a Boolean

Returns:

  • (Boolean)


150
151
152
# File 'lib/thinking_lobster.rb', line 150

def previous_review?
  self.previous_review != nil
end

#reset(current_time = Time.now) ⇒ Object

Resets all attributes related to spaced repetition. You still need to call save on the item to persist.

Example:

really_bad_item.reset
really_bad_item.save
# => #<SomeItem:0x123> # This item is now a new item, for all practical purposes.

Parameters:

  • (Time) current_time - The time that the items values will be reset to. Defaults to Time.now.



163
164
165
166
167
168
169
# File 'lib/thinking_lobster.rb', line 163

def reset(current_time = Time.now)
  self.times_reviewed   = 0
  self.winning_streak   = 0
  self.losing_streak    = 0
  self.review_due_at    = current_time
  self.previous_review  = nil
end

#time_since_due(current_time = Time.now) ⇒ Object

Indicates quantity of time since the item became ready for a review. This method is not used by ThinkingLobster at all, but may be useful as a helper method for application logic.

Example:

flash_card = SomeDocument.new
flash_card.time_since_due
# => 144000
  • (Time) current_time - Time object which defaults to Time.now. This is the time by which the method compares.

Returns an Integer



100
101
102
# File 'lib/thinking_lobster.rb', line 100

def time_since_due(current_time = Time.now)
  current_time - self.review_due_at
end

#time_since_review(current_time = Time.now) ⇒ Object

Indicates quantity of time since the item was last reviewed review. Be aware that this method is not the same thing as time_since_due().

Example:

flash_card = SomeDocument.new
flash_card.mark_correct!
# Wait 5 seconds...
flash_card.time_since_review
# => 5.0
  • (Time) current_time - Time object which defaults to Time.now. This is the time by which the method compares. Usually there is no need to provide this parameter.

Returns an Integer



116
117
118
119
120
121
122
# File 'lib/thinking_lobster.rb', line 116

def time_since_review(current_time = Time.now)
  if self.previous_review?
    return current_time - self.previous_review
  else
    return current_time - self.created_at
  end
end

#too_soon?(current_time = Time.now) ⇒ Boolean

Indicates if a review would be ‘premature’ at the indicated time, meaning that the application / user is trying to review a word too often.

Example:

flash_card = SomeDocument.new
flash_card.mark_correct! 
flash_card.too_soon? # In this example, we just finished the review. So it won't be due for a few more hours.
# => true
  • (Time) current_time - Time object which defaults to Time.now. This is the time by which the method compares.

Returns a Boolean

Returns:

  • (Boolean)


135
136
137
138
# File 'lib/thinking_lobster.rb', line 135

def too_soon?(current_time = Time.now)
  too_soon = current_time < self.review_due_at
  if too_soon then true else false end
end