ph_no_to_word 0.1.0 → 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.
- 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:
|