enf 0.0.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e55d0099cadb7696261d7142c429fab7af91d4a
4
- data.tar.gz: 85fd5160859456781784d49ceed188f4b26ed9f0
3
+ metadata.gz: 0fe4cc422bed7680506a19566446cf892a7a4f2b
4
+ data.tar.gz: 0032fa20fdc2ef7ac2343bc1587f3f749f8aa764
5
5
  SHA512:
6
- metadata.gz: 679913e249b668fa54d3da5303a9acb87aaa2e7444c9beaf50c0b35ea4f599b02e428caab10b548d56c0edd393b9901b195f85832f84de12333c975f24255ee0
7
- data.tar.gz: fe80390060f3cb8d6af9b843a116780bf8f996bb2f7bc01283d736db29eb37acfe6fc74b0eb684ea32e2c473b0ffe37ce5ce097acd596150a0b428d5397d0f63
6
+ metadata.gz: ba6d389d65cd195790b14bab10fc01af33e9b147046b38a40b3528bd5aeb44efba50bc2492fdfc010200bf97169f81bfd16874333395aeb4023a9d9823095b55
7
+ data.tar.gz: 65f92d19a83ff8fc5a46543e7847e5596c10933910a660b0fccf39ae79bdbfe76550d3ca4e0252a8d0b5566d36343c5b5669484e5a18511e258a41bd9f7e9f19
data/README.md CHANGED
@@ -7,6 +7,7 @@ Memory lightweight implementation of a white/black list
7
7
  *Building a dictionnary of all terms used in 'Les misérables'*
8
8
 
