spout 0.10.2 → 0.11.0.beta1

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -0
  3. data/README.md +3 -30
  4. data/lib/spout/commands/coverage.rb +2 -1
  5. data/lib/spout/commands/deploy.rb +82 -77
  6. data/lib/spout/commands/exporter.rb +2 -3
  7. data/lib/spout/commands/graphs.rb +68 -67
  8. data/lib/spout/commands/help.rb +155 -0
  9. data/lib/spout/helpers/array_statistics.rb +36 -30
  10. data/lib/spout/helpers/chart_types.rb +2 -2
  11. data/lib/spout/helpers/config_reader.rb +5 -5
  12. data/lib/spout/helpers/json_request.rb +1 -2
  13. data/lib/spout/helpers/json_request_generic.rb +87 -0
  14. data/lib/spout/helpers/quietly.rb +2 -4
  15. data/lib/spout/helpers/semantic.rb +7 -11
  16. data/lib/spout/helpers/send_file.rb +23 -25
  17. data/lib/spout/helpers/subject_loader.rb +41 -32
  18. data/lib/spout/helpers/table_formatting.rb +7 -6
  19. data/lib/spout/models/bucket.rb +5 -4
  20. data/lib/spout/models/coverage_result.rb +1 -1
  21. data/lib/spout/models/dictionary.rb +3 -1
  22. data/lib/spout/models/domain.rb +7 -6
  23. data/lib/spout/models/empty.rb +17 -0
  24. data/lib/spout/models/form.rb +8 -5
  25. data/lib/spout/models/graphables/default.rb +41 -18
  26. data/lib/spout/models/graphables/histogram.rb +6 -7
  27. data/lib/spout/models/graphables.rb +3 -5
  28. data/lib/spout/models/option.rb +6 -2
  29. data/lib/spout/models/outlier_result.rb +3 -3
  30. data/lib/spout/models/record.rb +21 -3
  31. data/lib/spout/models/subject.rb +4 -7
  32. data/lib/spout/models/tables/choices_vs_choices.rb +29 -17
  33. data/lib/spout/models/tables/choices_vs_numeric.rb +19 -12
  34. data/lib/spout/models/tables/default.rb +19 -32
  35. data/lib/spout/models/tables/numeric_vs_choices.rb +9 -13
  36. data/lib/spout/models/tables/numeric_vs_numeric.rb +9 -11
  37. data/lib/spout/models/tables.rb +4 -6
  38. data/lib/spout/models/variable.rb +51 -13
  39. data/lib/spout/tasks/engine.rake +1 -1
  40. data/lib/spout/templates/ruby-version +1 -1
  41. data/lib/spout/templates/travis.yml +1 -1
  42. data/lib/spout/tests/domain_format.rb +2 -2
  43. data/lib/spout/tests/domain_name_format.rb +15 -0
  44. data/lib/spout/tests/form_name_format.rb +14 -0
  45. data/lib/spout/tests/variable_name_format.rb +14 -0
  46. data/lib/spout/tests.rb +18 -13
  47. data/lib/spout/version.rb +3 -3
  48. data/lib/spout/views/index.html.erb +2 -2
  49. data/lib/spout/views/outliers.html.erb +1 -1
  50. data/lib/spout.rb +13 -58
  51. data/spout.gemspec +14 -15
  52. metadata +25 -25
  53. data/lib/spout/commands/images.rb +0 -199
  54. data/lib/spout/support/javascripts/data.js +0 -17
  55. data/lib/spout/support/javascripts/highcharts-convert.js +0 -583
  56. data/lib/spout/support/javascripts/highcharts-more.js +0 -50
  57. data/lib/spout/support/javascripts/highstock.js +0 -353
  58. data/lib/spout/support/javascripts/jquery.1.9.1.min.js +0 -5
@@ -12,28 +12,26 @@ require 'spout/models/graphables'
12
12
  require 'spout/models/tables'
13
13
  require 'spout/helpers/config_reader'
14
14
  require 'spout/helpers/send_file'
15
+ require 'spout/helpers/json_request_generic'
15
16
  require 'spout/version'
16
17
 
17
18
  module Spout
18
19
  module Commands
19
20
  class Graphs
20
- def initialize(variables, standard_version, deploy_mode = false, url = '', slug = '', token = '', webserver_name = '', subjects = nil)
21
+ def initialize(argv, standard_version, deploy_mode = false, url = '', slug = '', token = '', webserver_name = '', subjects = nil)
21
22
  @deploy_mode = deploy_mode
