ivanvc-dictionary 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ Army
2
+ Bid
3
+ Carthorse
4
+ Close
5
+ Difference
6
+ Mary
7
+ Orchestra
@@ -0,0 +1,7 @@
1
+ army
2
+ bid
3
+ carthorse
4
+ close
5
+ difference
6
+ mary
7
+ orchestra
@@ -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
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'dictionary'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
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