crosscounter 0.3.0 → 0.4.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d23bb8b769b17271893ecad937b0e452c9915f6d
4
+ data.tar.gz: 9430375da9fe90ffba3c47e9d0112f58ceb13e3d
5
+ SHA512:
6
+ metadata.gz: d77812e65a457eed6efe99f1804c514e59cc4ade31a7b73d901e7d3b7050babca2a76826617fba7d4ae0e5582bf8dd12e060420c9b0bf3370e43b002be8e203b
7
+ data.tar.gz: d665c48e4584ec3bb2a2e44aa6b493f770d5b24f924483038c8ac2eddd6f81ee59d63b2e381d58e004bbdbc3ab1c13a1bcb3a742fa085d07dfb9dc1101189752
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format progress
3
+ -r spec_helper
data/.travis.yml CHANGED
@@ -1,3 +1,5 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
4
  - 1.9.3
5
+ - 2.1.0
data/NOTES.txt CHANGED
@@ -1,70 +1,114 @@
1
- ---
1
+ # Profile as of dafc032
2
2
 
3
- n = 1_000_000
4
- Benchmark.bm do |x|
5
- x.report { n.times { friendly_words.include?('mandarin') } }
6
- x.report { n.times { friendly_string =~ /mandarin/ } }
7
- x.report { n.times { friendly_string['mandarin'] } }
8
- x.report { n.times { friendly_string.index('mandarin') } }
9
- end
3
+ Total: 145.487024
4
+ Sort by: self_time
10
5
 
11
- Matching against values as a string is ~7x faster
12
-
13
- user system total real
14
- 5.630000 0.000000 5.630000 ( 5.625129)
15
- 0.790000 0.000000 0.790000 ( 0.788589)
16
- 1.190000 0.000000 1.190000 ( 1.192151)
17
- 1.190000 0.000000 1.190000 ( 1.187852)
6
+ %self total self wait child calls name
7
+ 45.73 107.438 66.532 0.000 40.906 14675390 Hash#each
8
+ 14.30 128.248 20.812 0.000 107.437 14675388 Enumerable#all?
9
+ 12.15 30.163 17.675 0.000 12.488 8346096 Array#include?
10
+ 11.59 145.109 16.861 0.000 128.248 27482 Array#count
11
+ 8.58 12.488 12.488 0.000 0.000 21735448 String#==
12
+ 6.53 9.502 9.502 0.000 0.000 15295038 Kernel#kind_of?
13
+ 0.85 1.241 1.241 0.000 0.000 619650 String#sub
14
+ 0.14 143.935 0.202 0.000 143.733 836 Array#each
15
+ 0.03 145.158 0.049 0.000 145.109 27482 Crosscounter::Compute#compute
16
+ 0.03 0.036 0.036 0.000 0.000 54975 Array#last
17
+ 0.02 0.036 0.036 0.000 0.000 55054 Array#first
18
+ 0.01 0.037 0.020 0.000 0.017 615 Array#hash
19
+ 0.01 0.017 0.017 0.000 0.000 28187 String#hash
20
+ 0.00 145.487 0.004 0.000 145.483 13 *Array#map
21
+ 0.00 0.003 0.003 0.000 0.000 4806 Hash#delete
22
+ 0.00 0.003 0.003 0.000 0.000 5198 String#to_s
23
+ 0.00 0.040 0.002 0.000 0.037 304 Hash#hash
24
+ 0.00 0.043 0.002 0.000 0.041 303 Crosscounter::Util#tuplize
25
+ 0.00 0.017 0.001 0.000 0.015 534 Crosscounter::Util#stringify_keys
26
+ 0.00 143.921 0.001 0.000 143.920 302 Enumerable#inject
27
+ 0.00 0.000 0.000 0.000 0.000 534 Hash#keys
28
+ 0.00 145.487 0.000 0.000 145.487 1 Global#[No method]
29
+ 0.00 145.487 0.000 0.000 145.487 1 Crosscounter::Compute#compute_all
30
+ 0.00 0.001 0.000 0.000 0.001 2 Enumerable#flat_map
31
+ 0.00 0.017 0.000 0.000 0.017 1 Crosscounter::Util#stringify_all
18
32
 
