setfu 1.1.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98a90b0258e875fad04750814d8324d7a6a01d09
4
- data.tar.gz: 871a1632723b4d212128bc1cba8e08c455ea464c
3
+ metadata.gz: 134e00fed065a113e94ad7aa53d038a3123ce7e2
4
+ data.tar.gz: c255f820ed6460f627da42276830fa2a03cf1bbc
5
5
  SHA512:
6
- metadata.gz: b0ce98d4fdbfd73362b9a5d0b76b6fd5eecf623d47a9afd9e61e58ec81190c020210b21dc3547bb7c272f1295264b9c62c15af32d4a84a2e030a340da5822c4f
7
- data.tar.gz: bab004705084529b0391eb2354c94077b0a73b36d630e1500062361a67244fa8f1cda39a3a09e8b9ec3794ad55b519a70ac031fcdc151cc5ef1f4ac956c760b7
6
+ metadata.gz: c6da933de018e78187a64b1000c8cfd0c1da26eaa00a88e74668193b171f803e83b25340c90a6607ea96dab1f4a16988d9e171f41762646351ef88ef2888e26c
7
+ data.tar.gz: 5da251f1351be7e684a20bdb490edccee46da8a06aab0d1c81748b6d200c746909a154ed564ef1efd8d32d579e40023957345b635877d83c2d702dfe6ca591b3
data/README.md CHANGED
@@ -1,85 +1,10 @@
1
1
  # Setfu
2
2
 
3
- Purpose: A general purpose object implementing sets.
3
+ ##Purpose: A general purpose object implementing sets.
4
+
5
+ ##Documentation
6
+ See: http://bdlsys.com/gems/setfu.html
4
7
 
5
- Construction:
6
- Set.new >> creates an empty set
7
- Set.new(p) >> creates a set initialized with elements p
8
- Set.new.add!(p) >> chained with #add method
9
- ::parameter p::
10
- "abcxyz" >> ordinate values of each character added to set
11
- 'a'..'z' >> ordinate values of each range element added to set
12
- [6,19,'g'..'k'] >> items in an array added to set (recursively)
13
- 375 >> element number `375` added to set
14
- or set instance
15
- [v0,v1,...].to_set >> converts array to set instance
16
- ::array values::
17
- set instance
18
- array literal, array instance >> recursive values must comply to first-level rules
19
- string literal, string instance
20
- range literal, range instance
21
- positive small integers including zero, integer instance
22
- "a7P".to_set >> converts ordinate values of each char to set members
23
- ('a'..'k').to_set >> converts ordinate values of each char in range to set members
24
- parenthesis needed for literal. parenthesis not needed for instance variable
25
-
26
- Operators:
27
- a < b >> true if `a` is a "proper" subset of `b` ... a !=b and a in b
28
- a <= b >> true if `a` is a subset of `b`
29
- a - b >> set difference ... removes elements from a found in b
30
- a & b >> set intersection
31
- a | b >> set union
32
- a ^ b >> exclusive union
33
- s == a >> equality ... both sets contain exactly the same elements
34
- a === s >> case equality ... where `s` applies to case variable, and `a` applies to when clause
35
- see: .set_case(sym) for additonal configuration
36
- s != a >> inequality ... sets are different
37
- ~a >> inversion
38
- a ** b >> intersection test ... true if one or more elements are common to both sets
39
- s[i] >> true if 'i' is an element of the set
40
- s[i]=k >> if k==true, adds element `i` to set, otherwise removes element `i` from set
41
- where a,b === instances of Set, String, Array, Range
42
- s === instance of Set
43
- i === member index ... positive integer (0,1,2,3...) or char ('a')
44
- character indexes use #ord to convert to integer
45
- k === boolean
46
-
47
- Methods:
48
- .count >> returns number of elements in set
49
- .each_member {block} >> iterates on element ordinate of each element in set
50
- .add!(p) >> includes additional members to current set
51
- .include?(p) >> true if `p` is a subset of current set
52
- .empty? >> true if there are no elements in set
53
- .zap! >> removes all elements of set and resets entropy to zero
54
- .add_parse_chars! >> adds [0..47, 58..64, 91..96, 123..126] to set
55
- .dup >> creates a copy of the current set
56
- .to_i >> returns internal integer representing all bits of the set space
57
- .to_s >> returns a string representation of all elements
58
- .to_a >> returns an array of all elements (in integers)
59
- .set_bits!(n) >> replaces set with each set bit of integer `n` ... negative numbers are not allowed!
60
- .recalculate_entropy! >> calculates new entropy value based on current elements on set.
61
- recommended to call this method after #set_bits! is called.
62
- not necessary to be called for normal operation. Returns newly calculated entropy.
63
- .min >> returns element of smallest ordinate value, or nil if empty set
64
- .max >> returns element of highest ordinate value, or nil if empty set
65
- .to_set >> returns self ... Also exported to String, Range, and Array which creates an instance of Set
66
- .set_case(sym) >> sets case--when behavior as follows:
67
- :mode_equal (default) case(s) -> when a ... validates on a ==s
68
- :mode_intersection case(s) -> when a ... validates on a ** s
69
- :mode_sub case(s) -> when a ... validates on a <= s
70
- :mode_proper case(s) -> when a ... validates on a < s
71
- :mode_super case(s) -> when a ... validates on s <= a
72
- :mode_superproper case(s) -> when a ... validates on s < a
73
- .add_opposing_case! >> for every letter character in set, the inverse case of that character is added to the set.
74
- ex: y = "aBc".to_set.add_opposing_case! ... y == "abcABC"
75
- .add_lowercase_chars! >> same as .add!('a'..'z')
76
- .add_uppercase_chars! >> same as .add!('A'..'Z')
77
- .add_digit_chars! >> same as .add!('0'..'9')
78
- .add_parse_chars! >> adds white space and typical non-alphanumeric chars found on typical keyboard
79
-
80
- Properties:
81
- .entropy >> Total number of possible states. Like the universe, can only get bigger.
82
- Can be set to a higher number. Property may be read.
83
8
 
