module Rafini::Odometers

Constants

SCALE
SEC2TIME

Public Instance Methods

description() click to toggle source
# File lib/rafini/odometers.rb, line 47
def description
  string = ''
  reverse_each do |key, count|
    s = count==1 ? '' : 's'
    unless string.empty?
      string << " and #{count} #{key}#{s}" if count.positive?
      break
    end
    next if count.zero?
    string << "#{count} #{key}#{s}"
  end
  string
end
illion(type=:short) click to toggle source

1_230.illion.to_s #=> “1.23k” 1_230_000.illion.to_s #=> “1.23M” …etc Does both short and long scales, short by default. Returns a struct with the different scales of the number

m = 888_777_666_555_444_321.illion
m.ones #=> 1
m.tens #=> 2
m.hundreds #=> 3
m.thousands #=> 444
m.millions #=> 555
m.billions #=> 666
m.trillions #=> 777
m.quadrillions #=> 888
m.to_s #=> "888Q" It rounds up 888.7!
# File lib/rafini/odometers.rb, line 117
def illion(type=:short)
  scale = SCALE[:base].merge SCALE[type]
  struct = odoread(scale, factors:false) do
    def scale=(scale)
      @scale=scale
    end
    def type=(type)
      @type=type
    end
    def to_s
      number = to_i
      return number.to_s if number < 1_000
      if number < 1_000_000
        precision = number<10_000 ? 2 : number<100_000 ? 1 : 0
        return "#{(number/1000.0).round(precision)}K"
      end
      keys = @scale.keys.reverse_each
      loop do
        key = keys.next
        n = self[key]
        next if n.zero?
        if n < 1_000
          precision = n<10 ? 2 : n<100 ? 1 : 0
          scale = @scale[key].to_f
          f = (number/scale).round(precision)
          return "#{f}#{key[0].upcase}"
        end
        return "#{n.illion}#{key[0].upcase}"
      end
    end
    def to_i
      @scale.to_a.map{|k,v|v*self[k]}.sum
    end
  end
  struct.type  = type
  struct.scale = scale
  struct
end
odoread(scale, **kw, &) click to toggle source
# File lib/rafini/odometers.rb, line 66
def odoread(scale, **kw, &)
  counts = odometer(*scale.values, **kw)
  scale.keys.zip(counts).to_h.to_struct(&)
end
scale=(scale) click to toggle source
# File lib/rafini/odometers.rb, line 120
def scale=(scale)
  @scale=scale
end
sec2time() click to toggle source

Integer#sec2time Returns a struct with the different time scales for number of seconds.

10_000.sec2time.to_s #=> "2 hours and 46 minutes"
10_000.sec2time.hour #=> 2
# File lib/rafini/odometers.rb, line 75
def sec2time
  # Struct.new(*scale.keys).new(*counts){ method definitions }
  odoread(SEC2TIME, factors:false) do
    def to_s
      string = nil
      SEC2TIME.keys.reverse_each do |key|
        count=self[key]
        if string
          if count.positive?
            string << " and #{count} #{key}"
            string << 's' if count > 1
          end
          break
        end
        next if count.zero?
        string = "#{count} #{key}"
        string << 's' if count > 1
      end
      string ||= "0 #{SEC2TIME.first[0]}s"
      string
    end
    def to_i
      SEC2TIME.to_a.map{|k,v|v*self[k]}.sum.round
    end
  end
end
to_i() click to toggle source
# File lib/rafini/odometers.rb, line 96
def to_i
  SEC2TIME.to_a.map{|k,v|v*self[k]}.sum.round
end
to_s() click to toggle source
# File lib/rafini/odometers.rb, line 78
def to_s
  string = nil
  SEC2TIME.keys.reverse_each do |key|
    count=self[key]
    if string
      if count.positive?
        string << " and #{count} #{key}"
        string << 's' if count > 1
      end
      break
    end
    next if count.zero?
    string = "#{count} #{key}"
    string << 's' if count > 1
  end
  string ||= "0 #{SEC2TIME.first[0]}s"
  string
end
type=(type) click to toggle source
# File lib/rafini/odometers.rb, line 123
def type=(type)
  @type=type
end