19
- ---
33
+ # Profile as of 86b6735f
20
34
 
21
- # 1 Total: 194.028314
35
+ Total: 95.443315
36
+ Sort by: self_time
22
37
 
23
38
  %self total self wait child calls name
24
- 37.23 164.362 72.237 0.000 92.125 10681477 *Hash#each
25
- 11.02 21.382 21.380 0.000 0.001 10972331 <Module::Crosscounter::Compute>#regexify
26
- 10.90 21.147 21.146 0.000 0.000 10972547 String#sub
27
- 7.86 177.838 15.241 0.000 162.596 10676448 Enumerable#all?
28
- 7.02 13.617 13.617 0.000 0.000 10974955 String#=~
29
- 6.78 190.996 13.158 0.000 177.838 13566 Array#count
30
- 4.73 9.179 9.179 0.000 0.000 10972581 Hash#fetch
31
- 4.66 9.047 9.047 0.000 0.000 11043313 Symbol#to_s
32
- 4.47 8.676 8.676 0.000 0.000 10972786 String#to_sym
33
- 3.02 5.866 5.866 0.000 0.000 9305498 String#to_s
34
- 0.81 1.577 1.577 0.000 0.000 1706407 Fixnum#to_s
35
- 0.06 188.146 0.118 0.000 188.028 8381 *Array#each
36
- 0.05 192.566 0.105 0.000 192.460 4174 *Array#map
37
- 0.04 0.079 0.079 0.000 0.000 8026 String#gsub
39
+ 24.92 34.030 23.780 0.000 10.250 15295038 Set#include?
40
+ 18.47 78.989 17.624 0.000 61.365 14675388 Enumerable#all?
41
+ 17.04 95.254 16.265 0.000 78.989 27482 Array#count
42
+ 10.74 10.250 10.250 0.000 0.000 15295038 Hash#include?
43
+ 0.37 94.999 0.351 0.000 94.648 14676224 *Array#each
44
+ 0.05 95.299 0.045 0.000 95.254 27482 Crosscounter::Compute#compute
45
+ 0.02 0.054 0.017 0.000 0.037 837 Hash#each
46
+ 0.01 0.014 0.014 0.000 0.000 6884 Set#add
47
+ 0.00 0.004 0.004 0.000 0.000 5419 Kernel#kind_of?
48
+ 0.00 0.034 0.003 0.000 0.031 534 Set#initialize
49
+ 0.00 0.029 0.002 0.000 0.027 534 Set#merge
50
+ 0.00 95.443 0.002 0.000 95.441 2751 *Array#map
51
+ 0.00 0.056 0.002 0.000 0.055 837 Crosscounter::Util#stringify
52
+ 0.00 0.026 0.002 0.000 0.025 534 Set#do_with_enum
53
+ 0.00 0.055 0.001 0.000 0.054 837 Enumerable#flat_map
54
+ 0.00 0.061 0.001 0.000 0.060 534 Crosscounter::Util#setify
55
+ 0.00 0.035 0.001 0.000 0.034 1068 *Class#new
56
+ 0.00 0.024 0.001 0.000 0.023 534 Enumerable#each_entry
57
+ 0.00 94.319 0.001 0.000 94.318 302 Enumerable#inject
58
+ 0.00 0.001 0.001 0.000 0.000 534 Hash#initialize
59
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#respond_to?
60
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#nil?
61
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#instance_of?
62
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#class
63
+ 0.00 95.443 0.000 0.000 95.443 1 Global#[No method]
64
+ 0.00 95.443 0.000 0.000 95.443 1 Crosscounter::Compute#compute_all
65
+
66
+ # Profile as of 746633d
38
67
 
