sum_sum 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  pkg/*
2
2
  *.gem
3
3
  .bundle
4
+ doc
5
+ .yardoc
data/CHANGES.md CHANGED
@@ -1,6 +1,15 @@
1
1
  ### dev
2
2
 
3
- [full changelog](http://github.com/yolk/sum_sum/compare/v0.0.4...master)
3
+ [full changelog](http://github.com/yolk/sum_sum/compare/v0.0.5...master)
4
+
5
+ ### 0.0.5 / 2011-01-27
6
+
7
+ [full changelog](http://github.com/yolk/sum_sum/compare/v0.0.4...v0.0.5)
8
+
9
+ * Added SumSum#level
10
+ * Some code cleanup
11
+ * Added SumSum##total_share
12
+ * Added some rdoc/yard comments
4
13
 
5
14
  ### 0.0.4 / 2011-01-27
6
15
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sum_sum (0.0.3)
4
+ sum_sum (0.0.4)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/lib/sum_sum.rb CHANGED
@@ -1,80 +1,126 @@
1
+ # = SumSum
2
+ #
3
+ # SumSum allows you to generate simple reports on the count of values in hashes.
1
4
  class SumSum < Hash
5
+ # @overload initialize(*keys, options = {})
6
+ # @param [Symbol,String] *args the keys to anaylze on hashes
7
+ # @param [Hash] options are only used internaly
8
+ #
9
+ # @example Create a SumSum to analyze hashes with attributes :gender, :age and :name
10
+ # SumSum.new(:gender, :age, :name)
2
11
  def initialize(*args)
3
- @parent = args.pop if args[-1].is_a?(self.class)
4
- @name = args.shift
5
- @args = args.compact.dup
6
- @count = 0
12
+ options = args[-1].is_a?(Hash) ? args.pop : {}
13
+ @key, @parent, @level = options[:key], options[:parent], (options[:level] || 0)
14
+ @kind_of_children, @args, @count = args[level], args, 0
7
15
  super()
8
16
  end
9
-
10
- attr_reader :name, :args, :count, :parent
11
-
12
- def add(hash, increase_by=1)
13
- key = hash[name]
14
- @count = @count + increase_by
17
+
18
+ attr_reader :kind_of_children, :key, :args, :count, :parent, :level
19
+
20
+ # Add a new hash to analyze.
21
+ #
22
+ # @param [Hash,#[]] hash the data to add to the SumSum instance
23
+ # @param [Integer] increase_count_by amount to add to count
24
+ # @return [SumSum] Returns itself
25
+ #
26
+ # @example Add some data
27
+ # sum_sum.add(:gender => "W", :age => 23, :name => "Nina")
28
+ # sum_sum.add(:gender => "M", :age => 77, :name => "Carl")
29
+ # sum_sum.add(:gender => "W", :age => 33, :name => "Nora")
30
+ def add(hash, increase_count_by=1)
31
+ @count = @count + increase_count_by
15
32
  unless bottom?
16
- self[key] ||= SumSum.new(*args, self)
17
- self[key].add(hash, increase_by)
33
+ key = hash[kind_of_children]
34
+ self[key] ||= SumSum.new(*args, :parent => self, :key => key, :level => level + 1)
35
+ self[key].add(hash, increase_count_by)
18
36
  end
19
37
  self
20
38
  end
21
-
39
+
40
+ # Returns share compared to parent
41
+ #
42
+ # @return [Float] Returns the share between 0.0 and 1.0
43
+ #
44
+ # @example Get share of all (returns alway 1.0)
45
+ # sum_sum.share
46
+ # => 1.0
47
+ # @example Get share of all women compared to all entries (two out of three)
48
+ # sum_sum["W"].share
49
+ # => 0.75
50
+ # @example Get share of all women with age 23 compared to all women entries (one out of two)
51
+ # sum_sum["W"][23].share
52
+ # => 0.5
22
53
  def share
23
54
  root? ? 1.0 : count/parent.count.to_f
24
55
  end
25
-
56
+
57
+ # Returns share compared to all entries
58
+ #
59
+ # @return [Float] Returns the share between 0.0 and 1.0
60
+ #
61
+ # @example Get share of all (returns alway 1.0)
62
+ # sum_sum.total_share
63
+ # => 1.0
64
+ # @example Get share of all women compared to all entries (two out of three)
65
+ # sum_sum["W"].total_share
66
+ # => 0.75
67
+ # @example Get share of all women with age 23 compared to all entries (one out of three)
68
+ # sum_sum["W"][23].total_share
69
+ # => 0.3333333
70
+ def total_share
71
+ count/root.count.to_f
72
+ end
73
+
26
74
  def sort!
27
75
  return self if bottom?
28
76
  values.each(&:sort!)
29
77
  to_a.sort_by{|it| it[1].count}.reverse.tap do |array|
30
- clear
31
- array.each{|k, v| self[k] = v }
78
+ clear && array.each{|k, v| self[k] = v }
32
79
  end
33
80
  self
34
81
  end
35
-
82
+
36
83
  def root?
37
- parent.nil?
84
+ !parent
38
85
  end
39
-
86
+
40
87
  def bottom?
41
- name.nil?
88
+ !kind_of_children
89
+ end
90
+
91
+ def root
92
+ root? ? self : parent.root
42
93
  end
43
-
94
+
44
95
  def inspect
45
- bottom? ? "#{count}" : "{#{name}:#{count} #{super.gsub(/^\{|\}$/, "")}}"
96
+ bottom? ? "#{count}" : "{#{kind_of_children}:#{count} #{super.gsub(/^\{|\}$/, "")}}"
46
97
  end
47
-
98
+
48
99
  def pretty_print(pp)
49
100
  return pp.text(" #{count}") if bottom?
50
101
  super
51
102
  end
52
-
103
+
53
104
  def dump
54
105
  return count if bottom?
55
106
  hash = {}
56
107
  each{ |k, v| hash[k] = v.dump }
57
- root? ? [all_args, hash] : hash
108
+ root? ? [args, hash] : hash
58
109
  end
59
-
110
+
60
111
  def self.load(data)
61
112
  new(*data[0]).tap do |sum_sum|
62
113
  sum_sum.add_from_dump(data[1])
63
114
  end
64
115
  end
65
-
66
- def add_from_dump(data, hash={}, level=0)
67
- data.each do |key, value|
68
- hash[all_args[level]] = key
69
- value.is_a?(Hash) ?
70
- add_from_dump(value, hash, level + 1) :
71
- add(hash, value)
116
+
117
+ def add_from_dump(data, hash={}, on_level=0)
118
+ data.each do |k, v|
119
+ hash[args[on_level]] = k
120
+ v.is_a?(Hash) ?
121
+ add_from_dump(v, hash, on_level + 1) :
122
+ add(hash, v)
72
123
  end
73
124
  end
74
-
75
- private
76
-
77
- def all_args
78
- [name] + args
79
- end
125
+
80
126
  end
@@ -1,3 +1,3 @@
1
1
  class SumSum < Hash
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/spec/sum_sum_spec.rb CHANGED
@@ -53,6 +53,18 @@ describe SumSum do
53
53
  SumSum.load(sum.dump).dump.should eql(sum.dump)
54
54
  end
55
55
  end
56
+
57
+ context "#level" do
58
+ it "should return 0 on root" do
59
+ sum.level.should eql(0)
60
+ end
61
+
62
+ it "should return correct level on children" do
63
+ sum[:Browser].level.should eql(1)
64
+ sum[:Browser][:Firefox].level.should eql(2)
65
+ sum[:Browser][:Firefox]["3.6.0"].level.should eql(3)
66
+ end
67
+ end
56
68
  end
57
69
 
58
70
  context "adding multiple hashes" do
@@ -155,6 +167,28 @@ describe SumSum do
155
167
  sum[:Browser][:Firefox].share.should eql(0.25)
156
168
  end
157
169
  end
170
+
171
+ context "#total_share" do
172
+ it "should return 1.0 on root" do
173
+ sum.total_share.should eql(1.0)
174
+ end
175
+
176
+ it "should return 0.2 on branch with one out of five" do
177
+ sum[:Crawler].total_share.should eql(0.2)
178
+ end
179
+
180
+ it "should return 0.2 on branch with one out of five deeper in single" do
181
+ sum[:Crawler][:GoogleBot].total_share.should eql(0.2)
182
+ end
183
+
184
+ it "should return 0.8 on branch with four out of five" do
185
+ sum[:Browser].total_share.should eql(0.8)
186
+ end
187
+
188
+ it "should return 0.2 deeper in branch with one out of five" do
189
+ sum[:Browser][:Firefox].total_share.should eql(0.2)
190
+ end
191
+ end
158
192
 
159
193
  context "#dump" do
160
194
  it "should output serializable array" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Sebastian Munz