Reputation: 956
I can't for the life of me figure out why my: generate_receipt
method is returning 54.9
for my "imported dinner plates item" when it should equal 54.65
. I wrote RSpec tests to confirm that the array is indeed returning the correct values.
47.50 + 4.75 + 2.40 = 54.65
Why is it returning 54.9
instead of 54.65
?! Where is this rounding up occurring? How do I get it to return the correct value? I'm stumped.
describe :calcualte_sales_tax do
it "should return the correct array" do
calculate_sales_tax(@receipt).should eq([0, 4.75])
end
end
describe :calculate_import_tax do
it "should return the correct array" do
calculate_import_tax(@receipt).should eq([0.50, 2.40])
end
end
@receipt = {
"1"=>{:item=>"imported chocolates", :price=>10.00, :quantity=>1},
"2"=>{:item=>"imported dinner plates", :price=>47.50, :quantity=>1}
}
def generate_receipt(receipt)
n = 0
while n < receipt.length
receipt["#{n+1}"][:price]+=calculate_sales_tax(receipt)[n]
receipt["#{n+1}"][:price]+=calculate_import_tax(receipt)[n]
n+=1
end
receipt
end
def calculate_import_tax(receipt)
taxes = []
receipt.each do |k,v|
if (v[:item] =~ /imported/)
subtotal = v[:price]
# v[:price]+=(((((5 * subtotal)/100)*20.ceil) / 20.0))
# taxes<<(5 * subtotal)/100
taxes<<((5 * subtotal/100)*20).ceil/20.0.round(2)
else
taxes<<0
end
end
taxes
end
def calculate_sales_tax(receipt)
tax_free_items = ["book", "chocolate bar", "chocolates", "pills"]
taxes = []
receipt.each do |k,v|
if (v[:item] =~ /chocolate\s/) ||
(v[:item] =~ /chocolates/) ||
(v[:item] =~ /book/) ||
(v[:item] =~ /pills/)
taxes<<0
else
subtotal = v[:price]
# v[:price]+=(((((10 * subtotal)/100)*20.ceil) / 20.0))
# taxes<<(10 * subtotal)/100
taxes<<((10 * subtotal/100)*20).ceil/20.0
end
end
taxes
end
Upvotes: 0
Views: 168
Reputation: 1836
def generate_receipt(receipt)
n = 0
while n < receipt.length
puts receipt["#{n+1}"][:price].inspect
receipt["#{n+1}"][:price]+=calculate_sales_tax(receipt)[n].round(2)
puts receipt["#{n+1}"][:price].inspect
puts calculate_import_tax(receipt)[n]
receipt["#{n+1}"][:price]+=calculate_import_tax(receipt)[n].round(2)
puts receipt["#{n+1}"][:price].inspect
puts "-----"
n+=1
end
receipt
end
Returns:
47.5
52.25
2.65
54.9
The bug is in your calculate_import_tax method. It's returning 2.65, not 2.40.
EDIT:
Got it :).
receipt["#{n+1}"][:price]+=calculate_sales_tax(receipt)[n]
receipt["#{n+1}"][:price]+=calculate_import_tax(receipt)[n]
Those rows are updating the price of the receipt. Hence, your tests are running independently, but the sales tax is modifying the raw price before the import tax is calculated...
Upvotes: 1
Reputation: 4053
1) Ruby treat numbers without decimal part as INTEGERS. And WILL NOT create result that have decimal part unless computation include floating point number.
2) 10 * X / 100 * 20 == X * 2
3) LEGAL COUNTING may require specified accuracy, and so you may need to use specialized library for such number crunching.
Fast solution would be to change that code to:
10.0 * subtotal / 100.0 * 20.0
Now Ruby will treat all those numbers as float's.
Upvotes: 0