9
9
  ```ruby
10
+ require 'enf'
10
11
  require 'open-uri'
11
12
  URI = 'https://www.gutenberg.org/ebooks/135.txt.utf-8'
12
13
 
@@ -99,6 +100,43 @@ volume of data, it is recommended to use it when memory matters most and
99
100
  when words are easily factorizable (example : as a black list for twitter
100
101
  spam bots).
101
102
 
103
+ ## Note on completion suggestions
104
+
105
+ Enf::Elephant are now able to propose completion candidates from a word
106
+ beginning, thanks to the 'suggest' method:
107
+
108
+ ```ruby
109
+ require 'enf/suggest
110
+ require 'open-uri'
111
+ URI = 'https://www.gutenberg.org/ebooks/135.txt.utf-8'
112
+
113
+ elephant = Enf::Elephant.new
114
+
115
+ open(URI) do |file|
116
+ file.read.scan(/[[:alpha:]]*/).each do |token|
117
+ elephant.register! token.downcase
118
+ end
119
+ end
120
+
121
+ suggestions = elephant.suggest('ele', limit: 5, incompletes: false)
122
+ # => #<Set: {"ven", "venth", "vate", "vated", "vates", "ment",
123
+ # "ments", "gant", "gance", "gy", "onore", "phant",
124
+ # "ct", "ctor", "ctric", "cted", "usiac"}>
125
+
126
+ puts suggestions.map { |ending| 'ele' + ending }.inspect
127
+ # => ["eleven", "eleventh", "elevate", "elevated", "elevates",
128
+ # "element", "elements", "elegant", "elegance", "elegy",
129
+ # "eleonore", "elephant", "elect", "elector", "electric",
130
+ # "elected", "eleusiac"]
131
+
132
+ ```
133
+
134
+ *Parameters detail:*
135
+
136
+ * The first non optional parameter is the beginning of the words to search for.
137
+ * The limit optional parameter (default: :none) is the number of characters to allow the elephant to inquire for. That parameter allow 2 kinds of value: the :none symbol, that search deeply in the graph for corresponding completion candidates, or a strictly positive integer. (Example: with the value 2, the previous example would have only returned elegy and elect).
138
+ * The incompletes optional parameter (default: false) is a boolean parameter allowing to add intermediates incompletes words to the result set. (Example: with limit = 2 and incompletes = true, the previous result set would have been: ['ve', 'va', 'me', 'ga', 'gy', 'on', 'ph', 'ct', 'us'])
139
+
102
140
  ## Next ?
103
141
 
104
142
  I will probably be working on:
@@ -107,6 +145,4 @@ I will probably be working on:
107
145
  (example: bar, in the previous example), a hash is created for every
108
146
  letter of that specific path. We have to merge theim as a single element
109
147
  to avoid useless hash creation.
110
- 2. Completion: With that data structure, it will be quite easy and
111
- efficient to propose completion candidates from a start of word.
112
- 3. tbd
148
+ 2. tbd
@@ -1,5 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'enf/input'
4
+
3
5
  module Enf
4
6
  # Represent a node of the graph
5
7
  class Elephant
@@ -11,7 +13,7 @@ module Enf
11
13
  end
12
14
 
13
15
  def register!(element, payload = true)
14
- fail CannotRegister if frozen? || invalid?(element)
16
+ fail CannotRegister if frozen? || Input.invalid?(element)
15
17
  return (@leave = payload) if element.empty?
16
18
  @children[element[0]].register!(element[1..-1])
17
19
  end
@@ -31,7 +33,7 @@ module Enf
31
33
  end
32
34
 
33
35
  def include?(element)
34
- return @default_leave_value if invalid?(element)
36
+ return @default_leave_value if Input.invalid?(element)
35
37
  include_impl element
36
38
  end
37
39
 
@@ -39,17 +41,5 @@ module Enf
39
41
  return @leave if element.empty?
40
42
  @children.fetch(element[0]) { Nope.instance }.include_impl(element[1..-1])
41
43
  end
42
-
43
- protected
44
-
45
- require 'set'
46
-
47
- AUTHORIZED_TYPES = Set.new([String, Array]).freeze
48
-
49
- def invalid?(element)
50
- return true if element.nil?
51
- return true unless AUTHORIZED_TYPES.include? element.class
52
- false
53
- end
54
44
  end
55
45
  end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ module Enf
4
+ # Helper class for inputs
5
+ class Input
6
+ require 'set'
7
+
8
+ AUTHORIZED_TYPES = Set.new([String, Array]).freeze
9
+
10
+ def self.invalid?(element)
11
+ return true if element.nil?
12
+ return true unless AUTHORIZED_TYPES.include? element.class
13
+ false
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ require 'enf/elephant'
4
+
5
+ # Base module
6
+ module Enf
7
+ # Completion logic
8
+ module Complete
9
+ def suggest(start, limit: :none, incompletes: false)
10
+ once_validated!(start, limit, incompletes) do |s, l, i|
11
+ suggest_impl(s, l, i)
12
+ end
13
+ end
14
+
15
+ protected
16
+
17
+ # Nil class for suggestions
18
+ class Silent
19
+ require 'singleton'
20
+ include Singleton
21
+ def suggest_impl(_start, _limit, _incompletes, _prefix, results)
22
+ results
23
+ end
24
+ end
25
+
26
+ def suggest_impl(start, limit, incompletes, prefix = '', results = Set.new)
27
+ if start == ''
28
+ return results if limit != :none && limit < 0
29
+ results << prefix if @leave || (incompletes && limit == 0)
30
+ limit = limit - 1 unless limit == :none
31
+ if limit == :none || limit >= 0
32
+ @children.each do |key, child|
33
+ new_prefix = prefix + key
34
+ results =
35
+ child.suggest_impl(start, limit, incompletes, new_prefix, results)
36
+ end
37
+ end
38
+ else
39
+ child = @children.fetch(start[0]) { Silent.instance }
40
+ results =
41
+ child.suggest_impl(start[1..-1], limit, incompletes, prefix, results)
42
+ end
43
+ results
44
+ end
45
+
46
+ class SuggestParamError < StandardError; end
47
+
48
+ NEG_VAL_ERR = 'Strictly non negative values accepted only'
49
+
50
+ def validate_char_limit!(value)
51
+ return value if value == :none
52
+ fail SuggestParamError if value.nil?
53
+ value = Integer(value)
54
+ fail SuggestParamError, NEG_VAL_ERR if value <= 0
55
+ value
56
+ rescue StandardError => error
57
+ raise SuggestParamError, error.message
58
+ end
59
+
60
+ INVALID_ERR = 'Invalid input "%s"'
61
+
62
+ def once_validated!(start, char_limit, return_incompletes)
63
+ fail SuggestParamError, INVALID_ERR % start if Input.invalid? start
64
+ char_limit = validate_char_limit!(char_limit)
65
+ yield start, char_limit, return_incompletes
66
+ end
67
+ end
68
+ Elephant.send(:include, Complete)
69
+ end
@@ -3,7 +3,7 @@
3
3
  module Enf
4
4
  # This module holds the Enf version information.
5
5
  module Version
6
- STRING = '0.0.0'
6
+ STRING = '0.1.0'
7
7
 
8
8
  module_function
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Ignjatovic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-15 00:00:00.000000000 Z
11
+ date: 2015-07-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Graph based white/black list implementation. Your elephant won't forget.
14
14
  email: alexandre.ignjatovic@gmail.com
@@ -21,6 +21,8 @@ files:
21
21
  - enf.gemspec
22
22
  - lib/enf.rb
23
23
  - lib/enf/elephant.rb
24
+ - lib/enf/input.rb
25
+ - lib/enf/suggest.rb
24
26
  - lib/enf/version.rb
25
27
  homepage: https://github.com/bankair/enf
26
28
  licenses: