Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'feature/smoothing'

  • Loading branch information...
commit 22095a1d4b8fd3641682ba007950a5c0b6f48821 2 parents cece6ce + fb1d0f3
@betamatt betamatt authored
View
29 lib/updawg/checks/deviation_check.rb
@@ -5,12 +5,22 @@ class DeviationCheck < Check
def initialize(name, options = {}, &block)
super(name, options, &block)
- unknown_keys = options.keys - [:deviates_high, :deviates_low].flatten
+ unknown_keys = options.keys - [:deviates_high, :deviates_low, :scale_factor, :smoothing].flatten
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
@options = options
+ @scale_factor = options.fetch(:scale_factor, 2)
+ @smoothing = options.fetch(:smoothing, true)
end
+ def scale_factor
+ @scale_factor
+ end
+
+ def smoothing
+ @smoothing
+ end
+
private
def execute_check
@@ -21,12 +31,25 @@ def execute_check
aggregate = Aggregate.new
values.each {|v| aggregate << v}
std_dev = aggregate.std_dev
+
mean = aggregate.mean
- min = mean - 2 * std_dev
- max = mean + 2 * std_dev
+ min = mean - std_dev
+ max = mean + std_dev
+
+ if smoothing
+ without_outliers = values.select{|v| v >= min && v <= max}
+ smoothed_aggregate = Aggregate.new
+ without_outliers.each {|v| smoothed_aggregate << v}
+ mean = smoothed_aggregate.mean
+ std_dev = smoothed_aggregate.std_dev
+ end
+ min = mean - scale_factor * std_dev
+ max = mean + scale_factor * std_dev
+
return low(sample, min) if sample < min
return high(sample, max) if sample > max
+ return pass("#{sample} within expected range (#{min..max})")
end
true
end
View
105 spec/updawg/checks/deviation_check_spec.rb
@@ -22,40 +22,99 @@
check.perform.should be_success
end
+ describe 'by default' do
+ before(:each) do
+ @check = Updawg::DeviationCheck.new('test'){ }
+ end
+
+ it 'should have smoothing on' do
+ @check.smoothing.should be_true
+ end
+
+ it 'should have a scale factor of 2' do
+ @check.scale_factor.should == 2
+ end
+ end
+
describe 'with a value set' do
before(:each) do
@values = [19, 18, 16, 11, 18, 10, 16, 13, 11, 14]
@avg = 14.6
@std_dev = 3.27278338896896
+ @options = {:scale_factor => 2}
end
- it 'should error ewith a value above the range' do
- check = Updawg::DeviationCheck.new('test'){ @values + [@avg + 2 * @std_dev] }
- result = check.perform
- result.should be_error
- result.message.should match(/above expected maximum/)
- end
+ describe 'with smoothing enabled' do
+ before(:each) do
+ @options = {:smoothing => true}
+ @smooth_values = [16, 16, 13, 14]
+ @avg = 14.75
+ @std_dev = 1.5
+ end
+
+ it 'should error with a value above the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev + 0.01] }
+ result = check.perform
+ result.message.should match(/above expected maximum/)
+ result.should be_error
+ end
- it 'should error with a value below the range' do
- check = Updawg::DeviationCheck.new('test'){ @values + [@avg - 2 * @std_dev] }
- result = check.perform
- result.should be_error
- result.message.should match(/below expected minimum/)
- end
+ it 'should error with a value below the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev - 0.01] }
+ result = check.perform
+ result.message.should match(/below expected minimum/)
+ result.should be_error
+ end
- it 'should pass with value in the range' do
- check = Updawg::DeviationCheck.new('test'){ @values + [@avg] }
- check.perform.should be_success
- end
+ it 'should pass with value in the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg] }
+ check.perform.should be_success
+ end
- it 'should pass with high edge value in the range' do
- check = Updawg::DeviationCheck.new('test'){ @values + [@avg + 2 * @std_dev - 0.01] }
- check.perform.should be_success
- end
+ it 'should pass with high edge value in the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev] }
+ check.perform.should be_success
+ end
- it 'should pass with low edge value in the range' do
- check = Updawg::DeviationCheck.new('test'){ @values + [@avg - 2 * @std_dev + 0.01] }
- check.perform.should be_success
+ it 'should pass with low edge value in the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev] }
+ check.perform.should be_success
+ end
end
+
+ describe 'with smoothing disabled' do
+ before(:each) do
+ @options[:smoothing] = false
+ end
+
+ it 'should error with a value above the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev] }
+ result = check.perform
+ result.message.should match(/above expected maximum/)
+ result.should be_error
+ end
+
+ it 'should error with a value below the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev] }
+ result = check.perform
+ result.message.should match(/below expected minimum/)
+ result.should be_error
+ end
+
+ it 'should pass with value in the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg] }
+ check.perform.should be_success
+ end
+
+ it 'should pass with high edge value in the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev - 0.01] }
+ check.perform.should be_success
+ end
+
+ it 'should pass with low edge value in the range' do
+ check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev + 0.01] }
+ check.perform.should be_success
+ end
+ end
end
end

0 comments on commit 22095a1

Please sign in to comment.
Something went wrong with that request. Please try again.