22
23
  @url = url
23
24
  @standard_version = standard_version
24
25
  @slug = slug
25
26
  @token = token
26
27
  @webserver_name = webserver_name
27
-
28
- argv = variables
29
-
30
- @clean = (argv.delete('--no-resume') != nil or argv.delete('--clean'))
28
+ @clean = !(argv.delete('--no-resume').nil? && argv.delete('--clean').nil?)
31
29
 
32
30
  @config = Spout::Helpers::ConfigReader.new
33
31
 
34
32
  @stratification_variable = Spout::Models::Variable.find_by_id @config.visit
35
33
 
36
- if @stratification_variable == nil
34
+ if @stratification_variable.nil?
37
35
  if @config.visit == ''
38
36
  puts "The visit variable in .spout.yml can't be blank."
39
37
  else
@@ -42,56 +40,51 @@ module Spout
42
40
  return self
43
41
  end
44
42
 
45
- missing_variables = @config.charts.select{|c| Spout::Models::Variable.find_by_id(c['chart']) == nil}
43
+ missing_variables = @config.charts.select { |c| Spout::Models::Variable.find_by_id(c['chart']).nil? }
46
44
  if missing_variables.count > 0
47
45
  puts "Could not find the following chart variable#{'s' unless missing_variables.size == 1}: #{missing_variables.join(', ')}"
48
46
  return self
49
47
  end
50
48
 
51
- argv_string = variables.join(',')
52
- @number_of_rows = nil
49
+ rows_arg = argv.find { |arg| /^--rows=(\d*)/ =~ arg }
50
+ argv.delete(rows_arg)
51
+ @number_of_rows = rows_arg.gsub(/--rows=/, '').to_i if rows_arg
53
52
 
54
- if match_data = argv_string.match(/-rows=(\d*)/)
55
- @number_of_rows = match_data[1].to_i
56
- argv_string.gsub!(match_data[0], '')
57
- end
53
+ @valid_ids = argv.collect { |s| s.to_s.downcase }.compact.reject { |s| s == '' }
58
54
 
59
- @valid_ids = argv_string.split(',').compact.reject{|s| s == ''}
60
-
61
- @chart_variables = @config.charts.unshift( { "chart" => @config.visit, "title" => 'Histogram' } )
55
+ @chart_variables = @config.charts.unshift('chart' => @config.visit, 'title' => 'Histogram')
62
56
 
63
57
  @dictionary_root = Dir.pwd
64
58
  @variable_files = Dir.glob(File.join(@dictionary_root, 'variables', '**', '*.json'))
65
59
 
66
60
  t = Time.now
67
- @graphs_folder = File.join("graphs", @standard_version)
61
+ @graphs_folder = File.join('graphs', @standard_version)
68
62
  FileUtils.mkpath @graphs_folder
69
63
 
70
-
71
64
  @subjects = if subjects
72
- subjects
73
- else
74
- @subject_loader = Spout::Helpers::SubjectLoader.new(@variable_files, @valid_ids, @standard_version, @number_of_rows, @config.visit)
75
- @subject_loader.load_subjects_from_csvs!
76
- @subjects = @subject_loader.subjects
77
- end
65
+ subjects
66
+ else
67
+ @subject_loader = Spout::Helpers::SubjectLoader.new(@variable_files, @valid_ids, @standard_version, @number_of_rows, @config.visit)
68
+ @subject_loader.load_subjects_from_csvs!
69
+ @subjects = @subject_loader.subjects
70
+ end
78
71
 
79
72
  load_current_progress
80
73
 
81
74
  compute_tables_and_charts
82
75
 
83
- puts "Took #{Time.now - t} seconds." if @subjects.size > 0 and not @deploy_mode
76
+ puts "Took #{Time.now - t} seconds." if @subjects.size > 0 && !@deploy_mode
84
77
  end
85
78
 
86
79
  def load_current_progress
87
- @progress_file = File.join(@graphs_folder, ".progress.json")
80
+ @progress_file = File.join(@graphs_folder, '.progress.json')
88
81
  @progress = JSON.parse(File.read(@progress_file)) rescue @progress = {}
89
- @progress = {} if !@progress.kind_of?(Hash) or @clean or @progress['SPOUT_VERSION'] != Spout::VERSION::STRING
82
+ @progress = {} if !@progress.is_a?(Hash) || @clean || @progress['SPOUT_VERSION'] != Spout::VERSION::STRING
90
83
  @progress['SPOUT_VERSION'] = Spout::VERSION::STRING