39
- # 2 Total: 112.476687 (1.73x Faster)
68
+ Total: 50.415018
69
+ Sort by: self_time
40
70
 
41
71
  %self total self wait child calls name
42
- 39.07 84.951 43.949 0.000 41.002 10681477 *Hash#each
43
- 17.29 19.451 19.450 0.000 0.001 10972331 <Module::Crosscounter::Compute>#regexify
44
- 12.52 97.285 14.085 0.000 83.200 10676448 Enumerable#all?
45
- 11.02 12.400 12.400 0.000 0.000 10974955 String#=~
46
- 10.87 109.508 12.224 0.000 97.285 13566 Array#count
47
- 4.78 5.379 5.379 0.000 0.000 9305498 String#to_s
48
- 1.33 1.494 1.494 0.000 0.000 1706407 Fixnum#to_s
49
- 0.53 0.596 0.596 0.000 0.000 305605 String#sub
50
- 0.09 110.965 0.104 0.000 110.860 4174 *Array#map
51
- 0.09 108.632 0.096 0.000 108.536 9168 *Array#each
52
- 0.08 0.139 0.089 0.000 0.050 8605 ActiveSupport::Callbacks::ClassMethods#__callback_runner_name
53
- 0.06 0.088 0.068 0.000 0.021 4722 <Class::ActiveSupport::TimeZone>#seconds_to_utc_offset
54
- 0.04 0.050 0.050 0.000 0.000 64463 Symbol#to_s
55
- 0.04 0.108 0.049 0.000 0.059 7875 ActiveRecord::AttributeMethods::Read::ClassMethods#type_cast_attribute
56
- 0.04 0.056 0.047 0.000 0.009 4210 <Class::Hash>#[]
57
- 0.04 0.326 0.046 0.000 0.281 11530 ActiveRecord::AttributeMethods#respond_to?
58
- 0.04 0.684 0.044 0.000 0.641 4191 ActiveRecord::Base#init_with
59
- 0.04 0.041 0.041 0.000 0.000 8026 String#gsub
72
+ 47.33 33.178 23.862 0.000 9.317 15295038 Set#include?
73
+ 33.90 50.270 17.091 0.000 33.178 27482 Array#count
74
+ 18.48 9.317 9.317 0.000 0.000 15295038 Hash#include?
75
+ 0.10 49.839 0.050 0.000 49.789 836 Array#each
76
+ 0.09 50.315 0.045 0.000 50.270 27482 Crosscounter::Compute#compute
77
+ 0.03 0.013 0.013 0.000 0.000 6884 Set#add
78
+ 0.03 0.022 0.013 0.000 0.009 536 Hash#each
79
+ 0.01 0.003 0.003 0.000 0.000 4817 Kernel#kind_of?
80
+ 0.00 0.031 0.002 0.000 0.029 534 Set#initialize
81
+ 0.00 0.027 0.002 0.000 0.025 534 Set#merge
82
+ 0.00 50.415 0.002 0.000 50.413 2149 *Array#map
83
+ 0.00 0.024 0.001 0.000 0.023 534 Set#do_with_enum
84
+ 0.00 0.056 0.001 0.000 0.055 534 Crosscounter::Util#setify
85
+ 0.00 0.024 0.001 0.000 0.023 536 Crosscounter::Util#stringify
86
+ 0.00 0.032 0.001 0.000 0.031 1068 *Class#new
87
+ 0.00 0.023 0.001 0.000 0.022 536 Enumerable#flat_map
88
+ 0.00 49.818 0.001 0.000 49.817 302 Enumerable#inject
89
+ 0.00 0.022 0.001 0.000 0.022 534 Enumerable#each_entry
90
+ 0.00 0.001 0.001 0.000 0.000 534 Hash#initialize
91
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#respond_to?
92
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#instance_of?
93
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#class
94
+ 0.00 0.000 0.000 0.000 0.000 534 Kernel#nil?
95
+ 0.00 50.415 0.000 0.000 50.415 1 Global#[No method]
96
+ 0.00 50.415 0.000 0.000 50.415 1 Crosscounter::Compute#compute_all
60
97
 
61
- # Total: 92.512639 (1.21x Faster)
98
+ Total: 26.442810
99
+ Sort by: self_time
62
100
 
63
101
  %self total self wait child calls name
64
- 50.37 65.501 46.595 0.000 18.906 10681477 *Hash#each
65
- 14.75 77.401 13.648 0.000 63.753 10676448 Enumerable#all?
66
- 13.03 89.452 12.051 0.000 77.401 13566 Array#count
67
- 7.61 7.039 7.039 0.000 0.000 10894304 Kernel#kind_of?
68
- 2.15 3.004 1.986 0.000 1.018 1670405 String#==
69
- 2.12 1.959 1.958 0.000 0.000 1040575 Array#join
70
- 2.08 4.924 1.920 0.000 3.004 1670214 Fixnum#==
102
+ 64.06 26.310 16.939 0.000 9.371 27482 Array#count
103
+ 35.44 9.371 9.371 0.000 0.000 15295038 Hash#member?
104
+ 0.22 26.123 0.058 0.000 26.064 836 Array#each
105
+ 0.17 26.356 0.046 0.000 26.310 27482 Crosscounter::Compute#compute
106
+ 0.05 0.022 0.013 0.000 0.009 536 Hash#each
107
+ 0.01 0.003 0.003 0.000 0.000 4817 Kernel#kind_of?
108
+ 0.01 26.443 0.002 0.000 26.441 2149 *Array#map
109
+ 0.01 26.124 0.002 0.000 26.123 836 Enumerable#inject
110
+ 0.00 0.037 0.001 0.000 0.036 534 Crosscounter::Util#hashify
111
+ 0.00 0.024 0.001 0.000 0.023 536 Crosscounter::Util#stringify
112
+ 0.00 0.023 0.001 0.000 0.022 536 Enumerable#flat_map
113
+ 0.00 26.443 0.000 0.000 26.443 1 Global#[No method]
114
+ 0.00 26.443 0.000 0.000 26.443 1 Crosscounter::Compute#compute_all
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Code Climate](https://codeclimate.com/github/sorentwo/crosscounter.png)](https://codeclimate.com/github/sorentwo/crosscounter)
2
+ [![Build Status](https://travis-ci.org/sorentwo/crosscounter.png?branch=master)](https://travis-ci.org/sorentwo/crosscounter)
3
+
1
4
  # Crosscounter
2
5
 
3
6
  A set of functional tools for generating cross tabulations.
@@ -6,11 +9,50 @@ A set of functional tools for generating cross tabulations.
6
9
 
7
10
  Add this line to your application's Gemfile:
8
11
 
9
- gem 'crosscounter', '~> 0.1.0.beta'
12
+ ```ruby
13
+ gem 'crosscounter'
14
+ ```
10
15
 
11
16
  ## Usage
12
17
 
13
- This is in early development. It isn't intended for general use.
18
+ Crosscounter works entirely with standard data structures, i.e. arrays and
19
+ hashes. General usage is to provide an enumerable containing hashes of values,
20
+ followed by a rows hash and a columns hash.
21
+
22
+
23
+ ```ruby
24
+ enumerable = [
25
+ { age: 18, gender: 'male', tags: %w[happy sad] },
26
+ { age: 19, gender: 'female', tags: %w[happy mad] },
27
+ { age: 18, gender: 'male', tags: %w[mad sad] },
28
+ { age: 19, gender: 'male', tags: %w[sad] }
29
+ ]
30
+
31
+ rows = {
32
+ age: [18, 19],
33
+ gender: %w[male female],
34
+ tags: %w[happy sad mad]
35
+ }
36
+
37
+ cols = { tags: %w[happy sad mad] }
38
+
39
+ computer.compute_all(enumerable, rows, cols) #=> [
40
+ [18, 2, 1, 2, 1],
41
+ [19, 2, 1, 1, 1],
42
+ ['male', 3, 1, 3, 1],
43
+ ['female', 1, 1, 0, 1],
44
+ ['happy', 2, 2, 1, 1],
45
+ ['sad', 3, 1, 3, 1],
46
+ ['mad', 2, 1, 1, 2]
47
+ ]
48
+ ```
49
+
50
+ The resulting output is an array of arrays mapping out every row value against
51
+ every column value. In the example above the columns are:
52
+
53
+ | key | all | tags['happy'] | tags['sad'] | tags['mad'] |
54
+ | --- | --- | ------------- | ----------- | ----------- |
55
+ | 18 | 2 | 1 | 2 | 1 |
14
56
 
15
57
  ## Contributing
16
58
 
data/Rakefile CHANGED
@@ -4,4 +4,4 @@ require 'rspec/core/rake_task'
4
4
 
5
5
  RSpec::Core::RakeTask.new :spec
6
6
 
7
- task :default => :spec
7
+ task default: :spec
data/bench/cols.json ADDED
@@ -0,0 +1 @@
1
+ {"answers":["Q4 This is a big step forward.","Q4 This is a little step forward.","Q4 This is a big step back.","Q4 This is a little step back.","Q4 I'm not sure yet!","Q6 Apple is leading.","Q6 Apple is following.","Q9 constantly (many times daily)","Q9 often (daily)","Q9 sometimes (at least once a week)","Q9 infrequently (less than once a week)","Q9 very rarely (or never)"],"tags":["00: stuff","01: wacky","02: data","03: parking","0: parking lot","0: weird","1: air drop","1: battery life","1: control center","1: data detectors","1: fingerprint","1: folders","1: home screen","1: integration","1: lock screen","1: mulltitasking","1: notification center","1: other","1: ringtones","1: settings","1: siri","1: slide to","1: spotlight","2: app store","2: calendar","2: camera","2: clock","2: compass","2: facetime","2: game center","2: mail","2: maps","2: messages","2: music","2: notes","2: other","2: passbook","2: phone","2: photos","2: reminders","2: safari","2: videos","2: weather","3: backgrounds","3: colors","3: icons","3: motion","3: other","3: transparency","3: typography","4: bug/crash/etc","4: functionality","4: other","4: privacy","4: usability","5: aesthetics","5: integration","5: learning/context/automation","5: none","5: options/settings","5: other","5: revert","6: can't update","6: fantastic","6: gratuitious","at: android","at: apple","at: clean","at: color","at: control center","at: flashlight","at: flat","at: home","at: icon","at: multitasking","at: pretty","at: swipe","auto: color"]}
data/bench/compute.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'bundler'
2
+
3
+ Bundler.setup
4
+
5
+ require 'benchmark'
6
+ require 'crosscounter'
7
+ require 'json'
8
+
9
+ rows = JSON.load(IO.read('bench/rows.json'))
10
+ cols = JSON.load(IO.read('bench/cols.json'))
11
+ data = JSON.load(IO.read('bench/data.json'))
12
+
13
+ if ENV['PROFILE']
14
+ require 'ruby-prof'
15
+
16
+ result = RubyProf.profile do
17
+ Crosscounter::Compute.compute_all(data, rows, cols)
18
+ end
19
+
20
+ printer = RubyProf::FlatPrinter.new(result)
21
+ printer.print(STDOUT)
22
+ else
23
+ Benchmark.bmbm do |x|
24
+ x.report('compute_all' ) do
25
+ Crosscounter::Compute.compute_all(data, rows, cols)
26
+ end
27
+ end
28
+ end