diff --git a/Gemfile b/Gemfile index 58e8e2a..8d9a0c9 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,17 @@ # frozen_string_literal: true source "https://rubygems.org" +# allow testing for ruby environment gem "rspec" + +# command line tool to easily handle events on file system modifications +gem 'guard' + +# automatically runs shell commands when watched files are modified +gem 'guard-shell' + +# FSEvents API with Signals catching +gem 'rb-fsevent', '~> 0.9' + +# Debugging tool for Ruby +gem 'pry' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index fe56376..5b1aece 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,38 @@ GEM remote: https://rubygems.org/ specs: + coderay (1.1.3) diff-lcs (1.3) + ffi (1.15.4) + formatador (0.3.0) + guard (2.18.0) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.13.0) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-compat (1.2.1) + guard-shell (0.7.2) + guard (>= 2.0.0) + guard-compat (~> 1.0) + listen (3.7.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + lumberjack (1.2.8) + method_source (1.0.0) + nenv (0.3.0) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + pry (0.14.1) + coderay (~> 1.1) + method_source (~> 1.0) + rb-fsevent (0.11.0) + rb-inotify (0.10.1) + ffi (~> 1.0) rspec (3.8.0) rspec-core (~> 3.8.0) rspec-expectations (~> 3.8.0) @@ -15,12 +46,18 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) + shellany (0.0.1) + thor (1.1.0) PLATFORMS ruby DEPENDENCIES + guard + guard-shell + pry + rb-fsevent (~> 0.9) rspec BUNDLED WITH - 2.0.2 + 2.2.22 diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..979f716 --- /dev/null +++ b/Guardfile @@ -0,0 +1,27 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +## Uncomment and set this to only include directories you want to watch +# directories %w(app lib config test spec features) \ +# .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")} + +## Note: if you are using the `directories` clause above and you are not +## watching the project directory ('.'), then you will want to move +## the Guardfile to a watched dir and symlink it back, e.g. +# +# $ mkdir config +# $ mv Guardfile config/ +# $ ln -s config/Guardfile . +# +# and, you'll have to watch "config/Guardfile" instead of "Guardfile" + +# Add files and commands to this file, like the example: +# watch(%r{file/path}) { `command(s)` } +# +# guard :shell do +# watch(/(.*).txt/) {|m| `tail #{m[0]}` } +# end + +guard :shell do + watch(%r{^*\.rb}) { `bundle exec rspec spec/` } +end \ No newline at end of file diff --git a/README.md b/README.md index e69de29..af1cda4 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,23 @@ +References to completing this code challenge: + +1) https://ruby-doc.org/core-3.0.2/Enumerable.html#method-i-inject + +2) https://stackoverflow.com/questions/698300/how-can-i-initialize-a-modules-instance-variables-in-ruby + +3) https://ruby-doc.org/core-3.0.2/Enumerable.html#method-i-inject + +4) https://rspec.info/ + +5) https://commandercoriander.net/blog/2014/11/09/a-multiline-string-cheatsheet-for-ruby/ + +6) http://jeromedalbert.com/ruby-how-to-iterate-the-right-way/ + +7) https://stackoverflow.com/questions/36963844/difference-between-and-in-ruby + +8) https://stackoverflow.com/questions/32059200/convert-string-to-integer-preserving-leading-zeroes + +9) https://relishapp.com/rspec/rspec-core/v/2-11/docs/helper-methods/let-and-let + +10) https://stackoverflow.com/questions/26477464/describe-vs-context-in-rspec-differences + +11) https://relishapp.com/rspec/rspec-core/v/3-8/docs/example-groups/basic-structure-describe-it \ No newline at end of file diff --git a/lib/policy_ocr.rb b/lib/policy_ocr.rb index f35a036..7654406 100644 --- a/lib/policy_ocr.rb +++ b/lib/policy_ocr.rb @@ -1,2 +1,73 @@ +require 'pry' + module PolicyOcr + + # initializing global variables + # @file takes in sample.txt, maps and + # creates strings for each line, and + # chomps(removes) the "\n" by using the to_proc + # chomp method (.map { | foo | foo.chomp }) + + @file = File.readlines("./spec/fixtures/sample.txt").map(&:chomp) + @lines = @file.size / 4 # taking size of the file (44 lines) divided by 4 (1 ocr) + @columns = @file.first.size / 3 # taking the size of the first line (27 columns) divided by 3 (1 ocr digit) + + # method for mapping out digits into strings + # we are creating values for each string pattern + def self.digits + { + " _ | ||_| " => '0', + " | | " => '1', + " _ _||_ " => '2', + " _ _| _| " => '3', + " |_| | " => '4', + " _ |_ _| " => '5', + " _ |_ |_| " => '6', + " _ | | " => '7', + " _ |_||_| " => '8', + " _ |_| _| " => '9' + } + end + + # creates a string of the policy number, + # by injecting the bars and pipes into a + # string from @file. + + #line equals amount of lines(44) in each ocr_block(11) + #column equals amount of ocr_columns(9) in each ocr_block(11) + + def self.policy_number(line, column) + (0..3).inject("") do | ocr_num, sections | + ocr_num + @file[line * 4 + sections][column * 3, 3] + end + end + + # these bottom two methods take in an OCR file, + # and parces the ocr number using exclusive + # ranges, and converting them into a string to + # then be translated to their respective values + + def self.conversion(file) + (0...@lines).inject([]) do | policy_array, line | + policy_array << numbers(line) + end.map{ | number_string | number_string.to_i } # turning string to integer + end + + # call policy_number to inject the fetched + # digits using the digits method first and injecting + # them into an string, to be called in the conversion method + + def self.numbers(line) + (0...@columns).inject("") do |digit, column| + digit + digits.fetch(policy_number(line, column)) + end + end + end + +# unable to actually receive nine 0s as ruby +# counts multiple int 0s as the value of +# a single int 0 +p PolicyOcr.conversion(@file) + +PolicyOcr.conversion(@file).map{ | policy_num | p policy_num } # see each number individually diff --git a/spec/policy_ocr_spec.rb b/spec/policy_ocr_spec.rb index 2245a42..b360646 100644 --- a/spec/policy_ocr_spec.rb +++ b/spec/policy_ocr_spec.rb @@ -1,6 +1,17 @@ require_relative '../lib/policy_ocr' + # @file = File.readlines("./spec/fixtures/sample.txt").map(&:chomp) + # @lines = @file.size / 4 + # @columns = @file.first.size / 3 + describe PolicyOcr do + let(:policy) { PolicyOcr } + let(:file) { @file } + + before :context do + @file = File.readlines("./spec/fixtures/sample.txt").map(&:chomp) + end + it "loads" do expect(PolicyOcr).to be_a Module end @@ -8,4 +19,57 @@ it 'loads the sample.txt' do expect(fixture('sample').lines.count).to eq(44) end + + it 'should assign sample.txt to @file' do + expect(@file).to eq(File.readlines("./spec/fixtures/sample.txt").map(&:chomp)) + end + + it 'converts OCR to an array' do + expect(policy.conversion(file)).to be_an_instance_of(Array) + end + + it 'converts OCR to an integer in array' do + expect(policy.conversion(file)[0]).to be_an_instance_of(Integer) + end + + # it 'reads and injects each digit into a one line string' do + # expect(policy.policy_number) + # end + + context 'converts OCR to appropriate number' do + it 'recognizes 0' do + expect(policy.conversion(file)[0]).to eq(0) + end + it 'recognizes 1' do + expect(policy.conversion(file)[1]).to eq(111111111) + end + it 'recognizes 2' do + expect(policy.conversion(file)[2]).to eq(222222222) + end + it 'recognizes 3' do + expect(policy.conversion(file)[3]).to eq(333333333) + end + it 'recognizes 4' do + expect(policy.conversion(file)[4]).to eq(444444444) + end + it 'recognizes 5' do + expect(policy.conversion(file)[5]).to eq(555555555) + end + it 'recognizes 6' do + expect(policy.conversion(file)[6]).to eq(666666666) + end + it 'recognizes 7' do + expect(policy.conversion(file)[7]).to eq(777777777) + end + it 'recognizes 8' do + expect(policy.conversion(file)[8]).to eq(888888888) + end + it 'recognizes 9' do + expect(policy.conversion(file)[9]).to eq(999999999) + end + it 'recognizes mixed numbers' do + expect(policy.conversion(file)[10]).to eq(123456789) + end + end + end