bankocr 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|