active_reporter 0.6.5 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/active_reporter/dimension/bin/set.rb +1 -1
- data/lib/active_reporter/dimension/bin.rb +2 -2
- data/lib/active_reporter/dimension/time.rb +2 -2
- data/lib/active_reporter/report/aggregation.rb +6 -7
- data/lib/active_reporter/report/definition.rb +2 -2
- data/lib/active_reporter/report.rb +9 -10
- data/lib/active_reporter/serializer/base.rb +2 -1
- data/lib/active_reporter/serializer/nested_hash_with_id.rb +22 -0
- data/lib/active_reporter/serializer.rb +1 -0
- data/lib/active_reporter/version.rb +1 -1
- data/spec/acceptance/data_spec.rb +2 -2
- data/spec/active_reporter/dimension/enum_spec.rb +1 -1
- data/spec/active_reporter/report_spec.rb +3 -3
- data/spec/active_reporter/serializer/nested_hash_spec.rb +47 -0
- data/spec/active_reporter/serializer/nested_hash_with_id_spec.rb +69 -0
- data/spec/dummy/app/models/data_builder.rb +1 -1
- data/spec/dummy/config/environments/development.rb +3 -3
- data/spec/dummy/config/environments/production.rb +3 -3
- data/spec/dummy/config/initializers/assets.rb +1 -1
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +122758 -0
- data/spec/dummy/tmp/local_secret.txt +1 -0
- data/spec/factories/factories.rb +0 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/support/float.rb +1 -1
- metadata +58 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cdb5fb124ebcc7d60f4f7e51b3c832a7a9be93b3a9a4e456e7695ddb16e2a336
|
4
|
+
data.tar.gz: '08a7417b448df20464dea0cf66b2dfa83082eaf54c1eb5c423d0ef973eaebacf'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55f35f09f458c58c3429da7dc77756705fb79511651f62cb0c1b87726ccbd8629c4468ea9b5b7922831dde530f90c925abee0d4f1e306a2f0ed927ddb982e4f1
|
7
|
+
data.tar.gz: 19b800d38de1b9beb846fcdf2f0516a2281fce10898df5cfc4ea424c986aa06cb5ee8736b5897240adc959216362218ef72503ee6bbb0613f4c634c48743b60e
|
data/README.md
CHANGED
@@ -283,7 +283,7 @@ params[:dimensions][<time dimension>][:bin_width] = { months: 2, hours: 2 }
|
|
283
283
|
```
|
284
284
|
|
285
285
|
`Number`s will default to using 10 bins and `Time`s will
|
286
|
-
default to using a
|
286
|
+
default to using a sensible increment of time given the domain; you can
|
287
287
|
customize this by overriding methods in those classes.
|
288
288
|
|
289
289
|
Note that when you inspect `report.data` after grouping by a bin dimension, you
|
@@ -115,8 +115,8 @@ module ActiveReporter
|
|
115
115
|
|
116
116
|
def autopopulate_bins
|
117
117
|
return [] if bin_start.blank? || bin_end.blank?
|
118
|
-
|
119
|
-
bin_count = ((bin_end - bin_start)/(bin_width)).to_i
|
118
|
+
|
119
|
+
bin_count = [((bin_end - bin_start)/(bin_width)).to_i, 1].max
|
120
120
|
invalid_param!(:bin_width, "is too small for the domain; would generate #{bin_count.to_i} bins") if bin_count > max_bins
|
121
121
|
|
122
122
|
bins = bin_count.times.map { |i| { min: (bin_start + (bin_width*i)), max: (bin_start + (bin_width*i.next)) } }
|
@@ -11,7 +11,7 @@ module ActiveReporter
|
|
11
11
|
def validate_params!
|
12
12
|
super
|
13
13
|
|
14
|
-
invalid_param!(:bin_width, "must be a valid width value or a hash where each hash keys is a valid value and each hash value\n is
|
14
|
+
invalid_param!(:bin_width, "must be a valid width value or a hash where each hash keys is a valid value and each hash value\n is an integer representing the count of the key width\n valid :bin_width values include #{STEPS.to_sentence}.") if params.key?(:bin_width) && !valid_duration?(params[:bin_width])
|
15
15
|
end
|
16
16
|
|
17
17
|
def bin_width
|
@@ -29,7 +29,7 @@ module ActiveReporter
|
|
29
29
|
# ensure that each autogenerated bin represents a correctly aligned
|
30
30
|
# day/week/month/year
|
31
31
|
bin_start = super
|
32
|
-
|
32
|
+
|
33
33
|
return if bin_start.nil?
|
34
34
|
|
35
35
|
step = BIN_STEPS.detect { |step| bin_width == 1.send(step) }
|
@@ -80,7 +80,7 @@ module ActiveReporter
|
|
80
80
|
# Trackers can only be applied if the last grouper is a bin dimension, since bin dimensions are series of the
|
81
81
|
# same data set with a pre-defined sequence. Bin dimension results also allow us to determine if an empty set
|
82
82
|
# is present, because the bins are pre-defined.
|
83
|
-
# If additional
|
83
|
+
# If additional dimensions are included the trackers reset each time these groups change. For example, if the
|
84
84
|
# category dimension "author.id" and time dimension "created_at" with bin_width "day" are used, each time the
|
85
85
|
# "author.id" value (bin) changes the tracker is reset so we do not track changes from the last day of each
|
86
86
|
# "author.id" to the first day of the next "author.id".
|
@@ -121,7 +121,6 @@ module ActiveReporter
|
|
121
121
|
results[calculator_group] = calculable? ? (raw_data[calculator_group] || calculator.default_value) : nil
|
122
122
|
end
|
123
123
|
|
124
|
-
|
125
124
|
trackers.each do |name, tracker|
|
126
125
|
tracker_group = group + [name.to_s]
|
127
126
|
results[tracker_group] = trackable? ? (raw_data[tracker_group] || tracker.default_value) : nil
|
@@ -234,18 +233,18 @@ module ActiveReporter
|
|
234
233
|
# field with identical values. If the field type is integer we can deduce the bin width to be 1, but if the
|
235
234
|
# type is string or float the the width is less evident.
|
236
235
|
# For example, if the field is float and the first value is 1.0 should the next sequential value be 1.1? What
|
237
|
-
# if we have 1.0001? Should we skip 1.0002 if it does not exist and skip right to 1.01? What if we
|
236
|
+
# if we have 1.0001? Should we skip 1.0002 if it does not exist and skip right to 1.01? What if we have 1.0,
|
238
237
|
# 1.1, 1.11, and 1.13 but no 1.12? So we determine that 1.13 is sequentially after 1.11 or de we reset the
|
239
238
|
# tracker? Even if there is a "correct" method for one report it may not be correct for a different report. The
|
240
239
|
# same problem applies to strings. Which character is after "z"? The ASCII hex value is "{", which would work
|
241
240
|
# fine for ordering, but maybe not for determining when a tracker should be reset. Additionally, we need to
|
242
241
|
# deal with strings of different lengths. Alphabetically you could order "A", "AA", "AAA", "B" but how do know
|
243
|
-
# when to reset the tracker? If we get a new value of "AAAA" we have
|
244
|
-
# tracker value for the "B" row,
|
242
|
+
# when to reset the tracker? If we get a new value of "AAAA" we have entirely new values used to calculate the
|
243
|
+
# tracker value for the "B" row, effectively making the tracker values irrelevant.
|
245
244
|
# Even going back to the integer example, the value allowed to be stored increments by 1, but there is no
|
246
|
-
#
|
245
|
+
# guarantee that these are the actual values being used in the field.
|
247
246
|
# For these reasons we will not attempt to track any dimension that does not specifically specify a bin width.
|
248
|
-
|
247
|
+
|
249
248
|
# Any class that inherits from Bin will be evaluated, this includes both Number and Time classes, all other
|
250
249
|
# classes will be skipped.
|
251
250
|
return false unless dimension.is_a?(ActiveReporter::Dimension::Bin)
|
@@ -41,7 +41,7 @@ module ActiveReporter
|
|
41
41
|
# this data, and so multiple aggregator types are provided.
|
42
42
|
#
|
43
43
|
# Average aggregator would calculate the average value across all the data in the group.
|
44
|
-
#
|
44
|
+
#
|
45
45
|
# Sum aggregator would calculate the sum total of all values across all the data in the group.
|
46
46
|
#
|
47
47
|
# Additional aggregators are also available for many other calculation types
|
@@ -86,7 +86,7 @@ module ActiveReporter
|
|
86
86
|
# are configured and an aggregator to sum Likes is configured, a tracker to calculate Likes delta may also be
|
87
87
|
# used. Each Published date the delta will be calculated, as long as the previous row has a Published date
|
88
88
|
# sequentially immediately adjacent to the current row. If the bin with is date, the dates 2020/06/05 and
|
89
|
-
# 2020/06/06 are adjacent, but if there are no blog posts for 2020/06/07 then the
|
89
|
+
# 2020/06/06 are adjacent, but if there are no blog posts for 2020/06/07 then the delta will not be calculated
|
90
90
|
# on the 2020/06/08 row since 2020/06/06 is not adjacent. Additionally, when the Author changes no delta will
|
91
91
|
# be calculated, even if the Published date on the row is sequentially immediately adjacent.
|
92
92
|
#
|
@@ -5,7 +5,7 @@ module ActiveReporter
|
|
5
5
|
include ActiveReporter::Report::Definition
|
6
6
|
include ActiveReporter::Report::Validation
|
7
7
|
include ActiveReporter::Report::Metrics
|
8
|
-
include ActiveReporter::Report::Aggregation
|
8
|
+
include ActiveReporter::Report::Aggregation
|
9
9
|
|
10
10
|
attr_reader :params, :parent_report, :parent_groupers, :supplements
|
11
11
|
|
@@ -18,7 +18,7 @@ module ActiveReporter
|
|
18
18
|
# When using a Calculator you may need the parent report data. Pass in a ActiveReporter::Report object when
|
19
19
|
# instantiating a new ActiveReporter::Report instance as :parent_report. This will allow you to calculate a data
|
20
20
|
# based on the #total_report of this passed :parent_report. For example, if the parent report includes a sum
|
21
|
-
# aggregated "views" column, the child report can use Report::Calculator::Ratio to
|
21
|
+
# aggregated "views" column, the child report can use Report::Calculator::Ratio to calculate the ratio of "views"
|
22
22
|
# on a given row versus the total "views" from the parent report.
|
23
23
|
@parent_report = @params.delete(:parent_report)
|
24
24
|
@parent_groupers = @params.delete(:parent_groupers) || ( grouper_names & Array(parent_report&.grouper_names) )
|
@@ -26,8 +26,8 @@ module ActiveReporter
|
|
26
26
|
# Supplements -> supplemental reports and data
|
27
27
|
#
|
28
28
|
# we need 2 items:
|
29
|
-
# 1- the #supplements, a hash of reports and data, we can
|
30
|
-
# => this is passed into the report initializer, the key is the name the value is the
|
29
|
+
# 1- the #supplements, a hash of reports and data, we can reference by name
|
30
|
+
# => this is passed into the report initializer, the key is the name the value is the entire report object
|
31
31
|
# 2- a configuration class, this will allow you to specify a special aggregator in the report class that
|
32
32
|
# => take a block. The block defines { |key, row| return_value }, the block has access to the data in
|
33
33
|
# #supplements available to use when calculating return the value.
|
@@ -50,18 +50,17 @@ module ActiveReporter
|
|
50
50
|
|
51
51
|
validate_params!
|
52
52
|
|
53
|
-
# After params are parsed and validated you can call #data (or any
|
53
|
+
# After params are parsed and validated you can call #data (or any derivative of: #raw_data, #flat_data,
|
54
54
|
# #hashed_data, #nested_data, etc.) on the ActiveReporter::Report object to #aggregate the data. This will
|
55
55
|
# aggregate all the raw data by the configured dimensions, process any calculators, and then process any
|
56
56
|
# trackers.
|
57
|
-
|
58
|
-
# Caclulators calculate values using the current row data and the #parent_report.
|
59
|
-
|
60
|
-
# Trackers calculate values using the current row data and prior row data.
|
61
57
|
|
58
|
+
# Calculators calculate values using the current row data and the #parent_report.
|
59
|
+
|
60
|
+
# Trackers calculate values using the current row data and prior row data.
|
62
61
|
|
63
62
|
# If pre-compiled raw data was passed in, process all :calculators and :trackers now.
|
64
|
-
aggregate if
|
63
|
+
aggregate if @raw_data.present? && ( @params.include?(:calculators) || @params.include?(:trackers) )
|
65
64
|
total if @total_data.present?
|
66
65
|
end
|
67
66
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActiveReporter
|
2
|
+
module Serializer
|
3
|
+
class NestedHashWithId < Base
|
4
|
+
ID_DELIMITER = "✦".freeze
|
5
|
+
|
6
|
+
def table
|
7
|
+
report.hashed_data.collect { |row| row.map { |k,v| [k, (v.respond_to?(:min) ? v.min : v).to_s] }.to_h }.collect do |row|
|
8
|
+
row_with_id = row.merge(_id: row.slice(*report.grouper_names).values.join(key_delimiter))
|
9
|
+
report.grouper_names.reverse.inject(row_with_id.slice(*report.all_aggregators.keys.prepend(:_id))) do |nested_row_data, group|
|
10
|
+
{ row_with_id[group] => nested_row_data }
|
11
|
+
end
|
12
|
+
end.reduce({}, :deep_merge)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def key_delimiter
|
18
|
+
@key_delimiter ||= @options[:id_delimiter] || ID_DELIMITER
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -34,7 +34,7 @@ describe "more complicated case" do
|
|
34
34
|
def expect_equal(h1, h2)
|
35
35
|
# sqlite uses Float instead of BigDecimal, we need to normalize the JSON objects to use the
|
36
36
|
# same data type so the values match. We also round these at 9 decimal places to account for
|
37
|
-
# rounding
|
37
|
+
# rounding discrepancies between the two data types
|
38
38
|
|
39
39
|
h1_json = JSON.parse(h1.to_json).map do |a|
|
40
40
|
a.deep_transform_values do |v|
|
@@ -227,7 +227,7 @@ describe "more complicated case" do
|
|
227
227
|
{ key: :min_likes, value: 3 },
|
228
228
|
{ key: :max_likes, value: 3 }
|
229
229
|
] }
|
230
|
-
] }
|
230
|
+
] }
|
231
231
|
]
|
232
232
|
end
|
233
233
|
|
@@ -14,7 +14,7 @@ describe ActiveReporter::Dimension::Enum do
|
|
14
14
|
let(:enum_values) { { "draft" => 0, "unpublished" => 1, "published" => 2, "archived" => 3 } }
|
15
15
|
let(:group_values) { ["published", "archived"] }
|
16
16
|
let(:all_values) { enum_values.keys.unshift(nil) }
|
17
|
-
|
17
|
+
|
18
18
|
let(:status_dimension) do
|
19
19
|
dimension = ActiveReporter::Dimension::Enum.new(:status, report, { model: report_model, only: filter_values })
|
20
20
|
allow(dimension).to receive(:enum_values).and_return(enum_values)
|
@@ -24,12 +24,12 @@ describe ActiveReporter::Report do
|
|
24
24
|
let(:report) { report_model.new({groupers: groupers, aggregators: aggregators, dimensions: dimensions, parent_report: parent_report, parent_groupers: parent_groupers, calculators: calculators, trackers: trackers}.compact) }
|
25
25
|
|
26
26
|
let(:year) { 1.year.ago.year }
|
27
|
-
|
27
|
+
|
28
28
|
let(:jan_datetime) { Time.new(year,1,1,0,0,0,0) }
|
29
29
|
let(:feb_datetime) { Time.new(year,2,1,0,0,0,0) }
|
30
30
|
let(:mar_datetime) { Time.new(year,3,1,0,0,0,0) }
|
31
31
|
let(:apr_datetime) { Time.new(year,4,1,0,0,0,0) }
|
32
|
-
|
32
|
+
|
33
33
|
let(:jan) { { min: jan_datetime, max: jan_datetime.next_month } }
|
34
34
|
let(:feb) { { min: feb_datetime, max: feb_datetime.next_month } }
|
35
35
|
let(:mar) { { min: mar_datetime, max: mar_datetime.next_month } }
|
@@ -93,7 +93,7 @@ describe ActiveReporter::Report do
|
|
93
93
|
let!(:author1_jan01_post) { create(:post, author: author1, created_at: Date.new(year,1,1), likes: 7) }
|
94
94
|
let!(:author1_jan12_post) { create(:post, author: author1, created_at: Date.new(year,1,12), likes: 4) }
|
95
95
|
let!(:author1_mar08_post) { create(:post, author: author1, created_at: Date.new(year,3,8), likes: 11) }
|
96
|
-
|
96
|
+
|
97
97
|
let!(:author2_jan15_post) { create(:post, author: author2, created_at: Date.new(year,1,15), likes: 3) }
|
98
98
|
let!(:author2_feb27_post) { create(:post, author: author2, created_at: Date.new(year,2,27), likes: 24) }
|
99
99
|
let!(:author2_feb28_post) { create(:post, author: author2, created_at: Date.new(year,2,28), likes: 0) }
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActiveReporter::Serializer::NestedHash do
|
4
|
+
let(:report_model) do
|
5
|
+
Class.new(ActiveReporter::Report) do
|
6
|
+
report_on :Post
|
7
|
+
number_dimension :likes
|
8
|
+
time_dimension :created_at
|
9
|
+
category_dimension :title
|
10
|
+
count_aggregator :post_count
|
11
|
+
sum_aggregator :likes_count, attribute: :likes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:report) do
|
16
|
+
report_model.new(
|
17
|
+
aggregators: [:post_count, :likes_count],
|
18
|
+
groupers: %i[title created_at],
|
19
|
+
dimensions: { created_at: { bin_width: "1 day" } }
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:nested_hash_with_id) { ActiveReporter::Serializer::NestedHash.new(report) }
|
24
|
+
let!(:data_records) do
|
25
|
+
[
|
26
|
+
create(:post, created_at: "2016-01-01", likes: 2, title: "A"),
|
27
|
+
create(:post, created_at: "2016-01-01", likes: 2, title: "A"),
|
28
|
+
create(:post, created_at: "2016-01-01", likes: 1, title: "B"),
|
29
|
+
create(:post, created_at: "2016-01-02", likes: 1, title: "A"),
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#report" do
|
34
|
+
it "builds report" do
|
35
|
+
expect(nested_hash_with_id.table).to eq({
|
36
|
+
"A" => {
|
37
|
+
"2016-01-01 00:00:00 UTC" => { post_count: "2", likes_count: "4" },
|
38
|
+
"2016-01-02 00:00:00 UTC" => { post_count: "1", likes_count: "1" },
|
39
|
+
},
|
40
|
+
"B" => {
|
41
|
+
"2016-01-01 00:00:00 UTC" => { post_count: "1", likes_count: "1" },
|
42
|
+
"2016-01-02 00:00:00 UTC" => { post_count: "0", likes_count: "0" },
|
43
|
+
}
|
44
|
+
})
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActiveReporter::Serializer::NestedHashWithId do
|
4
|
+
let(:report_model) do
|
5
|
+
Class.new(ActiveReporter::Report) do
|
6
|
+
report_on :Post
|
7
|
+
number_dimension :likes
|
8
|
+
time_dimension :created_at
|
9
|
+
category_dimension :title
|
10
|
+
count_aggregator :post_count
|
11
|
+
sum_aggregator :likes_count, attribute: :likes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:report) do
|
16
|
+
report_model.new(
|
17
|
+
aggregators: [:post_count, :likes_count],
|
18
|
+
groupers: %i[title created_at],
|
19
|
+
dimensions: { created_at: { bin_width: "1 day" } }
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:nested_hash_with_id) { ActiveReporter::Serializer::NestedHashWithId.new(report) }
|
24
|
+
let!(:data_records) do
|
25
|
+
[
|
26
|
+
create(:post, created_at: "2016-01-01", likes: 2, title: "A"),
|
27
|
+
create(:post, created_at: "2016-01-01", likes: 2, title: "A"),
|
28
|
+
create(:post, created_at: "2016-01-01", likes: 1, title: "B"),
|
29
|
+
create(:post, created_at: "2016-01-02", likes: 1, title: "A"),
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#report" do
|
34
|
+
context "with :id_delimiter option" do
|
35
|
+
let(:id_delimiter) { "___" }
|
36
|
+
let(:nested_hash_with_id) { ActiveReporter::Serializer::NestedHashWithId.new(report, id_delimiter: id_delimiter) }
|
37
|
+
|
38
|
+
it "builds report" do
|
39
|
+
expect(nested_hash_with_id.table).to eq({
|
40
|
+
"A" => {
|
41
|
+
"2016-01-01 00:00:00 UTC" => { _id: "A#{id_delimiter}2016-01-01 00:00:00 UTC", post_count: "2", likes_count: "4" },
|
42
|
+
"2016-01-02 00:00:00 UTC" => { _id: "A#{id_delimiter}2016-01-02 00:00:00 UTC", post_count: "1", likes_count: "1" },
|
43
|
+
},
|
44
|
+
"B" => {
|
45
|
+
"2016-01-01 00:00:00 UTC" => { _id: "B#{id_delimiter}2016-01-01 00:00:00 UTC", post_count: "1", likes_count: "1" },
|
46
|
+
"2016-01-02 00:00:00 UTC" => { _id: "B#{id_delimiter}2016-01-02 00:00:00 UTC", post_count: "0", likes_count: "0" },
|
47
|
+
}
|
48
|
+
})
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "without :id_delimiter option" do
|
53
|
+
let(:id_delimiter) { ActiveReporter::Serializer::NestedHashWithId::ID_DELIMITER }
|
54
|
+
|
55
|
+
it "builds report" do
|
56
|
+
expect(nested_hash_with_id.table).to eq({
|
57
|
+
"A" => {
|
58
|
+
"2016-01-01 00:00:00 UTC" => { _id: "A#{id_delimiter}2016-01-01 00:00:00 UTC", post_count: "2", likes_count: "4" },
|
59
|
+
"2016-01-02 00:00:00 UTC" => { _id: "A#{id_delimiter}2016-01-02 00:00:00 UTC", post_count: "1", likes_count: "1" },
|
60
|
+
},
|
61
|
+
"B" => {
|
62
|
+
"2016-01-01 00:00:00 UTC" => { _id: "B#{id_delimiter}2016-01-01 00:00:00 UTC", post_count: "1", likes_count: "1" },
|
63
|
+
"2016-01-02 00:00:00 UTC" => { _id: "B#{id_delimiter}2016-01-02 00:00:00 UTC", post_count: "0", likes_count: "0" },
|
64
|
+
}
|
65
|
+
})
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -62,7 +62,7 @@ class DataBuilder
|
|
62
62
|
stddev_likes = gaussian(10, 2.5)
|
63
63
|
h[author] = [average_likes, stddev_likes]
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
likeability_for = Hash.new { |author_hash, author|
|
67
67
|
author_hash[author] = Hash.new { |title_hash, title|
|
68
68
|
average_likes, stddev_likes = author_likeability[author]
|
@@ -25,16 +25,16 @@ Rails.application.configure do
|
|
25
25
|
# Debug mode disables concatenation and preprocessing of assets.
|
26
26
|
# This option may cause significant delays in view rendering with a large
|
27
27
|
# number of complex assets.
|
28
|
-
config.assets.debug = true
|
28
|
+
# config.assets.debug = true
|
29
29
|
|
30
30
|
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
|
31
31
|
# yet still be able to expire them through the digest params.
|
32
|
-
config.assets.digest = true
|
32
|
+
# config.assets.digest = true
|
33
33
|
|
34
34
|
# Adds additional error checking when serving assets at runtime.
|
35
35
|
# Checks for improperly declared sprockets dependencies.
|
36
36
|
# Raises helpful error messages.
|
37
|
-
config.assets.raise_runtime_errors = true
|
37
|
+
# config.assets.raise_runtime_errors = true
|
38
38
|
|
39
39
|
# Raises error for missing translations
|
40
40
|
# config.action_view.raise_on_missing_translations = true
|
@@ -25,15 +25,15 @@ Rails.application.configure do
|
|
25
25
|
config.serve_static_files = ENV["RAILS_SERVE_STATIC_FILES"].present?
|
26
26
|
|
27
27
|
# Compress JavaScripts and CSS.
|
28
|
-
config.assets.js_compressor = :uglifier
|
28
|
+
# config.assets.js_compressor = :uglifier
|
29
29
|
# config.assets.css_compressor = :sass
|
30
30
|
|
31
31
|
# Do not fallback to assets pipeline if a precompiled asset is missed.
|
32
|
-
config.assets.compile = false
|
32
|
+
# config.assets.compile = false
|
33
33
|
|
34
34
|
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
|
35
35
|
# yet still be able to expire them through the digest params.
|
36
|
-
config.assets.digest = true
|
36
|
+
# config.assets.digest = true
|
37
37
|
|
38
38
|
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
|
39
39
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Be sure to restart your server when you modify this file.
|
2
2
|
|
3
3
|
# Version of your assets, change this if you want to expire all your assets.
|
4
|
-
Rails.application.config.assets.version = "1.0"
|
4
|
+
# Rails.application.config.assets.version = "1.0"
|
5
5
|
|
6
6
|
# Add additional assets to the asset load path
|
7
7
|
# Rails.application.config.assets.paths << Emoji.images_path
|
File without changes
|