From a81996a39dc2f456e1232b211cc14192efe3f907 Mon Sep 17 00:00:00 2001 From: John Lonetree Date: Fri, 12 Nov 2021 15:33:34 -0600 Subject: [PATCH 1/7] First Attempt without rspec --- Gemfile | 10 +++++++ Gemfile.lock | 38 +++++++++++++++++++++++++- Guardfile | 27 +++++++++++++++++++ README.md | 17 ++++++++++++ lib/policy_ocr.rb | 60 +++++++++++++++++++++++++++++++++++++++++ spec/policy_ocr_spec.rb | 44 ++++++++++++++++++++++++++++++ 6 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 Guardfile diff --git a/Gemfile b/Gemfile index 58e8e2a..76faf2c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,14 @@ # 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' diff --git a/Gemfile.lock b/Gemfile.lock index fe56376..9edf6b1 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,17 @@ 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 + 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..7cba1d4 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,17 @@ +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 \ No newline at end of file diff --git a/lib/policy_ocr.rb b/lib/policy_ocr.rb index f35a036..a6505e5 100644 --- a/lib/policy_ocr.rb +++ b/lib/policy_ocr.rb @@ -1,2 +1,62 @@ 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) + @columns = @file.first.size / 3 # taking the size of the first line + + # method for mapping out digits into strings + 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 + + # this method takes in an OCR file, + # and parces the number using exclusive + # ranges, and injecting them first into an string, + # then injecting them further into an array + + def self.conversion(file) + (0...@lines).inject([]) do | policy_array, line | + policy_array << (0...@columns).inject("") do |digit, column| + digit + digits.fetch(policy_number(line, column)) + end + end.map{ | number_string | number_string.to_i } # turning string to integer + end + + end + +# unable to actually receive 9 0s as ruby +# counts multiple int 0s as the value of +# a single int 0 + +p PolicyOcr.conversion(@file) diff --git a/spec/policy_ocr_spec.rb b/spec/policy_ocr_spec.rb index 2245a42..837815f 100644 --- a/spec/policy_ocr_spec.rb +++ b/spec/policy_ocr_spec.rb @@ -1,6 +1,12 @@ 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.new } + it "loads" do expect(PolicyOcr).to be_a Module end @@ -8,4 +14,42 @@ it 'loads the sample.txt' do expect(fixture('sample').lines.count).to eq(44) end + + # it '@file should be assigned sample.txt' do + # expect(@file).to eq(File.readlines("./spec/fixtures/sample.txt").map(&:chomp)) + # end + + # context 'converts OCR to appropriate number' do + # it 'recognizes 0' do + # expect(policy.conversion(file)).to eq(0) + # end + # it 'recognizes 1' do + # expect(policy.conversion(file)).to eq(1) + # end + # it 'recognizes 2' do + # expect(policy.conversion(file)).to eq(2) + # end + # it 'recognizes 3' do + # expect(policy.conversion(file)).to eq(3) + # end + # it 'recognizes 4' do + # expect(policy.conversion(file)).to eq(4) + # end + # it 'recognizes 5' do + # expect(policy.conversion(file)).to eq(5) + # end + # it 'recognizes 6' do + # expect(policy.conversion(file)).to eq(6) + # end + # it 'recognizes 7' do + # expect(policy.conversion(file)).to eq(7) + # end + # it 'recognizes 8' do + # expect(policy.conversion(file)).to eq(8) + # end + # it 'recognizes 9' do + # expect(policy.conversion(file)).to eq(9) + # end + # end + end From b047ef1815e1a22945b6885f5298504b26bd6be3 Mon Sep 17 00:00:00 2001 From: John Lonetree Date: Mon, 15 Nov 2021 09:10:13 -0600 Subject: [PATCH 2/7] Attempt with rspec --- lib/policy_ocr.rb | 6 +-- spec/policy_ocr_spec.rb | 90 ++++++++++++++++++++++++----------------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/lib/policy_ocr.rb b/lib/policy_ocr.rb index a6505e5..f824056 100644 --- a/lib/policy_ocr.rb +++ b/lib/policy_ocr.rb @@ -7,8 +7,8 @@ module PolicyOcr # 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) - @columns = @file.first.size / 3 # taking the size of the first line + @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 def self.digits @@ -55,7 +55,7 @@ def self.conversion(file) end -# unable to actually receive 9 0s as ruby +# unable to actually receive nine 0s as ruby # counts multiple int 0s as the value of # a single int 0 diff --git a/spec/policy_ocr_spec.rb b/spec/policy_ocr_spec.rb index 837815f..605ff7a 100644 --- a/spec/policy_ocr_spec.rb +++ b/spec/policy_ocr_spec.rb @@ -5,7 +5,12 @@ # @columns = @file.first.size / 3 describe PolicyOcr do - let(:policy) { PolicyOcr.new } + 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 @@ -15,41 +20,52 @@ expect(fixture('sample').lines.count).to eq(44) end - # it '@file should be assigned sample.txt' do - # expect(@file).to eq(File.readlines("./spec/fixtures/sample.txt").map(&:chomp)) - # end - - # context 'converts OCR to appropriate number' do - # it 'recognizes 0' do - # expect(policy.conversion(file)).to eq(0) - # end - # it 'recognizes 1' do - # expect(policy.conversion(file)).to eq(1) - # end - # it 'recognizes 2' do - # expect(policy.conversion(file)).to eq(2) - # end - # it 'recognizes 3' do - # expect(policy.conversion(file)).to eq(3) - # end - # it 'recognizes 4' do - # expect(policy.conversion(file)).to eq(4) - # end - # it 'recognizes 5' do - # expect(policy.conversion(file)).to eq(5) - # end - # it 'recognizes 6' do - # expect(policy.conversion(file)).to eq(6) - # end - # it 'recognizes 7' do - # expect(policy.conversion(file)).to eq(7) - # end - # it 'recognizes 8' do - # expect(policy.conversion(file)).to eq(8) - # end - # it 'recognizes 9' do - # expect(policy.conversion(file)).to eq(9) - # end - # 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 + + 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 From f3884645a94257b0a3accf81aa83b0a2fc4757f6 Mon Sep 17 00:00:00 2001 From: John Lonetree Date: Mon, 15 Nov 2021 10:39:22 -0600 Subject: [PATCH 3/7] Added additional read files, and added a gem --- Gemfile | 3 +++ README.md | 8 +++++++- spec/policy_ocr_spec.rb | 4 ++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 76faf2c..8d9a0c9 100644 --- a/Gemfile +++ b/Gemfile @@ -12,3 +12,6 @@ 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/README.md b/README.md index 7cba1d4..af1cda4 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,10 @@ References to completing this code challenge: 7) https://stackoverflow.com/questions/36963844/difference-between-and-in-ruby -8) https://stackoverflow.com/questions/32059200/convert-string-to-integer-preserving-leading-zeroes \ No newline at end of file +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/spec/policy_ocr_spec.rb b/spec/policy_ocr_spec.rb index 605ff7a..b360646 100644 --- a/spec/policy_ocr_spec.rb +++ b/spec/policy_ocr_spec.rb @@ -32,6 +32,10 @@ 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) From 6bed52712745dad4ec482550bcd9ec7771e60b36 Mon Sep 17 00:00:00 2001 From: John Lonetree Date: Mon, 15 Nov 2021 10:43:58 -0600 Subject: [PATCH 4/7] Added policy numbers to be read by number instead of array --- Gemfile.lock | 1 + lib/policy_ocr.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9edf6b1..5b1aece 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -55,6 +55,7 @@ PLATFORMS DEPENDENCIES guard guard-shell + pry rb-fsevent (~> 0.9) rspec diff --git a/lib/policy_ocr.rb b/lib/policy_ocr.rb index f824056..33a95b6 100644 --- a/lib/policy_ocr.rb +++ b/lib/policy_ocr.rb @@ -59,4 +59,4 @@ def self.conversion(file) # 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 } From ce335089560f01c9b642952fb06ea9e9c9a223c0 Mon Sep 17 00:00:00 2001 From: John Lonetree Date: Mon, 15 Nov 2021 10:54:33 -0600 Subject: [PATCH 5/7] added a map method at bottom for easier readability --- lib/policy_ocr.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/policy_ocr.rb b/lib/policy_ocr.rb index 33a95b6..4ce9a40 100644 --- a/lib/policy_ocr.rb +++ b/lib/policy_ocr.rb @@ -58,5 +58,6 @@ def self.conversion(file) # 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 } +PolicyOcr.conversion(@file).map{ | policy_num | p policy_num } # see each number individually From c748a69fa45119936b3e8a75a4af8a4ed47d6ba1 Mon Sep 17 00:00:00 2001 From: John Lonetree Date: Mon, 15 Nov 2021 12:48:52 -0600 Subject: [PATCH 6/7] separated injections to create two methods for easier management --- lib/policy_ocr.rb | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/lib/policy_ocr.rb b/lib/policy_ocr.rb index 4ce9a40..7935326 100644 --- a/lib/policy_ocr.rb +++ b/lib/policy_ocr.rb @@ -1,3 +1,5 @@ +require 'pry' + module PolicyOcr # initializing global variables @@ -11,18 +13,19 @@ module PolicyOcr @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' + " _ | ||_| " => '0', + " | | " => '1', + " _ _||_ " => '2', + " _ _| _| " => '3', + " |_| | " => '4', + " _ |_ _| " => '5', + " _ |_ |_| " => '6', + " _ | | " => '7', + " _ |_||_| " => '8', + " _ |_| _| " => '9' } end @@ -41,17 +44,23 @@ def self.policy_number(line, column) # this method takes in an OCR file, # and parces the number using exclusive - # ranges, and injecting them first into an string, - # then injecting them further into an array + # ranges def self.conversion(file) (0...@lines).inject([]) do | policy_array, line | - policy_array << (0...@columns).inject("") do |digit, column| - digit + digits.fetch(policy_number(line, column)) - end + policy_array << numbers(line) end.map{ | number_string | number_string.to_i } # turning string to integer end + # call policy_number to inject + # digits first 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 From c5b6e8c68f0863f3dba2e30fb6ac67f25efc63e0 Mon Sep 17 00:00:00 2001 From: John Lonetree Date: Mon, 15 Nov 2021 12:54:41 -0600 Subject: [PATCH 7/7] separated injections to create two methods for easier management - updated comments --- lib/policy_ocr.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/policy_ocr.rb b/lib/policy_ocr.rb index 7935326..7654406 100644 --- a/lib/policy_ocr.rb +++ b/lib/policy_ocr.rb @@ -42,9 +42,10 @@ def self.policy_number(line, column) end end - # this method takes in an OCR file, - # and parces the number using exclusive - # ranges + # 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 | @@ -52,9 +53,9 @@ def self.conversion(file) end.map{ | number_string | number_string.to_i } # turning string to integer end - # call policy_number to inject - # digits first into an string, - # to be called in the conversion method + # 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|