spout 0.10.2 → 0.11.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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
-