hf.benforeva 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/hf.rb +161 -0
  3. data/lib/hf/version.rb +3 -0
  4. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ddb2a2947592632c60492809e6e40efb98f77c2
4
+ data.tar.gz: e99e23002cf0a8df391e8ab6a9b786a97212bad1
5
+ SHA512:
6
+ metadata.gz: 62c50f2fcd9177b2406db3ae28048ba31aef46a6aebbd38385dd06a3c3171265de40a7ea62bfd77b99ad11c12462aa7cfe84b0632291ff854295e9ad26954b88
7
+ data.tar.gz: 87cd7f46064e473c1682ef815bffbe1179e254e500305918eede22efdbfb8a450c19d87c2ade897b99dbd754b0485aa81b0c1a8313761a3ac13ddc482a4d96f6
data/lib/hf.rb ADDED
@@ -0,0 +1,161 @@
1
+ module HF
2
+
3
+ WrongSize = Class.new(StandardError)
4
+ WrongType = Class.new(StandardError)
5
+ WrongArgumentType = Class.new(StandardError)
6
+
7
+ module ::Enumerable
8
+
9
+ SINGLE_SIZE = 1
10
+
11
+ # @return [Boolean] true when enum is a 1-tuple or single
12
+ def single?
13
+ return true if self.count == SINGLE_SIZE
14
+ return false
15
+ end
16
+
17
+ # Returns the only element in a 1-tuple/single.
18
+ # A more idiomatic and safer accessor than first when
19
+ # the Enumerator is expected to have only one element.
20
+ # @raise [WrongSize] when the enumerator is not a 1-tuple
21
+ # @return [Object] the element in the 1-tuple enumerator
22
+ def only
23
+ return self.first if self.single?
24
+ raise WrongSize, wrong_size_message(self.count, SINGLE_SIZE)
25
+ end
26
+
27
+ # @note Uses HF::Range
28
+ # Returns the range of the first one-member multiset collecting
29
+ # the specified value at the given multiplicity. This is a collection
30
+ # such as [3, 3, 3 ,3], where there is multiple instances of one member.
31
+ # Formally it is a multiset with only one member.
32
+ # The default multiplicity returns the range of an mset of arbirtrary size.
33
+ # The default value is not specified it returns the range of the first mset with distinct values.
34
+ # @param value [Object] the element in the mset
35
+ # @param multiplicity [Integer] the number of times value appears in mset
36
+ # @return [Range] the first range where the subset occurs
37
+ def find_mset(value, multiplicity=-1)
38
+ is_multiplicity_negative = multiplicity < 0
39
+ enums_chunked_on_value = self.chunk{|i| i == value}
40
+ sub_enums = enums_chunked_on_value.collect{|r| r.last}
41
+ sub_enums_is_mset =
42
+ if is_multiplicity_negative
43
+ enums_chunked_on_value.collect{|r| r.first && not(r.single?) }
44
+ else
45
+ enums_chunked_on_value.collect{|r| r.first && (r.last.size >= multiplicity) }
46
+ end
47
+ first_mset_chunked_index = sub_enums_is_mset.find_index(true)
48
+ return Range.new(self.count, self.count, true) if first_mset_chunked_index.nil?
49
+ first_mset_offset = sub_enums.take(first_mset_chunked_index).flatten.size
50
+ first_mset_size = is_multiplicity_negative ? sub_enums[first_mset_chunked_index].size : multiplicity
51
+ Range.new(0, first_mset_size.pred).bump(first_mset_offset)
52
+ end
53
+
54
+ private
55
+
56
+ # @param expected_size [Integer]
57
+ # @param actual_size [Integer]
58
+ # @return [String] the message for the WrongSize exception
59
+ def wrong_size_message(expected_size, actual_size)
60
+ elm_word = actual_size == 1 ? "element" : "elements"
61
+ "Enumerator is not a #{expected_size}-tuple. It has #{actual_size} #{elm_word} instead of #{expected_size}"
62
+ end
63
+ end
64
+
65
+ class ::Hash
66
+
67
+ DEFAULT_EMBED_AS = nil
68
+
69
+ # Add field to hash as is or embedded under a key given by embed_as. Addition
70
+ # only occurs when field contains data.
71
+ # @param field [Hash] The fields to add to the hash
72
+ # @param embed_as [#to_s] The key under which the field should be embedded
73
+ # in the hash
74
+ # @return [Hash] replace existing hash with modified hash
75
+ def add_optional!(field, embed_as: DEFAULT_EMBED_AS)
76
+ return self.merge!(field) if embed_as.eql?(DEFAULT_EMBED_AS)
77
+ return self if field.empty?
78
+ self.merge!({embed_as => field})
79
+ end
80
+
81
+ # Add field to hash as is or embedded under a key given by embed_as. Addition
82
+ # only occurs when field contains data.
83
+ # @param field [Hash] The fields to add to the hash
84
+ # @param embed_as [#to_s] The key under which the field should be embedded
85
+ # in the hash
86
+ # @return [Hash] creates a new has with modifications
87
+ def add_optional(field, embed_as: DEFAULT_EMBED_AS)
88
+ return self.merge(field) if embed_as.eql?(DEFAULT_EMBED_AS)
89
+ return self.clone if field.empty?
90
+ self.merge({embed_as => field})
91
+ end
92
+
93
+ # @param keys [HashKeyArray]
94
+ # @return [Hash] a Hash containing only the keys given.
95
+ def slice(*keys)
96
+ self.select{|k,_| keys.include?(k)}
97
+ end
98
+
99
+ # @param (see #slice)
100
+ # @return [Hash] a Hash containing none of the keys given
101
+ def drop(*keys)
102
+ self.reject{|k,_| keys.include?(k)}
103
+ end
104
+ end
105
+
106
+ class ::Integer
107
+
108
+ # Return an IntegerRange that captures all the values after the integer
109
+ # @return [IntegerRange] a new Range
110
+ def after
111
+ (1 + self)..-1
112
+ end
113
+
114
+ # Return an IntegerRange that captures all the positive values before the integer
115
+ # @return [IntegerRange] a new Range
116
+ def before
117
+ 0..(self - 1)
118
+ end
119
+ end
120
+
121
+ class ::Range
122
+
123
+ # Bump the beginning and end of an integer range by n
124
+ # @param n [Integer] the amount to raise both begin and end by
125
+ # @return [IntegerRange] a new Range
126
+ def bump(n)
127
+ raise(WrongType, wrong_type_message(Integer)) unless self.begin.is_a?(Integer)
128
+ raise(WrongArgumentType, wrong_argument_type_message(Integer, n.class)) unless n.is_a?(Integer)
129
+ Range.new(self.begin + n, self.end + n, self.exclude_end?)
130
+ end
131
+
132
+ # Return an IntegerRange that captures all the values after the end of the interval
133
+ # @return [IntegerRange] a new Range
134
+ def after
135
+ raise(WrongType, wrong_type_message(Integer)) unless self.begin.is_a?(Integer)
136
+ (1 + self.end)..-1
137
+ end
138
+
139
+ # Return an IntegerRange that captures all the values before the beginning of the interval
140
+ # @return [IntegerRange] a new Range
141
+ def before
142
+ raise(WrongType, wrong_type_message(Integer)) unless self.begin.is_a?(Integer)
143
+ 0..(self.begin - 1)
144
+ end
145
+
146
+ private
147
+
148
+ # @param expected_type [ClassName]
149
+ # @return [String] the message for the WrongType exception
150
+ def wrong_type_message(expected_type)
151
+ "Range must have #{expected_type} values and not #{self.begin.class}"
152
+ end
153
+
154
+ # @param expected_type [ClassName]
155
+ # @param actual_type [ClassName]
156
+ # @return [String] the message for the WrongArgumentType exception
157
+ def wrong_argument_type_message(expected_type, actual_type)
158
+ "Argument must be an #{expected_type} and not a #{actual_type}"
159
+ end
160
+ end
161
+ end
data/lib/hf/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module HF
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hf.benforeva
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andre Dickson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: andrebcdickson@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/hf.rb
20
+ - lib/hf/version.rb
21
+ homepage:
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.6.14.1
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: ruby extensions by Benforeva
45
+ test_files: []