Module: FsrsRuby::Helpers

Defined in:
lib/fsrs_ruby/helpers.rb

Class Method Summary collapse

Class Method Details

.clamp(value, min, max) ⇒ Object

Clamp value between min and max



12
13
14
# File 'lib/fsrs_ruby/helpers.rb', line 12

def self.clamp(value, min, max)
  [[value, min].max, max].min
end

.date_diff(now, pre, unit) ⇒ Integer

Calculate difference between two dates

Parameters:

  • now (Time)

    Current time

  • pre (Time)

    Previous time

  • unit (Symbol)

    :days or :minutes

Returns:

  • (Integer)

    Difference in specified units



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/fsrs_ruby/helpers.rb', line 34

def self.date_diff(now, pre, unit)
  diff_seconds = now - pre

  case unit
  when :days
    (diff_seconds / (24 * 60 * 60)).floor
  when :minutes
    (diff_seconds / 60).floor
  else
    raise ArgumentError, "Invalid unit: #{unit}. Use :days or :minutes"
  end
end

.date_diff_in_days(last, cur) ⇒ Integer

Calculate day difference ignoring time

Parameters:

  • last (Time)

    Last review time

  • cur (Time)

    Current time

Returns:

  • (Integer)

    Day difference



90
91
92
# File 'lib/fsrs_ruby/helpers.rb', line 90

def self.date_diff_in_days(last, cur)
  (cur.to_date - last.to_date).to_i
end

.date_scheduler(now, t, is_day = false) ⇒ Time

Add time offset to a date

Parameters:

  • now (Time)

    Current time

  • t (Numeric)

    Time offset value

  • is_day (Boolean) (defaults to: false)

    If true, t is in days; if false, t is in minutes

Returns:

  • (Time)

    New time with offset applied



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

def self.date_scheduler(now, t, is_day = false)
  if is_day
    now + (t * 24 * 60 * 60)  # Days to seconds
  else
    now + (t * 60)  # Minutes to seconds
  end
end

.format_date(time) ⇒ String

Format date as YYYY-MM-DD HH:MM:SS

Parameters:

  • time (Time)

    Time object

Returns:

  • (String)

    Formatted date string



82
83
84
# File 'lib/fsrs_ruby/helpers.rb', line 82

def self.format_date(time)
  time.strftime('%Y-%m-%d %H:%M:%S')
end

.get_fuzz_range(interval, elapsed_days, maximum_interval) ⇒ Hash

Calculate fuzz range for interval randomization

Parameters:

  • interval (Numeric)

    Base interval

  • elapsed_days (Integer)

    Days since last review

  • maximum_interval (Integer)

    Maximum allowed interval

Returns:

  • (Hash)

    { min_ivl:, max_ivl: }



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/fsrs_ruby/helpers.rb', line 52

def self.get_fuzz_range(interval, elapsed_days, maximum_interval)
  delta = 1.0

  # Apply fuzzing factors based on interval ranges
  if interval >= 2.5
    delta += (interval - 2.5) * 0.15 if interval < 7.0
    delta += (7.0 - 2.5) * 0.15 if interval >= 7.0
    delta += (interval - 7.0) * 0.10 if interval >= 7.0 && interval < 20.0
    delta += (20.0 - 7.0) * 0.10 if interval >= 20.0
    delta += (interval - 20.0) * 0.05 if interval >= 20.0
  end

  # Clamp interval to maximum
  interval = [interval, maximum_interval].min

  min_ivl = [2, (interval - delta).round].max
  max_ivl = [(interval + delta).round, maximum_interval].min

  # Ensure min_ivl is greater than elapsed_days if interval exceeds it
  min_ivl = [min_ivl, elapsed_days + 1].max if interval > elapsed_days

  # Ensure min <= max
  min_ivl = max_ivl if min_ivl > max_ivl

  { min_ivl: min_ivl, max_ivl: max_ivl }
end

.round8(value) ⇒ Object

Round to 8 decimal places for TypeScript compatibility



6
7
8
9
# File 'lib/fsrs_ruby/helpers.rb', line 6

def self.round8(value)
  return value if value.nil?
  (value * 100_000_000).round / 100_000_000.0
end