Credit Card Checker Problems

Hi all. I have looked at the solution code after trying out the credit card validator function by myself, and I see that the checking if the index is even or odd is a bit different on the solution, than the way I did it (the solution checks for odd numbers whereas I checked for even), and my way was actually from researching on Google how to check if the current index is even or odd (and actually the solution seems more confusing than the way my logic had thought up, and the only other difference is that the solution had put some of the math logic into a variable, whereas I put it all on one line, but I don’t think that matters). But the way I did it is obviously wrong and I can’t figure out why. It could be that just one little thing is off and my way of thinking is correct, or it could be that you just can’t do it at all for some unique reason… so if someone can point out why my “validateCred” function for this project is returning “false” EVERY single time I put in a different provided credit card number array (even the ones that are considered “valid” and should have the function returning “true”), and explain what I need to do to make it work without having to only use the solution code, I would really appreciate your explanation as to why it is wrong. I commented out my logic/thinking (to the right) in hopes that you can help me keep my logic. Thank you!

// test with these valid credit card numbers:

const valid4 = [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5];

const valid5 = [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6];

// test with these invalid credit card numbers:

const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];

const invalid2 = [5, 7, 9, 5, 5, 9, 3, 3, 9, 2, 1, 3, 4, 6, 4, 3];


// MY code/logic:

function validateCred (array) {
  let sum = 0       //counter
for (let i = array.length - 1; i >= 0; i--){
  if (i % 2 === 0) {       // if current index is even
    if ((array[i] * 2) > 9) {       // (if current element when multiplied by 2 is greater than 9)
      sum += (array[i] * 2) - 9
    } else {
      sum += array[i] * 2
    }
  } else {  // if current index is odd
    sum += array[i]
  } 
  return sum % 10 === 0 // (if no remainder when divided by 10, then the credit card numbers are 
// valid and will return true, otherwise if the numbers are invalid it will return false)
}
}

Just for easier reference, here is the solution code pasted:

function validateCred(numArr) {
  let total = 0;
  for (let i = numArr.length - 1; i >= 0; i--) {
    let currValue = numArr[i]
    if ((numArr.length - 1 - i) % 2 === 1) {
      currValue *= 2;
      if (currValue > 9) {
        currValue -= 9;
      }
    }
    total += currValue;
  }

  return total % 10 === 0;

As you can see, the solution checks for odd numbers, whereas my code checks for even. And other than putting some of the math logic into a variable, I really don’t see too much of a difference between the two codes, other than the odd/even check being opposite. Why can’t it check for even? Or can it, but I’m just doing something wrong? Thank you!

1 Like

The difference between these lines is worth observing.
Yours:

if (i % 2 === 0) { // if current index is even

Solution:

if ((numArr.length - 1 - i) % 2 === 1) {

The difference is significantly more that one checking for even and one checking for odd. I know it can be tedious, but try working through one of the valid arrays with a pencil and paper. Go through your code a line at a time, and compare what is different when you do the same with the solution. You could use a few console.log() statements to make these observations if you’d rather. The key would be to compare what you observe with your code to what you observe with the solution code.

Hint

Which numbers get doubled?
Does it matter whether the index is odd or even when we want to double every other digit starting from the right, but skipping the check digit?
Does your code skip the check digit?
What if a card number has an odd number of digits?

Hi midlindner,

Thank you for trying to help me figure this out. I am new to this type of logic/thinking so please bear with me.

So when I look at this page: cc validator v2@2x , it says that all even indexes, including the first number on the left (the 0 index) is multiplied by two. The very last number to the far-right is at the 15th index (also known as the “check” digit), and since the number 15 is an odd index number, that proves that this 15th index is NOT multiplied by two in my code, since I am only doing that to EVEN indexes. And on the solution’s code, it’s the same thing, this 15th index on the far right is not multiplied by two, it is ignored in the first if statement logic. Both codes are ignoring the 15th index (number on the far right), during this first if-statement, and both codes are including the zero index (number on the far left), during the first if-statement. I am only saying this because you said in your hint: “Does your code skip the check digit?”, yes it does skip it, since the check digit is an index of 15, and since 15 is an odd number and my logic ONLY multiplies by two the EVEN index numbers, then my logic doesn’t do anything to this number (except of course adding only that number to the sum, instead of multiplying by two, like you’re supposed to, which is demonstrated by my last else statement). Since the zero index is also even (has no remainder) that should be included. The 15th index is the number on the far right, and since 15 is an odd number, it is not included to be multiplied by two. That’s why I just decided to multiply by two, ONLY the even indexes, as that makes since on the algorithm demonstrated on that page.

In the solution, numArr.length would be 16, since there are 16 numbers. Minus 1, would be 15. 15 minus i (the current index) would mean that since the loop goes backwards from the 15th index, then the first loop would be 15 minus 15, which is zero. Then the second loop would be 15-14, which is 1. The third loop would be 15-13, which is 2 (and so on). In the solution it is saying to only do the if-statement logic of those numbers with a remainder of 1 (so odd). So it’s saying on the first loop of the 15th index (the number to the far right that you’re not supposed to multiply by 2- which equals zero after the if statement’s logic) you would skip the next line of logic inside the curly brackets, because zero does not have a remainder of 1. Since the second loop’s (index 14) if-statement logic equals 1, that is an odd number, so the following line’s logic inside the curly braces WILL happen on that index 14. The third loop’s index (13) if-statment logic equals 2, which is not odd so therefore the following line of logic inside the curly brackets WON’T happen. So as you can see, the solution’s code is STILL only doing the curly bracket logic on EVEN indexes, not on the odd indexes. It just has a funnier way of pulling it than mine. But it is still the same thing that my code was trying to do (which is multiply by 2 ONLY the even idexes, leaving the 15th index/last number alone, and only doing the if-statement logic on the even-numbered indexes). We are both doing the logic of multiplying the value of EVEN indexes by two. It’s just that the solution’s code has a much funnier (albeit confusing) way of only doing the logic on all the even indexes. Thus no difference. Which makes me think I must be doing something ELSE wrong here. I hope this all makes sense.
Thanks again! :slight_smile:

You’ll see what my hints were referring to when you use card numbers that have an odd number of digits (AMEX for example). I didn’t immediately see the main issue you’re having until I formatted your code just now. If you either add a console.log(), or run through your code with pencil and paper doing what it says at each step, you’ll see the problem. Your code should work fine with card numbers of even length once you spot the problem.

You might try:

Hi again midlindner,

I appreciate you pointing that out. Now I know I am not adding to the variable sum correctly. For some reason, I got a string of 16 numbers that don’t even make any sense as to how they got there. Now I’m even more confused. Don’t want to do this but I give up! lol I’ve been spending two days trying to figure this out… I wouldn’t mind you just telling me why it’s wrong and what I need to do lol

When I tried your code with the console.log() added, using valid4, the output was:

5
false

Where did the 5 come from?
Looking at the array:

:thinking:
5 is the final digit, or in this case the first digit accessed by your for loop. That might lead me to wonder whether the return statement is being executed too soon. Occasionally, I will label curly braces, so I can clearly see where each block ends. For example:

function someFunc (param) { // function opening brace
  // lots of really interesting and fantastic code
  if (someValue === someOtherValue) { // if opening brace
    // more impressive code
  } // if closing brace
  // yet more code
} // function closing brace

Don’t give up. You can do this.

Hint

Did you intend to return the result inside the for loop? Probably not, but that’s where it is. Unless a card number ends with 0, since sum is only the last digit of every card sum % 10 === 0 will always be false. Move the return outside the loop, and you should have much different results.

Wow, I guess I must have been tired because that was such a simple error! lol thank you I feel better knowing that I did the main logic correctly, just have to label my closing curly brackets like you suggested so I know where to put the return! Thank you so much!! :slight_smile:

Now i just have to figure out the Amex situation, I didn’t know they were only 15 numbers… I still think the solution code is confusing and wish there was a way for me to remember this or at least understand it for future problems that are the same.

The solution code only significantly differs from yours in the 2 lines I mentioned in my initial reply. Consider how (numArr.length - 1 - i) % 2 === 1 differs from i % 2 === 0 when the length of the array is 15 rather than 16. You already know what the end result is. It skips the last digit, and doubles every other digit regardless of array length while yours only works when the array length is an even number.

Initially i is assigned to the length of the array - 1, so if the length is 15, i is initially assigned to 14.
Plug the values in to both expressions:
(15 - 1 - 14) % 2 === 1 versus 14 % 2 === 0
The solution code evaluates to false, so the 15th digit (at index 14) is not doubled.
Your code evaluates to true, so the 15th digit is doubled which is incorrect.
Many choose to reverse the array, and iterate from left to right which is probably more simple, but less efficient since a copy of the array must be created. Your initial thinking was spot on. Just need a few tweaks. All in all, you’ve done excellent work.

1 Like

Well, this is embarrassing that I still messed up somehow on step 3 where I have to create a function that takes an array of multiple invalid card numbers, and depending on what the first digit of each of the numbers are, I have to add the name of the card company to a new array (but not have more than one of each company added). I checked the solution code, but it’s just my luck that it uses a “switch” statement instead of if statement which I feel more comfortable using, so having to compare the two codes to two different kinds of code makes things difficult. Can you point out where I went wrong again in my code?

const idInvalidCardCompanies = (invalidArray) => { let companies = [] for (i = 0; i < invalidArray.length; i++){ if (invalidArray[i][0] === 3 && companies.indexof('Amex') === -1) { companies.push('Amex') } if (invalidArray[i][0] === 4 && companies.indexof('Visa') === -1){ companies.push('Visa') } if (invalidArray[i][0] === 5 && companies.indexof('Mastercard') === -1) { companies.push('Mastercard') } if (invalidArray[i][0] === 6 && companies.indexof('Discover') === -1) { companies.push('Discover') } companies.push('Company not found') } return companies }

Thanks again! :slight_smile:

Oops… the codebyte doesn’t show the far right for some reason so here it is just pasted:

const idInvalidCardCompanies = (invalidArray) => { 
  let companies = []
  for (i = 0; i < invalidArray.length; i++){
  if (invalidArray[i][0] === 3 && companies.indexof('Amex') === -1) {
    companies.push('Amex')
  }
  if (invalidArray[i][0] === 4 && companies.indexof('Visa') === -1){
  companies.push('Visa')
  }
  if (invalidArray[i][0] === 5 && companies.indexof('Mastercard') === -1) {
  companies.push('Mastercard')
  }
  if (invalidArray[i][0] === 6 && companies.indexof('Discover') === -1) {
  companies.push('Discover')
  }
    companies.push('Company not found')
}
return companies
}

The Codebyte feature is really only useful for snippets of code that can be fully executed. To post snippets of code for review, its better to use the preformated text button </>, or manually type 3 backticks on a blank line before and after the code:

```
code goes here
```
1 Like
type or paste code here

Thank you for that, I was wondering how to do that lol

As to your question, the process for me to find the problem is the same as it would be for you to find it. We need to observe what is happening at each step, and compare that to what we were expecting. When they are different, we can look at the code, and see what needs to be adjusted. My first step would be to add console.log() statements to make the observations.

If we then run the code with a made up array for testing:

console.log(idInvalidCardCompanies([[3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [9, 9, 9]]));

We can observe what happens:
Output:

TypeError: companies.indexof is not a function

The error message references this line:

console.log(companies.indexof('Amex')) // same here

A quick google search reveals a typo:

Next step:
Change all instances of indexof to indexOf, and run the code again. Continue the process until the output is what is expected.

Wow i just forgot to capitalize the “O” in indexOf… silly me! lol

Thanks again!!

1 Like

There’s more to it than that, but that’s the first thing to fix. Debugging is a process, and an important skill to learn. Proofreading is not debugging. Staring at the code for a while may have lead to the discovery of the typo eventually, but running the code whilst observing what it is doing is a much more efficient process.

1 Like