84
9
  ## Installation
85
10
 
@@ -95,66 +20,6 @@ Or install it yourself as:
95
20
 
96
21
  $ gem install setfu
97
22
 
98
- ## Usage
99
-
100
- The Set class defines a group of
101
- positive integers including zero. Unlike the array, there is no implied order
102
- to each element of the set other than their chronological order implied by their ordinate value.
103
- Each set instance may not duplicate elements. The upper bounds of an element is only limited
104
- to the size of (1 << element) that a Bignum may hold. Performance degrades with elements
105
- larger than 65536. This is due to the amount of processing required to operate on large integers.
106
- One bit of storage is required to hold all possible values a set may hold. Internally, a Bignum
107
- instance is used to hold all the bits up to the highest ordinate value.
108
-
109
- Sets can simplify many programming paradigms. Instead of writing code like this:
110
-
111
- def valid_password_chars(str)
112
- str.each_char do |ch|
113
- return false unless (ch>='a' && ch <='z') || (ch>='A' && ch <='Z') || (ch>='0' && ch <='9') || (ch=='#') || (ch=='_') || (ch=='!')
114
- end
115
- return true
116
- end
117
-
118
- valid_password_chars "Not a valid password at all!" # false
119
- valid_password_chars "Secret#15_!" # true
120
-
121
- You can instead do this:
122
-
123
- valid_char_set = Set.new ['a'..'z','A'..'Z','0'..'9','#','_','!']
124
-
125
- "Not a valid password at all!" <= valid_char_set # false
126
- "Secret#15_!" <= valid_char_set # true
127
-
128
- Depending on the operator, the string expression above is converted in to a set instance.
129
- Fast bitwise math is then performed internally.
130
-
131
- Sets can often offer improved performance over regular expressions and arrays.
132
- This is possible thanks to very fast bit-wise operations on its internal Bignum representation.
133
- Each bit represents a placeholder for a possible element.
134
-
135
- Sets can be used within case statements. The entire case statement can be configured to use
136
- one of six different comparison modes. The case variable defines the modes of operation for the entire case statement.
137
- An alternate configuration is to set the same comparison modes on each when clause.
138
- Note that the case variable takes precedence over each and every when clause.
139
- The case variable must be of type `Set`. The left side of the comparison is always the case variable.
140
- An example is as follows:
141
-
142
- case [2,4,6..13].to_set.set_case(:mode_sub)
143
- when [1..31]
144
- puts "subset detected!"
145
- end
146
-
147
- In ruby, case statements use the `===` operator when evaluating the when clause.
148
- The `case` variable sits on the left, and the `when` clause sits on the right.
149
- The Set class overloads the `===` operator and decides what operations are performed on
150
- the left and right side of the operator. The `#set_case` method takes one of six symbol
151
- arguments to perform one of 6 comparison modes.
152
- Comparison modes can be set on either the left or the right, but the right takes precedence.
153
-
154
23
  ## Contributing
