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.
@@ -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