hf.benforeva 1.0.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.
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: []