totalr 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in totalr.gemspec
4
+ gemspec
5
+ gem 'rspec'
6
+ gem 'active_support'
data/README ADDED
@@ -0,0 +1,24 @@
1
+ Totalr is a ruby library which gives a dsl that lets you do aggregations in your model declaratively.
2
+ It is inspired by the statistical capabilities of R. Currently it does not even do 1 % of what R does.
3
+
4
+ But it still lets you do aggregations like totaling, percentage, grouping in your model easily:
5
+
6
+ class Team
7
+ total :players, using: :goals, by: :age
8
+ end
9
+
10
+ This creates a dynamic method total_player_goals_by_age which takes an age param.
11
+
12
+ class Team
13
+ percentage :total_player_goals, of: :total_player_attempts, as: :goals_to_attempts
14
+ end
15
+
16
+ This creates a method which calculates percentage of goals:attempts for all players in the model.
17
+
18
+ Totalr does not serve to replace any aggregation mechanism already provided by ORM or Enumerable.
19
+ It only complements them by generating methods like this.
20
+
21
+ You can give custom names to generated methods using :as key
22
+ For documentation/features look at spec/totalr_spec.rb
23
+
24
+ More features like mean, variance are still under development.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ module Totalr
2
+ VERSION = "0.0.1"
3
+ end
data/lib/totalr.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'active_support/inflector'
2
+
3
+ module Totalr
4
+ def self.included(klass)
5
+ klass.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def total(coll_name, options = {})
10
+ attribute = options[:using]
11
+ group_by = options[:by]
12
+ method_name = options[:as]
13
+ method_name ||= "total_#{ActiveSupport::Inflector.singularize(coll_name.to_s)}_#{attribute}_for_#{group_by}" if attribute and group_by
14
+ method_name ||= "total_#{ActiveSupport::Inflector.singularize(coll_name.to_s)}_#{attribute}" if attribute
15
+ method_name ||= "total_#{coll_name}_for_#{group_by}" if group_by
16
+ method_name ||= "total_#{coll_name}"
17
+
18
+ method_body = if group_by
19
+ if attribute
20
+ lambda do |group_value|
21
+ coll = send(coll_name)
22
+ coll.select {|e| e.send(group_by) == group_value}.map {|e| e.send(attribute)}.inject(:+)
23
+ end
24
+ else
25
+ lambda do |group_value|
26
+ coll = send(coll_name)
27
+ coll.select {|e| e.send(group_by) == group_value}.length
28
+ end
29
+ end
30
+
31
+ else
32
+ if attribute
33
+ lambda do
34
+ coll = send(coll_name)
35
+ coll.map {|e| e.send(attribute)}.inject(:+)
36
+ end
37
+ else
38
+ lambda do
39
+ coll = send(coll_name)
40
+ coll.length
41
+ end
42
+ end
43
+ end
44
+ define_method method_name, method_body
45
+ end
46
+
47
+ def percentage(part_count_method, options = {})
48
+ total_count_method = options[:of]
49
+ part_by = options[:by]
50
+ total_by = options[:total_by]
51
+
52
+ method_name = options[:as]
53
+ method_name ||= "percentage_#{part_count_method}_in_#{total_by}" if total_by
54
+ method_name ||= "percentage_#{part_count_method}"
55
+
56
+ if total_by and total_by != part_by
57
+ define_method method_name do |part_by_value, total_by_value|
58
+ part_count = send(part_count_method, part_by_value)
59
+ total_count = total_by ? send(total_count_method, total_by_value) : send(total_count_method)
60
+ part_count * 100.00 / total_count
61
+ end
62
+
63
+ else
64
+ define_method method_name do |part_by_value|
65
+ part_count = send(part_count_method, part_by_value)
66
+ total_count = total_by ? send(total_count_method, part_by_value) : send(total_count_method)
67
+ part_count * 100.00 / total_count
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'totalr'
@@ -0,0 +1,193 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe Totalr do
5
+
6
+ class Team
7
+ include Totalr
8
+ attr_accessor :players
9
+
10
+ def initialize(params)
11
+ @name = params[:name]
12
+ @players = []
13
+ end
14
+ end
15
+
16
+ class Player
17
+ attr_reader :goals
18
+ attr_reader :attempts
19
+ attr_reader :age
20
+ attr_reader :region
21
+ def initialize(params)
22
+ @name = params[:name]
23
+ @goals = params[:goals]
24
+ @attempts = params[:attempts]
25
+ @age = params[:age]
26
+ @region = params[:region]
27
+ end
28
+
29
+ end
30
+
31
+ describe "total" do
32
+
33
+ class Team
34
+ total :players
35
+ end
36
+
37
+ it "should total collection" do
38
+ real_madrid = Team.new(name: 'Real Madrid')
39
+ real_madrid.players << Player.new(name: 'Ronaldo')
40
+ real_madrid.players << Player.new(name: 'Beckham')
41
+
42
+ real_madrid.total_players.should == 2
43
+ end
44
+
45
+ class Team
46
+ total :players, as: :player_count
47
+ end
48
+
49
+ it "should total collection with custom name" do
50
+ real_madrid = Team.new(name: 'Real Madrid')
51
+ real_madrid.players << Player.new(name: 'Ronaldo')
52
+ real_madrid.players << Player.new(name: 'Beckham')
53
+
54
+ real_madrid.player_count.should == 2
55
+ end
56
+
57
+ class Team
58
+ total :players, using: :goals
59
+ end
60
+
61
+ it "should total collection using attribute" do
62
+ real_madrid = Team.new(name: 'Real Madrid')
63
+ real_madrid.players << Player.new(name: 'Ronaldo', goals: 25)
64
+ real_madrid.players << Player.new(name: 'Beckham', goals: 15)
65
+
66
+ real_madrid.total_player_goals.should == 40
67
+ end
68
+
69
+ class Team
70
+ total :players, using: :goals, as: :number_of_goals
71
+ end
72
+
73
+ it "should total collection using attribute with custom name" do
74
+ real_madrid = Team.new(name: 'Real Madrid')
75
+ real_madrid.players << Player.new(name: 'Ronaldo', goals: 25)
76
+ real_madrid.players << Player.new(name: 'Beckham', goals: 15)
77
+
78
+ real_madrid.number_of_goals.should == 40
79
+ end
80
+
81
+ class Team
82
+ total :players, by: :age
83
+ end
84
+
85
+ it "should total collection grouping by attribute" do
86
+ real_madrid = Team.new(name: 'Real Madrid')
87
+ real_madrid.players << Player.new(name: 'Ronaldo', age: 25)
88
+ real_madrid.players << Player.new(name: 'Beckham', age: 25)
89
+ real_madrid.players << Player.new(name: 'Figo', age: 30)
90
+
91
+ real_madrid.total_players_for_age(25).should == 2
92
+ real_madrid.total_players_for_age(30).should == 1
93
+ end
94
+
95
+ class Team
96
+ total :players, using: :goals, by: :age
97
+ end
98
+
99
+ it "should total collection mapping by attribute and grouping by attribute" do
100
+ real_madrid = Team.new(name: 'Real Madrid')
101
+ real_madrid.players << Player.new(name: 'Ronaldo', goals: 25, age: 25)
102
+ real_madrid.players << Player.new(name: 'Beckham', goals: 15, age: 25)
103
+ real_madrid.players << Player.new(name: 'Figo', goals: 10, age: 30)
104
+
105
+ real_madrid.total_player_goals_for_age(25).should == 40
106
+ real_madrid.total_player_goals_for_age(30).should == 10
107
+ end
108
+
109
+ end
110
+
111
+ describe "percentage" do
112
+ class Team
113
+ total :players
114
+ total :players, by: :age
115
+ percentage :total_players_for_age, by: :age, of: :total_players
116
+ end
117
+
118
+ it "should calculate percentage of total" do
119
+ real_madrid = Team.new(name: 'Real Madrid')
120
+ real_madrid.players << Player.new(name: 'Ronaldo', age: 25)
121
+ real_madrid.players << Player.new(name: 'Beckham', age: 25)
122
+ real_madrid.players << Player.new(name: 'Figo', age: 30)
123
+
124
+ real_madrid.percentage_total_players_for_age(25).round(2).should == 66.67
125
+ real_madrid.percentage_total_players_for_age(30).round(2).should == 33.33
126
+ end
127
+
128
+ class Team
129
+ percentage :total_players_for_age, by: :age, of: :total_players, as: :distribution_by_age
130
+ end
131
+
132
+ it "should calculate percentage of total with custom name" do
133
+ real_madrid = Team.new(name: 'Real Madrid')
134
+ real_madrid.players << Player.new(name: 'Ronaldo', age: 25)
135
+ real_madrid.players << Player.new(name: 'Beckham', age: 25)
136
+ real_madrid.players << Player.new(name: 'Figo', age: 30)
137
+
138
+ real_madrid.distribution_by_age(25).round(2).should == 66.67
139
+ real_madrid.distribution_by_age(30).round(2).should == 33.33
140
+ end
141
+
142
+ class Team
143
+ percentage :total_player_goals_for_age, by: :age, of: :total_player_goals, as: :percentage_goals_by_age
144
+ end
145
+
146
+ it "should calculate percentage of total using attribute" do
147
+ real_madrid = Team.new(name: 'Real Madrid')
148
+ real_madrid.players << Player.new(name: 'Ronaldo', goals: 25, age: 25)
149
+ real_madrid.players << Player.new(name: 'Beckham', goals: 15, age: 25)
150
+ real_madrid.players << Player.new(name: 'Figo', goals: 10, age: 30)
151
+
152
+ real_madrid.percentage_goals_by_age(25).should == 80.00
153
+ real_madrid.percentage_goals_by_age(30).should == 20.00
154
+ end
155
+
156
+ class Team
157
+ total :players, using: :goals, by: :region
158
+ percentage :total_player_goals_for_age, by: :age,
159
+ of: :total_player_goals_for_region, total_by: :region
160
+ end
161
+
162
+ it "should calculate percentage totaling by attribute" do
163
+ real_madrid = Team.new(name: 'Real Madrid')
164
+ real_madrid.players << Player.new(name: 'Ronaldo', goals: 25, age: 28, region: 'southamerica')
165
+ real_madrid.players << Player.new(name: 'Beckham', goals: 20, age: 25, region: 'europe')
166
+ real_madrid.players << Player.new(name: 'Carlos', goals: 10, age: 28, region: 'southamerica')
167
+ real_madrid.players << Player.new(name: 'Figo', goals: 12, age: 30, region: 'europe')
168
+ real_madrid.players << Player.new(name: 'Zidane', goals: 18, age: 30, region: 'europe')
169
+
170
+ real_madrid.percentage_total_player_goals_for_age_in_region(30, 'europe').should == 60.00
171
+ real_madrid.percentage_total_player_goals_for_age_in_region(25, 'europe').should == 40.00
172
+ end
173
+
174
+ class Team
175
+ total :players, using: :goals, by: :age
176
+ total :players, using: :attempts, by: :age
177
+ percentage :total_player_goals_for_age, by: :age,
178
+ of: :total_player_attempts_for_age, total_by: :age,
179
+ as: :goal_to_attempts
180
+
181
+ end
182
+
183
+ it "should calculate percentage totaling by same attribute as percentage" do
184
+ real_madrid = Team.new(name: 'Real Madrid')
185
+ real_madrid.players << Player.new(name: 'Ronaldo', goals: 21, attempts: 30, age: 25)
186
+ real_madrid.players << Player.new(name: 'Beckham', goals: 15, attempts: 20, age: 25)
187
+ real_madrid.players << Player.new(name: 'Figo', goals: 10, attempts: 15, age: 30)
188
+
189
+ real_madrid.goal_to_attempts(25).should == 72.00
190
+ end
191
+ end
192
+
193
+ end
data/totalr.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "totalr/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "totalr"
7
+ s.version = Totalr::VERSION
8
+ s.authors = ["Sathish"]
9
+ s.email = ["sathish316@gmail.com"]
10
+ s.homepage = "http://www.github.com/sathish316/totalr"
11
+ s.summary = %q{Totalr is a lib which provides a simple dsl to do aggregation in models, like totals, percentage, grouping, mean, variance et
12
+ c}
13
+ s.description = %q{Totalr is a lib which provides a simple dsl to do aggregation in models, like totals, percentage, grouping, mean, variance et
14
+ c}
15
+ s.rubyforge_project = "totalr"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ # specify any dependencies here; for example:
23
+ # s.add_development_dependency "rspec"
24
+ # s.add_runtime_dependency "rest-client"
25
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: totalr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sathish
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-05 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ! 'Totalr is a lib which provides a simple dsl to do aggregation in models,
15
+ like totals, percentage, grouping, mean, variance et
16
+
17
+ c'
18
+ email:
19
+ - sathish316@gmail.com
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - .gitignore
25
+ - Gemfile
26
+ - README
27
+ - Rakefile
28
+ - lib/totalr.rb
29
+ - lib/totalr/version.rb
30
+ - spec/spec_helper.rb
31
+ - spec/totalr_spec.rb
32
+ - totalr.gemspec
33
+ homepage: http://www.github.com/sathish316/totalr
34
+ licenses: []
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project: totalr
53
+ rubygems_version: 1.8.6
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: Totalr is a lib which provides a simple dsl to do aggregation in models,
57
+ like totals, percentage, grouping, mean, variance et c
58
+ test_files: []