bankocr 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +9 -6
- data/bin/bankocr +1 -6
- data/lib/account_number.rb +3 -10
- data/lib/bankocr.rb +1 -2
- data/lib/bankocr/version.rb +1 -1
- data/lib/file_parser.rb +3 -2
- data/lib/report_generator.rb +12 -3
- data/spec/lib/account_number_spec.rb +0 -3
- data/spec/lib/file_parser_spec.rb +2 -2
- metadata +1 -2
- data/lib/utils.rb +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c718e8a72b9c3926e904bd07c21637270d96ccc
|
4
|
+
data.tar.gz: 78622c054b4183e0f6b022aedd5cdf492dd2b8e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fd91b34998b1be1886fff104925b24ebcbe871848ad35f069da570d6f075def69336f6b96f412983f7d236b03c0f54fd9d00ae82778db30aa04fd9ce061fb4c
|
7
|
+
data.tar.gz: 77f43c26adb1c807c338d56ba8b38779e6bcb54a9657100394b9ab86ce373c093bf662bac25604f5e3bbfa6f41ff409264d6132515d45ba2006b6627f7bcb06e
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -9,17 +9,20 @@ This repository provides a solution for BankOCR kata.
|
|
9
9
|
* Description of the problem can be found here: http://code.joejag.com/coding-dojo-bank-ocr/
|
10
10
|
* Current implementation covers the first 3 use cases.
|
11
11
|
|
12
|
-
## How to
|
13
|
-
|
14
|
-
Use the following commands:
|
12
|
+
## How to install
|
15
13
|
|
16
14
|
```
|
17
15
|
gem install backocr
|
18
|
-
bankocr process ./bin/input.in ./bin/output
|
19
16
|
```
|
20
17
|
|
21
|
-
|
22
|
-
|
18
|
+
## How to run?
|
19
|
+
|
20
|
+
* You can download a sample input file from here: https://github.com/solojavier/BankOCR/raw/master/bin/input.in
|
21
|
+
* To process input file and generate a report use the following command:
|
22
|
+
|
23
|
+
```
|
24
|
+
bankocr process input_path output_path
|
25
|
+
```
|
23
26
|
|
24
27
|
## Tests
|
25
28
|
|
data/bin/bankocr
CHANGED
@@ -9,12 +9,7 @@ module BankOCR
|
|
9
9
|
'Generates a report for account numbers read from input'
|
10
10
|
|
11
11
|
def process(input, output)
|
12
|
-
|
13
|
-
BankOCR.process(input, output)
|
14
|
-
p 'OCR accounts report generated succesfully'
|
15
|
-
rescue Exception => ex
|
16
|
-
p ex.message
|
17
|
-
end
|
12
|
+
BankOCR.process(input, output)
|
18
13
|
end
|
19
14
|
end
|
20
15
|
end
|
data/lib/account_number.rb
CHANGED
@@ -1,24 +1,17 @@
|
|
1
1
|
module BankOCR
|
2
2
|
# Object representing an account number
|
3
3
|
class AccountNumber
|
4
|
-
attr_reader :error_message, :digits
|
5
4
|
|
6
5
|
def initialize(digits)
|
7
6
|
@digits = digits
|
8
|
-
@valid = false
|
9
|
-
|
10
|
-
validate!
|
11
7
|
end
|
12
8
|
|
13
9
|
def valid?
|
14
|
-
@valid
|
10
|
+
@valid ||= sum(@digits) % 11 == 0
|
15
11
|
end
|
16
12
|
|
17
|
-
def
|
18
|
-
@
|
19
|
-
@error_message ||= 'ERR' if sum(@digits) % 11 != 0
|
20
|
-
|
21
|
-
@valid = true unless @error_message
|
13
|
+
def to_s
|
14
|
+
@digits
|
22
15
|
end
|
23
16
|
|
24
17
|
private
|
data/lib/bankocr.rb
CHANGED
@@ -8,8 +8,7 @@ module BankOCR
|
|
8
8
|
autoload :ReportGenerator, 'report_generator'
|
9
9
|
|
10
10
|
def self.process(input, output)
|
11
|
-
|
12
|
-
account_numbers = digit_strings.map { |d| BankOCR::AccountNumber.new(d) }
|
11
|
+
account_numbers = BankOCR::FileParser.new(input).entries
|
13
12
|
|
14
13
|
BankOCR::ReportGenerator.new(output, account_numbers).save!
|
15
14
|
end
|
data/lib/bankocr/version.rb
CHANGED
data/lib/file_parser.rb
CHANGED
@@ -14,9 +14,10 @@ module BankOCR
|
|
14
14
|
file = File.open(@input_path)
|
15
15
|
@entries << parse_entry(file) until file.eof?
|
16
16
|
|
17
|
-
@entries
|
17
|
+
@entries.map{|e| BankOCR::AccountNumber.new(e) }
|
18
18
|
rescue
|
19
|
-
|
19
|
+
p 'Error reading input file, please validate'
|
20
|
+
[]
|
20
21
|
ensure
|
21
22
|
file.close if file
|
22
23
|
end
|
data/lib/report_generator.rb
CHANGED
@@ -10,12 +10,21 @@ module BankOCR
|
|
10
10
|
file = File.open(@output_path, 'w+')
|
11
11
|
|
12
12
|
@account_numbers.each do |account|
|
13
|
-
file.write account
|
14
|
-
file.write " #{account.error_message}" unless account.valid?
|
15
|
-
file.write "\n"
|
13
|
+
file.write "#{account}#{error(account)}\n"
|
16
14
|
end
|
17
15
|
|
18
16
|
file.close
|
19
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def error(account)
|
22
|
+
if account.to_s.include?('?')
|
23
|
+
' ILL'
|
24
|
+
elsif !account.valid?
|
25
|
+
' ERR'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
20
29
|
end
|
21
30
|
end
|
@@ -13,7 +13,6 @@ describe BankOCR::AccountNumber do
|
|
13
13
|
account = described_class.new(n)
|
14
14
|
|
15
15
|
expect(account.valid?).to eq(true)
|
16
|
-
expect(account.error_message).to eq(nil)
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
@@ -22,7 +21,6 @@ describe BankOCR::AccountNumber do
|
|
22
21
|
account = described_class.new(n)
|
23
22
|
|
24
23
|
expect(account.valid?).to eq(false)
|
25
|
-
expect(account.error_message).to eq('ERR')
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
@@ -31,7 +29,6 @@ describe BankOCR::AccountNumber do
|
|
31
29
|
account = described_class.new(n)
|
32
30
|
|
33
31
|
expect(account.valid?).to eq(false)
|
34
|
-
expect(account.error_message).to eq('ILL')
|
35
32
|
end
|
36
33
|
end
|
37
34
|
|
@@ -14,13 +14,13 @@ describe BankOCR::FileParser do
|
|
14
14
|
it 'returns an array with account numbers' do
|
15
15
|
parser = described_class.new(input_path)
|
16
16
|
|
17
|
-
expect(parser.entries).to eq(account_numbers)
|
17
|
+
expect(parser.entries.map(&:to_s)).to eq(account_numbers)
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'returns empty account_numbers if error reading file' do
|
21
21
|
parser = described_class.new('invalid_path')
|
22
22
|
|
23
|
-
expect
|
23
|
+
expect(parser.entries).to eq([])
|
24
24
|
end
|
25
25
|
|
26
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bankocr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Cervantes
|
@@ -74,7 +74,6 @@ files:
|
|
74
74
|
- lib/bankocr/version.rb
|
75
75
|
- lib/file_parser.rb
|
76
76
|
- lib/report_generator.rb
|
77
|
-
- lib/utils.rb
|
78
77
|
- spec/bin/bankocr_spec.rb
|
79
78
|
- spec/bin/input.in
|
80
79
|
- spec/lib/account_number_spec.rb
|
data/lib/utils.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
# Module for BankOCR Application
|
2
|
-
module BankOCR
|
3
|
-
# Utility functions to perform data conversions
|
4
|
-
module Utils
|
5
|
-
# Parses an OCR machine input file and returns an array of account numbers
|
6
|
-
def parse_file(input_path)
|
7
|
-
file = File.open(input_path)
|
8
|
-
numbers = []
|
9
|
-
|
10
|
-
numbers << next_entry_to_digits(file) until file.eof?
|
11
|
-
numbers
|
12
|
-
rescue
|
13
|
-
[]
|
14
|
-
ensure
|
15
|
-
file.close if file
|
16
|
-
end
|
17
|
-
|
18
|
-
# Receives a list of account numbers and returns validation information
|
19
|
-
def validate_accounts(account_numbers)
|
20
|
-
account_numbers.map do |number|
|
21
|
-
valid, message = validate(number.to_s)
|
22
|
-
|
23
|
-
{ account_number: number, valid: valid, message: message }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Creates a file report in ouput path with accounts received
|
28
|
-
def generate_report(output_path, accounts)
|
29
|
-
file = File.open(output_path, 'w+')
|
30
|
-
|
31
|
-
accounts.select { |a| a[:account_number] }.each do |acc|
|
32
|
-
file.write acc[:account_number]
|
33
|
-
file.write " #{acc[:message]}" if !acc[:valid] && acc[:message]
|
34
|
-
file.write "\n"
|
35
|
-
end
|
36
|
-
|
37
|
-
file.close
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def next_entry_to_digits(file)
|
43
|
-
top = file.readline
|
44
|
-
middle = file.readline
|
45
|
-
bottom = file.readline
|
46
|
-
_blank = file.readline
|
47
|
-
|
48
|
-
(0..8).map do |i|
|
49
|
-
low = (i * 3)
|
50
|
-
high = ((i + 1) * 3) - 1
|
51
|
-
shape = top[low..high] + middle[low..high] + bottom[low..high]
|
52
|
-
|
53
|
-
conversions[shape] || '?'
|
54
|
-
end.join
|
55
|
-
end
|
56
|
-
|
57
|
-
def conversions
|
58
|
-
{ ' _ | ||_|' => '0',
|
59
|
-
' | |' => '1',
|
60
|
-
' _ _||_ ' => '2',
|
61
|
-
' _ _| _|' => '3',
|
62
|
-
' |_| |' => '4',
|
63
|
-
' _ |_ _|' => '5',
|
64
|
-
' _ |_ |_|' => '6',
|
65
|
-
' _ | |' => '7',
|
66
|
-
' _ |_||_|' => '8',
|
67
|
-
' _ |_| _|' => '9' }
|
68
|
-
end
|
69
|
-
|
70
|
-
def sum(account_number)
|
71
|
-
(0..8).map { |i| account_number[i].to_i * (i + 2) }.reduce(:+)
|
72
|
-
end
|
73
|
-
|
74
|
-
def validate(number)
|
75
|
-
if number.include?('?')
|
76
|
-
[false, 'ILL']
|
77
|
-
elsif sum(number) % 11 != 0
|
78
|
-
[false, 'ERR']
|
79
|
-
else
|
80
|
-
[true, 'OK']
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|