eymiha_util 0.1.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.
data/gem_package.rb ADDED
@@ -0,0 +1,31 @@
1
+ class GemPackage
2
+
3
+ attr_reader :name, :version, :files
4
+
5
+ def initialize
6
+ @name = 'eymiha_util'
7
+ @version = '0.1.0'
8
+ @files = FileList[
9
+ '*.rb',
10
+ 'lib/*',
11
+ 'test/*',
12
+ 'html/**/*'
13
+ ]
14
+ end
15
+
16
+ def fill_spec(s)
17
+ s.name = name
18
+ s.version = version
19
+ s.summary = "Eymiha general utility classes and methods"
20
+ s.files = files.to_a
21
+ s.require_path = 'lib'
22
+ s.autorequire = name
23
+ s.has_rdoc = true
24
+ s.rdoc_options << "--all"
25
+ s.author = "Dave Anderson"
26
+ s.email = "dave@eymiha.com"
27
+ s.homepage = "http://www.eymiha.com"
28
+ s.rubyforge_project = "cori"
29
+ end
30
+
31
+ end
data/lib/envelope.rb ADDED
@@ -0,0 +1,126 @@
1
+ # Envelopes are useful when finding the boundaries of a set of instances.
2
+ # They expand as new values are added, and keep track of how many items
3
+ # have been added to construct them.
4
+
5
+ # An EnvelopeException is generally raised when adding an object to an
6
+ # instance that it does not know how to interpret, or when requesting
7
+ # bounderies before any values have been added.
8
+ class EnvelopeException < Exception
9
+ end
10
+
11
+
12
+ # A BaseEnvelope provides a means to keep and provide a count of objects that
13
+ # have been added to an envelope.
14
+ class BaseEnvelope
15
+
16
+ # Called when requesting envelope bounderies before any values have been
17
+ # added.
18
+ def raise_no_envelope
19
+ raise EnvelopeException, "No values are enveloped"
20
+ end
21
+
22
+ # Called when the value cannot be compared with the the boundaries of the
23
+ # instance.
24
+ def raise_no_compare(value=nil)
25
+ value = "'#{value}' " unless value == nil
26
+ raise EnvelopeException,
27
+ "The value #{value}cannot be compared with the envelope"
28
+ end
29
+
30
+ # count of added values reader.
31
+ attr_reader :count
32
+
33
+ # Returns a new instance with no values added.
34
+ def initialize
35
+ @count = 0
36
+ end
37
+
38
+ end
39
+
40
+
41
+ # An Envelope is the minimum envelope that will completely contain a set of
42
+ # values. Values may be added to an instance, and it can return the number
43
+ # of values considered so far and its high and low boundaries.
44
+ #
45
+ # Envelopes can be used to generate ranges, however the result may be of
46
+ # limited utility if the types of values being enveloped don't play nicely
47
+ # with ranges.
48
+ class Envelope < BaseEnvelope
49
+
50
+ # Creates and returns an instance. If an argument is given, it is passed to
51
+ # the set method to initialize the new instance.
52
+ def initialize(value=nil)
53
+ super()
54
+ add(value) unless value == nil
55
+ end
56
+
57
+ # Returns a string representation of the instance.
58
+ def to_s
59
+ values = (count > 0)? "\n high #{high}\n low #{low}" : ""
60
+ "Envelope: count #{count}#{values}"
61
+ end
62
+
63
+ # Adds a value to the instance. When
64
+ # * x is an Envelope, it is coalesced into the instance.
65
+ # * otherwise, the envelope is extened to contain the value.
66
+ # * if the value cannot be compared to the boundaries, an EnvelopeException is raised.
67
+ # The modified instance is returned.
68
+ def add(value)
69
+ if value.kind_of? Envelope
70
+ count = value.count
71
+ if (count > 0)
72
+ add value.high
73
+ add value.low
74
+ @count += (count-2)
75
+ end
76
+ self
77
+ else
78
+ begin
79
+ @high = value if (@count == 0 || value > @high)
80
+ @low = value if (@count == 0 || value < @low)
81
+ @count += 1
82
+ self
83
+ rescue
84
+ raise_no_compare value
85
+ end
86
+ end
87
+ end
88
+
89
+ # Returns the high boundary of the instance.
90
+ # * if there are no boundaries, an EnvelopeException is raised.
91
+ def high
92
+ raise_no_envelope if @count == 0
93
+ @high
94
+ end
95
+
96
+ # Returns the low boundary of the instance.
97
+ # * if there are no boundaries, an EnvelopeException is raised.
98
+ def low
99
+ raise_no_envelope if @count == 0
100
+ @low
101
+ end
102
+
103
+ # Returns true if the instance completely contains the argument:
104
+ # * value is an Envelope, its high and low are contained.
105
+ # * otherwise, the value is contained.
106
+ # * if the value cannot be compared to the boundaries, an EnvelopeException is raised.
107
+ def contains?(value)
108
+ if value.kind_of? Envelope
109
+ (contains? value.high) && (contains? value.low)
110
+ else
111
+ begin
112
+ (value >= low) && (value <= high)
113
+ rescue
114
+ raise_no_compare value
115
+ end
116
+ end
117
+ end
118
+
119
+ alias === contains?
120
+
121
+ # Returns an inclusive range from the low to high boundaries
122
+ def to_range
123
+ low..high
124
+ end
125
+
126
+ end
data/lib/histogram.rb ADDED
@@ -0,0 +1,109 @@
1
+ # Histograms have lots of uses - whenever you need to keep track of the
2
+ # occurences of items and how many times they've occured, a histogram is
3
+ # just what's needed.
4
+
5
+
6
+ # An exception thrown when adding Arrays to Histograms that cannot be
7
+ # meaningfully interpretted.
8
+ class HistogramException < Exception
9
+ end
10
+
11
+
12
+ # A Histogram is a hash whose values are counts of the occurences of the keys.
13
+ class Histogram < Hash
14
+
15
+ # Creates and returns an instance. If arguments are given, they are passed to
16
+ # the add method to initialize the new instance.
17
+ def initialize(key=nil,number=1)
18
+ super()
19
+ add(key,number) unless key == nil
20
+ end
21
+
22
+ # Returns the number of occurences of the given key. If an array of keys
23
+ # is given, the sum of the number of occurences of those keys is returned.
24
+ def count(check_keys = keys)
25
+ check_keys = [check_keys] if ! check_keys.kind_of? Array
26
+ count = 0
27
+ check_keys.each { |key| count += self[key] if has_key? key }
28
+ count
29
+ end
30
+
31
+ # Adds the key to the instance if it doesn't already exist, and adds the
32
+ # specified count to it value. If the key is
33
+ # * an Array, each member of the array is added. if the member itself is an Array, then if that array has one member, the member is added as a key; if two members, the member is added as a key and a count; otherwise, a HistogramException is thrown.
34
+ # * another histogram, the keys and counts in the key are added to the instance.
35
+ def add(key,count=1)
36
+ if key.kind_of? Array
37
+ key.each { |member|
38
+ if member.kind_of? Array
39
+ if member.size == 1
40
+ add(member[0])
41
+ elsif (member.size == 2) && (member[1].kind_of? Fixnum)
42
+ add(member[0],member[1])
43
+ else
44
+ raise HistogramException, "add cannot interpret Array to add"
45
+ end
46
+ else
47
+ add member
48
+ end
49
+ }
50
+ elsif key.kind_of? Histogram
51
+ key.each_pair { |k,v| add(k,v) }
52
+ else
53
+ self[key] = ((value = self[key]) == nil) ? count : value+count
54
+ end
55
+ self
56
+ end
57
+
58
+ # Returns the number of keys in the instance.
59
+ def key_count
60
+ keys.size
61
+ end
62
+
63
+ # Returns a new Histogram containing the elements with occurences greater
64
+ # than or equal to the given count.
65
+ def >=(count)
66
+ result = Histogram.new
67
+ each_pair { |k,v| result.add(k,v) if v >= count }
68
+ result
69
+ end
70
+
71
+ # Returns a new Histogram containing the elements with occurences greater
72
+ # than the given count.
73
+ def >(count)
74
+ result = Histogram.new
75
+ each_pair { |k,v| result.add(k,v) if v > count }
76
+ result
77
+ end
78
+
79
+ # Returns a new Histogram containing the elements with occurences less than
80
+ # or equal to the given count.
81
+ def <=(count)
82
+ result = Histogram.new
83
+ each_pair { |k,v| result.add(k,v) if v <= count }
84
+ result
85
+ end
86
+
87
+ # Returns a new Histogram containing the elements with occurences less than
88
+ # the given count.
89
+ def <(count)
90
+ result = Histogram.new
91
+ each_pair { |k,v| result.add(k,v) if v < count }
92
+ result
93
+ end
94
+
95
+ # If count is a number, a new Histogram containing the elements with
96
+ # occurences equal to the given countis returned. If the count is a
97
+ # histogram, true is returned if the instance contains the same keys and
98
+ # values; false otherwise.
99
+ def ==(count)
100
+ if count.kind_of? Numeric
101
+ result = Histogram.new
102
+ each_pair { |k,v| result.add(k,v) if v >= count }
103
+ result
104
+ else
105
+ super
106
+ end
107
+ end
108
+
109
+ end
data/rakefile.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'gem_package'
2
+ require 'gem_raker'
@@ -0,0 +1,99 @@
1
+ require 'test/unit'
2
+
3
+ require 'envelope'
4
+
5
+ class TC_Envelope < Test::Unit::TestCase
6
+
7
+ def test_count
8
+ base = BaseEnvelope.new
9
+ assert(base.count == 0)
10
+ end
11
+
12
+ def test_empty
13
+ envelope = Envelope.new
14
+ assert(envelope.count == 0)
15
+ assert_raise(EnvelopeException) { envelope.high }
16
+ assert_raise(EnvelopeException) { envelope.low }
17
+ end
18
+
19
+ def test_add_numbers
20
+ envelope = Envelope.new
21
+ envelope.add 1
22
+ assert(envelope.high == 1)
23
+ assert(envelope.low == 1)
24
+ assert(envelope.count == 1)
25
+ envelope.add 2
26
+ envelope.add(-3)
27
+ envelope.add 4.5
28
+ assert(envelope.high == 4.5)
29
+ assert(envelope.low == -3)
30
+ assert(envelope.count == 4)
31
+ envelope.add envelope
32
+ assert(envelope.high == 4.5)
33
+ assert(envelope.low == -3)
34
+ assert(envelope.count == 8)
35
+ assert_raise(EnvelopeException) { envelope.add "bad" }
36
+ assert(envelope.count == 8)
37
+ envelope = Envelope.new
38
+ end
39
+
40
+ def test_add_letters
41
+ envelope = Envelope.new('c').add('m').add('e')
42
+ assert(envelope.low == 'c')
43
+ assert(envelope.high == 'm')
44
+ assert(envelope.contains?('d'))
45
+ assert(!(envelope.contains?('a')))
46
+ assert(!(envelope.contains?('r')))
47
+ assert(envelope.contains?(envelope))
48
+ assert(envelope.contains?(Envelope.new('e').add('h')))
49
+ assert(!(envelope.contains?(Envelope.new('a').add('h'))))
50
+ assert(!(envelope.contains?(Envelope.new('e').add('s'))))
51
+ assert(envelope === 'd')
52
+ assert(!(envelope === 'a'))
53
+ assert(!(envelope === 'r'))
54
+ assert(envelope === envelope)
55
+ assert(envelope === Envelope.new('e').add('h'))
56
+ assert(!(envelope === Envelope.new('a').add('h')))
57
+ assert(!(envelope === Envelope.new('e').add('s')))
58
+ range = envelope.to_range
59
+ assert(range === 'd')
60
+ assert(!(range === 'a'))
61
+ assert(!(range === 'r'))
62
+ end
63
+
64
+ def test_add_strings
65
+ envelope = Envelope.new("carl").add("marie").add("edward")
66
+ assert(envelope.low == "carl")
67
+ assert(envelope.high == "marie")
68
+ assert(envelope.contains?("dennis"))
69
+ assert(!(envelope.contains?("aaron")))
70
+ assert(!(envelope.contains?("ralph")))
71
+ assert(envelope.contains?(envelope))
72
+ assert(envelope.contains?(Envelope.new("edward").add("harry")))
73
+ assert(!(envelope.contains?(Envelope.new("aaron").add("harry"))))
74
+ assert(!(envelope.contains?(Envelope.new("edward").add("sally"))))
75
+ range = envelope.to_range
76
+ assert(range === "dennis")
77
+ assert(!(range === "aaron"))
78
+ assert(!(range === "ralph"))
79
+ end
80
+
81
+ def test_contains
82
+ envelope = Envelope.new(0.75).add(3)
83
+ assert(envelope.contains?(1))
84
+ assert(envelope.contains?(3))
85
+ assert(envelope.contains?(2))
86
+ assert(!(envelope.contains?(0)))
87
+ assert(!(envelope.contains?(4)))
88
+ assert(envelope.contains?(envelope))
89
+ assert(envelope.contains?(Envelope.new(1.5).add(2.5)))
90
+ assert(!(envelope.contains?(Envelope.new(0.5).add(2.5))))
91
+ assert(!(envelope.contains?(Envelope.new(1.5).add(3.5))))
92
+ assert_raise(EnvelopeException) { envelope.add "bad" }
93
+ range = envelope.to_range
94
+ assert(range === 2.5)
95
+ assert(!(range === 0))
96
+ assert(!(range === 4))
97
+ end
98
+
99
+ end
@@ -0,0 +1,52 @@
1
+ require 'test/unit'
2
+
3
+ require 'histogram'
4
+
5
+ class TC_Histogram < Test::Unit::TestCase
6
+
7
+ def test_empty
8
+ histogram = Histogram.new
9
+ assert(histogram.count == 0)
10
+ assert(histogram.keys == [])
11
+ end
12
+
13
+ def test_loading
14
+ h1 = Histogram.new "hello"
15
+ h1.add "goodbye",2
16
+ assert(h1.count == 3)
17
+ assert(h1.count("hello") == 1)
18
+ assert(h1.count("goodbye") == 2)
19
+ assert(h1.count("everyone") == 0)
20
+ assert(h1.key_count == 2)
21
+ h2 = Histogram.new [["hello", 4], "goodbye", "everyone"]
22
+ assert(h2.count == 6)
23
+ assert(h2.count("hello") == 4)
24
+ assert(h2.count("goodbye") == 1)
25
+ assert(h2.count("everyone") == 1)
26
+ assert(h2.key_count == 3)
27
+ h1.add h2
28
+ assert(h1.count == 9)
29
+ assert(h1.count("hello") == 5)
30
+ assert(h1.count("goodbye") == 3)
31
+ assert(h1.count("everyone") == 1)
32
+ assert(h1.key_count == 3)
33
+ assert(h1.has_key?("hello"))
34
+ assert(h1.has_key?("goodbye"))
35
+ assert(h1.has_key?("everyone"))
36
+ assert(!(h1.has_key? "help"))
37
+ end
38
+
39
+ def test_subset
40
+ h = Histogram.new [["hello", 4], ["goodbye", 3], "everyone"]
41
+ h1 = Histogram.new [["hello", 4], ["goodbye", 3]]
42
+ assert((h >= 3) == h1)
43
+ h2 = Histogram.new [["hello", 4]]
44
+ assert((h > 3) == h2)
45
+ assert((h == 4) == h2)
46
+ h3 = Histogram.new [["goodbye", 3], "everyone"]
47
+ assert((h <= 3) == h3)
48
+ h4 = Histogram.new "everyone"
49
+ assert((h < 3) == h4)
50
+ end
51
+
52
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: eymiha_util
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-05-10 00:00:00 -04:00
8
+ summary: Eymiha general utility classes and methods
9
+ require_paths:
10
+ - lib
11
+ email: dave@eymiha.com
12
+ homepage: http://www.eymiha.com
13
+ rubyforge_project: cori
14
+ description:
15
+ autorequire: eymiha_util
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Dave Anderson
31
+ files:
32
+ - gem_package.rb
33
+ - rakefile.rb
34
+ - lib/envelope.rb
35
+ - lib/histogram.rb
36
+ - test/tc_envelope.rb
37
+ - test/tc_histogram.rb
38
+ test_files: []
39
+
40
+ rdoc_options:
41
+ - --all
42
+ extra_rdoc_files: []
43
+
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ requirements: []
49
+
50
+ dependencies: []
51
+