Credit Card Checker Project - Running into some trouble

Project Link

Hey guys, I’m attempting to work my way through the credit card checker project here, and I’m a little bit stumped.

I was able to get the first function, validateCred working, i think.
I think I have a nesting error somewhere in my second function, because when I call it on the provided batch variable, I get a TypeError: cannot read property ‘slice’ of undefined…

code below:

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:

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

const findInvalidCards = array => {
    let invalidCards = [];
    for(let i = 0; i <= array.length; i++){
        if(!validateCred(array[i])) {
            invalidCards.push(array[i]);
        }
    }
};

const idInvalidCardCompanies = array => {
    let invalidArray = [];
    let firstDigitArray = [];
    for(let i = 0; i < array.length; i++) {
        firstDigitArray.push(array[i][0]);
    }
    for(let n = 0; n < firstDigitArray.length; n++) {
        const x = firstDigitArray[n];
        switch (x) {
            case '3': invalidArray.push('Amex (American Express)');
            break;
            case '4': invalidArray.push('Visa');
            break;
            case '5': invalidArray.push('Mastercard');
            break;
            case '6': invalidArray.push('Discover');
            break;
            default: invalidArray.push('Company Not Found');
        }
    }
    /* Before this function finishes, I need to filter the array so that duplicate entries are removed */
};```

Notice any difference in the above snippets?

1 Like

yes. yes i do.

that got me onto my next hurdle, thanks.

I’ll be back if I’m stuck here for too long :slight_smile:

1 Like

Ok so I’m still getting all sorts of problems it turns out. But I’m not getting any error messages.

The output of the below code is 1. With no other error messages or issues.

Just 1.


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:

const validateCred = card => {

    const reversed = card.slice().reverse();

    for(let i = 0; i < reversed.length; i++) {

        if(i % 2 != 0) {

            reversed[i] = 2 * (reversed[i]);

            if(reversed[i] > 9) {

                reversed[i] -= 9;

            }

        }

    }

    

    let cardSum = reversed.reduce((a, b) => a + b, 0);

    if(cardSum % 10 == 0) {

        return true;

    }   else {

        return false;

    }

};

const findInvalidCards = array => {

    let invalidCards = [];

    for(let i = 0; i < array.length; i++){

        if(validateCred(array[i]) === false) {

            invalidCards.push(array[i]);

            console.log(invalidCards[0]);

        }

    }

};

const idInvalidCardCompanies = array => {

    let invalidArray = [];

    let firstDigitArray = [];

    for(let i = 0; i < array.length; i++) {

        firstDigitArray.push(array[i][0]);

    }

    console.log(firstDigitArray[0]);

    for(let n = 0; n < firstDigitArray.length; n++) {

        const x = firstDigitArray[n];

        switch (x) {

            case '3': invalidArray.push('Amex (American Express)');

            break;

            case '4': invalidArray.push('Visa');

            break;

            case '5': invalidArray.push('Mastercard');

            break;

            case '6': invalidArray.push('Discover');

            break;

            default: invalidArray.push('Company Not Found');

        }

    }

    console.log(firstDigitArray);

    console.log(invalidArray);

    

    /* Before this function finishes, I need to filter the array so that duplicate entries are removed */

};

console.log(validateCred(valid1));

console.log(validateCred(invalid1));

console.log(findInvalidCards(batch));

console.log(idInvalidCardCompanies(batch));```

I ran your code after adding some labels to your console.log statements, so I could see what was what.

Output:

validateCred(valid1): true
validateCred(invalid1): false
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
InvalidCards[0]: [ 4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5 ]
findInvalidCards(batch): undefined
firstDigitArray[0]: 4
firstDigitArray: [ 4, 5, 3, 6, 4, 4, 5, 3, 6, 5, 3, 5, 6, 4, 4 ]
invalidArray: [ ‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’,
‘Company Not Found’ ]
idInvalidCardCompanies: undefined

Starting from the top, the first 2 items output are expected.

After that we have the same output printed 8 times. Can you see why? How could you see if each invalid card number is being added to the array rather than printing the same (first) element of the array 8 times?

Then we have undefined printed. What was the expected output?

I’ll stop here for now.

