Credit Card Checker project

Hi!

Could somebody please point out what is wrong with my code for the project Credit Card Checker project?
It fails to identify the invalid card numbers when using function findInvalidCards ()in the output I can see all credit card numbers from all sections, however validateCred function works fine.

// All valid credit card numbers
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9];
const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
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];

// All 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];
const invalid3 = [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];
const invalid4 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
const invalid5 = [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4];

// Can be either valid or invalid
const mystery1 = [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4];
const mystery2 = [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9];
const mystery3 = [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3];
const mystery4 = [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3];
const mystery5 = [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3];

// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4, mystery5];


// Add your functions below:
var doubleNumbersSum = 0;
var singleNumbersSum = 0;
function validateCred(arr) {
  let lastElement = arr[arr.length - 1];
  let newArray = arr.slice(0, -1);
  newArray.reverse();
  for (let i = 0; i < newArray.length; i += 2) {
    newArray[i] *= 2;
    if (newArray[i] > 9) {
      newArray[i] -= 9;
    }
    doubleNumbersSum += newArray[i];
  }
  for (let j = 1; j < newArray.length; j += 2) {
    singleNumbersSum += newArray[j];
  }
  let checkForModulo = (singleNumbersSum + doubleNumbersSum + lastElement) % 10;
  return checkForModulo === 0;
}
//console.log(validateCred(valid3));


function findInvalidCards(cards) {
  let invalidCards = [];

  for (let k = 0; k < cards.length; k++) {
      if (!validateCred(cards[k])) {
      invalidCards.push(cards[k]);
    }
  }
   return invalidCards;
}
console.log(findInvalidCards(batch));

Hello, @micro3227863613

Your problem is with these 2 variables. Try logging their values at the very end of your code, and you should see the problem.

3 Likes

Thanks a lot, @midlindner!

Managed to fix it like this:

// All valid credit card numbers
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9];
const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
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];

// All 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];
const invalid3 = [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];
const invalid4 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
const invalid5 = [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4];

// Can be either valid or invalid
const mystery1 = [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4];
const mystery2 = [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9];
const mystery3 = [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3];
const mystery4 = [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3];
const mystery5 = [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3];

// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4, mystery5];


// Add your functions below:

function validateCred(arr) {
  let checkForModulo = 0;
  let lastElement = arr[arr.length - 1];
  let newArray = arr.slice(0, -1);
  newArray.reverse();
  for (let i = 0; i < newArray.length; i += 2) {
    newArray[i] *= 2;
    if (newArray[i] > 9) {
      newArray[i] -= 9;
    }
    checkForModulo += newArray[i];
  }
  for (let j = 1; j < newArray.length; j += 2) {
    checkForModulo += newArray[j];
  }
  return (checkForModulo + lastElement) % 10 === 0;
}

console.log(validateCred(mystery5));


function findInvalidCards(cards) {
  let invalidCards = [];

  for (let k = 0; k < cards.length; k++) {
      if (validateCred(cards[k]) == true) {
      invalidCards.push(cards[k]);
    }
  }
   return invalidCards;
}
console.log(findInvalidCards(batch));
1 Like

It is fun to see how everyone has their own method/code ;).

This is mine:

const validateCred = (card) => {
  let cardInverted = card.slice().reverse(); // make a copy of the card and invert the array right to left.
  for (let i=0; i < cardInverted.length; i++) { // check each index and pick out the even numbers
    if (i % 2 != 0) {
      cardInverted[i] = cardInverted[i] * 2; // double the value of the array at each even index
      if (cardInverted[i] > 9) {
        cardInverted[i] -= 9; // if the value is higher then 9 deduct it by 9
      }  
    }
  }
  let sum = cardInverted.reduce((a, b) => a + b, 0); // add all numbers of the array
  if (sum % 10 == 0) { // check if the modulus 10 equals zero (luhn algorithm)
    return true; // if so return true, card is valid
  } else {
    return false; // if not return false, card is invalid
  }  
}

const findInvalidCards = (cards) => {
  let invalidCards = [];
  for (card of cards) {
    if (!validateCred(card)) {
    	invalidCards.push(card);
    }  
  }
  console.log(invalidCards);
  return invalidCards;
}
3 Likes

Thanks for sharing @janneslohmeijer!

Learned new things from your code, that .slice can be used without arguments and .reduce.
Very helpful!

2 Likes

Did you spot this nifty trick too?

for (let k = 0; k < cards.length; k++) {
      if (validateCred(cards[k]) == true) { // this is your code, but why are you pushing valid cards to the invalid list?
      invalidCards.push(cards[k]);
    }
  }

Can be written as:

for (card of cards) { 
    if (!validateCred(card)) {
    	invalidCards.push(card);
    }  
  }
3 Likes

Yeah, I corrected it when I saw the output.
Thanks for the hint.

1 Like

Speaking of nifty tricks:

Can be written as:

return sum % 10 == 0;
1 Like

Thanks will implement it straight away :wink:

Hi everyone
I have a problem with the credit card checker project, for some reason in the findInvalidCards function it wont get in to my for loop, i could really use some help, thank:)

Hello, @doritfish.

Welcome to the forums.

You’ll need to post your code for us to be of any assistance. When you post your code, make sure you click the </> button first, then paste your code in the space indicated. That will preserve your formatting, so those wanting to help you can copy and test it themselves.

hi midlindner

thank for the replay:)
i found the problem about the for loop, i treated the condition as it was an array so i put batch.array instade i needed to write it as an object like this Object.keys(batch).length and it worked. this is my function:

let findInvalidCards = (batch) =>{
    let invalidcards=[];
    for(var counter=0;counter<Object.keys(batch).length;counter+=1)
    {
        if(validateCred(batch[counter]))
        {
            console.log("this is a valid card"); 
        }
        else{
            invalidcards.push(batch[counter]);
        }
    }
    return invalidcards;

}

but i would like to get help for another issue:
i am trying to run the credit card checker project in visual studio code and i understand from the instruction that i need to down load git and node.js so i download it. although i am not sure how to run the code? do i need to see the output in the terminal? how to link git, node and visual studio code to run togather?
i am writing node main.js in the terminal and i get this error:

`PS C:\Users\fishman\AppData\Local\Programs\Microsoft VS Code\codeacademy> node main.js
internal/modules/cjs/loader.js:638
    throw err;
    ^

Error: Cannot find module 'C:\Users\fishman\AppData\Local\Programs\Microsoft VS Code\codeacademy\main.js'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)`

thanks in advance and i hope i didnt write to much.
Dorit

Hi @doritfish,

I haven’t used objects, this is my code:

function findInvalidCards(cards) {
  let invalidCards = [];

  for (let k = 0; k < cards.length; k++) {
      if (!validateCred(cards[k])) {
      invalidCards.push(cards[k]);
    }
  }
   return invalidCards;
}

As for running the project in Visual Studio, try reading these links:
with Node.js
with TypeScript

But I personally use Sublime Text.

There was no need to use Object.keys(batch).length. batch.length would suffice. batch is an array. It’s an array whose elements are also arrays, but an array nevertheless.

Also, since you are evidently familiar with the use of let and const, you should consider changing for(var counter = 0; ...) to for (let counter = 0; ...) Using var gives the counter variable function scope which is not necessary. let gives counter block scope which is all that is needed.
Consider this simplistic example:

const nums = [[1,2,3],[4,5,6]];

const doStuff = () => {
  for (var counter = 0; counter < nums.length; counter++) {
    console.log(nums[counter][1]); //output: first line: 2 second line: 5
  }

  counter += 10;

  console.log(counter); //output: 12

  for (let counter = 0; counter < nums.length; counter++) {
    counter *= 10;   
  }
  
  console.log(counter); //what will this output?
}

doStuff();
Output:

2
5
12
12

Are you still having trouble with this issue?

hi midlindner
Yes, i managed to solve some of the problems.
about the for loop i changed the name of the variable that the method gets and now it simply works with the .length propertie.
About the running, i tried to change the terminal path by using some cmd lines. i wish there was a better way to use the terminal so i wont need to change the path every time i run a program from a different folder in my computer.
another thing that i bumped in to is that i can’t for some reason find some of my codeacademy path folders on my computer but thats not related to the credit card cheker project, maybe i should ask this question in some other topic in the forums.
any way thanks a lot for your replay.
dorit

1 Like

hi micro
thanks i used the cmd to change the path of the terminal and managed to run the function with the length propertie.
thanks a lot
dorit

Please I’m having an issue with this. I’m trying to find a way to create a function that returns the companies that give invalid card numbers(the last instruction). This is my code from the beginning:

const validateCred = (card) => {
  let newCard = card.reverse();
  //return newCard;
  for (let i = 0; i < newCard.length; i++){
    if (i % 2 != 0) {
      newCard[i] *= 2;
    if(newCard[i] > 9) {
      newCard[i] -= 9;
    }
}
  }
  let total = newCard.reduce((a,b) => a + b, 0)
   if (total % 10 == 0) {
     return true;
   } else {
     return false;
   }
  }
const findInvalidCards = (cards) =>{
  let invalidCard = [];
  for (let j = 0; j < cards.length; j++) {
    if(validateCred(cards[j]) === false) {
      invalidCard.push(cards[j])
      
    }
  }
  return invalidCard;
}
const idInvalidCardCompanies = (cards) => {
  let invalidCardCompanies = [];
 for (let k = 0; k < cards.length; k++){
   
  }
}
console.log(findInvalidCards(batch));

@bened03 Could you please enclose your code like this:

let myCode = true;
console.log(myCode);

Annotation%202019-10-07%20150741

I’ve been trying to. I don’t know how

Annotation%202019-10-07%20150741