crosscounter 0.4.0 → 0.5.0

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.
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