91
84
  end
92
85
 
93
86
  def save_current_progress
94
- File.open(@progress_file,"w") do |f|
87
+ File.open(@progress_file, 'w') do |f|
95
88
  f.write(JSON.pretty_generate(@progress) + "\n")
96
89
  end
97
90
  end
@@ -104,30 +97,25 @@ module Spout
104
97
  end
105
98
  end
106
99
 
107
- def send_to_server(chart_json_file)
108
- response = Spout::Helpers::SendFile.post("#{@url}/datasets/#{@slug}/upload_graph.json", chart_json_file, @standard_version, @token)
109
- end
110
-
111
-
112
100
  def iterate_through_variables
113
101
  variable_files_count = @variable_files.count
114
102
  @variable_files.each_with_index do |variable_file, file_index|
115
103
  variable = Spout::Models::Variable.new(variable_file, @dictionary_root)
116
104
 
117
105
  next unless variable.errors.size == 0
118
- next unless @valid_ids.include?(variable.id) or @valid_ids.size == 0
119
- next unless ["numeric", "integer", "choices"].include?(variable.type)
106
+ next unless @valid_ids.include?(variable.id) || @valid_ids.size == 0
107
+ next unless %w(numeric integer choices).include?(variable.type)
120
108
  next unless Spout::Models::Subject.method_defined?(variable.id)
121
109
 
122
110
  if @deploy_mode
123
111
  print "\r Graph Generation: " + "#{"% 3d" % ((file_index+1)*100/variable_files_count)}% Uploaded".colorize(:white)
124
112
  else
125
- puts "#{file_index+1} of #{variable_files_count}: #{variable.folder}#{variable.id}"
113
+ puts "#{file_index + 1} of #{variable_files_count}: #{variable.folder}#{variable.id}"
126
114
  end
127
115
 
128
116
  @progress[variable.id] ||= {}
129
117
  @progress[variable.id]['uploaded'] ||= []
130
- next if (not @deploy_mode and @progress[variable.id]['generated'] == true) or (@deploy_mode and @progress[variable.id]['uploaded'].include?(@webserver_name))
118
+ next if (!@deploy_mode && @progress[variable.id]['generated'] == true) || (@deploy_mode && @progress[variable.id]['uploaded'].include?(@webserver_name))
131
119
 
132
120
  stats = {
133
121
  charts: {},
@@ -135,51 +123,64 @@ module Spout
135
123
  }
136
124
 
137
125
  @chart_variables.each do |chart_type_hash|
138
- chart_type = chart_type_hash["chart"]
139
- chart_title = chart_type_hash["title"].downcase.gsub(' ', '-')
126
+ chart_type = chart_type_hash['chart']
127
+ chart_title = chart_type_hash['title'].downcase.gsub(' ', '-')
140
128
  chart_variable = Spout::Models::Variable.find_by_id(chart_type)
141
129
 
130
+ filtered_subjects = @subjects.reject { |s| s.send(chart_type).nil? || s.send(variable.id).nil? }
131
+
132
+ next if filtered_subjects.collect(&variable.id.to_sym).compact_empty.count == 0
142
133
  if chart_type == @config.visit
143
- filtered_subjects = @subjects.select{ |s| s.send(chart_type) != nil }
144
- if filtered_subjects.count > 0
145
- graph = Spout::Models::Graphables.for(variable, chart_variable, nil, filtered_subjects)
146
- stats[:charts][chart_title] = graph.to_hash
147
- table = Spout::Models::Tables.for(variable, chart_variable, filtered_subjects, nil)
148
- stats[:tables][chart_title] = table.to_hash
149
- end
134
+ graph = Spout::Models::Graphables.for(variable, chart_variable, nil, filtered_subjects)
135
+ stats[:charts][chart_title] = graph.to_hash
136
+ table = Spout::Models::Tables.for(variable, chart_variable, filtered_subjects, nil, totals: false)
137
+ stats[:tables][chart_title] = table.to_hash
150
138
  else