Your code with the modified console.log() statements (for reference):
const validateCred = card => {

    const reversed = card.slice().reverse();

    for(let i = 0; i < reversed.length; i++) {

        if(i % 2 != 0) {

            reversed[i] = 2 * (reversed[i]);

            if(reversed[i] > 9) {

                reversed[i] -= 9;

            }

        }

    }

    

    let cardSum = reversed.reduce((a, b) => a + b, 0);

    if(cardSum % 10 == 0) {

        return true;

    }   else {

        return false;

    }

};

const findInvalidCards = array => {

    let invalidCards = [];

    for(let i = 0; i < array.length; i++){

        if(validateCred(array[i]) === false) {

            invalidCards.push(array[i]);

            console.log('InvalidCards[0]:', invalidCards[0]);

        }

    }

};

const idInvalidCardCompanies = array => {

    let invalidArray = [];

    let firstDigitArray = [];

    for(let i = 0; i < array.length; i++) {

        firstDigitArray.push(array[i][0]);

    }

    console.log('firstDigitArray[0]:', firstDigitArray[0]);

    for(let n = 0; n < firstDigitArray.length; n++) {

        const x = firstDigitArray[n];

        switch (x) {

            case '3': invalidArray.push('Amex (American Express)');

            break;

            case '4': invalidArray.push('Visa');

            break;

            case '5': invalidArray.push('Mastercard');

            break;

            case '6': invalidArray.push('Discover');

            break;

            default: invalidArray.push('Company Not Found');

        }

    }

    console.log('firstDigitArray:', firstDigitArray);

    console.log('invalidArray:', invalidArray);

    

    /* Before this function finishes, I need to filter the array so that duplicate entries are removed */

};

console.log('validateCred(valid1):', validateCred(valid1));

console.log('validateCred(invalid1):', validateCred(invalid1));

console.log('findInvalidCards(batch):', findInvalidCards(batch));

console.log('idInvalidCardCompanies:', idInvalidCardCompanies(batch));

Thank you so much for your help.

I think I got there, but I thought I’d just toss it up here in case I missed something, or you had any more suggestions on how I could clean it up a bit nicer.

// All valid CC #s
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:

const validateCred = card => {
    const reversed = card.slice().reverse();
    for(let i = 0; i < reversed.length; i++) {
        if(i % 2 != 0) {
            reversed[i] = 2 * (reversed[i]);
            if(reversed[i] > 9) {
                reversed[i] -= 9;
            }
        }
    }
    
    let cardSum = reversed.reduce((a, b) => a + b, 0);
    return cardSum % 10 === 0;
};

const findInvalidCards = cardList => {
    let invalidCards = [];
    for(let i = 0; i < cardList.length; i++){
        if(validateCred(cardList[i]) === false) {
            invalidCards.push(cardList[i]);
        }
    }
    return invalidCards;
};

const idInvalidCardCompanies = list => {
    let invalid = findInvalidCards(list);
    let firstDigitArray = [];
    for(let i = 0; i < invalid.length; i++) {
        firstDigitArray.push(invalid[i][0]);
    }

    let cardCompanies = [];

    for(let n = 0; n < firstDigitArray.length; n++) {
        const x = firstDigitArray[n];
        switch (x) {
            case 3: cardCompanies.push('Amex (American Express)');
            case 4: cardCompanies.push('Visa');
            case 5: cardCompanies.push('Mastercard');
            case 6: cardCompanies.push('Discover');
            break
            default: cardCompanies.push('Company Not Found');
        }
        let compSet = new Set(cardCompanies);
        let companies = [...compSet];
        return companies;
    }
};
1 Like

Nice work, so far. You do have some issues here though:

When I run the following:

console.log('idInvalidCardCompanies:', idInvalidCardCompanies(batch));

I get:

idInvalidCardCompanies: [ ‘Visa’, ‘Mastercard’, ‘Discover’ ]

‘Amex (American Express)’ is noticeably missing. There are 3 elements in your returned array, but the for loop is only executing once. We can add a few console.log() statements to see what is happening:

const idInvalidCardCompanies = list => {
    let invalid = findInvalidCards(list);
    let firstDigitArray = [];
    for(let i = 0; i < invalid.length; i++) {
        firstDigitArray.push(invalid[i][0]);
    }

    let cardCompanies = [];

    for(let n = 0; n < firstDigitArray.length; n++) {
        console.log(`The for loop should run once for each element in the firstDigitArray which has ${firstDigitArray.length} elements. Does it?`) //debug print
        console.log(`for loop iteration #${n + 1}`); //debug print
        const x = firstDigitArray[n];
        switch (x) {
            case 3: cardCompanies.push('Amex (American Express)');
            case 4: cardCompanies.push('Visa');
            case 5: cardCompanies.push('Mastercard');
            case 6: cardCompanies.push('Discover');
            break
            default: cardCompanies.push('Company Not Found');
        }
        let compSet = new Set(cardCompanies);
        let companies = [...compSet];
        console.log(companies); //debug print
        return companies;
    }
};

Output:

The for loop should run once for each element in the firstDigitArray which has 8 elements. Does it?
for loop iteration #1
[ ‘Visa’, ‘Mastercard’, ‘Discover’ ]
idInvalidCardCompanies: [ ‘Visa’, ‘Mastercard’, ‘Discover’ ]

Hint:

Should the return be inside the for loop?

Even though the loop is only iterating once, how are you getting 3 elements in the returned array?

Hint:

switch...case sends control to the first matching case then executes line by line. There are no break statements following each of the first 4 cases. The first matching case is 4, so 'Visa' is pushed into the array then 'Mastercard' is pushed into the array then 'Discover' then finally a break is reached, so control is passed to the next line after the end of the switch...case block.

ok, i am grasping some of your hint, but then i seem to be not grasping something.

I added the break statements into my switch/case portion of the code, and then when I tried to move the return statement outside of the for loop, I can’t get the variable I need to be accessible in order to return.

Something silly I’m missing perhaps?

The issue there is one of scope. There are a few ways you could approach the problem. What if you declared an empty array before the for loop, pushed the card companies into it inside the loop, and then after the loop use your Set constructor to remove the duplicates, etc.?

before the loop declaration is what I was dancing around but not implementing properly. Thanks, I’m gonna go dive in on that approach!

1 Like

You were already initializing the empty array before the loop, but your method of removing duplicates was inside the loop (you only need to do that once, so it shouldn’t be in the loop).

Ok. I think I’m there. I got an array that makes sense by using console.log on the main batch.
I checked with console.log statements in a few other places, and my variables seemed to be what I think they should be, and my loop appeared to iterate the right number of times.

All that said, I’m still posting here for one last lookover, since last time I thought I was finished, it took a few steps to get here :slight_smile:

// All valid CC #s
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:

const validateCred = card => {
    const reversed = card.slice().reverse();
    for(let i = 0; i < reversed.length; i++) {
        if(i % 2 != 0) {
            reversed[i] = 2 * (reversed[i]);
            if(reversed[i] > 9) {
                reversed[i] -= 9;
            }
        }
    }
    
    let cardSum = reversed.reduce((a, b) => a + b, 0);
    return cardSum % 10 === 0;
};

const findInvalidCards = cardList => {
    let invalidCards = [];
    for(let i = 0; i < cardList.length; i++){
        if(validateCred(cardList[i]) === false) {
            invalidCards.push(cardList[i]);
        }
    }
    return invalidCards;
};

const idInvalidCardCompanies = list => {
    let invalid = findInvalidCards(list);
    let firstDigitArray = [];
    for(let i = 0; i < invalid.length; i++) {
        firstDigitArray.push(invalid[i][0]);
    }

    let cardCompanies = [];

    for(let n = 0; n < firstDigitArray.length; n++) {
        const x = firstDigitArray[n];
        switch (x) {
            case 3: cardCompanies.push('Amex (American Express)');
            //console.log(cardCompanies);
            break;
            case 4: cardCompanies.push('Visa');
            //console.log(cardCompanies);
            break;
            case 5: cardCompanies.push('Mastercard');
            //console.log(cardCompanies);
            break;
            case 6: cardCompanies.push('Discover');
            //console.log(cardCompanies);
            break;
            default: cardCompanies.push('Company Not Found');
        }
    }
    let companies = [];
    let compSet = new Set(cardCompanies);
    //console.log(compSet);
    companies = [...compSet];
    return companies;
};

console.log(idInvalidCardCompanies(batch));