155
24
 
156
- 1. Fork it
157
- 2. Create your feature branch (`git checkout -b my-new-feature`)
158
- 3. Commit your changes (`git commit -am 'Add some feature'`)
159
- 4. Push to the branch (`git push origin my-new-feature`)
160
- 5. Create new Pull Request
25
+ Not on github yet ... stay tuned!
@@ -7,92 +7,98 @@ class Set
7
7
  @entropy = ent unless @entropy > ent
8
8
  end
9
9
 
10
- def to_set
11
- return self
10
+ def self.uppercase_chars
11
+ set = Set.new
12
+ set.set_bits!(2475880041677272402379145216)
13
+ set.entropy=91
14
+ return set
12
15
  end
13
16
 
14
- def mode
15
- return @mode
17
+ def self.lowercase_chars
18
+ set = Set.new
19
+ set.set_bits!(10633823807823001954701781295154855936)
20
+ set.entropy=123
21
+ return set
16
22
  end
17
23
 
18
- def initialize(data=nil)
19
- @bits = 0
20
- @entropy = 0
21
- add!(data) unless data.nil?
22
- self
24
+ def self.letter_chars
25
+ set = Set.new
26
+ set.set_bits!(10633823810298881996379053697534001152)
27
+ set.entropy=123
28
+ return set
23
29
  end
24
-
25
- def zap!
26
- @bits = 0
27
- @entropy = 0
28
- self
30
+
31
+ def self.digit_chars
32
+ set = Set.new
33
+ set.set_bits!(287948901175001088)
34
+ set.entropy=58
35
+ return set
29
36
  end
30
37
 
31
- def recalculate_entropy!
32
- @entropy = 0
33
- bits = @bits
34
- num = 1 << 8192
35
- while(bits > num)
36
- @entropy += 8192
37
- bits >>= 8192
38
- end
39
- num = 1 << 256
40
- while(bits > num)
41
- @entropy += 256
42
- bits >>= 256
43
- end
44
- num = 1 << 16
45
- while(bits > num)
46
- @entropy += 16
47
- bits >>= 16
48
- end
49
- while(bits > 0)
50
- @entropy += 1
51
- bits >>= 1
52
- end
53
- #@entropy += 1
54
- @entropy
38
+ def self.parse_chars
39
+ set = Set.new
40
+ set.set_bits!(159507359650170349735020301117175103487)
41
+ set.entropy=127
42
+ return set
55
43
  end
56
-
44
+
45
+ def replace(ent)
46
+ ent = ent.to_set
47
+ @mode = ent.mode
48
+ @entropy = ent.entropy
49
+ @bits = ent.to_i
50
+ self
51
+ end
52
+
57
53
  def add_parse_chars!
58
- add! [0..47, 58..64, 91..96, 123..126]
54
+ # add! [0..47, 58..64, 91..96, 123..126]
55
+ add! Set.parse_chars
59
56
  self
