ivanvc-dictionary 0.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.
- data/.document +5 -0
- data/.gitignore +2 -0
- data/README.rdoc +13 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/bin/anagram_extractor +10 -0
- data/extras/3k_english.txt +3000 -0
- data/extras/capitalized_english.txt +7 -0
- data/extras/english.txt +7 -0
- data/lib/dictionary/anagram_extractor.rb +98 -0
- data/lib/dictionary/error.rb +25 -0
- data/lib/dictionary.rb +26 -0
- data/spec/anagram_extactor_spec.rb +94 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- metadata +90 -0
data/extras/english.txt
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
module Dictionary
|
2
|
+
# The class AnagramExtactor, contains the implementation to get all the anagrams
|
3
|
+
# from a dictionary provided text file.
|
4
|
+
#
|
5
|
+
# @example Example Usage
|
6
|
+
# extractor = AnagramExtractor.new('my_dictionary.txt')
|
7
|
+
# extractor.extract!
|
8
|
+
# extractor.export('anagrams.txt')
|
9
|
+
class AnagramExtractor
|
10
|
+
# Holds the dictionary file.
|
11
|
+
attr_reader :file
|
12
|
+
# Holds the anagrams extracted.
|
13
|
+
attr_reader :anagrams
|
14
|
+
|
15
|
+
# An AnagramExtactor instance should be initialized with the location of the file to scan.
|
16
|
+
#
|
17
|
+
# @raise [Dictionary::Error::FileNotFoundError] if the provided file is not found.
|
18
|
+
# @param [String, Pathname] file the location of the file.
|
19
|
+
def initialize(file=nil)
|
20
|
+
self.file = file if file
|
21
|
+
end
|
22
|
+
|
23
|
+
# Replaces the dictionary file. Also resets the dictionary and the extracted anagrams.
|
24
|
+
#
|
25
|
+
# @raise [Dictionary::Error::FileNotFoundError] if the provided file is not found.
|
26
|
+
# @param [String, Pathname] file the location of the file.
|
27
|
+
def file=(file)
|
28
|
+
reset_dictionaries
|
29
|
+
@file = get_full_location file
|
30
|
+
raise Error::FileNotFoundError unless File.exists?(@file)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Extracts the anagrams from the provided file.
|
34
|
+
#
|
35
|
+
# @return [Array] the anagram list.
|
36
|
+
def extract!
|
37
|
+
reset_dictionaries
|
38
|
+
File.read(@file).each_line do |word|
|
39
|
+
word = word.strip
|
40
|
+
has_an_anagram = anagram_for? word
|
41
|
+
@anagrams += [word, has_an_anagram] if has_an_anagram
|
42
|
+
@dictionary << word
|
43
|
+
end
|
44
|
+
@anagrams
|
45
|
+
end
|
46
|
+
|
47
|
+
# Saves the anagram dictionary to a provided file.
|
48
|
+
#
|
49
|
+
# @param [String, Pathname] location the location of the file to write.
|
50
|
+
# @raise [Dictionary::Error::FileAlreadyExistsError] if the file already exists.
|
51
|
+
# @raise [Dictionary::Error::PathNotFoundError] if the export path does not exists.
|
52
|
+
# @return [String] the full path to the exported file.
|
53
|
+
def export(location)
|
54
|
+
location = get_full_location location
|
55
|
+
@anagrams ||= []
|
56
|
+
|
57
|
+
raise Dictionary::Error::FileAlreadyExistsError if File.exists? location
|
58
|
+
unless File.directory? File.dirname(location)
|
59
|
+
raise Dictionary::Error::PathNotFoundError
|
60
|
+
end
|
61
|
+
File.open(location, 'w') { |file| file.puts @anagrams.join("\n") }
|
62
|
+
location
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
# Will return if a word has an anagram in the currently extracted dictionary.
|
67
|
+
#
|
68
|
+
# @private
|
69
|
+
# @param [String] word the word to check
|
70
|
+
# @return [nil, String] nil if the dictionary is empty or, there are no anagrams for
|
71
|
+
# this word. Else, the matching word.
|
72
|
+
def anagram_for?(word)
|
73
|
+
word_letters = word.downcase.scan(/\w/).sort
|
74
|
+
@dictionary.find do |test_word|
|
75
|
+
test_word_letters = test_word.downcase.scan(/\w/)
|
76
|
+
test_word_letters.size == word_letters.size &&
|
77
|
+
test_word_letters.sort == word_letters
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Resets the dictionary and the anagrams.
|
82
|
+
#
|
83
|
+
# @return [nil]
|
84
|
+
def reset_dictionaries
|
85
|
+
@dictionary = []
|
86
|
+
@anagrams = []
|
87
|
+
end
|
88
|
+
|
89
|
+
# Standardizes the location of the passed file.
|
90
|
+
#
|
91
|
+
# @param [String, Pathname] file the file to scan.
|
92
|
+
# @return [String] the standardized location.
|
93
|
+
def get_full_location(file)
|
94
|
+
file = "#{Dir.pwd}/#{file}" unless Pathname.new(file).absolute?
|
95
|
+
File.expand_path(file)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Module for Exceptions from the Dictionary Module.
|
2
|
+
module Dictionary::Error
|
3
|
+
# A FileNotFoundError may be raised by an AnagramExtactor class if the source file is not
|
4
|
+
# found.
|
5
|
+
#
|
6
|
+
# @see Dictionary::AnagramExtractor#initialize
|
7
|
+
# @see Dictionary::AnagramExtractor#file=
|
8
|
+
class FileNotFoundError < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
# A PathNotFoundError may be raised by an AnagramExtactor class if the path to a file is not
|
12
|
+
# found.
|
13
|
+
#
|
14
|
+
# @see Dictionary::AnagramExtractor#export
|
15
|
+
# @see Dictionary::AnagramExtractor#file=
|
16
|
+
class PathNotFoundError < StandardError
|
17
|
+
end
|
18
|
+
|
19
|
+
# A FileAlreadyExistsError may be raised by an AnagramExtactor class if the file already exists.
|
20
|
+
#
|
21
|
+
# @see Dictionary::AnagramExtractor#export
|
22
|
+
# @see Dictionary::AnagramExtractor#file=
|
23
|
+
class FileAlreadyExistsError < StandardError
|
24
|
+
end
|
25
|
+
end
|
data/lib/dictionary.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
# Module that contains the AnagramExtractor.
|
4
|
+
module Dictionary
|
5
|
+
base_dir = File.expand_path(File.dirname(__FILE__) + '/dictionary') + '/'
|
6
|
+
autoload :AnagramExtractor, base_dir + 'anagram_extractor.rb'
|
7
|
+
autoload :Error, base_dir + 'error.rb'
|
8
|
+
|
9
|
+
# Extracts the anagrams from a file, and exports the results.
|
10
|
+
#
|
11
|
+
# @param [String, Pathname] file the location of the dictionary
|
12
|
+
# @param [String, Pathname] export_location the export location for the results.
|
13
|
+
# @return [String] The result of the extraction.
|
14
|
+
def self.extract_anagrams(file, export_location)
|
15
|
+
extractor = AnagramExtractor.new(file)
|
16
|
+
extractor.extract!
|
17
|
+
extractor.export(export_location)
|
18
|
+
"Exported anagram list to #{export_location}."
|
19
|
+
rescue Error::FileNotFoundError
|
20
|
+
"The source file seems to be missing."
|
21
|
+
rescue Error::PathNotFoundError
|
22
|
+
"The export path does not exist."
|
23
|
+
rescue Error::FileAlreadyExistsError
|
24
|
+
"The export file already exists."
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Dictionary::AnagramExtractor do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@extractor = Dictionary::AnagramExtractor.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ".file=" do
|
10
|
+
|
11
|
+
it "should raise an error if file not found" do
|
12
|
+
lambda { @extractor.file = 'extras/notfound.txt' }.should\
|
13
|
+
raise_error(Dictionary::Error::FileNotFoundError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should set it to the absolute path" do
|
17
|
+
@extractor.file = 'extras/english.txt'
|
18
|
+
Pathname.new(@extractor.file).should be_absolute
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should clear the anagram list" do
|
22
|
+
@extractor.file = 'extras/english.txt'
|
23
|
+
@extractor.extract!
|
24
|
+
|
25
|
+
lambda { @extractor.file = 'extras/english.txt' }.should change(@extractor, :anagrams)
|
26
|
+
@extractor.anagrams.should be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ".extract!" do
|
32
|
+
|
33
|
+
before(:each) do
|
34
|
+
@extractor.file = 'extras/english.txt'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return an Array" do
|
38
|
+
@extractor.extract!.should be_an_instance_of(Array)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return four matches" do
|
42
|
+
@extractor.extract!.size.should == 4
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return four matches even if words are capitalized" do
|
46
|
+
@extractor.file = 'extras/capitalized_english.txt'
|
47
|
+
@extractor.extract!.size.should == 4
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should contain mary and army as anagrams" do
|
51
|
+
@extractor.extract!.should include('mary', 'army')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "export" do
|
57
|
+
before(:each) do
|
58
|
+
@location = "#{Dir.pwd}/example.txt"
|
59
|
+
end
|
60
|
+
|
61
|
+
after(:each) do
|
62
|
+
FileUtils.rm_rf @location
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should raise an error if the output file already exists" do
|
66
|
+
lambda { @extractor.export 'extras/english.txt' }.should\
|
67
|
+
raise_error(Dictionary::Error::FileAlreadyExistsError)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should raise an error if the path of the file does not exist" do
|
71
|
+
lambda { @extractor.export 'chunky/bacon.txt' }.should\
|
72
|
+
raise_error(Dictionary::Error::PathNotFoundError)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should return the location of the output" do
|
76
|
+
@extractor.export('example.txt').should == @location
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should write a file" do
|
80
|
+
@extractor.export 'example.txt'
|
81
|
+
File.exists?(@location).should be_true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should contain all the lines in @anagrams" do
|
85
|
+
@extractor.file = 'extras/english.txt'
|
86
|
+
@extractor.extract!
|
87
|
+
@extractor.export 'example.txt'
|
88
|
+
|
89
|
+
File.read(@location).split("\n").size.should == 4
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ivanvc-dictionary
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- "Iv\xC3\xA1n Vald\xC3\xA9s (@ivanvc)"
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-09 00:00:00 -05:00
|
18
|
+
default_executable: anagram_extractor
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
- 9
|
31
|
+
version: 1.2.9
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Dictionary
|
35
|
+
email: iv@nvald.es
|
36
|
+
executables:
|
37
|
+
- anagram_extractor
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- README.rdoc
|
42
|
+
files:
|
43
|
+
- .document
|
44
|
+
- .gitignore
|
45
|
+
- README.rdoc
|
46
|
+
- Rakefile
|
47
|
+
- VERSION
|
48
|
+
- bin/anagram_extractor
|
49
|
+
- extras/3k_english.txt
|
50
|
+
- extras/capitalized_english.txt
|
51
|
+
- extras/english.txt
|
52
|
+
- lib/dictionary.rb
|
53
|
+
- lib/dictionary/anagram_extractor.rb
|
54
|
+
- lib/dictionary/error.rb
|
55
|
+
- spec/anagram_extactor_spec.rb
|
56
|
+
- spec/spec.opts
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
has_rdoc: true
|
59
|
+
homepage: http://github.com/ivanvc/dictionary
|
60
|
+
licenses: []
|
61
|
+
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options:
|
64
|
+
- --charset=UTF-8
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.3.6
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Dictionary
|
88
|
+
test_files:
|
89
|
+
- spec/anagram_extactor_spec.rb
|
90
|
+
- spec/spec_helper.rb
|