differential 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8056552239b827530db049760009cb2e98458599
4
+ data.tar.gz: b27b320eb9fe5c3345d5ef537481314a947845c4
5
+ SHA512:
6
+ metadata.gz: 3c917a846233ba35dee29e3f09de018c1e964103999cc93ae99b313fe4186e1196c5d03f52d5c9c3a1f5ee40da42681fd10b49554ddb1a742a3f1c41e476d499
7
+ data.tar.gz: 3e3ff548564c27080426c905ebb234fb557e82fd29a0704e09ad8b4169e2ead965a0fba155f812c821575a06b1367a9fe2fd8df9dda4d167f8d838e4694838a9
data/.editorconfig ADDED
@@ -0,0 +1,8 @@
1
+ # See http://editorconfig.org/
2
+
3
+ [*]
4
+ trim_trailing_whitespace = true
5
+ indent_style = space
6
+ indent_size = 2
7
+ insert_final_newline = true
8
+ end_of_line = lf
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ *.gem
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+
4
+ Metrics/BlockLength:
5
+ ExcludedMethods: ['it', 'describe', 'context']
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.7
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.1
4
+ - 2.3.7
5
+ cache: bundler
6
+ script:
7
+ - bundle exec rubocop
8
+ - bundle exec rspec
9
+ notifications:
10
+ hipchat:
11
+ rooms:
12
+ secure: OpIo19mre1zR5gJlr1T7BD/jVBYadikM49ueC4HWPt3Wln6LlNM3G1gcXVw4A5Ppd7p+6251aOhLHA44HdjXSo+VrhfgiFO9tfkyNuVIrLxeZr/eQwEnv1JJlPJdL/y2sGsBS5WRIgo+txIkLflQ0zoDpvnR6zkWRaRYZcRWo+X9Q890VHRR0emHURX5Kqsi5sJjHac69uIRbEAtlvdd1KnfNXF6+2udMnH6Kb4BxrSUp6voQ+VTyTGM4f2uMInxvjTVNzCCLgb4zBa5KwZNjjLRXWwIsWC0jVia0IRNskaeoFkFQxsVb33kq55t8XxR/ZuHUr5exFUazPnEc3ht9L/GOCYX4qFwbVPyxwyVZ64hHLx3E5g4ozlVCvBH3MDqkoasep7x+Ml8RuA6lSM2hIM88Eo5g98wpXW2WPiHUTxbtIc/2qKTmMKPZI+J23tuR7kza/5kGyPlqKA5OXr++0MFIUtFhWs1iSSQnq0Anssfxd1EhXPKqR/vqpQVgNSpv/cJOMQInPHSkvcq7kMRQWxka9uXHFT1+YH3kYCsAB30bdp8IPMNKQuemGhqS7GZXke9M32Yx9TKykGyAkzv6NGSc1pUAEViGHuydm6mTdvXYBfTQ3ZE6SIP+Rx5/WCyAyPerADPMI26enlFzzSPucdVU8wErceH1Uq7AleVNFw=
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,87 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ differential (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.0)
10
+ coderay (1.1.2)
11
+ diff-lcs (1.3)
12
+ ffi (1.9.25)
13
+ formatador (0.2.5)
14
+ guard (2.15.0)
15
+ formatador (>= 0.2.4)
16
+ listen (>= 2.7, < 4.0)
17
+ lumberjack (>= 1.0.12, < 2.0)
18
+ nenv (~> 0.1)
19
+ notiffany (~> 0.0)
20
+ pry (>= 0.9.12)
21
+ shellany (~> 0.0)
22
+ thor (>= 0.18.1)
23
+ guard-compat (1.2.1)
24
+ guard-rspec (4.7.3)
25
+ guard (~> 2.1)
26
+ guard-compat (~> 1.1)
27
+ rspec (>= 2.99.0, < 4.0)
28
+ jaro_winkler (1.5.1)
29
+ listen (3.1.5)
30
+ rb-fsevent (~> 0.9, >= 0.9.4)
31
+ rb-inotify (~> 0.9, >= 0.9.7)
32
+ ruby_dep (~> 1.2)
33
+ lumberjack (1.0.13)
34
+ method_source (0.9.2)
35
+ nenv (0.3.0)
36
+ notiffany (0.1.1)
37
+ nenv (~> 0.1)
38
+ shellany (~> 0.0)
39
+ parallel (1.12.1)
40
+ parser (2.5.3.0)
41
+ ast (~> 2.4.0)
42
+ powerpack (0.1.2)
43
+ pry (0.12.2)
44
+ coderay (~> 1.1.0)
45
+ method_source (~> 0.9.0)
46
+ rainbow (3.0.0)
47
+ rb-fsevent (0.10.3)
48
+ rb-inotify (0.9.10)
49
+ ffi (>= 0.5.0, < 2)
50
+ rspec (3.8.0)
51
+ rspec-core (~> 3.8.0)
52
+ rspec-expectations (~> 3.8.0)
53
+ rspec-mocks (~> 3.8.0)
54
+ rspec-core (3.8.0)
55
+ rspec-support (~> 3.8.0)
56
+ rspec-expectations (3.8.2)
57
+ diff-lcs (>= 1.2.0, < 2.0)
58
+ rspec-support (~> 3.8.0)
59
+ rspec-mocks (3.8.0)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.8.0)
62
+ rspec-support (3.8.0)
63
+ rubocop (0.59.2)
64
+ jaro_winkler (~> 1.5.1)
65
+ parallel (~> 1.10)
66
+ parser (>= 2.5, != 2.5.1.1)
67
+ powerpack (~> 0.1)
68
+ rainbow (>= 2.2.2, < 4.0)
69
+ ruby-progressbar (~> 1.7)
70
+ unicode-display_width (~> 1.0, >= 1.0.1)
71
+ ruby-progressbar (1.10.0)
72
+ ruby_dep (1.5.0)
73
+ shellany (0.0.1)
74
+ thor (0.20.3)
75
+ unicode-display_width (1.4.0)
76
+
77
+ PLATFORMS
78
+ ruby
79
+
80
+ DEPENDENCIES
81
+ differential!
82
+ guard-rspec (~> 4.7)
83
+ rspec (~> 3.8)
84
+ rubocop (~> 0.59)
85
+
86
+ BUNDLED WITH
87
+ 1.17.1
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard :rspec, cmd: 'bundle exec rspec' do
4
+ require 'guard/rspec/dsl'
5
+ dsl = Guard::RSpec::Dsl.new(self)
6
+
7
+ # RSpec files
8
+ rspec = dsl.rspec
9
+ watch(rspec.spec_helper) { rspec.spec_dir }
10
+ watch(rspec.spec_support) { rspec.spec_dir }
11
+ watch(rspec.spec_files)
12
+
13
+ # Ruby files
14
+ ruby = dsl.ruby
15
+ dsl.watch_spec_files_for(ruby.lib_files)
16
+ end
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2018 Blue Marble Payroll, LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,223 @@
1
+ # Differential
2
+
3
+ [![Build Status](https://travis-ci.org/bluemarblepayroll/differential.svg?branch=master)](https://travis-ci.org/bluemarblepayroll/differential)
4
+
5
+ Have you ever had two numerical-based data sets of mostly the same data and you wanted to see the summations and deltas of each data set at the report, group, and line level? Look no further! Differential allows you to pass in two data sets and it will calculate all that for you.
6
+
7
+ Consider the following two data sets showing commute times for employees:
8
+
9
+ **Week 1 Commute Times:**
10
+
11
+ | Name | Transport | Minutes
12
+ | ----- | --------- | -------
13
+ | Matt | Car | 50
14
+ | Nick | Car | 75
15
+ | Sam | Train | 48
16
+ | Katie | Bike | 12
17
+
18
+ **Week 2 Commute Times:**
19
+
20
+ | Name | Transport | Minutes
21
+ | ----- | --------- | -------
22
+ | Matt | Car | 30
23
+ | Nick | Car | 50
24
+ | Sam | Train | 60
25
+ | Nate | Walk | 12
26
+
27
+ You could use Differential to compute the following reports:
28
+
29
+ **By Employee:**
30
+
31
+ | Name | Wk. 1 Minutes | Wk. 2 Minutes | Difference
32
+ | --------- | ------------- | ------------- | ----------
33
+ | Matt | 50 | 30 | -20
34
+ | Nick | 75 | 50 | -25
35
+ | Sam | 48 | 60 | 12
36
+ | Katie | 12 | 0 | -12
37
+ | Nate | 0 | 12 | 12
38
+ | **TOTAL** | **185** | **152** | **-33**
39
+
40
+ **By Transport Type:**
41
+
42
+ | Transport | Wk. 1 Minutes | Wk. 2 Minutes | Difference
43
+ | --------- | ------------- | ------------- | ----------
44
+ | Car | 125 | 80 | -20
45
+ | Train | 48 | 60 | -25
46
+ | Bike | 12 | 0 | 12
47
+ | Walk | 0 | 12 | -12
48
+ | **TOTAL** | **185** | **152** | **-33**
49
+
50
+ **By Employee, Grouped By Transport Type**
51
+
52
+ | Transport | Employee | Wk. 1 Minutes | Wk. 2 Minutes | Difference
53
+ | ------------ | ------------- | ------------- | ------------- | ----------
54
+ | Car | Matt | 50 | 30 | -20
55
+ | Car | Nick | 75 | 50 | -25
56
+ | **SUBTOTAL** | | **125** | **80** | **-45**
57
+ | Train | Sam | 48 | 60 | 12
58
+ | **SUBTOTAL** | | **48** | **60** | **12**
59
+ | Bike | Katie | 12 | 0 | -12
60
+ | **SUBTOTAL** | | **12** | **0** | **-12**
61
+ | Walk | Nate | 0 | 12 | 12
62
+ | **SUBTOTAL** | | **0** | **12** | **12**
63
+ | **TOTAL** | | **185** | **152** | **-33**
64
+
65
+ ## Installation
66
+
67
+ To install through Rubygems:
68
+
69
+ ````
70
+ gem install install differential
71
+ ````
72
+
73
+ You can also add this to your Gemfile:
74
+
75
+ ````
76
+ bundle add differential
77
+ ````
78
+
79
+ ## Examples
80
+
81
+ In the above example the data sets could be represented as:
82
+
83
+ ```
84
+ week1_data = [
85
+ { name: 'Matt', transport: 'Car', minutes: 50 },
86
+ { name: 'Nick', transport: 'Car', minutes: 75 },
87
+ { name: 'Sam', transport: 'Train', minutes: 48 },
88
+ { name: 'Katie', transport: 'Bike', minutes: 12 }
89
+ ]
90
+
91
+ week2_data = [
92
+ { name: 'Matt', transport: 'Car', minutes: 30 },
93
+ { name: 'Nick', transport: 'Car', minutes: 50 },
94
+ { name: 'Sam', transport: 'Train', minutes: 60 },
95
+ { name: 'Nate', transport: 'Walk', minutes: 12 }
96
+ ]
97
+ ```
98
+
99
+ ### By Employee Report
100
+
101
+ There is a couple key pieces of configuration you need to establish. Below is the configuration necessary for the 'By Employee' report:
102
+
103
+ ```
104
+ reader_config = {
105
+ record_id_key: :name,
106
+ value_key: :minutes
107
+ }
108
+ ```
109
+
110
+ To run the report, run:
111
+
112
+ ```
113
+ report = Differential.calculate(week1_data, week2_data, reader_config)
114
+ ```
115
+
116
+ The report variable will now hold a Report object with the following methods:
117
+
118
+ * a_sigma: sum of all A record values
119
+ * b_sigma: sum of all B record values
120
+ * delta: difference of B - A
121
+ * groups: all groups and their respective items
122
+
123
+ You can further iterate over groups. Similar to Report, each group provides the following methods:
124
+
125
+ * a_sigma: sum of all items in the group for dataset A
126
+ * b_sigma: sum of all items in the group for dataset B
127
+ * delta: difference of all the items in the group: B - A
128
+ * items: all items belonging to the group
129
+
130
+ Finally, you can iterate over the items array and access the following:
131
+
132
+ * a_sigma: sum of items in dataset A
133
+ * b_sigma: sum of items in dataset B
134
+ * delta: difference of items B - A
135
+ * a_records: all dataset A records that were aggregated together to produce this item
136
+ * b_records: all dataset B records that were aggregated together to produce this item
137
+
138
+ ### By Transport Report
139
+
140
+ Change the options like so:
141
+
142
+ ```
143
+ reader_config = {
144
+ record_id_key: :transport,
145
+ value_key: :minutes
146
+ }
147
+ ```
148
+
149
+ Then execute:
150
+
151
+ ```
152
+ report = Differential.calculate(week1_data, week2_data, reader_config)
153
+ ```
154
+
155
+ ### By Employee, Grouped By Transport Type Report
156
+
157
+ Change the options like so:
158
+
159
+ ```
160
+ reader_config = {
161
+ record_id_key: :name,
162
+ value_key: :minutes,
163
+ group_id_key: :transport
164
+ }
165
+ ```
166
+
167
+ Then execute:
168
+
169
+ ```
170
+ report = Differential.calculate(week1_data, week2_data, reader_config)
171
+ ```
172
+
173
+ Now, this will output a report with two groups instead of one which will allow you to present this with sub-totals.
174
+
175
+ ### Compound ID Keys
176
+
177
+ You are not restricted to automatically derive a unique ID per record, the library can also handle this like so:
178
+
179
+ ```
180
+ reader_config = {
181
+ record_id_key: [:company_id, :employee_id],
182
+ value_key: :minutes,
183
+ group_id_key: [:transport, :direction]
184
+ }
185
+ ```
186
+
187
+ In this example we are showing that a unique identifier for an employee is not just the employee's ID, but also the companies ID. The above configuration would output a dataset that is grouped by transport type and direction (i.e. Outbound Train, Inbound Train, Outbound Car, etc...) and lists each unique employee per company in each group.
188
+
189
+ ## Contributing
190
+
191
+ ### Development Environment Configuration
192
+
193
+ Basic steps to take to get this repository compiling:
194
+
195
+ 1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/) (check differential.gemspec for versions supported)
196
+ 2. Install bundler (gem install bundler)
197
+ 3. Clone the repository (git clone git@github.com:bluemarblepayroll/differential.git)
198
+ 4. Navigate to the root folder (cd differential)
199
+ 5. Install dependencies (bundle)
200
+
201
+ ### Running Tests
202
+
203
+ To execute the test suite run:
204
+
205
+ ````
206
+ bundle exec rspec spec --format documentation
207
+ ````
208
+
209
+ Alternatively, you can have Guard watch for changes:
210
+
211
+ ````
212
+ bundle exec guard
213
+ ````
214
+
215
+ Also, do not forget to run Rubocop:
216
+
217
+ ````
218
+ bundle exec rubocop
219
+ ````
220
+
221
+ ## License
222
+
223
+ This project is MIT Licensed.
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/differential/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'differential'
7
+ s.version = Differential::VERSION
8
+ s.summary = 'Dataset Differential Engine'
9
+
10
+ s.description = <<-DESCRIPTION
11
+ Differential is a numeric-based library will compare two datasets and give you three
12
+ levels of comparison: report, group, and item level.
13
+ Each level provides the sum of each dataset and the difference.
14
+ DESCRIPTION
15
+
16
+ s.authors = ['Matthew Ruggio']
17
+ s.email = ['mruggio@bluemarblepayroll.com']
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
+ s.homepage = 'https://github.com/bluemarblepayroll/differential'
22
+ s.license = 'MIT'
23
+
24
+ s.required_ruby_version = '>= 2.3.1'
25
+
26
+ s.add_development_dependency('guard-rspec', '~>4.7')
27
+ s.add_development_dependency('rspec', '~> 3.8')
28
+ s.add_development_dependency('rubocop', '~> 0.59')
29
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2018-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require_relative 'differential/differential'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2018-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require_relative 'side'
11
+ require_relative 'has_totals'
12
+ require_relative 'item'
13
+ require_relative 'group'
14
+ require_relative 'report'
15
+ require_relative 'totals'