crosscounter 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.travis.yml +2 -0
- data/NOTES.txt +102 -58
- data/README.md +44 -2
- data/Rakefile +1 -1
- data/bench/cols.json +1 -0
- data/bench/compute.rb +28 -0
- data/bench/data.json +1 -0
- data/bench/rows.json +1 -0
- data/crosscounter.gemspec +4 -2
- data/lib/crosscounter/compute.rb +23 -18
- data/lib/crosscounter/expansion.rb +5 -3
- data/lib/crosscounter/util.rb +14 -13
- data/lib/crosscounter/version.rb +1 -1
- data/lib/crosscounter.rb +3 -2
- data/spec/crosscounter/compute_spec.rb +14 -37
- data/spec/crosscounter/expansion_spec.rb +2 -2
- data/spec/crosscounter/util_spec.rb +12 -3
- data/spec/spec_helper.rb +6 -0
- metadata +46 -23
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
data/.travis.yml
CHANGED
data/NOTES.txt
CHANGED
@@ -1,70 +1,114 @@
|
|
1
|
-
|
1
|
+
# Profile as of dafc032
|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
0.
|
16
|
-
|
17
|
-
|
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
|
-
|
35
|
+
Total: 95.443315
|
36
|
+
Sort by: self_time
|
22
37
|
|
23
38
|
%self total self wait child calls name
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
0.
|
35
|
-
0.
|
36
|
-
0.
|
37
|
-
0.
|
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
|
-
|
68
|
+
Total: 50.415018
|
69
|
+
Sort by: self_time
|
40
70
|
|
41
71
|
%self total self wait child calls name
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
0.
|
50
|
-
0.
|
51
|
-
0.
|
52
|
-
0.
|
53
|
-
0.
|
54
|
-
0.
|
55
|
-
0.
|
56
|
-
0.
|
57
|
-
0.
|
58
|
-
0.
|
59
|
-
0.
|
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
|
-
|
98
|
+
Total: 26.442810
|
99
|
+
Sort by: self_time
|
62
100
|
|
63
101
|
%self total self wait child calls name
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
12
|
+
```ruby
|
13
|
+
gem 'crosscounter'
|
14
|
+
```
|
10
15
|
|
11
16
|
## Usage
|
12
17
|
|
13
|
-
|
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
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
|