ph_no_to_word 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +37 -6
- data/lib/ph_no_to_word/constants.rb +2 -1
- data/lib/ph_no_to_word/helpers.rb +4 -0
- data/lib/ph_no_to_word/logger.rb +16 -2
- data/lib/ph_no_to_word/version.rb +1 -1
- data/lib/ph_no_to_word.rb +65 -38
- data/ph_no_to_word.gemspec +1 -1
- metadata +4 -4
- data/lib/ph_no_to_word/word_files/dictionary.txt +0 -178691
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20f2ae407d619aaa35e1ff828c41176cf5da1b9558097633163f1fa9d5ca3708
|
4
|
+
data.tar.gz: 4b7eada9bf025db4eb22f4b53a0241826868b855b6834c4a1b25f566f88a27c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 211c21a5530f534b323b6b90b1a2ea851d4a63742d31191339b5a16d2802d790424e03889f0e9307610ddc95c9498db941441a5f467cc43f1f8500996d43e0a5
|
7
|
+
data.tar.gz: 485d7c4b494dba3b3724ec529520b94b2b6562d60c1eea7a48bcc8366b6a84ed53ab5963e5d63161275eca5ca0e84c9fa186276d60627389de33f13fb8b40afb
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [1.0.0] - 2019-05-25
|
10
|
+
### Added
|
11
|
+
- New visual identity by [@abhilashak](https://github.com/abhilashak).
|
12
|
+
- ChangeLog file added
|
13
|
+
- Return value of `convert` method now provided with an Array for better use of output for developers
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- Code optimizations
|
17
|
+
- Modified readme file
|
18
|
+
- Added the link to the dictionary file, keeping dictionary sample file
|
19
|
+
|
20
|
+
### Removed
|
21
|
+
- Printing of the results
|
22
|
+
- Huge dictionary file as we have splitted files on live
|
23
|
+
|
24
|
+
## [0.1.0] - 2019-05-24
|
25
|
+
### Added
|
26
|
+
- Added the functionailty of Phone number to word, tested and published to the world.
|
27
|
+
|
28
|
+
### Changed
|
29
|
+
- Moved the splitting code to separate namespace
|
30
|
+
### Removed
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
`ph_no_to_word` allows given 10 character phone number to convert into a word that is contained in a dictionary.
|
4
4
|
The phone number should not contain 0 or 1. The matching words contain atleast 3 characters.
|
5
|
+
You can find the dictionary file here: https://gist.github.com/abhilashak/fde080091463ca0f03b12b41e8b66108
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
@@ -21,21 +22,51 @@ Or install it yourself as:
|
|
21
22
|
|
22
23
|
|
23
24
|
## Usage
|
25
|
+
After installing the gem goto
|
24
26
|
|
25
27
|
```ruby
|
26
|
-
|
27
|
-
|
28
|
+
irb(main):001:0> require 'ph_no_to_word'
|
29
|
+
=> true
|
30
|
+
irb(main):002:0> PhNoToWord::convert "2282668687"
|
28
31
|
Results:
|
29
|
-
* catamounts
|
30
|
-
* acta, mounts
|
31
32
|
* act, amounts
|
33
|
+
* act, boo, tots
|
34
|
+
* act, boo, tour
|
35
|
+
* act, boot, mus
|
36
|
+
* act, boot, nus
|
37
|
+
* act, boot, our
|
38
|
+
* act, con, tots
|
39
|
+
* act, con, tour
|
32
40
|
* act, contour
|
33
|
-
|
41
|
+
.......
|
42
|
+
.......
|
43
|
+
* cat, con, tour
|
44
|
+
* cat, contour
|
45
|
+
* cat, coo, tots
|
46
|
+
* cat, coo, tour
|
47
|
+
* cat, coot, mus
|
48
|
+
* cat, coot, nus
|
49
|
+
* cat, coot, our
|
50
|
+
* catamounts
|
51
|
+
```
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
irb(main):004:0> PhNoToWord::convert '6686787825'
|
55
|
+
* motortruck
|
56
|
+
* motor, truck
|
57
|
+
* motor, usual
|
58
|
+
* mot, opt, puck
|
59
|
+
* mot, opt, ruck
|
60
|
+
* mot, opt, suck
|
61
|
+
* noun, struck
|
62
|
+
* not, opt, puck
|
63
|
+
.......
|
64
|
+
.......
|
34
65
|
```
|
35
66
|
|
36
67
|
## Contributing
|
37
68
|
|
38
|
-
Bug reports and pull requests are welcome on
|
69
|
+
Bug reports and pull requests are welcome on Github at https://github.com/abhilashak/ph_no_to_word. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
39
70
|
|
40
71
|
## License
|
41
72
|
|
@@ -5,6 +5,7 @@ module PhNoToWord
|
|
5
5
|
module Constants
|
6
6
|
ERRORS = {
|
7
7
|
missing_ph: 'Please provide a phone number',
|
8
|
+
ph_length: 'Please provide 10 digit phone number',
|
8
9
|
malformed_ph_no: 'Cannot contain 0 or 1 in the phone number'
|
9
10
|
}.freeze
|
10
11
|
NO_CHAR_MAP = {
|
@@ -27,6 +28,6 @@ module PhNoToWord
|
|
27
28
|
DEFAULT_WORD_FILES_PATH = '/word_files'
|
28
29
|
DEFAULT_WORD_FILE_DIR = DEFAULT_WORD_FILES_PATH + '/level_1'
|
29
30
|
DEFAULT_WD_FILE_DIR_LVL_2 = DEFAULT_WORD_FILES_PATH + '/level_2'
|
30
|
-
DEFAULT_DICTIONARY_FILE_PATH = DEFAULT_WORD_FILES_PATH + '/
|
31
|
+
DEFAULT_DICTIONARY_FILE_PATH = DEFAULT_WORD_FILES_PATH + '/dictionary_sample' + FILE_EXT
|
31
32
|
end
|
32
33
|
end
|
data/lib/ph_no_to_word/logger.rb
CHANGED
@@ -1,8 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This modules helps to write into the log file
|
4
|
+
# Usage:
|
5
|
+
# include PhNoToWord::Logger
|
6
|
+
# def do_something
|
7
|
+
# begin
|
8
|
+
# # do something
|
9
|
+
# rescue StandardError => e
|
10
|
+
# log :error, e.message
|
11
|
+
# end
|
12
|
+
# end
|
1
13
|
module PhNoToWord
|
2
14
|
module Logger
|
3
15
|
# Log a PhNoToWord-specific line.
|
4
|
-
def log(message)
|
5
|
-
|
16
|
+
def log(level, message)
|
17
|
+
File.open('log.txt', 'a') do |f|
|
18
|
+
f.write "#{level}: #{message}"
|
19
|
+
end
|
6
20
|
end
|
7
21
|
end
|
8
22
|
end
|
data/lib/ph_no_to_word.rb
CHANGED
@@ -40,49 +40,73 @@ module PhNoToWord
|
|
40
40
|
# @return words [Array]
|
41
41
|
# Ex: PhNoToWord::convert "2282668687"
|
42
42
|
# Add 2nd parameter: file_path = nil
|
43
|
-
# And add `split_files(file_path)` for splitting the provided dictionary
|
43
|
+
# And add `split_files(file_path)` for splitting the provided dictionary file
|
44
44
|
def self.convert(phone_no = '')
|
45
|
-
raise RequiredArgumentMissingError, ERRORS[:missing_ph] if phone_no.empty?
|
46
|
-
|
47
45
|
ph_numbers = phone_no.split(//)
|
48
|
-
|
49
|
-
raise MalformattedArgumentError, ERRORS[:malformed_ph_no]
|
50
|
-
end
|
46
|
+
validate phone_no, ph_numbers
|
51
47
|
|
52
48
|
ph_to_word_mapping = ph_numbers.map { |ph_no| NO_CHAR_MAP[ph_no.to_sym] }
|
49
|
+
|
53
50
|
result = find_word(ph_to_word_mapping)
|
54
51
|
map_num_to_word(result, ph_numbers)
|
55
|
-
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param phone_no [String]
|
55
|
+
# Populate error if not a valid phone number given
|
56
|
+
def self.validate(phone_no, ph_numbers)
|
57
|
+
raise RequiredArgumentMissingError, ERRORS[:missing_ph] if phone_no.empty?
|
58
|
+
|
59
|
+
unless phone_no.length.eql?(PH_LENGTH)
|
60
|
+
raise MalformattedArgumentError, ERRORS[:ph_length]
|
61
|
+
end
|
62
|
+
return if (ph_numbers & FORBIDDEN_NOS).empty?
|
63
|
+
|
64
|
+
raise MalformattedArgumentError, ERRORS[:malformed_ph_no]
|
56
65
|
end
|
57
66
|
|
58
67
|
# Position the words matched to corresponding phone number
|
59
|
-
# @param wd_ary [Set] ph_ary [Array] parent_wd [String]
|
68
|
+
# @param wd_ary [Set] ph_ary [Array] parent_wd [String] level [Integer] wd_hash [Hash]
|
60
69
|
# Ex: ph_ary ["2", "2", "8", "2", "6", "6", "8", "6", "8", "7"]
|
61
70
|
# Ex: wd_ary #<Set: {"MOT", "OPT", "PUB", "PUCK", "QUA", "RUB", "RUCK"}>
|
71
|
+
# wd_hash is a tricky implementation that is using to add the commas in
|
72
|
+
# between the words found in the result, should try to avoid in future
|
73
|
+
# Ex: level 1, 2, 3 because Maximum 3 words can only contain in the result
|
74
|
+
# Ex: wd_hash { :first => "asasa", :second => "dfdfdf", :third => "ddfdfdf"}
|
62
75
|
def self.map_num_to_word(wd_ary, ph_ary, parent_wd = '', level = 1, wd_hash = {})
|
76
|
+
@matching_wd_ary ||= []
|
77
|
+
|
63
78
|
wd_ary.each do |wd|
|
64
|
-
wd_hash =
|
79
|
+
wd_hash = arrange_result(wd_hash, level, wd)
|
65
80
|
total_len = (parent_wd + wd).length
|
66
|
-
|
81
|
+
|
82
|
+
if total_len == PH_LENGTH
|
83
|
+
result = full_mapping_to_wd(parent_wd + wd, ph_ary, wd_hash)
|
84
|
+
@matching_wd_ary << result if result
|
85
|
+
end
|
86
|
+
|
67
87
|
next if total_len > MAX_FST_WD_LEN
|
68
88
|
|
69
|
-
|
89
|
+
if level < MAXIMUM_WDS
|
90
|
+
map_num_to_word(wd_ary, ph_ary, parent_wd + wd, level + 1, wd_hash)
|
91
|
+
end
|
70
92
|
end
|
93
|
+
|
94
|
+
@matching_wd_ary
|
71
95
|
end
|
72
96
|
|
73
97
|
# Add first, second and third words in order to display
|
74
98
|
# @param wd_hash [Hash] level [Integer] wd [String]
|
75
|
-
def self.
|
99
|
+
def self.arrange_result(wd_hash, level, word)
|
76
100
|
case level
|
77
101
|
when 1
|
78
|
-
wd_hash[:first] =
|
79
|
-
wd_hash[:third] = wd_hash[:second] = nil if
|
102
|
+
wd_hash[:first] = word
|
103
|
+
wd_hash[:third] = wd_hash[:second] = nil if word.length > MAX_FST_WD_LEN
|
80
104
|
when 2
|
81
|
-
wd_hash[:second] =
|
82
|
-
wd_hash[:third] = nil if (wd_hash[:first] +
|
83
|
-
when 3
|
84
|
-
wd_hash[:third] = wd
|
105
|
+
wd_hash[:second] = word
|
106
|
+
wd_hash[:third] = nil if (wd_hash[:first] + word).length > MAX_FST_WD_LEN
|
107
|
+
when 3 then wd_hash[:third] = word
|
85
108
|
end
|
109
|
+
|
86
110
|
wd_hash
|
87
111
|
end
|
88
112
|
|
@@ -91,25 +115,30 @@ module PhNoToWord
|
|
91
115
|
# Ex: wd_ary ["c", "a", "t", "a", "m", "o", "u", "n", "t", "s"]
|
92
116
|
def self.full_mapping_to_wd(word, ph_numbers, disply_wrd)
|
93
117
|
word_ary = word.split(//)
|
118
|
+
|
94
119
|
ph_numbers.each_with_index do |number, index|
|
95
120
|
return false unless NO_CHAR_MAP[number.to_sym].include?(word_ary[index].downcase)
|
96
121
|
end
|
97
|
-
|
122
|
+
|
123
|
+
disply_wrd.values.compact.join(', ').downcase
|
98
124
|
end
|
99
125
|
|
100
126
|
# finds the matching words and prints it
|
101
127
|
# calls from 0 - 9 chars and finds the matching
|
102
128
|
def self.find_word(char_ary = [], start = 0, str = '')
|
103
129
|
@result ||= Set.new
|
130
|
+
|
104
131
|
loop_phone = proc do |ary, pos, match|
|
105
132
|
(ary[pos] || []).each do |char|
|
106
133
|
result = print_result(match + char) if pos > 1
|
134
|
+
|
107
135
|
@result.add(result) if result
|
108
136
|
find_next_word(char_ary, result)
|
109
|
-
|
137
|
+
|
110
138
|
loop_phone.call(ary, pos + 1, match + char) if pos < (PH_LENGTH - 1)
|
111
139
|
end
|
112
140
|
end
|
141
|
+
|
113
142
|
loop_phone.call(char_ary, start, str)
|
114
143
|
@result
|
115
144
|
end
|
@@ -131,31 +160,28 @@ module PhNoToWord
|
|
131
160
|
# @param str [String]
|
132
161
|
# Level 1: 3 char words
|
133
162
|
# Level 2: > 3 char words
|
163
|
+
# Ex: str acfdrt in if condition
|
164
|
+
# Ex: str asde, act, aem in else condition
|
134
165
|
def self.search_word(str)
|
135
166
|
level = (str.length == MIN_WD_LENGTH ? 1 : 2)
|
136
|
-
# Ex: str acfdrt
|
137
167
|
filename = if str.length > MAX_SPLIT_DEPTH
|
138
168
|
str[0..MAX_SPLIT_DEPTH - 1] + FILE_EXT
|
139
169
|
else
|
140
|
-
# Ex: str asde, act, aem
|
141
170
|
str + FILE_EXT
|
142
171
|
end
|
172
|
+
|
143
173
|
new_file_path = find_file_to_search(level, filename)
|
144
174
|
return nil unless File.file?(new_file_path)
|
145
175
|
|
146
|
-
|
147
|
-
word_found
|
176
|
+
check_file_cnt_matches(new_file_path, str)
|
148
177
|
end
|
149
178
|
|
150
179
|
# if level is 1, search in file three_char_wrds
|
151
180
|
# else search in file with name of first 4 char wrd
|
152
181
|
def self.find_file_to_search(lvl, filename)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
word_file_folder_path(lvl) + '/' + filename
|
157
|
-
end
|
158
|
-
file_path
|
182
|
+
return (word_file_folder_path(lvl) + '/' + THREE_CHAR_FILE) if lvl == 1
|
183
|
+
|
184
|
+
word_file_folder_path(lvl) + '/' + filename
|
159
185
|
end
|
160
186
|
|
161
187
|
# @param file_path [String] str [String]
|
@@ -163,20 +189,21 @@ module PhNoToWord
|
|
163
189
|
def self.check_file_cnt_matches(file_path, str)
|
164
190
|
word_found = nil
|
165
191
|
File.open(file_path, 'r') do |f|
|
166
|
-
f.each_line
|
167
|
-
# exit loop if finds the str from dictionary
|
168
|
-
if line.strip.casecmp(str).zero?
|
169
|
-
word_found = line.strip
|
170
|
-
break
|
171
|
-
end
|
172
|
-
end
|
192
|
+
f.each_line { |line| (word_found = line.strip) && break if cmp(line, str) }
|
173
193
|
end
|
174
194
|
word_found
|
175
195
|
end
|
176
196
|
|
197
|
+
# Compare two strings irrespective of case
|
198
|
+
def self.cmp(line, str)
|
199
|
+
return false unless line && str
|
200
|
+
|
201
|
+
line.strip.casecmp(str.strip).zero?
|
202
|
+
end
|
203
|
+
|
177
204
|
class << self
|
178
205
|
private :find_word, :write_to_file, :search_word, :word_file_folder_path,
|
179
206
|
:check_file_cnt_matches, :find_file_to_search, :print_result,
|
180
|
-
:
|
207
|
+
:arrange_result, :find_next_word, :cmp
|
181
208
|
end
|
182
209
|
end
|
data/ph_no_to_word.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
21
21
|
spec.metadata["homepage_uri"] = spec.homepage
|
22
22
|
spec.metadata["source_code_uri"] = spec.homepage
|
23
|
-
spec.metadata["changelog_uri"] = spec.homepage
|
23
|
+
spec.metadata["changelog_uri"] = spec.homepage + '/blob/master/CHANGELOG.md'
|
24
24
|
else
|
25
25
|
raise "RubyGems 2.0 or newer is required to protect against " \
|
26
26
|
"public gem pushes."
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ph_no_to_word
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abhilash A K
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -60,6 +60,7 @@ executables: []
|
|
60
60
|
extensions: []
|
61
61
|
extra_rdoc_files: []
|
62
62
|
files:
|
63
|
+
- CHANGELOG.md
|
63
64
|
- CODE_OF_CONDUCT.md
|
64
65
|
- README.md
|
65
66
|
- bin/console
|
@@ -71,7 +72,6 @@ files:
|
|
71
72
|
- lib/ph_no_to_word/logger.rb
|
72
73
|
- lib/ph_no_to_word/split_dictionary.rb
|
73
74
|
- lib/ph_no_to_word/version.rb
|
74
|
-
- lib/ph_no_to_word/word_files/dictionary.txt
|
75
75
|
- lib/ph_no_to_word/word_files/dictionary_sample.txt
|
76
76
|
- lib/ph_no_to_word/word_files/level_1/three_char_wrds.txt
|
77
77
|
- lib/ph_no_to_word/word_files/level_2/aahe.txt
|
@@ -14350,7 +14350,7 @@ licenses:
|
|
14350
14350
|
metadata:
|
14351
14351
|
homepage_uri: https://github.com/abhilashak/ph_no_to_word
|
14352
14352
|
source_code_uri: https://github.com/abhilashak/ph_no_to_word
|
14353
|
-
changelog_uri: https://github.com/abhilashak/ph_no_to_word
|
14353
|
+
changelog_uri: https://github.com/abhilashak/ph_no_to_word/blob/master/CHANGELOG.md
|
14354
14354
|
post_install_message:
|
14355
14355
|
rdoc_options: []
|
14356
14356
|
require_paths:
|