Permalink
Browse files

clean up calculate_best method. Check that an optimal match is being …

…returned
  • Loading branch information...
SelenaSmall committed Sep 4, 2017
1 parent 1d97d00 commit b3c7b73cc5483b71b9247df037a4eacd0b433235
Showing with 84 additions and 29 deletions.
  1. +12 −23 lib/order_line.rb
  2. +6 −6 lib/shop.rb
  3. +60 −0 spec/order_line_spec.rb
  4. +6 −0 spec/shop_spec.rb
@@ -26,39 +26,28 @@ def optimal(product)
calculate_best(same_packs, diff_packs)
end
def calculate_best(exact, partial)
# If there are no matches on same_packs, return diff_packs
unless exact.any?
puts "\nThis is it #{partial.inspect}"
return partial
end
# Calculate best method
# @param same_packs [Enumerator]
# @param diff_packs [Enumerator]
# @return optimum combo of packs [Enumerator]
def calculate_best(same_packs, diff_packs)
return diff_packs unless same_packs.any?
# If there are no matches on diff_packs, return same_packs
unless partial.any?
puts "\nThis is it #{exact.inspect}"
return exact
end
return same_packs unless diff_packs.any?
# If there's one of each, work out which is the better price
# Get the total price of diff_packs
sub_total = []
partial.each do |_x, _y, _z, val|
sub_total << val
end
diff_packs.each { |_x, _y, _z, val| sub_total << val }
# # Find total cost of sub_items for a partial match
line_total = sub_total.inject(:+)
# Return the cheapest option
if [exact.min[3], line_total].min == line_total
puts "\nThis is it #{partial.inspect}"
return partial
end
return diff_packs if [same_packs.min[3], line_total].min == line_total
exact
same_packs
end
def present_line(packs)
puts "PACKS: #{packs}"
sub_total = []
sub_item = []
packs.each do |k, v, i|
@@ -119,7 +108,7 @@ def diff_match(pack_qtys, matches, part_order)
matches.each do |x, y, z|
val = order_qty - (x * y)
pack_qtys.detect do |a|
# TODO: This can be optimised. a.include?(val) does not cooperate with Money
# TODO: Optimised. a.include?(val) does not cooperate with Money
if a[0] == val || a[0] == val || a[0] * 3 == val
part_order << [x, y, z]
part_order << [val / a[0], a[0], a[1]]
@@ -36,12 +36,12 @@ def choose_items(input)
end
def exec(order_line)
order.add_item(
order_line,
order_line.present_line(
order_line.optimal(order_line.order_item.name)
)
)
optimal = order_line.optimal(order_line.order_item.name)
return unless optimal.any?
order.add_item(order_line,
order_line.present_line(optimal))
order_line
end
@@ -32,6 +32,66 @@
end
end
describe '#calculate_best' do
it 'should return optimum combination of packs which is an Enumerator' do
order_item = Item.new('rockmelons')
instance = OrderLine.new(13, order_item)
pack_qtys = []
order_item.packs(instance.order_item.name).each { |p| pack_qtys << [p.qty, p.price] }
same_packs = instance.send(:price_check, instance.send(:same_match, pack_qtys, []), [])
diff_packs = instance.send(:price_check, instance.send(:diff_match, pack_qtys, [], []), [])
expect(instance.calculate_best(same_packs, diff_packs)).to be_a Enumerator
end
end
describe '#calculate_best' do
it 'should return optimum combination of packs which is an Enumerator' do
order_item = Item.new('watermelons')
instance = OrderLine.new(10, order_item)
pack_qtys = []
order_item.packs(instance.order_item.name).each { |p| pack_qtys << [p.qty, p.price] }
same_packs = instance.send(:price_check, instance.send(:same_match, pack_qtys, []), [])
diff_packs = instance.send(:price_check, instance.send(:diff_match, pack_qtys, [], []), [])
expect(instance.calculate_best(same_packs, diff_packs)).to be_a Enumerator
end
end
describe '#calculate_best' do
it 'should return optimum combination of packs which is an Enumerator' do
order_item = Item.new('pineapples')
instance = OrderLine.new(14, order_item)
pack_qtys = []
order_item.packs(instance.order_item.name).each { |p| pack_qtys << [p.qty, p.price] }
same_packs = instance.send(:price_check, instance.send(:same_match, pack_qtys, []), [])
diff_packs = instance.send(:price_check, instance.send(:diff_match, pack_qtys, [], []), [])
expect(instance.calculate_best(same_packs, diff_packs)).to be_a Enumerator
end
end
describe '#calculate_best' do
it 'should return an Enumerator which is empty if the quantity cannot be made up of packs' do
order_item = Item.new('pineapples')
instance = OrderLine.new(1, order_item)
pack_qtys = []
order_item.packs(instance.order_item.name).each { |p| pack_qtys << [p.qty, p.price] }
same_packs = instance.send(:price_check, instance.send(:same_match, pack_qtys, []), [])
diff_packs = instance.send(:price_check, instance.send(:diff_match, pack_qtys, [], []), [])
expect(instance.calculate_best(same_packs, diff_packs)).to be_a Enumerator
end
end
describe '#present_line' do
it 'should return whole_packs which is an Array' do
instance = OrderLine.new(12, Item.new('watermelons'))
@@ -48,5 +48,11 @@
expect(instance.send(:exec, OrderLine.new(10, Item.new('watermelons')))).to be_a OrderLine
end
it 'should return nil if an optimal order cannot be made up of packs' do
instance = Shop.new(Order.new)
expect(instance.send(:exec, OrderLine.new(1, Item.new('watermelons')))).to be_nil
end
end
end

0 comments on commit b3c7b73

Please sign in to comment.