Class: GithubStats::Data

Inherits:
Object
  • Object
show all
Includes:
MethodCacher
Defined in:
lib/githubstats/data.rb

Overview

Data class for calculations

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ Data

Create a data object and turn on caching


31
32
33
34
35
# File 'lib/githubstats/data.rb', line 31

def initialize(data)
  @raw = data.map { |d, s| Datapoint.new(Date.parse(d), s.to_i) }
  enable_caching [:to_h, :today, :streaks, :longest_streak, :streak, :max,
                  :mean, :std_var, :quartile_boundaries, :quartiles]
end

Instance Attribute Details

#rawObject (readonly) Also known as: to_a

Returns the value of attribute raw


25
26
27
# File 'lib/githubstats/data.rb', line 25

def raw
  @raw
end

Instance Method Details

#[](date) ⇒ Object

The score for a given day


54
55
56
# File 'lib/githubstats/data.rb', line 54

def [](date)
  to_h[Date.parse(date)]
end

#gh_outliersObject

Outliers as calculated by GitHub They only consider the first 3 or 1, based on the mean and max of the set


126
127
128
# File 'lib/githubstats/data.rb', line 126

def gh_outliers
  outliers.take((6 > max.score - mean || 15 > max.score) ? 1 : 3)
end

#longest_streakObject

The longest streak


79
80
81
82
# File 'lib/githubstats/data.rb', line 79

def longest_streak
  return [] if streaks.empty?
  streaks.max { |a, b| a.length <=> b.length }
end

#maxObject

The highest scoring day


95
96
97
# File 'lib/githubstats/data.rb', line 95

def max
  @raw.max { |a, b| a.score <=> b.score }
end

#meanObject

The mean score


102
103
104
# File 'lib/githubstats/data.rb', line 102

def mean
  scores.reduce(:+) / @raw.size.to_f
end

#outliersObject

Outliers of the set


117
118
119
120
# File 'lib/githubstats/data.rb', line 117

def outliers
  return [] if scores.uniq.size < 5
  scores.select { |x| ((mean - x) / std_var).abs > GITHUB_MAGIC }.uniq
end

#pad(fill_value = -1,, data = @raw.clone) ⇒ Object

Pad the dataset to full week increments


166
167
168
169
# File 'lib/githubstats/data.rb', line 166

def pad(fill_value = -1, data = @raw.clone)
  data = _pad data, 0, fill_value, 0
  _pad data, -1, fill_value, 6
end

#quartile(score) ⇒ Object

Return the quartile of a given score


158
159
160
161
# File 'lib/githubstats/data.rb', line 158

def quartile(score)
  return nil if score < 0 || score > max.score
  quartile_boundaries.count { |bound| score > bound }
end

#quartile_boundariesObject

The boundaries of the quartiles The index represents the quartile number The value is the upper bound of the quartile (inclusive)


135
136
137
138
139
140
141
142
143
144
145
# File 'lib/githubstats/data.rb', line 135

def quartile_boundaries # rubocop:disable Metrics/AbcSize
  top = scores.reject { |x| gh_outliers.include? x }.max
  range = (1..top).to_a
  range = [0] * 3 if range.empty?
  mids = (1..3).map do |q|
    index = q * range.size / 4 - 1
    range[index]
  end
  bounds = (mids + [max.score]).uniq.sort
  [0] * (5 - bounds.size) + bounds
end

#quartilesObject

Return the list split into quartiles


150
151
152
153
# File 'lib/githubstats/data.rb', line 150

def quartiles
  quartiles = Array.new(5) { [] }
  @raw.reduce(quartiles) { |a, e| a[quartile(e.score)] << e && a }
end

#scoresObject

Scores in chronological order


61
62
63
# File 'lib/githubstats/data.rb', line 61

def scores
  @raw.map(&:score)
end

#std_varObject

The standard variance (two pass)


109
110
111
112
# File 'lib/githubstats/data.rb', line 109

def std_var
  first_pass = @raw.reduce(0) { |a, e| (e.score.to_f - mean)**2 + a }
  Math.sqrt(first_pass / (@raw.size - 1))
end

#streakObject

The current streak, or nil


87
88
89
90
# File 'lib/githubstats/data.rb', line 87

def streak
  return [] if streaks.empty?
  streaks.last.last.date >= Date.today - 1 ? streaks.last : []
end

#streaksObject

All streaks for a user


68
69
70
71
72
73
74
# File 'lib/githubstats/data.rb', line 68

def streaks
  streaks = @raw.each_with_object(Array.new(1, [])) do |point, acc|
    point.score == 0 ? acc << [] : acc.last << point
  end
  streaks.reject!(&:empty?)
  streaks
end

#to_hObject

The data as a hash where the keys are dates and values are scores


40
41
42
# File 'lib/githubstats/data.rb', line 40

def to_h
  @raw.reduce(Hash.new(0)) { |a, e| a.merge(e.date => e.score) }
end

#todayObject

The score for today


47
48
49
# File 'lib/githubstats/data.rb', line 47

def today
  to_h[Date.today]
end