Credit Card Checker - trouble looping the batch array and luhn algorithm

https://www.codecademy.com/practice/projects/credit-card-checker
I am currently doing a Credit Card Checker Project. I am having trouble looping the batch array and luhn algorithm.
the Link is above:

 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];
let invalidCred = [];
let validCred = [];

const validateCred = (num) => {
  for (let card = 0; card < batch.length ; card ++) {
    let arr = (num + '')
    .split('')
    .reverse()
    .map(x => parseInt(x));
  let lastDigit = arr.splice(0, 1)[0];
  let sum = arr.reduce((acc, val, i) => (i % 2 !== 0 ? acc + val : acc + ((val * 2) % 9) || 9), 0);
  sum += lastDigit;
  return sum % 10 === 0; 
    }
  };
console.log(validateCred());

const findInvalidCards = num => { 
  for (let card = 0; card < batch.length ; card ++) {
  validateCred ();  
  if(true) {
   return validCred.push(batch[card]);
  }
  else {
    return invalidCred.push(batch[card])
  }
}
};

const idInvalidCardCompanies = () => {
  
}

What is it you are having troubles with?

2 Likes

I am having trouble looping the array of credit card numbers.

Ok, fair enough. Thought so, I can see some issues there :wink: . The for loop is ok, problems arise with your function call and if…else statement as well as pushing the cards to their specific arrays.

First question I ask you is:
What do you need to call a function which requires input parameters?

Second question:
How do you set up a condition for an if…else statement?

Third question:
What does return do inside a function? Is this what we need?

Fourth question: You are now pushing to an array outside of the function, yet it has been stated that findInvalidCards should return a list of invalid cards.

Fifth question: Does validateCred even work? Please talk me through how it works exactly

6th question: Do you know how to proper indent your code, proper indentation aids massively towards better debugging.

Hope I helped you a bit in the right direction. Feel free to ask me specific questions.

The validateCred does not seem to work. I got the block of code online.

Maybe we should focus on that first :wink: . First lets define what validateCred has to do, what inputs does it require and what output does it need to generate?

const validateCred = batch => {
for (let card = 0; card < batch.length ; card ++) {
let arr = (batch + ‘’)
.split(’’)
.reverse()
.map(x => parseInt(x));
let lastDigit = arr.splice(0, 1)[0];
let sum = arr.reduce((acc, val, i) => (i % 2 !== 0 ? acc + val : acc + ((val * 2) % 9) || 9), 0);
sum += lastDigit;
return sum % 10 === 0;
}
console.log(validateCred(batch));
};

const findInvalidCards = batch => {
for (let card = 0; card < batch.length ; card ++) {
validateCred ();
if(ValidateCred === true) {
validCred.push();
}
else {
invalidCred.push();
}
}
};

const idInvalidCardCompanies = () => {

}

I want it to generate a true or false output. I made some corrections.

Ok validateCred is not working as it should you say.

Now lets see. What should validateCred do?

  • It takes an input of a card which is an array of numbers.
  • The array of numbers should somehow be reversed for easier analyzing.
  • Now, we have to double each uneven digit.
  • If a digit is then bigger than 9, 9 should be deducted from this number.
  • The whole array should be added up together
  • If the modulus 10 of this sum equals 0, the card is valid
  • We need to return a boolean value of true as output of the function.

Now all we have to do is turn those points into code. One step at the time. If you don’t know how, open the summary below.

Summary
const validateCred = (card) => { // function validateCred that takes an input of 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(digit) 
    if (i % 2 != 0) { // pick out the uneven numbers using modulo 2
      cardInverted[i] = cardInverted[i] * 2; // double the value of the array at each uneven index
      if (cardInverted[i] > 9) { // if the value is higher then 9
        cardInverted[i] -= 9;  // deduct it by 9
      }  
    }
  }
  let sum = cardInverted.reduce((a, b) => a + b, 0); // add all numbers of the array using reduce
  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
  }  
} 
2 Likes

Thanks for the solution. I am still having issues withe the input parameters.
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4, mystery5];

// Add your functions below:
let invalidCred = ;
let validCred = ;

const validateCred = batch => {
let cardInverted = card.slice().reverse();
for (let i=0; i < cardInverted.length; i++) {
if (i % 2 != 0) {
cardInverted[i] = cardInverted[i] * 2;
if (cardInverted[i] > 9) {
cardInverted[i] -= 9;
}
}
}
let sum = cardInverted.reduce((a, b) => a + b, 0);
if (sum % 10 == 0) {
return true;
} else {
return false;
}
console.log(validateCred());
};