151
- filtered_subjects = @subjects.select{ |s| s.send(chart_type) != nil }
152
- if filtered_subjects.collect(&variable.id.to_sym).compact.count > 0
153
- graph = Spout::Models::Graphables.for(variable, chart_variable, @stratification_variable, filtered_subjects)
154
- stats[:charts][chart_title] = graph.to_hash
155
- stats[:tables][chart_title] = @stratification_variable.domain.options.collect do |option|
156
- visit_subjects = filtered_subjects.select{ |s| s._visit == option.value }
157
- unknown_subjects = visit_subjects.select{ |s| s.send(variable.id) == nil }
158
- table = Spout::Models::Tables.for(variable, chart_variable, visit_subjects, option.display_name)
159
- (visit_subjects.count > 0 && visit_subjects.count != unknown_subjects.count) ? table.to_hash : nil
160
- end.compact
161
- end
139
+ graph = Spout::Models::Graphables.for(variable, chart_variable, @stratification_variable, filtered_subjects)
140
+ stats[:charts][chart_title] = graph.to_hash
141
+ stats[:tables][chart_title] = @stratification_variable.domain.options.collect do |option|
142
+ visit_subjects = filtered_subjects.select { |s| s._visit == option.value }
143
+ Spout::Models::Tables.for(variable, chart_variable, visit_subjects, option.display_name).to_hash
144
+ end.compact
162
145
  end
163
146
  end
164
147
 
165
148
  chart_json_file = File.join(@graphs_folder, "#{variable.id}.json")
166
- File.open(chart_json_file, 'w') { |file| file.write( JSON.pretty_generate(stats) + "\n" ) }
167
-
149
+ File.open(chart_json_file, 'w') { |file| file.write(JSON.pretty_generate(stats) + "\n") }
168
150
  @progress[variable.id]['generated'] = true
169
151
 
170
- if @deploy_mode and not @progress[variable.id]['uploaded'].include?(@webserver_name)
171
- response = send_to_server(chart_json_file)
172
- if response.kind_of?(Hash) and response['upload'] == 'success'
173
- @progress[variable.id]['uploaded'] << @webserver_name
174
- else
175
- puts "\nUPLOAD FAILED: ".colorize(:red) + File.basename(chart_json_file)
152
+ if @deploy_mode && !@progress[variable.id]['uploaded'].include?(@webserver_name)
153
+ values = @subjects.collect(&variable.id.to_sym).compact_empty
154
+ variable.n = values.n
155
+ variable.unknown = values.unknown
156
+ variable.total = values.count
157
+ if %w(numeric integer).include?(variable.type)
158
+ variable.mean = values.mean
159
+ variable.stddev = values.standard_deviation
160
+ variable.median = values.median
161
+ variable.min = values.min
162
+ variable.max = values.max
176
163
  end
164
+ send_variable_params_to_server(variable, stats)
177
165
  end
178
166
  end
179
-
180
167
  end
181
168
 
182
-
169
+ def send_variable_params_to_server(variable, stats)
170
+ params = { auth_token: @token, version: @standard_version,
171
+ dataset: @slug, variable: variable.deploy_params,
172
+ domain: (variable.domain ? variable.domain.deploy_params : nil),
173
+ forms: variable.forms.collect(&:deploy_params) }
174
+ params[:variable][:spout_stats] = stats.to_json
175
+ (response, status) = Spout::Helpers::JsonRequestGeneric.post("#{@url}/api/v1/variables/create_or_update.json", params)
176
+ if response.is_a?(Hash) && status.is_a?(Net::HTTPSuccess)
177
+ # puts "response: #{response}".colorize(:blue)
178
+ @progress[variable.id]['uploaded'] << @webserver_name
179
+ else
180
+ puts "\nUPLOAD FAILED: ".colorize(:red) + variable.id
181
+ puts "- Error: #{response.inspect}"
182
+ end
183
+ end
183
184
  end
184
185
  end
185
186
  end
