Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
class Allocate | ||
attr_accessor :amount | ||
attr_accessor :ratios | ||
|
||
def initialize(amount = 0 , ratios = []) | ||
@amount = amount | ||
@ratios = ratios | ||
end | ||
|
||
def divided | ||
divided_ratios = @ratios.map { |ratio| ratio.to_d/ratios.sum.to_d } | ||
compensate_last_slice( divided_ratios.map { |ratio| (@amount * ratio).round(2) } ) | ||
end | ||
|
||
def compensate_last_slice(rates) | ||
rates.tap do |rates| | ||
rates[-1] = rates[-1] + (amount - rates.sum).round(2) | ||
if ( amount > 0 && ( rates.select {|item| item <= 0 }.count > 0 ) ) || | ||
( amount < 0 && ( rates.select {|item| item >= 0 }.count > 0 ) ) | ||
raise "Number is too small to be allocated on that number of slices(#@amount on #{@ratios.size} slices)." | ||
end | ||
end | ||
end | ||
|
||
def self.evenly(amount, number_of_slices) | ||
Allocate.new.tap do |a| | ||
a.amount = amount | ||
a.ratios = (1..number_of_slices).map { 1.to_d/number_of_slices } | ||
end.divided | ||
end | ||
end #Allocate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
require 'guerrilla_patch/allocate' | ||
|
||
describe Allocate do | ||
it 'should divide whole numbers' do | ||
subject.amount = 100 | ||
subject.ratios = [0.1,0.9] | ||
subject.divided.should == [10, 90] | ||
end | ||
|
||
it 'should divide equally on two decimals' do | ||
subject.amount = 100 | ||
subject.ratios = [1.0/3, 1.0/3,1.0/3] | ||
subject.divided.should == [33.33, 33.33, 33.34] | ||
subject.divided.inject(0) { | sum, item | sum += item }.should == subject.amount | ||
end | ||
|
||
it 'should calculate ratios if they are over 1' do | ||
subject.amount = 100 | ||
subject.ratios = [50,70,90] | ||
subject.divided.should == [23.81, 33.33, 42.86 ] | ||
subject.divided.inject(0) { | sum, item | sum += item }.should == subject.amount | ||
end | ||
|
||
it 'should calculade real example' do | ||
subject.amount = 2297.19 | ||
subject.ratios = [2170.29, 126.90 ] | ||
subject.divided.should == [2170.29, 126.90 ] | ||
end | ||
|
||
it 'should divide equally on number of slices' do | ||
Allocate.evenly(100,3).should == [33.33,33.33,33.34] | ||
end | ||
|
||
it 'should divide equally on number of slices for small number' do | ||
Allocate.evenly(0.1,3).should == [0.03,0.03,0.04] | ||
end | ||
|
||
it 'should divide equally on number of slices for really small number' do | ||
Allocate.evenly(0.1,9).should == [0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.02] | ||
end | ||
|
||
it 'should divide equally on two decimals negative numbers' do | ||
subject.amount = -100 | ||
subject.ratios = [1.0/3, 1.0/3,1.0/3] | ||
subject.divided.should == [-33.33, -33.33, -33.34] | ||
subject.divided.inject(0) { | sum, item | sum += item }.should == subject.amount | ||
end | ||
|
||
it 'should raise exception for number that is too small' do | ||
lambda do | ||
Allocate.evenly(0.1,20) | ||
end.should raise_error 'Number is too small to be allocated on that number of slices(0.1 on 20 slices).' | ||
end | ||
|
||
it 'should raise exception for number that is too small negative' do | ||
lambda do | ||
Allocate.evenly(-0.1,20) | ||
end.should raise_error 'Number is too small to be allocated on that number of slices(-0.1 on 20 slices).' | ||
end | ||
|
||
it 'should support costructor based params' do | ||
subject = Allocate.new( 100, [1.0/3, 1.0/3,1.0/3] ) | ||
subject.divided.should == [33.33, 33.33, 33.34] | ||
subject.divided.inject(0) { | sum, item | sum += item }.should == subject.amount | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters