mork 0.8.1 → 0.9.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/README.md +107 -35
- data/lib/mork/coord.rb +1 -1
- data/lib/mork/extensions.rb +3 -0
- data/lib/mork/grid.rb +13 -6
- data/lib/mork/grid_const.rb +11 -9
- data/lib/mork/grid_omr.rb +15 -5
- data/lib/mork/grid_pdf.rb +1 -0
- data/lib/mork/magicko.rb +46 -28
- data/lib/mork/mimage.rb +113 -52
- data/lib/mork/mimage_list.rb +6 -5
- data/lib/mork/npatch.rb +16 -18
- data/lib/mork/sheet_omr.rb +210 -125
- data/lib/mork/sheet_pdf.rb +15 -8
- data/lib/mork/version.rb +1 -1
- data/mork.gemspec +2 -0
- data/mork.sublime-project +1 -1
- data/spec/mork/extensions_spec.rb +3 -3
- data/spec/mork/grid_omr_spec.rb +2 -1
- data/spec/mork/grid_spec.rb +34 -35
- data/spec/mork/magicko_spec.rb +2 -2
- data/spec/mork/mimage_spec.rb +22 -63
- data/spec/mork/sheet_omr_spec.rb +96 -201
- data/spec/mork/sheet_pdf_spec.rb +9 -10
- data/spec/out/{.gitignore → barcode/.gitignore} +0 -0
- data/spec/out/highlight/.gitignore +4 -0
- data/spec/out/mark/.gitignore +4 -0
- data/spec/out/outline/.gitignore +4 -0
- data/spec/out/pdf/.gitignore +4 -0
- data/spec/out/registration/.gitignore +4 -0
- data/spec/out/text/.gitignore +4 -0
- data/spec/samples/angolo.jpg +0 -0
- data/spec/samples/angolo2.jpg +0 -0
- data/spec/samples/angolo3.jpg +0 -0
- data/spec/samples/boxy.yml +0 -0
- data/spec/samples/grid.yml +0 -0
- data/spec/samples/grid160.yml +0 -0
- data/spec/samples/grid_omr_layout.yml +56 -0
- data/spec/samples/info.yml +15 -39
- data/spec/samples/jdoe/JohnDoe1.jpeg +0 -0
- data/spec/samples/jdoe/JohnDoe2.jpeg +0 -0
- data/spec/samples/jdoe/JohnDoe3.jpeg +0 -0
- data/spec/samples/jdoe/layout.yml +58 -0
- data/spec/samples/layout.yml +2 -2
- data/spec/samples/lucrezia/border1.pdf +0 -0
- data/spec/samples/lucrezia/border2.pdf +0 -0
- data/spec/samples/lucrezia/bw1.pdf +0 -0
- data/spec/samples/lucrezia/bw2.pdf +0 -0
- data/spec/samples/lucrezia/gray1.pdf +0 -0
- data/spec/samples/lucrezia/gray2.pdf +0 -0
- data/spec/samples/{syst/IMG_20150104_0004.jpg → marisol/marisol1.jpg} +0 -0
- data/spec/samples/{syst/IMG_20150104_0009.jpg → marisol/marisol2.jpg} +0 -0
- data/spec/samples/{syst/IMG_20150104_0011.jpg → marisol/marisol3.jpg} +0 -0
- data/spec/samples/reg_mark.jpg +0 -0
- data/spec/samples/rm00.jpeg +0 -0
- data/spec/samples/rm01.jpeg +0 -0
- data/spec/samples/rm02.jpeg +0 -0
- data/spec/samples/rm03.jpeg +0 -0
- data/spec/samples/rm04.jpeg +0 -0
- data/spec/samples/rm05.jpeg +0 -0
- data/spec/samples/syst/barr0.jpg +0 -0
- data/spec/samples/syst/barr1.jpg +0 -0
- data/spec/samples/syst/barr2.jpg +0 -0
- data/spec/samples/syst/bell0.jpg +0 -0
- data/spec/samples/syst/bell1.jpg +0 -0
- data/spec/samples/syst/bell2.jpg +0 -0
- data/spec/samples/syst/bila0.jpg +0 -0
- data/spec/samples/syst/bila1.jpg +0 -0
- data/spec/samples/syst/bila2.jpg +0 -0
- data/spec/samples/syst/bila3.jpg +0 -0
- data/spec/samples/syst/bila4.jpg +0 -0
- data/spec/samples/syst/bone0.jpg +0 -0
- data/spec/samples/syst/bone1.jpg +0 -0
- data/spec/samples/syst/bone2.jpg +0 -0
- data/spec/samples/syst/cost0.jpg +0 -0
- data/spec/samples/syst/cost1.jpg +0 -0
- data/spec/samples/syst/cost2.jpg +0 -0
- data/spec/samples/syst/cost3.jpg +0 -0
- data/spec/samples/syst/cost4.jpg +0 -0
- data/spec/samples/syst/dald0.jpg +0 -0
- data/spec/samples/syst/dald1.jpg +0 -0
- data/spec/samples/syst/dald2.jpg +0 -0
- data/spec/samples/syst/dald3.jpg +0 -0
- data/spec/samples/syst/dald4.jpg +0 -0
- data/spec/samples/syst/dign0.jpg +0 -0
- data/spec/samples/syst/dign1.jpg +0 -0
- data/spec/samples/syst/dign2.jpg +0 -0
- data/spec/samples/syst/dive0.jpg +0 -0
- data/spec/samples/syst/dive1.jpg +0 -0
- data/spec/samples/syst/dive2.jpg +0 -0
- data/spec/samples/syst/histo.m +0 -0
- data/spec/samples/{syst_grid.yml → syst/layout.yml} +0 -0
- data/spec/spec_helper.rb +29 -29
- metadata +49 -62
- data/auto.txt +0 -0
- data/spec/samples/out-1.jpg +0 -0
- data/spec/samples/qzc013.jpg +0 -0
- data/spec/samples/sample02.jpg +0 -0
- data/spec/samples/sample_gray.jpg +0 -0
- data/spec/samples/sheet.jpg +0 -0
- data/spec/samples/sheet666.jpg +0 -0
- data/spec/samples/slanted.jpg +0 -0
- data/spec/samples/slanted.yml +0 -54
- data/spec/samples/syst/IMG_20150104_0004.txt +0 -4955
- data/spec/samples/syst/IMG_20150104_0009.txt +0 -4955
- data/spec/samples/syst/IMG_20150104_0011.txt +0 -4955
- data/spec/samples/syst/SCN_0001.jpg +0 -0
- data/spec/samples/syst/SCN_0001.txt +0 -4955
- data/spec/samples/syst/barr0.txt +0 -4955
- data/spec/samples/syst/barr1.txt +0 -4955
- data/spec/samples/syst/barr2.txt +0 -4955
- data/spec/samples/syst/bell0.txt +0 -4955
- data/spec/samples/syst/bell1.txt +0 -4955
- data/spec/samples/syst/bell2.txt +0 -4955
- data/spec/samples/syst/bila0.txt +0 -4955
- data/spec/samples/syst/bila1.txt +0 -4955
- data/spec/samples/syst/bila2.txt +0 -4955
- data/spec/samples/syst/bila3.txt +0 -4955
- data/spec/samples/syst/bila4.txt +0 -4955
- data/spec/samples/syst/bone0.txt +0 -4955
- data/spec/samples/syst/bone1.txt +0 -4955
- data/spec/samples/syst/bone2.txt +0 -4955
- data/spec/samples/syst/cost0.txt +0 -4955
- data/spec/samples/syst/cost1.txt +0 -4955
- data/spec/samples/syst/cost2.txt +0 -4955
- data/spec/samples/syst/cost3.txt +0 -4955
- data/spec/samples/syst/cost4.txt +0 -4955
- data/spec/samples/syst/dald0.txt +0 -4955
- data/spec/samples/syst/dald1.txt +0 -4955
- data/spec/samples/syst/dald2.txt +0 -4955
- data/spec/samples/syst/dald3.txt +0 -4955
- data/spec/samples/syst/dald4.txt +0 -4955
- data/spec/samples/syst/dign0.txt +0 -4955
- data/spec/samples/syst/dign1.txt +0 -4955
- data/spec/samples/syst/dign2.txt +0 -4955
- data/spec/samples/syst/dive0.txt +0 -4955
- data/spec/samples/syst/dive1.txt +0 -4955
- data/spec/samples/syst/dive2.txt +0 -4955
- data/spec/samples/syst/out0000.jpg +0 -0
- data/spec/samples/syst/out0000.txt +0 -4955
- data/spec/samples/syst/out0001.jpg +0 -0
- data/spec/samples/syst/out0001.txt +0 -4955
- data/spec/samples/syst/out0002.jpg +0 -0
- data/spec/samples/syst/out0002.txt +0 -4955
- data/spec/samples/syst/qzc013.jpg +0 -0
- data/spec/samples/syst/qzc013.txt +0 -4955
- data/spec/samples/syst/sample_gray.jpg +0 -0
- data/spec/samples/syst/sample_gray.txt +0 -4955
- data/spec/samples/two_pages.pdf +0 -0
data/spec/mork/mimage_spec.rb
CHANGED
|
@@ -4,81 +4,40 @@ module Mork
|
|
|
4
4
|
describe Mimage do
|
|
5
5
|
let(:qna) { [5] * 100 }
|
|
6
6
|
|
|
7
|
-
context '
|
|
8
|
-
let(:img) { sample_img '
|
|
9
|
-
let(:
|
|
7
|
+
context 'John Doe' do
|
|
8
|
+
let(:img) { sample_img 'jdoe1' }
|
|
9
|
+
let(:fn) { File.basename(img.image_path) }
|
|
10
|
+
let(:mim) { Mimage.new img.image_path, [img.nchoices]*img.nitems, GridOMR.new(img.grid_path) }
|
|
10
11
|
describe 'basics' do
|
|
11
12
|
it 'should be valid' do
|
|
12
|
-
mim.highlight_rm_centers
|
|
13
|
-
mim.highlight_rm_areas
|
|
14
|
-
mim.write 'spec/out/slanted.jpg', false
|
|
15
13
|
expect(mim.valid?).to be_truthy
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
it 'should return the correct regmark coordinates' do
|
|
19
17
|
[:tl, :tr, :br, :bl].each do |corner|
|
|
20
18
|
crn = mim.rm[corner]
|
|
21
|
-
expect(crn[:x]).to be_within(2).of(img.
|
|
22
|
-
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context 'problematic sheets' do
|
|
29
|
-
let(:mim) { Mimage.new 'spec/samples/out-1.jpg', qna, GridOMR.new('spec/samples/grid.yml') }
|
|
30
|
-
let(:bila) { Mimage.new 'spec/samples/syst/bila0.jpg', qna, GridOMR.new('spec/samples/grid.yml') }
|
|
31
|
-
|
|
32
|
-
it 'writes all cell values to a text file', exclude: true do
|
|
33
|
-
d=Dir['spec/samples/syst/*.jpg']
|
|
34
|
-
d.each do |f|
|
|
35
|
-
fn = File.basename f, '.jpg'
|
|
36
|
-
m = Mimage.new "spec/samples/syst/#{fn}.jpg", qna, GridOMR.new('spec/samples/grid.yml')
|
|
37
|
-
puts fn
|
|
38
|
-
File.open("spec/samples/syst/#{fn}.txt",'w') do |f|
|
|
39
|
-
f.puts "ink:#{m.send :ink_black}"
|
|
40
|
-
f.puts "drk:#{m.send :darkest_cell_mean}"
|
|
41
|
-
f.puts "pap:#{m.send :paper_white}"
|
|
42
|
-
f.puts "cal:#{m.send :cal_cell_mean}"
|
|
43
|
-
f.puts "cho:#{m.send :choice_threshold}"
|
|
44
|
-
100.times do |q|
|
|
45
|
-
5.times do |c|
|
|
46
|
-
f.puts m.send('choice_cell_averages')[q, c]
|
|
47
|
-
end
|
|
48
|
-
end
|
|
19
|
+
expect(crn[:x]).to be_within(2).of(img.send(corner)[0])
|
|
20
|
+
expect(crn[:x]).to be_within(2).of(img.send(corner)[0])
|
|
49
21
|
end
|
|
50
22
|
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
context 'Old specs' do
|
|
55
|
-
let(:sgi) { sample_img 'sample-gray' }
|
|
56
|
-
let(:sg) { Mimage.new sgi.filename, qna, GridOMR.new(sgi.grid_file) }
|
|
57
|
-
|
|
58
|
-
describe 'basics' do
|
|
59
|
-
it 'returns the pixels as an array' do
|
|
60
|
-
expect(sg.send :reg_pixels).to be_a NPatch
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it 'returns the correct number of pixels' do
|
|
64
|
-
expect(sg.send(:reg_pixels).length).to eq sgi.width * sgi.height
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it 'returns the stretched array' do
|
|
68
|
-
expect(sg.send(:reg_pixels).length).to eq sgi.width * sgi.height
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
23
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
24
|
+
xit 'writes all cell values to a text file' do
|
|
25
|
+
d=Dir['spec/samples/syst/*.jpg']
|
|
26
|
+
d.each do |f|
|
|
27
|
+
fname = File.basename f, '.jpg'
|
|
28
|
+
m = Mimage.new "spec/samples/syst/#{fname}.jpg", qna, GridOMR.new('spec/samples/grid.yml')
|
|
29
|
+
puts fname
|
|
30
|
+
File.open("spec/out/text/#{fname}.txt",'w') do |f|
|
|
31
|
+
f.puts "ink:#{m.send :ink_black}"
|
|
32
|
+
f.puts "drk:#{m.send :darkest_cell_mean}"
|
|
33
|
+
f.puts "pap:#{m.send :paper_white}"
|
|
34
|
+
f.puts "cal:#{m.send :cal_cell_mean}"
|
|
35
|
+
f.puts "cho:#{m.send :choice_threshold}"
|
|
36
|
+
100.times do |q|
|
|
37
|
+
5.times do |c|
|
|
38
|
+
f.puts m.send('choice_cell_averages')[q, c]
|
|
39
|
+
end
|
|
80
40
|
end
|
|
81
|
-
f.puts "#{q+1}: #{t.join(' ')}"
|
|
82
41
|
end
|
|
83
42
|
end
|
|
84
43
|
end
|
data/spec/mork/sheet_omr_spec.rb
CHANGED
|
@@ -3,258 +3,153 @@ require 'fileutils'
|
|
|
3
3
|
|
|
4
4
|
module Mork
|
|
5
5
|
describe SheetOMR do
|
|
6
|
-
context '
|
|
7
|
-
let(:img) { sample_img '
|
|
8
|
-
let(:
|
|
6
|
+
context 'with a valid response sheet' do
|
|
7
|
+
let(:img) { sample_img 'jdoe1' }
|
|
8
|
+
let(:fn) { File.basename(img.image_path) }
|
|
9
|
+
let(:omr) { SheetOMR.new img.image_path, choices: [img.nchoices]*img.nitems, layout: img.grid_path }
|
|
9
10
|
describe '#new' do
|
|
10
|
-
it 'raises an error if the provided path is invalid' do
|
|
11
|
-
expect { SheetOMR.new 'non_existing_file.jpg'}.to raise_error IOError
|
|
12
|
-
end
|
|
13
|
-
|
|
14
11
|
it 'creates a SheetOMR object' do
|
|
15
12
|
expect(omr).to be_a SheetOMR
|
|
16
13
|
end
|
|
17
14
|
|
|
18
|
-
it '
|
|
19
|
-
expect
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it 'writes out the registration' do
|
|
23
|
-
omr.write_registration 'spec/out/slanted2.jpg'
|
|
15
|
+
it 'raises an error if the provided path is invalid' do
|
|
16
|
+
expect { SheetOMR.new 'non_existing_file.jpg'}.to raise_error IOError
|
|
24
17
|
end
|
|
25
18
|
end
|
|
26
|
-
end
|
|
27
|
-
# context 'problematic' do
|
|
28
|
-
# let(:shinfo) { sample_img 'bianchi' }
|
|
29
|
-
# let(:sheet) { SheetOMR.new shinfo.filename, shinfo.grid_file }
|
|
30
|
-
#
|
|
31
|
-
# it 'has a status' do
|
|
32
|
-
# sheet.status.should == {:tl=>:ok, :tr=>:ok, :br=>:ok, :bl=>:ok, :write=>nil}
|
|
33
|
-
# end
|
|
34
|
-
#
|
|
35
|
-
# it 'has a barcode' do
|
|
36
|
-
# sheet.barcode.should == shinfo.barcode_int
|
|
37
|
-
# end
|
|
38
|
-
#
|
|
39
|
-
# it 'writes the registered and marked image' do
|
|
40
|
-
# sheet.cross_marked
|
|
41
|
-
# sheet.write 'spec/out/bianchi.jpg'
|
|
42
|
-
# sheet.status[:write].should == :fail
|
|
43
|
-
# end
|
|
44
|
-
#
|
|
45
|
-
# it 'writes the registration areas' do
|
|
46
|
-
# sheet.highlight_registration
|
|
47
|
-
# sheet.write_raw 'spec/out/reg_bianchi.jpg'
|
|
48
|
-
# end
|
|
49
|
-
#
|
|
50
|
-
# end
|
|
51
|
-
#
|
|
52
|
-
context 'slanted' do
|
|
53
|
-
let(:sh) { sample_img 'slanted' }
|
|
54
|
-
let(:sheet) { SheetOMR.new sh.filename, [5]*120, sh.grid_file }
|
|
55
|
-
|
|
56
|
-
it 'gets in trouble' do
|
|
57
|
-
sheet.write_registration 'spec/out/laurout.jpg'
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it 'gets more in trouble' do
|
|
61
|
-
sheet.highlight_marked
|
|
62
|
-
sheet.write 'spec/out/lauraout2.jpg'
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it 'should be valid' do
|
|
66
|
-
expect(sheet.valid?).to be_truthy
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
context 'highlighting' do
|
|
71
|
-
# since these specs change the @crop, they must be run in isolation
|
|
72
|
-
# with the SheetOMR rebuilt each time, even though it is time consuming!
|
|
73
|
-
let(:shinfo) { sample_img 'sample-gray' }
|
|
74
|
-
let(:sheet) { SheetOMR.new shinfo.filename, [5]*120, shinfo.grid_file }
|
|
75
|
-
|
|
76
|
-
it 'writes the sheet with registrations highlighted' do
|
|
77
|
-
sheet.write_registration 'spec/out/sample_gray_registered.jpg'
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it 'highlights all choice cells' do
|
|
81
|
-
sheet.highlight_all_choices
|
|
82
|
-
sheet.write 'spec/out/all_highlights.jpg'
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it 'highlights marked cells' do
|
|
86
|
-
sheet.highlight_marked
|
|
87
|
-
sheet.write 'spec/out/marked_highlights.jpg'
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it 'crossed marked cells' do
|
|
91
|
-
sheet.cross_marked
|
|
92
|
-
sheet.write 'spec/out/marked_crosses.jpg'
|
|
93
|
-
end
|
|
94
19
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
20
|
+
describe '#valid?' do
|
|
21
|
+
it 'registers correctly' do
|
|
22
|
+
expect(omr.valid?).to be_truthy
|
|
23
|
+
end
|
|
98
24
|
end
|
|
99
25
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
26
|
+
describe '#status' do
|
|
27
|
+
it 'returns the registration status for each of the four corners' do
|
|
28
|
+
expect(omr.status).to eq({ tl: :ok, tr: :ok, br: :ok, bl: :ok })
|
|
29
|
+
end
|
|
103
30
|
end
|
|
104
31
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
tsheet.write
|
|
32
|
+
describe '#barcode' do
|
|
33
|
+
it 'returns the integer form of the barcode' do
|
|
34
|
+
expect(omr.barcode).to eq img.barcode_int
|
|
35
|
+
end
|
|
110
36
|
end
|
|
111
37
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
38
|
+
describe '#barcode_string' do
|
|
39
|
+
it 'returns the binary string version of the barcode' do
|
|
40
|
+
expect(omr.barcode_string).to eq img.barcode_str
|
|
41
|
+
end
|
|
116
42
|
end
|
|
117
43
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
44
|
+
describe '#marked?' do
|
|
45
|
+
it 'returns true if the given cell was marked, false otherwise' do
|
|
46
|
+
expect(omr.marked? 0, 0).to be_truthy
|
|
47
|
+
expect(omr.marked? 0, 1).to be_falsy
|
|
48
|
+
expect(omr.marked? 119, 4).to be_truthy
|
|
49
|
+
expect(omr.marked? 119, 3).to be_falsy
|
|
50
|
+
end
|
|
123
51
|
end
|
|
124
52
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
s.write 'spec/out/code_bits.jpg'
|
|
53
|
+
describe '#marked_choices' do
|
|
54
|
+
it 'returns an array of marked choices as position indices' do
|
|
55
|
+
expect(omr.marked_choices).to eq standard_mark_array(24)
|
|
56
|
+
end
|
|
130
57
|
end
|
|
131
|
-
end
|
|
132
58
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
end
|
|
59
|
+
describe '#marked_choices' do
|
|
60
|
+
it 'returns an array of marked choices as position indexes' do
|
|
61
|
+
expect(omr.marked_choices ).to eq standard_mark_array(24)
|
|
62
|
+
end
|
|
138
63
|
|
|
139
|
-
|
|
140
|
-
it 'returns
|
|
141
|
-
|
|
64
|
+
let(:om2) { SheetOMR.new img.image_path, choices: [5, 4, 3, 2, 1], layout: img.grid_path }
|
|
65
|
+
it 'returns marked choices only for existing choice cells' do
|
|
66
|
+
expect(om2.marked_choices).to eq [[0], [1], [2], [], []]
|
|
142
67
|
end
|
|
143
68
|
end
|
|
144
69
|
|
|
145
|
-
describe '#
|
|
146
|
-
it 'returns
|
|
147
|
-
expect(
|
|
148
|
-
expect(@sheet.marked?(1,1)).to be_truthy
|
|
149
|
-
expect(@sheet.marked?(2,2)).to be_truthy
|
|
70
|
+
describe '#marked_logicals' do
|
|
71
|
+
it 'returns an array of logicals for the marked choices' do
|
|
72
|
+
expect(omr.marked_logicals).to eq standard_mark_logical_array(24)
|
|
150
73
|
end
|
|
74
|
+
end
|
|
151
75
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
expect(
|
|
155
|
-
expect(@sheet.marked?(2,3)).to be_falsy
|
|
76
|
+
describe '#marked_letters' do
|
|
77
|
+
it 'returns an array of characters for the marked choices' do
|
|
78
|
+
expect(omr.marked_letters).to eq standard_mark_char_array(24)
|
|
156
79
|
end
|
|
80
|
+
end
|
|
157
81
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
end
|
|
164
|
-
mf.puts x.join(' ')
|
|
82
|
+
it 'writes out markedness' do
|
|
83
|
+
mf = File.open('spec/out/text/marked.txt', 'w')
|
|
84
|
+
img.nitems.times do |q|
|
|
85
|
+
x = 5.times.collect do |c|
|
|
86
|
+
omr.marked?(q,c) ? '1' : '0'
|
|
165
87
|
end
|
|
166
|
-
mf.
|
|
88
|
+
mf.puts x.join(' ')
|
|
167
89
|
end
|
|
90
|
+
mf.close
|
|
168
91
|
end
|
|
169
92
|
|
|
170
|
-
|
|
171
|
-
it '
|
|
172
|
-
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
it 'should return an array of marked choices for the specified question set' do
|
|
176
|
-
@sheet.mark_array([0, 1, 13, 16, 31, 104, 21]).should == [[0], [1], [3,4], [2], [1], [], [0,1,2,3,4]]
|
|
93
|
+
context 'creating overlays' do
|
|
94
|
+
it 'registration highlighted' do
|
|
95
|
+
omr.save_registration "spec/out/registration/#{fn}"
|
|
177
96
|
end
|
|
178
97
|
|
|
179
|
-
it '
|
|
180
|
-
|
|
98
|
+
it 'highlights all choice cells' do
|
|
99
|
+
omr.overlay :highlight, :all
|
|
100
|
+
omr.save "spec/out/highlight/#{fn}"
|
|
181
101
|
end
|
|
182
|
-
end
|
|
183
102
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
[true, false, false, false, false],
|
|
188
|
-
[false, true, false, false, false],
|
|
189
|
-
[false, false, true, false, false],
|
|
190
|
-
[false, false, false, true, false],
|
|
191
|
-
[false, false, false, false, true],
|
|
192
|
-
]
|
|
103
|
+
it 'highlights marked cells' do
|
|
104
|
+
omr.overlay :highlight, :marked
|
|
105
|
+
omr.save "spec/out/highlight/marked-#{fn}"
|
|
193
106
|
end
|
|
194
|
-
end
|
|
195
107
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
@sheet.barcode.should == 1099511627775
|
|
108
|
+
it 'checks marked cells' do
|
|
109
|
+
omr.overlay :check, :marked
|
|
110
|
+
omr.save "spec/out/mark/#{fn}"
|
|
200
111
|
end
|
|
201
112
|
|
|
202
|
-
it '
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
s2.barcode.should == 8608
|
|
113
|
+
it 'outlines and crosses marked cells' do
|
|
114
|
+
omr.overlay :outline, standard_mark_array(24)
|
|
115
|
+
omr.overlay :check
|
|
116
|
+
omr.save "spec/out/outline/#{fn}"
|
|
207
117
|
end
|
|
208
118
|
|
|
209
|
-
it '
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
s2.barcode.should == sh.barcode_int
|
|
119
|
+
it 'highlights the barcode' do
|
|
120
|
+
omr.overlay :outline, :barcode
|
|
121
|
+
omr.save "spec/out/barcode/#{fn}"
|
|
213
122
|
end
|
|
214
123
|
end
|
|
215
|
-
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
context 'marking a problematic sheet' do
|
|
219
|
-
let(:sheet) { SheetOMR.new 'spec/samples/out-1.jpg', [5]*100, 'spec/samples/grid.yml' }
|
|
220
|
-
|
|
221
|
-
it 'highlights the registration' do
|
|
222
|
-
sheet.write_registration 'spec/out/problematic.jpg'
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
it 'highlights the barcode' do
|
|
226
|
-
sheet.highlight_barcode
|
|
227
|
-
sheet.write 'spec/out/barcode.jpg'
|
|
228
|
-
end
|
|
229
124
|
end
|
|
230
125
|
|
|
231
|
-
context 'systematic tests' do
|
|
126
|
+
context 'systematic tests', exclude: true do
|
|
232
127
|
let(:bila) { 'CCEBEBCEEACCDCABDBEBCADEADDCCCACCACDBBDAECDDABDEEBCEEDCBAAADEEEEDCADEABCBDECCCCDDDCABBECAADADBBEEABA'.split '' }
|
|
233
|
-
let(:bila0) { SheetOMR.new 'spec/samples/syst/bila0.jpg', [5]*100,
|
|
234
|
-
let(:bila1) { SheetOMR.new 'spec/samples/syst/bila1.jpg', [5]*100,
|
|
235
|
-
let(:bila2) { SheetOMR.new 'spec/samples/syst/bila2.jpg', [5]*100,
|
|
236
|
-
let(:bila3) { SheetOMR.new 'spec/samples/syst/bila3.jpg', [5]*100,
|
|
237
|
-
let(:bila4) { SheetOMR.new 'spec/samples/syst/bila4.jpg', [5]*100,
|
|
128
|
+
let(:bila0) { SheetOMR.new 'spec/samples/syst/bila0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
129
|
+
let(:bila1) { SheetOMR.new 'spec/samples/syst/bila1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
130
|
+
let(:bila2) { SheetOMR.new 'spec/samples/syst/bila2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
131
|
+
let(:bila3) { SheetOMR.new 'spec/samples/syst/bila3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
132
|
+
let(:bila4) { SheetOMR.new 'spec/samples/syst/bila4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
238
133
|
let(:dald) { 'DDDBECAAADBAEEEAEEEBAACAEDBDECDBDCDCDDEDCCDCDBDCADEEDBCCBEBBAADDCDBBECBBBDEABADABADADBABAEABACBDADDA'.split '' }
|
|
239
|
-
let(:dald0) { SheetOMR.new 'spec/samples/syst/dald0.jpg', [5]*100,
|
|
240
|
-
let(:dald1) { SheetOMR.new 'spec/samples/syst/dald1.jpg', [5]*100,
|
|
241
|
-
let(:dald2) { SheetOMR.new 'spec/samples/syst/dald2.jpg', [5]*100,
|
|
242
|
-
let(:dald3) { SheetOMR.new 'spec/samples/syst/dald3.jpg', [5]*100,
|
|
243
|
-
let(:dald4) { SheetOMR.new 'spec/samples/syst/dald4.jpg', [5]*100,
|
|
134
|
+
let(:dald0) { SheetOMR.new 'spec/samples/syst/dald0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
135
|
+
let(:dald1) { SheetOMR.new 'spec/samples/syst/dald1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
136
|
+
let(:dald2) { SheetOMR.new 'spec/samples/syst/dald2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
137
|
+
let(:dald3) { SheetOMR.new 'spec/samples/syst/dald3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
138
|
+
let(:dald4) { SheetOMR.new 'spec/samples/syst/dald4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
244
139
|
let(:cost) { 'ABBDDBAEAEBAADEAAECBCDBBDABABADEECCACBCAEDDAEBEABBCDABECAACEEEBADECBBEAADBBBEABDAEBDEEABBABEBEDDAEEC'.split '' }
|
|
245
|
-
let(:cost0) { SheetOMR.new 'spec/samples/syst/cost0.jpg', [5]*100,
|
|
246
|
-
let(:cost1) { SheetOMR.new 'spec/samples/syst/cost1.jpg', [5]*100,
|
|
247
|
-
let(:cost2) { SheetOMR.new 'spec/samples/syst/cost2.jpg', [5]*100,
|
|
248
|
-
let(:cost3) { SheetOMR.new 'spec/samples/syst/cost3.jpg', [5]*100,
|
|
249
|
-
let(:cost4) { SheetOMR.new 'spec/samples/syst/cost4.jpg', [5]*100,
|
|
140
|
+
let(:cost0) { SheetOMR.new 'spec/samples/syst/cost0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
141
|
+
let(:cost1) { SheetOMR.new 'spec/samples/syst/cost1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
142
|
+
let(:cost2) { SheetOMR.new 'spec/samples/syst/cost2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
143
|
+
let(:cost3) { SheetOMR.new 'spec/samples/syst/cost3.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
144
|
+
let(:cost4) { SheetOMR.new 'spec/samples/syst/cost4.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
250
145
|
let(:bone) { 'CECBBABAECADEDCACBBDEECBADBECDCEDECABCAADCBDEDACAEEDCCADBEDCEBCCBBDCCACDEDDAAECEBDBADCBAAEBAEDABCBDC'.split '' }
|
|
251
|
-
let(:bone0) { SheetOMR.new 'spec/samples/syst/bone0.jpg', [5]*100,
|
|
252
|
-
let(:bone1) { SheetOMR.new 'spec/samples/syst/bone1.jpg', [5]*100,
|
|
253
|
-
let(:bone2) { SheetOMR.new 'spec/samples/syst/bone2.jpg', [5]*100,
|
|
146
|
+
let(:bone0) { SheetOMR.new 'spec/samples/syst/bone0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
147
|
+
let(:bone1) { SheetOMR.new 'spec/samples/syst/bone1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
148
|
+
let(:bone2) { SheetOMR.new 'spec/samples/syst/bone2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
254
149
|
let(:barr) { 'ACECAAADDBCECCCDBEBECDEDAECEDDEEDCDEADDCCBCCCBBEACBCAEDEEDDDABBBBABEBDCEADEEDEBCBADBCEDCDBACEBCBDCDA'.split '' }
|
|
255
|
-
let(:barr0) { SheetOMR.new 'spec/samples/syst/barr0.jpg', [5]*100,
|
|
256
|
-
let(:barr1) { SheetOMR.new 'spec/samples/syst/barr1.jpg', [5]*100,
|
|
257
|
-
let(:barr2) { SheetOMR.new 'spec/samples/syst/barr2.jpg', [5]*100,
|
|
150
|
+
let(:barr0) { SheetOMR.new 'spec/samples/syst/barr0.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
151
|
+
let(:barr1) { SheetOMR.new 'spec/samples/syst/barr1.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
152
|
+
let(:barr2) { SheetOMR.new 'spec/samples/syst/barr2.jpg', choices: [5]*100, layout: 'spec/samples/syst/layout.yml'}
|
|
258
153
|
|
|
259
154
|
it 'checks bila' do
|
|
260
155
|
expect(bila0.mark_char_array.flatten).to eq(bila)
|
data/spec/mork/sheet_pdf_spec.rb
CHANGED
|
@@ -40,8 +40,8 @@ module Mork
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it 'creates a basic PDF sheet' do
|
|
43
|
-
s = SheetPDF.new(content
|
|
44
|
-
s.save('spec/out/sheet.pdf')
|
|
43
|
+
s = SheetPDF.new(content)
|
|
44
|
+
s.save('spec/out/pdf/sheet.pdf')
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it 'creates a boxed PDF sheet' do
|
|
@@ -52,39 +52,38 @@ module Mork
|
|
|
52
52
|
signature: 'Signature'
|
|
53
53
|
}
|
|
54
54
|
s = SheetPDF.new(content.merge({header: h}), 'spec/samples/boxy.yml')
|
|
55
|
-
s.save('spec/out/boxy.pdf')
|
|
55
|
+
s.save('spec/out/pdf/boxy.pdf')
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it 'creates a basic PDF sheet with a code of 15' do
|
|
59
59
|
s = SheetPDF.new(content.merge({barcode: 15}))
|
|
60
|
-
s.save('spec/out/sheet16.pdf')
|
|
60
|
+
s.save('spec/out/pdf/sheet16.pdf')
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it 'creates a basic PDF sheet with a code of 666666666666' do
|
|
64
64
|
s = SheetPDF.new(content.merge({barcode: 666666666666}))
|
|
65
|
-
s.save('spec/out/sheet666.pdf')
|
|
65
|
+
s.save('spec/out/pdf/sheet666.pdf')
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
it 'creates a PDF sheet with the maximum possible barcode' do
|
|
69
69
|
s = SheetPDF.new(content.merge({barcode: 1099511627775}))
|
|
70
|
-
s.save('spec/out/maxcode.pdf')
|
|
70
|
+
s.save('spec/out/pdf/maxcode.pdf')
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
it 'creates a PDF sheet with 160 items' do
|
|
74
74
|
s = SheetPDF.new(content.merge({choices: [5] * 160}), 'spec/samples/grid160.yml')
|
|
75
|
-
s.save('spec/out/i160.pdf')
|
|
76
|
-
# system 'open spec/out/i160.pdf'
|
|
75
|
+
s.save('spec/out/pdf/i160.pdf')
|
|
77
76
|
end
|
|
78
77
|
|
|
79
78
|
it 'creates a PDF sheet with unequal choices per item' do
|
|
80
79
|
s = SheetPDF.new(content.merge({choices: [5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]}), 'spec/samples/layout.yml')
|
|
81
|
-
s.save('spec/out/uneq.pdf')
|
|
80
|
+
s.save('spec/out/pdf/uneq.pdf')
|
|
82
81
|
end
|
|
83
82
|
|
|
84
83
|
it 'creates 20 PDF sheets' do
|
|
85
84
|
c = content
|
|
86
85
|
s = SheetPDF.new([c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c])
|
|
87
|
-
s.save('spec/out/p20.pdf')
|
|
86
|
+
s.save('spec/out/pdf/p20.pdf')
|
|
88
87
|
end
|
|
89
88
|
end
|
|
90
89
|
end
|
|
File without changes
|
data/spec/samples/angolo.jpg
CHANGED
|
File without changes
|
|
Binary file
|
|
Binary file
|
data/spec/samples/boxy.yml
CHANGED
|
File without changes
|
data/spec/samples/grid.yml
CHANGED
|
File without changes
|
data/spec/samples/grid160.yml
CHANGED
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
page_size: # all measurements in mm
|
|
2
|
+
width: 210 # width of the paper sheet
|
|
3
|
+
height: 297 # height of the paper sheet
|
|
4
|
+
reg_marks:
|
|
5
|
+
margin: 10 # distance from each page border to registration mark center
|
|
6
|
+
radius: 2.5 # registration mark radius
|
|
7
|
+
offset: 2 # distance between the search area and each page border (*)
|
|
8
|
+
crop: 20
|
|
9
|
+
blur: 2
|
|
10
|
+
dilate: 5
|
|
11
|
+
header:
|
|
12
|
+
name: # ‘name’ is just a label; you can add arbitrary header elements
|
|
13
|
+
top: 5 # margin relative to registration frame top side
|
|
14
|
+
left: 15 # margin relative to registration frame left side
|
|
15
|
+
width: 170 # text will be fitted to this width
|
|
16
|
+
height: 7 # text will be fitted to this height
|
|
17
|
+
size: 14 # font size
|
|
18
|
+
title:
|
|
19
|
+
top: 15
|
|
20
|
+
left: 15
|
|
21
|
+
width: 180
|
|
22
|
+
height: 12
|
|
23
|
+
size: 12
|
|
24
|
+
code:
|
|
25
|
+
top: 5
|
|
26
|
+
left: 165
|
|
27
|
+
width: 20
|
|
28
|
+
height: 10
|
|
29
|
+
size: 14
|
|
30
|
+
signature:
|
|
31
|
+
top: 30
|
|
32
|
+
left: 7.5
|
|
33
|
+
width: 120
|
|
34
|
+
height: 15
|
|
35
|
+
size: 7
|
|
36
|
+
box: true # header element will be enclosed in a box
|
|
37
|
+
items:
|
|
38
|
+
top: 55.5 # response area margin, relative to reg frame
|
|
39
|
+
left: 10.5 # response area margin, relative to reg frame
|
|
40
|
+
rows: 30 # number of items per column
|
|
41
|
+
columns: 4 # number of columns
|
|
42
|
+
column_width: 44 #
|
|
43
|
+
x_spacing: 7 # horizontal distance between ajacent cell centers
|
|
44
|
+
y_spacing: 7 # vertical distance between ajacent cell centers
|
|
45
|
+
cell_width: 6 # width of each choice and calibration cell
|
|
46
|
+
cell_height: 5 # height of each choice and calibration cell
|
|
47
|
+
max_cells: 5 # maximum number of choices per item
|
|
48
|
+
font_size: 9 # size of both the item number and choice cell letter
|
|
49
|
+
number_width: 8 #
|
|
50
|
+
number_margin: 2 # margin between
|
|
51
|
+
barcode:
|
|
52
|
+
bits: 40 # the maximum sheet identifier is 2 to the power or bits
|
|
53
|
+
left: 15 # distance between registration frame side and the first barcode bit
|
|
54
|
+
width: 3 # width of each barcode bit
|
|
55
|
+
height: 2.5 # height of each barcode bit from the registration frame bottom side
|
|
56
|
+
spacing: 4 # horizontal distance between adjacent barcode bit centers
|