@@ -0,0 +1,155 @@
1
+ require 'colorize'
2
+
3
+ module Spout
4
+ module Commands
5
+ class Help
6
+ def initialize(argv)
7
+ send((Spout::COMMANDS[argv[1].to_s.scan(/\w/).first] || :help))
8
+ end
9
+
10
+ def help
11
+ puts <<-EOT
12
+ Usage: spout COMMAND [ARGS]
13
+
14
+ The most common spout commands are:
15
+ [n]ew Create a new Spout dictionary.
16
+ `spout new <project_name>` creates a new
17
+ data dictionary in `./<project_name>`
18
+ [t]est Run tests and show failing tests
19
+ [i]mport Import a CSV file into the JSON dictionary
20
+ [e]xport [1.0.0] Export the JSON dictionary to CSV format
21
+ [c]overage Coverage report, requires dataset CSVs
22
+ in `<project_name>/csvs/<version>`
23
+ [o]utliers Outlier report, requires dataset CSVs
24
+ in `<project_name>/csvs/<version>`
25
+ [g]raphs Generates JSON graphs for each variable
26
+ in a dataset and places them
27
+ in `<project_name>/graphs/<version>/`
28
+ [d]eploy NAME Push dataset and data dictionary to a
29
+ webserver specified in `.spout.yml`
30
+ [v]ersion Returns the version of Spout
31
+
32
+ Commands can be referenced by the first letter:
33
+ Ex: `spout t`, for test
34
+
35
+ You can also get more in depth help by typing:
36
+ Ex: `spout help deploy`, to list all deploy flags
37
+
38
+ EOT
39
+ end
40
+
41
+ def new_project
42
+ puts <<-EOT
43
+ Usage: spout new <project_name>
44
+
45
+ More information here:
46
+
47
+ https://github.com/sleepepi/spout#generate-a-new-repository-from-an-existing-csv-file
48
+
49
+ EOT
50
+ end
51
+
52
+ def version
53
+ puts <<-EOT
54
+ Usage: spout version
55
+
56
+ EOT
57
+ end
58
+
59
+ def test
60
+ puts <<-EOT
61
+ Usage: spout test
62
+
63
+ EOT
64
+ end
65
+
66
+ def importer
67
+ puts <<-EOT
68
+ Usage: spout import <csv_file>
69
+
70
+ Optional Flags:
71
+ --domains Specify to import CSV of domains
72
+
73
+ More information:
74
+ https://github.com/sleepepi/spout#generate-a-new-repository-from-an-existing-csv-file
75
+ https://github.com/sleepepi/spout#importing-domains-from-an-existing-csv-file
76
+ EOT
77
+ end
78
+
79
+ def exporter
80
+ puts <<-EOT
81
+ Usage: spout export
82
+
83
+ Exports data dictionary to CSV format.
84
+
85
+ More information here:
86
+
87
+ https://github.com/sleepepi/spout#create-a-csv-data-dictionary-from-your-json-repository
88
+
89
+ EOT
90
+ end
91
+
92
+ def coverage_report
93
+ puts <<-EOT
94
+ Usage: spout coverage
95
+
96
+ Generates `coverage/index.html` that can be viewed in browser.
97
+
98
+ EOT
99
+ end
100
+
101
+ def generate_charts_and_tables
102
+ puts <<-EOT
103
+ Usage: spout graphs
104
+
105
+ Optional Flags:
106
+ --clean Regenerate all graphs (default is to resume
107
+ where command last left off)
108
+ --rows=N Limit the number of rows read from CSVs to a
109
+ maximum of N rows
110
+ <variable> Only generate graphs for the specified variable(s)
111
+ Ex: spout graphs age gender
112
+
113
+ EOT
114
+ end
115
+
116
+ def outliers_report
117
+ puts <<-EOT
118
+ Usage: spout outliers
119
+
120
+ Generates `coverage/outliers.html` that can be viewed in browser.
121
+
122
+ More information here:
123
+
124
+ https://github.com/sleepepi/spout#identify-outliers-in-your-dataset
125
+
126
+ EOT
127
+ end
128
+
129
+ def deploy
130
+ puts <<-EOT
131
+ Usage: spout deploy NAME
132
+
133
+ NAME is the name of the webserver listed in `.spout.yml` file
134
+ Optional Flags:
135
+ --clean Regenerate all variables (default is to resume
136
+ where command last left off)
137
+ --rows=N Limit the number of rows read from CSVs to a
138
+ maximum of N rows
139
+ <variable> Only deploy specified variable(s)
140
+ Ex: spout deploy production age gender
141
+ --skip-checks Skips Spout checks
142
+ --skip-graphs Skip generation of variable graphs
143
+ --skip-csvs Skip upload of Data Dictionary and Dataset CSVs
144
+ --token=TOKEN Provide token via command-line for automated
145
+ processes
146
+
147
+ More information here:
148
+
149
+ https://github.com/sleepepi/spout#deploy-your-data-dictionary-to-a-staging-or-production-webserver
150
+
151
+ EOT
152
+ end
153
+ end
154
+ end
155
+ end
@@ -1,41 +1,46 @@
1
+ # Extensions to the Array class to calculate quartiles, outliers, and statistics
1
2
  class Array
