Skip to content

Commit

Permalink
in process of adding back in specs with rspec
Browse files Browse the repository at this point in the history
  • Loading branch information
jtprince committed Aug 27, 2013
1 parent c1f9b59 commit b63bb5b
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 103 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.swp
pkg
/*.swp
/pkg
/coverage
5 changes: 3 additions & 2 deletions histogram.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ Gem::Specification.new do |spec|


[ "bundler ~> 1.3",
"rake",
"simplecov"
"rake ~> 10.1.0",
"simplecov ~> 0.7.1",
"rspec ~> 2.13.0",
].each do |argline|
spec.add_development_dependency *argline.split(' ', 2).compact
end
Expand Down
16 changes: 8 additions & 8 deletions lib/histogram.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ def number_bins(methd=:fd)
# <Integer> give the number of bins
# <Array> specify the bins themselves
#
# :tp => :avg boundary is the avg between bins (default)
# :min bins specify the minima for binning
# :bin_boundary => :avg boundary is the avg between bins (default)
# :min bins specify the minima for binning
#
# :bin_width => <float> width of a bin (overrides :bins)
# :min => <float> # explicitly set the min
Expand All @@ -111,10 +111,10 @@ def number_bins(methd=:fd)
# ar = [-2,1,2,3,3,3,4,5,6,6]
# # these return: [bins, freqencies]
# ar.histogram(20) # use 20 bins
# ar.histogram([-3,-1,4,5,6], :tp => :avg) # custom bins
# ar.histogram([-3,-1,4,5,6], :bin_boundary => :avg) # custom bins
#
# # returns [bins, freq1, freq2 ...]
# (bins, *freqs) = ar.histogram(30, :tp => :avg, :other_sets => [3,3,4,4,5], [-1,0,0,3,3,6])
# (bins, *freqs) = ar.histogram(30, :bin_boundary => :avg, :other_sets => [3,3,4,4,5], [-1,0,0,3,3,6])
# (ar_freqs, other1, other2) = freqs
#
# # histogramming with heights (uses the second array for heights)
Expand Down Expand Up @@ -171,12 +171,12 @@ def histogram(*args)
raise ArgumentError, "accepts no more than 2 args"
end

opts = ({ :tp => :avg, :other_sets => [] }).merge(opts)
opts = ({ :bin_boundary => :avg, :other_sets => [] }).merge(opts)

bins = opts[:bins] if opts[:bins]
bins = :fd unless bins

tp = opts[:tp]
bin_boundary = opts[:bin_boundary]
other_sets = opts[:other_sets]

bins_array_like = bins.kind_of?(Array) || bins.kind_of?(NArray) || opts[:bin_width]
Expand Down Expand Up @@ -218,7 +218,7 @@ def histogram(*args)
elsif bins.is_a?(NArray)
bins.to_f
end
case tp
case bin_boundary
when :avg
freqs_ar = all.map do |vec|

Expand Down Expand Up @@ -313,7 +313,7 @@ def histogram(*args)

# Create the bins:
iconv = 1.0/conv
case tp
case bin_boundary
when :avg
(0...bins).each do |i|
_bins[i] = ((i+0.5) * iconv) + dmin
Expand Down
208 changes: 117 additions & 91 deletions spec/histogram_spec.rb
Original file line number Diff line number Diff line change
@@ -1,116 +1,142 @@
require File.expand_path(File.dirname(__FILE__) + "/spec_helper.rb")
require 'spec_helper'

require 'histogram'

class Array
def to_f
self.map {|v| v.to_f }
end
end

shared 'a histogram' do

before do
#@obj1 = (0..10).to_a
#@obj2 = [0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9]
end

it 'can make histograms (bins created on the fly)' do
# Test with # bins:
bins,freqs = @obj1.histogram(5)
bins.isa @obj1.class
freqs.isa @obj1.class
bins.enums [1,3,5,7,9].to_f
freqs.enums [2,2,2,2,3].to_f

bins,freqs = @obj1.histogram(5, :tp => :min)
bins.enums [0,2,4,6,8].to_f
freqs.enums [2,2,2,2,3].to_f
def round(n=nil)
self.map {|v| v.to_f.round(n) }
end
end

it 'can make histograms (given bins)' do
# Test with given bins:
bins, freqs = @obj2.histogram([1,3,5,7,9], :tp => :avg)
bins.enums [1,3,5,7,9].to_f
freqs.enums [3,1,1,2,3].to_f
bins, freqs = @obj3.histogram([1,3,5,7,9], :tp => :min)
bins.enums [1,3,5,7,9].to_f
freqs.enums [3,0,2,2,3].to_f
shared_examples 'something that can histogram' do
it 'makes histograms with the specified number of bins' do
(bins, freqs) = obj0.histogram(5)
bins.should be_a(obj0.class)
freqs.should be_a(obj0.class)
bins.round(8).should == [1,3,5,7,9].round(8)
freqs.round(8).should == [2,2,2,2,3].round(8)
end

it 'can histogram multiple sets' do
(bins, freq1, freq2, freq3) = @obj4.histogram([1,2,3,4], :tp => :avg, :other_sets => [@obj5, @obj5])
bins.enums [1,2,3,4].to_f
freq1.enums [2.0, 2.0, 2.0, 3.0]
freq2.enums [0.0, 5.0, 0.0, 1.0]
freq3.enums freq2
it 'returns bins as the min boundary if given that option' do
(bins, freqs) = obj0.histogram(5, :bin_boundary => :min)
bins.round(8).should == [0,2,4,6,8].round(8)
freqs.round(8).should == [2,2,2,2,3].round(8)
end

it 'can take height values' do
obj2 = [0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9]
heights = Array.new(obj2.size, 3)
obj = [obj2, heights]
bins, freqs = obj.histogram([1,3,5,7,9], :tp => :avg)
bins.enums [1,3,5,7,9].to_f
freqs.enums [3,1,1,2,3].map {|v| v * 3}

obj2 = [0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9]
heights = [10, 0, 0, 0, 50, 0, 0, 0, 0.2, 0.2]
obj = [obj2, heights]
(bins, freqs) = obj.histogram([1,3,5,7,9], :tp => :avg)
bins.enums [1,3,5,7,9].to_f
freqs.enums [10, 0, 50, 0, 0.4]
it 'makes histograms when given the bins' do
bins, freqs = obj1.histogram([1,3,5,7,9], :bin_boundary => :avg)
bins.round(8).should == [1,3,5,7,9].round(8)
freqs.round(8).should == [3,1,1,2,3].round(8)
end

it 'works with given min and max vals' do
[1,2,3,3,3,4,5,6,7,8].histogram(4, :min => 2, :tp => :min).first.first.is 2.0
[1,2,3,3,3,4,5,6,7,8].histogram(4, :max => 7, :tp => :min).first.last.is 5.5 # since the bin-width is 1.5
bs = [1,2,3,3,3,4,5,6,7,8].histogram(4, :min => 2, :max => 7, :tp => :min)
bs.first.first.is 2.0
bs.first.last.is 5.75 # bin-width of 1.25
it 'interprets bins as the min boundary when given the bin_boundary option' do
bins, freqs = obj2.histogram([1,3,5,7,9], :bin_boundary => :min)
bins.round(8).should == [1,3,5,7,9].round(8)
freqs.round(8).should == [3,0,2,2,3].round(8)
end

end

TestArrays = [[0,1,2,3,4,5,6,7,8,9,10], [0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9],
[-1, 0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9, 10], [1, 1, 2, 2, 3, 3, 4, 4, 4],
[2, 2, 2, 2, 2, 4]]
# it 'can histogram multiple sets' do
#(bins, freq1, freq2, freq3) = @obj4.histogram([1,2,3,4], :tp => :avg, :other_sets => [@obj5, @obj5])
#bins.enums [1,2,3,4].to_f
#freq1.enums [2.0, 2.0, 2.0, 3.0]
#freq2.enums [0.0, 5.0, 0.0, 1.0]
#freq3.enums freq2
#end

require 'histogram/array'
class LilClass < Array
include Histogram
end

describe 'calculating bins' do
it 'calculates :sturges, :scott, :fd, or :middle' do
answers = [6,3,4,4]
[:sturges, :scott, :fd, :middle].zip(answers) do |mth, answ|
ar = LilClass.new([0,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,5,5,9,9,10,20,15,15,15,16,17])
# these are merely frozen, not checked to see if correct
ar.number_bins(mth).is answ
end
end
end

describe 'histogramming an Array' do
before do
TestArrays.each_with_index do |ar,i|
instance_variable_set("@obj#{i+1}", ar)
end
describe Histogram do
let(:data) do
[ (0..10).to_a,
[0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9],
[-1, 0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9, 10],
].to_f
end
behaves_like 'a histogram'
end

begin
require 'histogram/narray'
describe 'histogramming an NArray' do
before do
TestArrays.each_with_index do |ar,i|
instance_variable_set("@obj#{i+1}", NArray.to_na(ar).to_f)
describe Array do
it_behaves_like 'something that can histogram' do
[:obj0, :obj1, :obj2].each_with_index do |obj,i|
let(obj) { data[i].dup.extend(Histogram) }
end
end
behaves_like 'a histogram'
end
rescue LoadError
puts ""
puts "YOU NEED NArray installed to run NArray tests!"
puts ""
end


#it 'can take height values' do
#obj2 = [0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9]
#heights = Array.new(obj2.size, 3)
#obj = [obj2, heights]
#bins, freqs = obj.histogram([1,3,5,7,9], :tp => :avg)
#bins.enums [1,3,5,7,9].to_f
#freqs.enums [3,1,1,2,3].map {|v| v * 3}

#obj2 = [0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9]
#heights = [10, 0, 0, 0, 50, 0, 0, 0, 0.2, 0.2]
#obj = [obj2, heights]
#(bins, freqs) = obj.histogram([1,3,5,7,9], :tp => :avg)
#bins.enums [1,3,5,7,9].to_f
#freqs.enums [10, 0, 50, 0, 0.4]
#end

#it 'works with given min and max vals' do
#[1,2,3,3,3,4,5,6,7,8].histogram(4, :min => 2, :tp => :min).first.first.is 2.0
#[1,2,3,3,3,4,5,6,7,8].histogram(4, :max => 7, :tp => :min).first.last.is 5.5 # since the bin-width is 1.5
#bs = [1,2,3,3,3,4,5,6,7,8].histogram(4, :min => 2, :max => 7, :tp => :min)
#bs.first.first.is 2.0
#bs.first.last.is 5.75 # bin-width of 1.25
#end






#TestArrays = [[0,1,2,3,4,5,6,7,8,9,10], [0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9],
#[-1, 0, 1, 1.5, 2.0, 5.0, 6.0, 7, 8, 9, 9, 10], [1, 1, 2, 2, 3, 3, 4, 4, 4],
#[2, 2, 2, 2, 2, 4]]

#require 'histogram/array'
#class LilClass < Array
#include Histogram
#end

#describe 'calculating bins' do
#it 'calculates :sturges, :scott, :fd, or :middle' do
#answers = [6,3,4,4]
#[:sturges, :scott, :fd, :middle].zip(answers) do |mth, answ|
#ar = LilClass.new([0,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,5,5,9,9,10,20,15,15,15,16,17])
## these are merely frozen, not checked to see if correct
#ar.number_bins(mth).is answ
#end
#end
#end

#describe 'histogramming an Array' do
#before do
#TestArrays.each_with_index do |ar,i|
#instance_variable_set("@obj#{i+1}", ar)
#end
#end
#behaves_like 'a histogram'
#end

#begin
#require 'histogram/narray'
#describe 'histogramming an NArray' do
#before do
#TestArrays.each_with_index do |ar,i|
#instance_variable_set("@obj#{i+1}", NArray.to_na(ar).to_f)
#end
#end
#behaves_like 'a histogram'
#end
#rescue LoadError
#puts ""
#puts "YOU NEED NArray installed to run NArray tests!"
#puts ""
#end

0 comments on commit b63bb5b

Please sign in to comment.