column_pack 1.0.0 → 1.0.1
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/MIT-LICENSE +20 -20
- data/Rakefile +32 -32
- data/lib/column_pack.rb +9 -9
- data/lib/column_pack/bin_packer.rb +106 -104
- data/lib/column_pack/column_packer.rb +54 -54
- data/lib/column_pack/railtie.rb +11 -11
- data/lib/column_pack/version.rb +3 -3
- data/lib/column_pack/view_helpers.rb +51 -51
- data/test/bin_packer_test.rb +139 -139
- data/test/bp_perf.rb +26 -26
- data/test/column_packer_test.rb +16 -16
- data/test/fixtures/files/five.txt +5 -5
- data/test/fixtures/files/hundred.txt +100 -100
- data/test/fixtures/files/pack.html.erb +11 -11
- data/test/fixtures/files/ten.txt +10 -10
- data/test/fixtures/files/thirty.txt +31 -31
- data/test/fixtures/files/twenty.txt +20 -20
- data/test/test_helper.rb +13 -13
- data/test/view_helper_test.rb +45 -45
- data/vendor/assets/stylesheets/column_pack.css +30 -30
- metadata +16 -13
- data/lib/tasks/column_pack_tasks.rake +0 -4
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +0 -8820
data/lib/column_pack/railtie.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require 'column_pack/view_helpers'
|
2
|
-
require 'column_pack/bin_packer'
|
3
|
-
require 'column_pack/column_packer'
|
4
|
-
|
5
|
-
module ColumnPack
|
6
|
-
class Railtie < Rails::Railtie
|
7
|
-
initializer "column_pack.view_helpers" do |app|
|
8
|
-
ActionView::Base.send :include, ViewHelpers
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
1
|
+
require 'column_pack/view_helpers'
|
2
|
+
require 'column_pack/bin_packer'
|
3
|
+
require 'column_pack/column_packer'
|
4
|
+
|
5
|
+
module ColumnPack
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer "column_pack.view_helpers" do |app|
|
8
|
+
ActionView::Base.send :include, ViewHelpers
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/column_pack/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module ColumnPack
|
2
|
-
VERSION = "1.0.
|
3
|
-
end
|
1
|
+
module ColumnPack
|
2
|
+
VERSION = "1.0.1"
|
3
|
+
end
|
@@ -1,51 +1,51 @@
|
|
1
|
-
module ColumnPack
|
2
|
-
module ViewHelpers
|
3
|
-
|
4
|
-
# Packs content into columns.
|
5
|
-
#
|
6
|
-
# pack_in_columns expect a block to be passed:
|
7
|
-
#
|
8
|
-
# pack_in_columns(3) do
|
9
|
-
# pack_element(100) do
|
10
|
-
# "A"
|
11
|
-
# end
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# Options:
|
15
|
-
# :algorithm specify a different bin packing algorithm (default :best_fit_decreasing)
|
16
|
-
# available algorithms are :best_fit_decreasing, :best_fit_increasing
|
17
|
-
#
|
18
|
-
# :shuffle_in_col after packing columns, shuffle the elements in each column (defaults to true)
|
19
|
-
#
|
20
|
-
def pack_in_columns(total_columns, options = {})
|
21
|
-
@column_packer = ColumnPacker.new(total_columns, options)
|
22
|
-
|
23
|
-
yield
|
24
|
-
|
25
|
-
@column_packer.render
|
26
|
-
end
|
27
|
-
|
28
|
-
# Packs a single element with a given height into a column.
|
29
|
-
#
|
30
|
-
# pack_element should be called withing pack_in_columns's block:
|
31
|
-
#
|
32
|
-
# pack_in_columns(3) do
|
33
|
-
# pack_element(100) do
|
34
|
-
# "A"
|
35
|
-
# end
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# Accepts parameter strings or block content (ERB, strings, etc).
|
39
|
-
#
|
40
|
-
def pack_element(height, content = nil, &block)
|
41
|
-
return if @column_packer.nil?
|
42
|
-
|
43
|
-
if block_given?
|
44
|
-
@column_packer.add(height.to_i, capture(&block))
|
45
|
-
else
|
46
|
-
@column_packer.add(height.to_i, content)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
1
|
+
module ColumnPack
|
2
|
+
module ViewHelpers
|
3
|
+
|
4
|
+
# Packs content into columns.
|
5
|
+
#
|
6
|
+
# pack_in_columns expect a block to be passed:
|
7
|
+
#
|
8
|
+
# pack_in_columns(3) do
|
9
|
+
# pack_element(100) do
|
10
|
+
# "A"
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# Options:
|
15
|
+
# :algorithm specify a different bin packing algorithm (default :best_fit_decreasing)
|
16
|
+
# available algorithms are :best_fit_decreasing, :best_fit_increasing
|
17
|
+
#
|
18
|
+
# :shuffle_in_col after packing columns, shuffle the elements in each column (defaults to true)
|
19
|
+
#
|
20
|
+
def pack_in_columns(total_columns, options = {})
|
21
|
+
@column_packer = ColumnPacker.new(total_columns, options)
|
22
|
+
|
23
|
+
yield
|
24
|
+
|
25
|
+
@column_packer.render
|
26
|
+
end
|
27
|
+
|
28
|
+
# Packs a single element with a given height into a column.
|
29
|
+
#
|
30
|
+
# pack_element should be called withing pack_in_columns's block:
|
31
|
+
#
|
32
|
+
# pack_in_columns(3) do
|
33
|
+
# pack_element(100) do
|
34
|
+
# "A"
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Accepts parameter strings or block content (ERB, strings, etc).
|
39
|
+
#
|
40
|
+
def pack_element(height, content = nil, &block)
|
41
|
+
return if @column_packer.nil?
|
42
|
+
|
43
|
+
if block_given?
|
44
|
+
@column_packer.add(height.to_i, capture(&block))
|
45
|
+
else
|
46
|
+
@column_packer.add(height.to_i, content)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/test/bin_packer_test.rb
CHANGED
@@ -1,139 +1,139 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class BinPackerTest < ActiveSupport::TestCase
|
4
|
-
include ColumnPack
|
5
|
-
|
6
|
-
test "initilizes with three columns" do
|
7
|
-
bp = BinPacker.new(3)
|
8
|
-
assert_equal BinPacker, bp.class
|
9
|
-
assert_equal Array, bp.bins.class
|
10
|
-
end
|
11
|
-
|
12
|
-
test "can't init with a non-positive number of cols" do
|
13
|
-
assert_raises ArgumentError do
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
assert_raises ArgumentError do
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
test "adds element" do
|
23
|
-
bp = BinPacker.new(1)
|
24
|
-
assert bp.add(400, 'A')
|
25
|
-
assert_equal 'A', bp.bins[0][0]
|
26
|
-
end
|
27
|
-
|
28
|
-
test "height must be greater than zero" do
|
29
|
-
bp = BinPacker.new(3)
|
30
|
-
assert_raises ArgumentError do
|
31
|
-
bp.add(0, 'A')
|
32
|
-
end
|
33
|
-
|
34
|
-
assert_raises ArgumentError do
|
35
|
-
bp.add(-1, 'A')
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
test "adds two elements" do
|
40
|
-
bp = BinPacker.new(2, {:algorithm => :best_fit_decreasing})
|
41
|
-
assert bp.add(400, 'A')
|
42
|
-
assert bp.add(500, 'B')
|
43
|
-
|
44
|
-
assert_equal 'A', bp.bins[1][0]
|
45
|
-
assert_equal 'B', bp.bins[0][0]
|
46
|
-
end
|
47
|
-
|
48
|
-
test "add six elements" do
|
49
|
-
bp = BinPacker.new(3)
|
50
|
-
bp.add(600, 'F')
|
51
|
-
bp.add(300, 'C')
|
52
|
-
bp.add(500, 'E')
|
53
|
-
bp.add(400, 'D')
|
54
|
-
bp.add(200, 'B')
|
55
|
-
bp.add(100, 'A')
|
56
|
-
assert_equal 3, bp.bins.length
|
57
|
-
|
58
|
-
assert_equal Array, bp.bins[0].class
|
59
|
-
assert_operator 1, :<, bp.bins[0].length
|
60
|
-
|
61
|
-
assert_equal Array, bp.bins[1].class
|
62
|
-
assert_operator 1, :<, bp.bins[1].length
|
63
|
-
|
64
|
-
assert_equal Array, bp.bins[2].class
|
65
|
-
assert_operator 1, :<, bp.bins[2].length
|
66
|
-
end
|
67
|
-
|
68
|
-
test "can iterate bins" do
|
69
|
-
bp = BinPacker.new(3)
|
70
|
-
bp.add(600, 'F')
|
71
|
-
bp.add(300, 'C')
|
72
|
-
bp.add(500, 'E')
|
73
|
-
bp.add(400, 'D')
|
74
|
-
bp.add(200, 'B')
|
75
|
-
bp.add(100, 'A')
|
76
|
-
|
77
|
-
assert_equal Array, bp.bins.class
|
78
|
-
|
79
|
-
bp.bins.each do |bin|
|
80
|
-
bin.each do |element|
|
81
|
-
assert_includes ['A', 'B', 'C', 'D', 'E', 'F'], element.to_s
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
test "empty space" do
|
87
|
-
bp = BinPacker.new(3)
|
88
|
-
bp.add(200, 'A')
|
89
|
-
bp.add(900, 'B')
|
90
|
-
assert_equal 1600, bp.empty_space
|
91
|
-
end
|
92
|
-
|
93
|
-
test "test different packing algorithms" do
|
94
|
-
bp = BinPacker.new(3, {:algorithm => :best_fit_decreasing})
|
95
|
-
bp.add(100, 'A')
|
96
|
-
bp.add(900, 'B')
|
97
|
-
end
|
98
|
-
|
99
|
-
test "can turn off shuffling" do
|
100
|
-
bp = BinPacker.new(1, {:algorithm => :best_fit_decreasing, :shuffle_in_col => false})
|
101
|
-
bp.add(900, 'A')
|
102
|
-
bp.add(800, 'B')
|
103
|
-
bp.add(700, 'C')
|
104
|
-
bp.add(600, 'D')
|
105
|
-
bp.add(500, 'E')
|
106
|
-
bp.add(400, 'F')
|
107
|
-
|
108
|
-
assert_equal 'A', bp.bins[0][0]
|
109
|
-
assert_equal 'B', bp.bins[0][1]
|
110
|
-
assert_equal 'C', bp.bins[0][2]
|
111
|
-
assert_equal 'D', bp.bins[0][3]
|
112
|
-
assert_equal 'E', bp.bins[0][4]
|
113
|
-
assert_equal 'F', bp.bins[0][5]
|
114
|
-
end
|
115
|
-
|
116
|
-
test "big data set" do
|
117
|
-
(2..10).each do |num_bins|
|
118
|
-
assert bp = BinPacker.new(num_bins)
|
119
|
-
|
120
|
-
File.readlines(File.expand_path('test/fixtures/files/hundred.txt')).each do |line|
|
121
|
-
number, name, = line.split(' ')
|
122
|
-
assert bp.add(number.to_i, name)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
test "six items with a perfect fit" do
|
128
|
-
bp = BinPacker.new(3)
|
129
|
-
bp.add(100, 'A')
|
130
|
-
bp.add(300, 'B')
|
131
|
-
bp.add(50, 'C')
|
132
|
-
bp.add(350, 'D')
|
133
|
-
bp.add(200, 'E')
|
134
|
-
bp.add(200, 'F')
|
135
|
-
|
136
|
-
assert_equal 0, bp.empty_space
|
137
|
-
end
|
138
|
-
|
139
|
-
end
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BinPackerTest < ActiveSupport::TestCase
|
4
|
+
include ColumnPack
|
5
|
+
|
6
|
+
test "initilizes with three columns" do
|
7
|
+
bp = BinPacker.new(3)
|
8
|
+
assert_equal BinPacker, bp.class
|
9
|
+
assert_equal Array, bp.bins.class
|
10
|
+
end
|
11
|
+
|
12
|
+
test "can't init with a non-positive number of cols" do
|
13
|
+
assert_raises ArgumentError do
|
14
|
+
BinPacker.new(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_raises ArgumentError do
|
18
|
+
BinPacker.new(-100)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
test "adds element" do
|
23
|
+
bp = BinPacker.new(1)
|
24
|
+
assert bp.add(400, 'A')
|
25
|
+
assert_equal 'A', bp.bins[0][0]
|
26
|
+
end
|
27
|
+
|
28
|
+
test "height must be greater than zero" do
|
29
|
+
bp = BinPacker.new(3)
|
30
|
+
assert_raises ArgumentError do
|
31
|
+
bp.add(0, 'A')
|
32
|
+
end
|
33
|
+
|
34
|
+
assert_raises ArgumentError do
|
35
|
+
bp.add(-1, 'A')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
test "adds two elements" do
|
40
|
+
bp = BinPacker.new(2, {:algorithm => :best_fit_decreasing})
|
41
|
+
assert bp.add(400, 'A')
|
42
|
+
assert bp.add(500, 'B')
|
43
|
+
|
44
|
+
assert_equal 'A', bp.bins[1][0]
|
45
|
+
assert_equal 'B', bp.bins[0][0]
|
46
|
+
end
|
47
|
+
|
48
|
+
test "add six elements" do
|
49
|
+
bp = BinPacker.new(3)
|
50
|
+
bp.add(600, 'F')
|
51
|
+
bp.add(300, 'C')
|
52
|
+
bp.add(500, 'E')
|
53
|
+
bp.add(400, 'D')
|
54
|
+
bp.add(200, 'B')
|
55
|
+
bp.add(100, 'A')
|
56
|
+
assert_equal 3, bp.bins.length
|
57
|
+
|
58
|
+
assert_equal Array, bp.bins[0].class
|
59
|
+
assert_operator 1, :<, bp.bins[0].length
|
60
|
+
|
61
|
+
assert_equal Array, bp.bins[1].class
|
62
|
+
assert_operator 1, :<, bp.bins[1].length
|
63
|
+
|
64
|
+
assert_equal Array, bp.bins[2].class
|
65
|
+
assert_operator 1, :<, bp.bins[2].length
|
66
|
+
end
|
67
|
+
|
68
|
+
test "can iterate bins" do
|
69
|
+
bp = BinPacker.new(3)
|
70
|
+
bp.add(600, 'F')
|
71
|
+
bp.add(300, 'C')
|
72
|
+
bp.add(500, 'E')
|
73
|
+
bp.add(400, 'D')
|
74
|
+
bp.add(200, 'B')
|
75
|
+
bp.add(100, 'A')
|
76
|
+
|
77
|
+
assert_equal Array, bp.bins.class
|
78
|
+
|
79
|
+
bp.bins.each do |bin|
|
80
|
+
bin.each do |element|
|
81
|
+
assert_includes ['A', 'B', 'C', 'D', 'E', 'F'], element.to_s
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
test "empty space" do
|
87
|
+
bp = BinPacker.new(3)
|
88
|
+
bp.add(200, 'A')
|
89
|
+
bp.add(900, 'B')
|
90
|
+
assert_equal 1600, bp.empty_space
|
91
|
+
end
|
92
|
+
|
93
|
+
test "test different packing algorithms" do
|
94
|
+
bp = BinPacker.new(3, {:algorithm => :best_fit_decreasing})
|
95
|
+
bp.add(100, 'A')
|
96
|
+
bp.add(900, 'B')
|
97
|
+
end
|
98
|
+
|
99
|
+
test "can turn off shuffling" do
|
100
|
+
bp = BinPacker.new(1, {:algorithm => :best_fit_decreasing, :shuffle_in_col => false})
|
101
|
+
bp.add(900, 'A')
|
102
|
+
bp.add(800, 'B')
|
103
|
+
bp.add(700, 'C')
|
104
|
+
bp.add(600, 'D')
|
105
|
+
bp.add(500, 'E')
|
106
|
+
bp.add(400, 'F')
|
107
|
+
|
108
|
+
assert_equal 'A', bp.bins[0][0]
|
109
|
+
assert_equal 'B', bp.bins[0][1]
|
110
|
+
assert_equal 'C', bp.bins[0][2]
|
111
|
+
assert_equal 'D', bp.bins[0][3]
|
112
|
+
assert_equal 'E', bp.bins[0][4]
|
113
|
+
assert_equal 'F', bp.bins[0][5]
|
114
|
+
end
|
115
|
+
|
116
|
+
test "big data set" do
|
117
|
+
(2..10).each do |num_bins|
|
118
|
+
assert bp = BinPacker.new(num_bins)
|
119
|
+
|
120
|
+
File.readlines(File.expand_path('test/fixtures/files/hundred.txt')).each do |line|
|
121
|
+
number, name, = line.split(' ')
|
122
|
+
assert bp.add(number.to_i, name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
test "six items with a perfect fit" do
|
128
|
+
bp = BinPacker.new(3)
|
129
|
+
bp.add(100, 'A')
|
130
|
+
bp.add(300, 'B')
|
131
|
+
bp.add(50, 'C')
|
132
|
+
bp.add(350, 'D')
|
133
|
+
bp.add(200, 'E')
|
134
|
+
bp.add(200, 'F')
|
135
|
+
|
136
|
+
assert_equal 0, bp.empty_space
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
data/test/bp_perf.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
require_relative '../lib/column_pack/bin_packer'
|
2
|
-
|
3
|
-
include ColumnPack
|
4
|
-
|
5
|
-
hundred = File.readlines(File.expand_path('./dummy/test/fixtures/files/hundred.txt'))
|
6
|
-
|
7
|
-
algos = [:best_fit_increasing, :best_fit_decreasing]
|
8
|
-
|
9
|
-
algos.each do |algo|
|
10
|
-
empty_spaces = []
|
11
|
-
|
12
|
-
(2..20).each do |num_bins|
|
13
|
-
|
14
|
-
bp = BinPacker.new(num_bins, {:algorithm => algo})
|
15
|
-
hundred.each do |line|
|
16
|
-
number, name, = line.split(' ')
|
17
|
-
bp.add(number.to_i, name)
|
18
|
-
end
|
19
|
-
|
20
|
-
empty_spaces << bp.empty_space
|
21
|
-
end
|
22
|
-
|
23
|
-
puts "#{algo.to_s} average empty space: " + (empty_spaces.reduce(:+).to_f / empty_spaces.size).to_i.to_s
|
24
|
-
puts "#{algo.to_s} max empty space: " + empty_spaces.max.to_s
|
25
|
-
puts "#{algo.to_s} min empty space: " + empty_spaces.min.to_s
|
26
|
-
end
|
1
|
+
require_relative '../lib/column_pack/bin_packer'
|
2
|
+
|
3
|
+
include ColumnPack
|
4
|
+
|
5
|
+
hundred = File.readlines(File.expand_path('./dummy/test/fixtures/files/hundred.txt'))
|
6
|
+
|
7
|
+
algos = [:best_fit_increasing, :best_fit_decreasing]
|
8
|
+
|
9
|
+
algos.each do |algo|
|
10
|
+
empty_spaces = []
|
11
|
+
|
12
|
+
(2..20).each do |num_bins|
|
13
|
+
|
14
|
+
bp = BinPacker.new(num_bins, {:algorithm => algo})
|
15
|
+
hundred.each do |line|
|
16
|
+
number, name, = line.split(' ')
|
17
|
+
bp.add(number.to_i, name)
|
18
|
+
end
|
19
|
+
|
20
|
+
empty_spaces << bp.empty_space
|
21
|
+
end
|
22
|
+
|
23
|
+
puts "#{algo.to_s} average empty space: " + (empty_spaces.reduce(:+).to_f / empty_spaces.size).to_i.to_s
|
24
|
+
puts "#{algo.to_s} max empty space: " + empty_spaces.max.to_s
|
25
|
+
puts "#{algo.to_s} min empty space: " + empty_spaces.min.to_s
|
26
|
+
end
|