crosscounter 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d23bb8b769b17271893ecad937b0e452c9915f6d
4
- data.tar.gz: 9430375da9fe90ffba3c47e9d0112f58ceb13e3d
3
+ metadata.gz: 1597840a6d492374dda49be70c7037fd43dd7220
4
+ data.tar.gz: f5631aec3a1ec0469e8bd088e7ddd146fd3fee95
5
5
  SHA512:
6
- metadata.gz: d77812e65a457eed6efe99f1804c514e59cc4ade31a7b73d901e7d3b7050babca2a76826617fba7d4ae0e5582bf8dd12e060420c9b0bf3370e43b002be8e203b
7
- data.tar.gz: d665c48e4584ec3bb2a2e44aa6b493f770d5b24f924483038c8ac2eddd6f81ee59d63b2e381d58e004bbdbc3ab1c13a1bcb3a742fa085d07dfb9dc1101189752
6
+ metadata.gz: 2d0e1f9820f5ca86203fec298bc52f12ab69e083eb31a20e63f99df374ae7078716514e8ddccf17d9713d0fd8940c964c230cea9ae03a35a1233f20fff5ac54b
7
+ data.tar.gz: 8a98d0599eb8e5b46ef4a0f35ab8f28eff3ca38250f068670b3e7ba2e802fc4d9a39a91bd3fb49580b77f2f8cca55d05b2f03ae0664866648b885239db4914f7
data/.travis.yml CHANGED
@@ -3,3 +3,4 @@ cache: bundler
3
3
  rvm:
4
4
  - 1.9.3
5
5
  - 2.1.0
6
+ - jruby
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in crosscounter.gemspec
4
3
  gemspec
4
+
5
+ platform :mri do
6
+ gem 'ruby-prof'
7
+ end
data/bench/compute.rb CHANGED
@@ -10,6 +10,8 @@ rows = JSON.load(IO.read('bench/rows.json'))
10
10
  cols = JSON.load(IO.read('bench/cols.json'))
11
11
  data = JSON.load(IO.read('bench/data.json'))
12
12
 
13
+ sub_cols = { 'answers' => cols['answers'].take(1), 'tags' => cols['tags'].take(2) }
14
+
13
15
  if ENV['PROFILE']
14
16
  require 'ruby-prof'
15
17
 
@@ -21,8 +23,12 @@ if ENV['PROFILE']
21
23
  printer.print(STDOUT)
22
24
  else
23
25
  Benchmark.bmbm do |x|
24
- x.report('compute_all' ) do
26
+ x.report('compute_all') do
25
27
  Crosscounter::Compute.compute_all(data, rows, cols)
26
28
  end
29
+
30
+ x.report('compute_sum') do
31
+ Crosscounter::Compute.compute_all(data, rows, sub_cols)
32
+ end
27
33
  end
28
34
  end
data/crosscounter.gemspec CHANGED
@@ -20,5 +20,4 @@ Gem::Specification.new do |gem|
20
20
 
21
21
  gem.add_development_dependency 'rake', '~> 10.1'
22
22
  gem.add_development_dependency 'rspec', '~> 2.99.0.beta1'
23
- gem.add_development_dependency 'ruby-prof'
24
23
  end
@@ -4,6 +4,32 @@ module Crosscounter
4
4
  module Compute
5
5
  extend self
6
6
 
7
+ def compute_all(enumerable, rows, cols)
8
+ hashified = enumerable.map { |hash| Util.hashify(hash) }
9
+ string_cols = Util.stringify(cols)
10
+ string_rows = Util.stringify(rows)
11
+
12
+ string_rows.map! do |row|
13
+ initial = [row, compute(hashified, row)]
14
+
15
+ string_cols.each do |col|
16
+ initial << compute(hashified, row, col)
17
+ end
18
+
19
+ initial
20
+ end
21
+ end
22
+
23
+ def compute_sum(enumerable, rows, cols)
24
+ hashified = enumerable.map { |hash| Util.hashify(hash) }
25
+ string_rows = Util.stringify(rows)
26
+ string_cols = Util.stringify(cols)
27
+
28
+ string_rows.map! do |row|
29
+ computex(hashified, row, string_cols).unshift(row)
30
+ end
31
+ end
32
+
7
33
  def compute(hashes, prop_a, prop_b = nil)
8
34
  count = 0
9
35
  index = 0
@@ -20,19 +46,22 @@ module Crosscounter
20
46
  count
21
47
  end
22
48
 
23
- def compute_all(enumerable, rows, columns)
24
- setified = enumerable.map { |hash| Util.hashify(hash) }
25
- scolumns = Util.stringify(columns)
26
-
27
- Util.stringify(rows).map do |row|
28
- initial = [row, compute(setified, row)]
49
+ def computex(hashes, base_prop, other_props)
50
+ count = 0
51
+ cross = 0
52
+ index = 0
53
+ length = hashes.length
29
54
 
30
- scolumns.each do |col|
31
- initial << compute(setified, row, col)
55
+ while index < length
56
+ if hashes[index].member?(base_prop)
57
+ count += 1
58
+ cross += 1 if other_props.any? && other_props.all? { |prop| hashes[index].member?(prop) }
32
59
  end
