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 +4 -4
- data/README.md +39 -3
- data/lib/enf/elephant.rb +4 -14
- data/lib/enf/input.rb +16 -0
- data/lib/enf/suggest.rb +69 -0
- data/lib/enf/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fe4cc422bed7680506a19566446cf892a7a4f2b
|
4
|
+
data.tar.gz: 0032fa20fdc2ef7ac2343bc1587f3f749f8aa764
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
111
|
-
efficient to propose completion candidates from a start of word.
|
112
|
-
3. tbd
|
148
|
+
2. tbd
|
data/lib/enf/elephant.rb
CHANGED
@@ -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
|
data/lib/enf/input.rb
ADDED
@@ -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
|
data/lib/enf/suggest.rb
ADDED
@@ -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
|
data/lib/enf/version.rb
CHANGED
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.
|
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-
|
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:
|