60
57
  end
61
58
 
62
59
  def add_parse_chars
63
- dup.add_parse_chars!
60
+ return Set.parse_chars | self
64
61
  end
65
62
 
66
63
  def add_digit_chars!
67
- add! [48..57]
64
+ add! Set.digit_chars
68
65
  self
69
66
  end
70
67
 
71
68
  def add_digit_chars
72
- dup.add_digit_chars!
69
+ return Set.digit_chars | self
73
70
  end
74
71
 
75
72
  def add_uppercase_chars!
76
- add! [65..90]
73
+ add! Set.uppercase_chars
77
74
  self
78
75
  end
79
76
 
80
77
  def add_uppercase_chars
81
- dup.add_uppercase_chars!
78
+ return Set.uppercase_chars | self
82
79
  end
83
80
 
84
81
  def add_lowercase_chars!
85
- add! [97..122]
82
+ add! Set.lowercase_chars
86
83
  self
87
84
  end
88
85
 
89
86
  def add_lowercase_chars
90
- dup.add_lowercase_chars!
87
+ return Set.lowercase_chars | self
88
+ end
89
+
90
+ def add_letter_chars
91
+ return Set.letter_chars | self
92
+ end
93
+
94
+ def add_letter_chars!
95
+ add! Set.letter_chars
96
+ self
91
97
  end
92
98
 
93
99
  def add_opposing_case!
94
- aa = Set.new.add_lowercase_chars!
95
- bb = Set.new.add_uppercase_chars!
100
+ aa = Set.lowercase_chars
101
+ bb = Set.uppercase_chars
96
102
  ka = aa & self # subset lower case
97
103
  kb = bb & self # subset upper case
98
104
  @bits |= ka.to_i >> 32
@@ -104,6 +110,53 @@ class Set
104
110
  def add_opposing_case
105
111
  dup.add_opposing_case!
106
112
  end
113
+
114
+ def to_set
115
+ return self
116
+ end
117
+
118
+ def mode
119
+ return @mode
120
+ end
121
+
122
+ def initialize(data=nil)
123
+ @bits = 0
124
+ @entropy = 0
125
+ add!(data) unless data.nil?
126
+ self
127
+ end
128
+
129
+ def zap!
130
+ @bits = 0
131
+ @entropy = 0
132
+ self
133
+ end
134
+
135
+ def recalculate_entropy!
136
+ @entropy = 0
137
+ bits = @bits
138
+ num = 1 << 8192
139
+ while(bits > num)
140
+ @entropy += 8192
141
+ bits >>= 8192
142
+ end
143
+ num = 1 << 256
144
+ while(bits > num)
145
+ @entropy += 256
146
+ bits >>= 256
147
+ end
148
+ num = 1 << 16
149
+ while(bits > num)
150
+ @entropy += 16
151
+ bits >>= 16
152
+ end
153
+ while(bits > 0)
154
+ @entropy += 1
155
+ bits >>= 1
156
+ end
157
+ #@entropy += 1
158
+ @entropy
159
+ end
107
160
 
108
161
  # this only works on integer ... String, Array, Range does not implement: &, |, ^
109
162
  def coerce(other)
@@ -113,9 +166,8 @@ class Set
113
166
 
114
167
  def dup
115
168
  rtn = Set.new
116
- rtn.set_bits!(@bits)
117
- rtn.entropy = entropy
118
- rtn
169
+ rtn.replace(self)
170
+ return rtn
119
171
  end
120
172
 
121
173
  def ^(item)
@@ -386,32 +438,40 @@ class Set
386
438
  rtn.set_bits!(mask ^ @bits)
387
439
  rtn
388
440
  end
389
-
390
- def [](pos)
391
- idx = pos.ord if pos.class==String
392
- idx = pos.to_i
393
- raise "Negative indexes are illegal for Set" if idx < 0
394
- self.entropy = idx+1
395
- y = @bits & (1<<idx)
396
- return true if y > 0
397
- false
398
- end
399
441
 
400
- def []=(pos,value)
401
- idx = pos.ord if pos.class==String
402
- idx = pos.to_i
403
- raise "Negative indexes are illegal for Set" if idx < 0
404
- state = value ? true : false
405
- self.entropy = idx+1
406
- if state # set bit
407
- @bits |= 1 << idx
408
- else # clear bit
409
- mask = 1 << idx
410
- @bits |= mask
411
- @bits ^= mask
442
+ # new behavior ... single element returns true/false
443
+ # multi element ... returns subset
444
+ def [](*pset)
445
+ idx = nil
446
+ if pset.count==1 # check for single instance inst[5], inst['t']
447
+ if pset.first.kind_of? Integer
448
+ idx = pset.first
449
+ elsif pset.first.kind_of? String
450
+ if pset.first.length == 1
451
+ idx = pset.first.ord
452
+ end
453
+ end
454
+ end
455
+ unless idx.nil?
456
+ raise "Negative indexes are illegal for Set" if idx < 0
457
+ self.entropy = idx+1
458
+ y = @bits & (1<<idx)
459
+ return true if y > 0
460
+ return false
412
461
  end
413
- return state
462
+ return pset.to_set & self
414
463
  end
464
+
465
+ def []=(*pset,value) # pset goes in the box, value after '='
466
+ pset = pset.to_set
467
+ state = value ? true : false
468
+ if state
469
+ replace pset | self # add elements to set
470
+ else
471
+ replace self - pset # remove elements from set
472
+ end
473
+ return state # this gets ignored, but to be safe, do what the previous version did
474
+ end
415
475
 
416
476
  def min
417
477
  return nil if empty?
@@ -441,6 +501,33 @@ class Set
441
501
  return range.first if (self[range.first])
442
502
  range.last
443
503
  end
504
+
505
+ # :array :array_chars :string :set
506
+ def rand(elm_count, format = :set)
507
+ raise "rand minimum count too low" if elm_count < 1
508
+ ary = self.to_a
509
+ ary.shuffle!
510
+ ary = ary[0..(elm_count-1)]
511
+ case format
512
+ when :array
513
+ return ary
514
+ when :array_chars
515
+ rtn = []
516
+ ary.each do |elm|
517
+ rtn.push elm.chr
518
+ end
519
+ return rtn
520
+ when :string
521
+ rtn = []
522
+ ary.each do |elm|
523
+ rtn.push elm.chr
524
+ end
525
+ return rtn.join ""
526
+ else # :set
527
+ return ary.to_set
528
+ end
529
+ end
530
+
444
531
  end # end Set
445
532
 
446
533
  module SetFuMixinBinaryAndOperator
@@ -1,3 +1,3 @@
1
1
  module Setfu
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -23,9 +23,10 @@ When characters are used, the ordinate value sets the element bit of the interna
23
23
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
24
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
25
  spec.require_paths = ["lib"]
26
+ spec.required_ruby_version = '>= 1.9.1'
26
27
 
27
28
  spec.add_development_dependency "bundler", "~> 1.3"
28
- spec.add_development_dependency "rake"
29
- spec.add_development_dependency 'rspec'
30
- spec.add_development_dependency 'byebug'
29
+ spec.add_development_dependency "rake", ">= 10.1.0"
30
+ spec.add_development_dependency 'rspec', ">= 3.3.0"
31
+ spec.add_development_dependency 'byebug', ">= 5.0.0"
31
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: setfu
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Colvin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-25 00:00:00.000000000 Z
11
+ date: 2015-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,42 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 10.1.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 10.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 3.3.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 3.3.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: byebug
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 5.0.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 5.0.0
69
69
  description: |2-
70
70
 
71
71
  Creates a Set class with methods that allow you to construct and opperate on
@@ -100,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: 1.9.1
104
104
  required_rubygems_version: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - ">="