33
60
 
34
- initial
61
+ index += 1
35
62
  end
63
+
64
+ [count, cross]
36
65
  end
37
66
  end
38
67
  end
@@ -1,17 +1,27 @@
1
1
  require 'set'
2
2
 
3
3
  module Crosscounter
4
+ DEFAULT_SEPARATOR = '|'
5
+
4
6
  module Util
5
7
  extend self
6
8
 
9
+ def separator=(sep)
10
+ @@separator = sep
11
+ end
12
+
13
+ def separator
14
+ @@separator ||= DEFAULT_SEPARATOR
15
+ end
16
+
7
17
  def hashify(hash)
8
18
  stringify(hash).inject({}) do |memo, key|
9
- memo[key] = 0
19
+ memo[key] = true
10
20
  memo
11
21
  end
12
22
  end
13
23
 
14
- def stringify(hash, sep = '|')
24
+ def stringify(hash, sep = separator)
15
25
  hash.flat_map do |key, value|
16
26
  if value.kind_of?(Enumerable)
17
27
  value.map { |elem| "#{key}#{sep}#{elem}" }
@@ -1,3 +1,3 @@
1
1
  module Crosscounter
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -11,10 +11,10 @@ describe Crosscounter::Compute do
11
11
  Set.new(['age-18', 'gender-male'])
12
12
  ]
13
13
 
14
- computer.compute(enumerable, 'age-18').should == 2
15
- computer.compute(enumerable, 'age-18', 'gender-male').should == 2
16
- computer.compute(enumerable, 'age-19', 'gender-male').should == 0
17
- computer.compute(enumerable, 'age-19', 'gender-female').should == 1
14
+ expect(computer.compute(enumerable, 'age-18')).to eq(2)
15
+ expect(computer.compute(enumerable, 'age-18', 'gender-male')).to eq(2)
16
+ expect(computer.compute(enumerable, 'age-19', 'gender-male')).to eq(0)
17
+ expect(computer.compute(enumerable, 'age-19', 'gender-female')).to eq(1)
18
18
  end
19
19
  end
20
20
 
@@ -32,7 +32,7 @@ describe Crosscounter::Compute do
32
32
  { tags: %w[happy sad mad] }
33
33
  )
34
34
 
35
- computed.should == [
35
+ expect(computed).to eq([
36
36
  ['age|18', 2, 1, 2, 1],
37
37
  ['age|19', 2, 1, 1, 1],
38
38
  ['gender|male', 3, 1, 3, 1],
@@ -40,7 +40,33 @@ describe Crosscounter::Compute do
40
40
  ['tags|happy', 2, 2, 1, 1],
41
41
  ['tags|sad', 3, 1, 3, 1],
42
42
  ['tags|mad', 2, 1, 1, 2]
43
+ ])
44
+ end
45
+ end
46
+
47
+ describe '.compute_sum' do
48
+ it 'tabulates all rows against all columns combined' do
49
+ enumerable = [
50
+ { age: 18, gender: 'male', tags: %w[happy sad] },
51
+ { age: 19, gender: 'female', tags: %w[happy mad] },
52
+ { age: 18, gender: 'male', tags: %w[mad sad] },
53
+ { age: 19, gender: 'male', tags: %w[happy sad] }
43
54
  ]
55
+
56
+ computed = computer.compute_sum(enumerable,
57
+ { age: [18, 19], gender: %w[male female], tags: %w[happy sad mad] },
58
+ { tags: %w[happy sad] }
59
+ )
60
+
61
+ expect(computed).to eq([
62
+ ['age|18', 2, 1],
63
+ ['age|19', 2, 1],
64
+ ['gender|male', 3, 2],
65
+ ['gender|female', 1, 0],
66
+ ['tags|happy', 3, 2],
67
+ ['tags|sad', 3, 2],
68
+ ['tags|mad', 2, 0]
69
+ ])
44
70
  end
45
71
  end
46
72
  end
@@ -1,6 +1,17 @@
1
1
  require 'crosscounter/util'
2
2
 
3
3
  describe Crosscounter::Util do
4
+ describe '.separator=' do
5
+ after do
6
+ Crosscounter::Util.separator = Crosscounter::DEFAULT_SEPARATOR
7
+ end
8
+
9
+ it 'sets the separator for future usage' do
10
+ Crosscounter::Util.separator = '.::.'
11
+ expect(Crosscounter::Util.separator).to eq('.::.')
12
+ end
13
+ end
14
+
4
15
  describe '.stringify' do
5
16
  it 'unzips a hash into key-value strings' do
6
17
  expect(Crosscounter::Util.stringify(age: [18, 19, 20])).to eq([
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crosscounter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Parker Selbert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-31 00:00:00.000000000 Z
11
+ date: 2014-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 2.99.0.beta1
41
- - !ruby/object:Gem::Dependency
42
- name: ruby-prof
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  description: Functionally create cross tabulations
56
42
  email:
57
43
  - parker@sorentwo.com