Having a little issue with my code to see if a credit card number adheres to the Luhn Algorithm. The code is returning true when the Credit Card is divisible by 10, but also is returning true when the CC number is not divisible by 10. I have printed out the final sum to make sure the numbers were actually adding to the sum variable, and they seem to be.. Below is my code. I know it can be cleaner, but at this stage I would like to see it work first.
def check_card
c_num= []
sum=0
s_numbers=@card_numbers.to_s.reverse.split("")
s_numbers.each_slice(2) do |x|
c_num << (x.last.to_s.to_i*2)
c_num << (x.first.to_s.to_i)
end
c_num.each do |num|
if num.to_i > 9
sum+= (num.to_i % 10)+1
else
sum += num.to_i
end
end
sum % 10==0
end
Here is how it is being called:
it 'returns false for a bad card' do
card = CreditCard.new(4408041234567892)
card.check_card.should eq false
end
posting my answer because I thought it was clean:
It seems you're confusing the output of the test with the output of the
check_card
method. You've confirmed thatsum == 69
, sosum % 10 == 0
should returnfalse
(unless Ruby's math is broken), so yourcheck_card
method should also returnfalse
— add the lineputs card.check_card
after the linecard = CreditCard.new(4408041234567892)
(but before the next line) in your testing block to show the value returned.The next line,
card.check_card.should eq false
, asserts that the returned value "should equal"false
— that is, it expectscheck_card
to befalse
for that value of@card_numbers
, and will returntrue
if that's the case. I suspect that you're seeing the test come uptrue
and taking that to mean the method is returning the incorrect value oftrue
.Without seeing the output of the test, this is only speculation, of course. However, your code seems correct and, for me, gives the correct result.
Now that another answer has appeared I will offer a suggested coding. This does not answer your question, but I thought it might be of interest and couldn't very well put it in a comment, because of formatting limitations.
This is your code, commented and adapted to behave like the wikipedia description.