3
+ def compact_empty
4
+ compact.reject { |a| a.is_a?(Spout::Models::Empty) }
5
+ end
6
+
2
7
  def n
3
- self.compact.count
8
+ compact_empty.count
4
9
  end
5
10
 
6
11
  def mean
7
- array = self.compact
12
+ array = compact_empty
8
13
  return nil if array.size == 0
9
14
  array.inject(:+).to_f / array.size
10
15
  end
11
16
 
12
17
  def sample_variance
13
- array = self.compact
18
+ array = compact_empty
14
19
  m = array.mean
15
- sum = array.inject(0){|accum, i| accum +(i-m)**2 }
20
+ sum = array.inject(0) { |a, e| a + (e - m)**2 }
16
21
  sum / (array.length - 1).to_f
17
22
  end
18
23
 
19
24
  def standard_deviation
20
- array = self.compact
25
+ array = compact_empty
21
26
  return nil if array.size < 2
22
- return Math.sqrt(array.sample_variance)
27
+ Math.sqrt(array.sample_variance)
23
28
  end
24
29
 
25
30
  def median
26
- array = self.compact.sort
31
+ array = compact_empty.sort
27
32
  return nil if array.size == 0
28
33
  len = array.size
29
- len % 2 == 1 ? array[len/2] : (array[len/2 - 1] + array[len/2]).to_f / 2
34
+ len.odd? ? array[len / 2] : (array[len / 2 - 1] + array[len / 2]).to_f / 2
30
35
  end
31
36
 
32
37
  def unknown
33
- self.select{|s| s == nil}.count
38
+ count { |a| a.is_a?(Spout::Models::Empty) }
34
39
  end
35
40
 
36
41
  def quartile_sizes
37
- quartile_size = self.count / 4
38
- quartile_fraction = self.count % 4
42
+ quartile_size = count / 4
43
+ quartile_fraction = count % 4
39
44
 
40
45
  quartile_sizes = [quartile_size] * 4
41
46
  (0..quartile_fraction - 1).to_a.each do |index|
@@ -46,75 +51,76 @@ class Array
46
51
  end
47
52
 
48
53
  def quartile_one
49
- self[0..(self.quartile_sizes[0] - 1)]
54
+ self[0..(quartile_sizes[0] - 1)]
50
55
  end
51
56
 
52
57
  def quartile_two
53
- sizes = self.quartile_sizes
58
+ sizes = quartile_sizes
54
59
  start = sizes[0]
55
60
  stop = start + sizes[1] - 1
56
61
  self[start..stop]
57
62
  end
58
63
 
59
64
  def quartile_three
60
- sizes = self.quartile_sizes
65
+ sizes = quartile_sizes
61
66
  start = sizes[0] + sizes[1]
62
67
  stop = start + sizes[2] - 1
63
68
  self[start..stop]
64
69
  end
65
70
 
66
71
  def quartile_four
67
- sizes = self.quartile_sizes
72
+ sizes = quartile_sizes
68
73
  start = sizes[0] + sizes[1] + sizes[2]
69
74
  stop = start + sizes[3] - 1
70
75
  self[start..stop]
71
76
  end
72
77
 
73
78
  def compact_min
74
- self.compact.min
79
+ compact_empty.min
75
80
  end
76
81
 
77
82
  def compact_max
78
- self.compact.max
83
+ compact_empty.max
79
84
  end
80
85
 
81
86
  def outliers
82
- array = self.compact.sort.select{|v| v.kind_of?(Numeric)}
87
+ array = compact_empty.sort.select { |v| v.is_a?(Numeric) }
83
88
  q1 = (array.quartile_one + array.quartile_two).median
84
89
  q3 = (array.quartile_three + array.quartile_four).median
85
- return [] if q1 == nil or q3 == nil
90
+ return [] if q1.nil? || q3.nil?
86
91
  iq_range = q3 - q1
87
92
  inner_fence_lower = q1 - iq_range * 1.5
88
93
  inner_fence_upper = q3 + iq_range * 1.5
89
- outer_fence_lower = q1 - iq_range * 3
90
- outer_fence_upper = q3 + iq_range * 3
91
- array.select{ |v| v > inner_fence_upper or v < inner_fence_lower }
94
+ array.select { |v| v > inner_fence_upper || v < inner_fence_lower }
92
95
  end
93
96
 
94
97
  def major_outliers
95
- array = self.compact.sort.select{|v| v.kind_of?(Numeric)}
98
+ array = compact_empty.sort.select { |v| v.is_a?(Numeric) }
96
99
  q1 = (array.quartile_one + array.quartile_two).median
97
100
  q3 = (array.quartile_three + array.quartile_four).median
98
- return [] if q1 == nil or q3 == nil
101
+ return [] if q1.nil? || q3.nil?
99
102
  iq_range = q3 - q1
100
- inner_fence_lower = q1 - iq_range * 1.5
101
- inner_fence_upper = q3 + iq_range * 1.5
102
103
  outer_fence_lower = q1 - iq_range * 3
103
104
  outer_fence_upper = q3 + iq_range * 3
104
- array.select{ |v| v > outer_fence_upper or v < outer_fence_lower }
105
+ array.select { |v| v > outer_fence_upper || v < outer_fence_lower }
105
106
  end
106
107
 
107
108
  def minor_outliers
108
- self.outliers - self.major_outliers
109
+ outliers - major_outliers
109
110
  end
110
-
111
111
  end
112
112
 
113
113
  module Spout
114
114
  module Helpers
115
115
  class ArrayStatistics
116
116
  def self.calculations
117
- [["N", :n, :count], ["Mean", :mean, :decimal], ["StdDev", :standard_deviation, :decimal, "± %s"], ["Median", :median, :decimal], ["Min", :compact_min, :decimal], ["Max", :compact_max, :decimal], ["Unknown", :unknown, :count]]
117
+ [['N', :n, :count],
118
+ ['Mean', :mean, :decimal],
119
+ ['StdDev', :standard_deviation, :decimal, '± %s'],
120
+ ['Median', :median, :decimal],
121
+ ['Min', :compact_min, :decimal],
122
+ ['Max', :compact_max, :decimal],
123
+ ['Unknown', :unknown, :count]]
118
124
  end
119
125
  end
120
126
  end
@@ -5,7 +5,7 @@ module Spout
5
5
  module Helpers
6
6
  class ChartTypes
7
7
  def self.get_bucket(buckets, value)
8
- return nil if buckets.size == 0 or not value.kind_of?(Numeric)
8
+ return nil if buckets.size == 0 or not value.is_a?(Numeric)
9
9
  buckets.each do |b|
10
10
  return "#{b[0]} to #{b[1]}" if value >= b[0] and value <= b[1]
11
11
  end
@@ -17,7 +17,7 @@ module Spout
17
17
  end
18
18
 
19
19
  def self.continuous_buckets(values)
20
- values.select!{|v| v.kind_of? Numeric}
20
+ values.select!{|v| v.is_a? Numeric}
21
21
  return [] if values.count == 0
22
22
  minimum_bucket = values.min
23
23
  maximum_bucket = values.max
@@ -17,18 +17,18 @@ module Spout
17
17
  def parse_yaml_file
18
18
  spout_config = YAML.load_file('.spout.yml')
19
19
 
20
- if spout_config.kind_of?(Hash)
20
+ if spout_config.is_a?(Hash)
21
21
  @slug = spout_config['slug'].to_s.strip
22
22
  @visit = spout_config['visit'].to_s.strip
23
23
 
24
- @charts = if spout_config['charts'].kind_of?(Array)
25
- spout_config['charts'].select{|c| c.kind_of?(Hash)}
24
+ @charts = if spout_config['charts'].is_a?(Array)
25
+ spout_config['charts'].select{|c| c.is_a?(Hash)}
26
26
  else
27
27
  []
28
28
  end
29
29
 
30
- @webservers = if spout_config['webservers'].kind_of?(Array)
31
- spout_config['webservers'].select{|c| c.kind_of?(Hash)}
30
+ @webservers = if spout_config['webservers'].is_a?(Array)
31
+ spout_config['webservers'].select{|c| c.is_a?(Hash)}
32
32
  else
33
33
  []
34
34
  end
@@ -2,6 +2,7 @@ require 'openssl'
2
2
  require 'net/http'
3
3
  require 'json'
4
4
 
5
+ # TODO: Deprecated, use JsonRequestGeneric instead
5
6
  module Spout
6
7
  module Helpers
7
8
  class JsonRequest
@@ -41,5 +42,3 @@ module Spout
41
42
  end
42
43
  end
43
44
  end
44
-
45
-