Hey,

I have noticed you have changed the function to take “batch” as input parameter. That’s not how this function works. First of all it processes only 1 array not and array of arrays. After all this is the validateCred function. This function is made to check single cards for example valid1.

And then there is a huge difference between a variable and a parameter. ‘batch’ is a variable, an array of variables, each being an array.

Whilst card (as in const validateCred = card => {) inside the validateCred function is an input parameter. Upon calling a function, you pass a variable as the input like function(input); Thus to call valaidateCred you will have to pass any of the card variables.

For example:

validateCred(valid1);

Before you do that, you should first change the function back to take a card and not batch.

Hey @begees,

Any chance you can start a new topic? Will make it more easier to keep track of every ones progress to help. And please post your code using the </> button.

1 Like

2 posts were split to a new topic: [PENDING] Error in Credit Card Checker Instructions Graphic

Hello) Thank you very much for the solution, can you look pls at my code, is it correct?

I combine mine and yours and it works, look please at my first part.

// Add your functions below:
const validateCred = arrayChk => {
for (let i = 13; i >= 0; i-=2) {
arrayChk[i] = arrayChk[i] *= 2;
if (arrayChk[i] > 9) { // if the value is higher then 9
arrayChk[i] -= 9; // deduct it by 9
}
let sum = arrayChk.reduce((a, b) => a + b, 0); // add all numbers of the array using reduce
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
}
}
};
console.log(validateCred(invalid5));

1 Like

If it works, it works ;).

Well done, I like how you iterate backwards by skipping 1 spot :wink: .
You combined my code with yours, were you struggling with the 2nd part?
Do you understand what is happening in my code?

1 Like

Thank you, it’s nice to hear) The second part I will start to do today. I have a couple of questions:

  1. Why did you use slice in this code?

let cardInverted = card.slice (). reverse (); // make a copy of the card and invert the array right to left.

Why do we need the slice method here?

I also had difficulty in understanding when some numbers were greater than 9 and I had to subtract 9, I was afraid that if I write (code example below), then I will subtract 9 from all the numbers contained in the array.

Why is 9 subtracted only from those numbers that are greater than 9?

if (arrayChk [i]> 9) {// if the value is higher then 9
arrayChk [i] - = 9; // deduct it by 9
}

Thank you very much for your help!:slight_smile:

Hey,

I used the slice method because you are not allowed to change the original array, and I reversed it to check the numbers from left to right instead or right to left. I could have iterated backwards but I somehow didn’t think of that :stuck_out_tongue: .

Concerning the subtraction. This has to do with how the Luhn algorythm works:

source Wikipedia:

From the rightmost digit (excluding the check digit) and moving left, double the value of every second digit. The check digit is neither doubled nor included in this calculation; the first digit doubled is the digit located immediately left of the check digit.

If the result of this doubling operation is greater than 9 (e.g., 8 × 2 = 16), then add the digits of the result (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9) or, alternatively, the same final result can be found by subtracting 9 from that result (e.g., 16: 16 − 9 = 7, 18: 18 − 9 = 9).

1 Like

Hi) Thanks for your answer) I understood about the Luhn algorithm, but my doubts were about realization, how we selectively deduct only numbers that are greater than 9 in the code?)

I mean in this code (below in this post) look like we deduct 9 from all the numbers in the array, not only from numbers which are greater than 9)

arrayChk [i] - = 9

The above code has an if statement, only when the value is higher for that particular index (i), it subtracts 9.

1 Like

Thanks for the answer) I thought I know everything about if)))

Sorry and the last question) In the last section of this task, Codecademy solution looks like this (code below). What it means === -1? Why not !==4 and so on?)

function idInvalidCardCompanies(invalidBatch) {
const companies = ;
for (let i = 0; i < invalidBatch.length; i++) {
switch (invalidBatch[i][0]) {
case 3:
if (companies.indexOf(‘Amex’) === -1) {
companies.push(‘Amex’);
}
break
case 4:
if (companies.indexOf(‘Visa’) === -1) {
companies.push(‘Visa’);
}
break
case 5:
if (companies.indexOf(‘Mastercard’) === -1) {
companies.push(‘Mastercard’);
}
break
case 6:
if (companies.indexOf(‘Discover’) === -1) {
companies.push(‘Discover’);
}
break
default:
console.log(‘Company not found’);
}
}
return companies;
}