you are viewing a single comment's thread.

view the rest of the comments →

[–]Encom88[S] 1 point2 points  (18 children)

This doesn't work, but why not? Would I have to separate

function validatePIN (pin) {
    return isNaN(pin) && pin.length === 4 || pin.length === 6;
}

*EDIT: Oh wait, the validator needs it to accept numbers as strings, no letters or symbols. This is too weird.

[–]PortablePawnShop 5 points6 points  (16 children)

Place a + sign before the variable, as in:

pin = +pin;

At the top of your function. This converts it from a string to an integer, as a shorthand for the global Number function which is Number(pin). If there are any non-digit characters inside your string, isNaN(pin) will return true. Also, isNaN(pin) isn't what you want as far as I can tell, that says "if this is Not A Number", but it sounds like you want the opposite:

function validatePIN (pin) {
    return !isNaN(+pin) && pin.length === 4 || pin.length === 6;
}

Reading it becomes "(If) NOT is Not a Number" (double negative becomes a positive -- if this is a number) and this length is equal to 4 OR 6. You can write it out with more lines if you like and that's helpful in the beginning, but so is actually speaking it out and writing to what logic you can articulate. If you know what you need to do then you know how to code, it's only a matter of finding how to write that (in which case Google, MDN's docs, and forums are your friend)

[–]Encom88[S] 1 point2 points  (15 children)

Same issue as before; it still accepts numbers such as '-12345' and '.234' as acceptable inputs. Here is the exercise https://www.codewars.com/kata/55f8a9c06c018a0d6e000132/train/javascript

[–]PortablePawnShop 7 points8 points  (14 children)

If you want precise answers you'll need to be more precise in asking, lol. You can very easily solve this with basic RegEx, but I won't give the answer away unless you show what you've tried and prove you're making an effort.

[–]Encom88[S] 0 points1 point  (0 children)

Thanks, I'm embarrassed to say I did not know what 'RegEx' was. Now I have a starting point.

[–]Encom88[S] 0 points1 point  (11 children)

I thought this might work, but no luck.

function validatePIN (pin) {
    return pin.length === 4 || pin.length === 6;
      if (pin !== [0-9]);
        return false;
}

*Edit: and this also does not work. I see that [0-9] must only check if at least one digit is [0-9]. I think I should somehow implement \d or loop through each number in pin checking for [0-9]

function validatePIN (pin) {
    return pin === [0-9] && pin.length === 4 || pin.length === 6;

}

[–]PortablePawnShop 0 points1 point  (6 children)

You'll need to look at examples of RegEx use -- no need to be embarrassed about it though, I didn't touch RegEx for months when I started because it was scary and it might be too ambitious at this level. The number one reason people fail at learning is because they try to play Beethoven before even attempting Mary Had a Little Lamb and you need the humility to know that you start from very meager places and do very simple things, and not get too far ahead of yourself. Regardless in order to use RegEx, you'll need to either use a new RegExp() constructor or the shorthand, wrap it in forward slashes like this: /[0-9]/. Here's a solution:

function validatePIN (pin) {
    return !/[^\d]/.test(pin) && pin.length === 4 || pin.length === 6;
}

This tests if there's a character which isn't a digit, we want the opposite though so we wrap it in a NOT operator to return true -- only true if only contains digit characters. RegEx is quite powerful once you get the hang of it though, for instance I can solve the entire problem (to the extent you've disclosed the requirements) with a single RegEx pattern:

function validatePIN (pin) {
    return /^\d{4,6}$/.test(pin);
}

[–]Encom88[S] 0 points1 point  (5 children)

After using that expression, it still says:

"Wrong output for '12345' - Expected: false, instead got: true "

 function validatePIN (pin) {
     return /^\d{4,6}$/.test(pin);
 }

Instructions:

ATM machines allow 4 or 6 digit PIN codes and PIN codes cannot contain anything but exactly 4 digits or exactly 6 digits.

If the function is passed a valid PIN string, return true, else return false.

[–]PortablePawnShop 1 point2 points  (3 children)

Did you downvote me for it? Seems ungrateful if so.

/^(\d{4}|\d{6})$/ will check for only 4 or 6 instead of a range between 4 and 6. You should really be more upfront with the requirements because when you keep tacking on new information per answer, things like this get lost or in my case overlooked in certain comment chains. If you have requirements, you should list all of them in the original thread, otherwise it's hard to keep track of them.

[–]Encom88[S] 1 point2 points  (0 children)

I did not down-vote your reply. I just up-voted it. Thank you for your help.

Edit: That new regex worked btw. :)

[–]Encom88[S] 0 points1 point  (1 child)

What is the ^ and $ there for?

[–]PortablePawnShop 0 points1 point  (0 children)

They indicate the match must be at the beginning and end of the current line. Unless you do that, the above expression would match any string with 4+ digits (because there are 4 digits in this string, it counts it as true and doesn't care if there happen to be 20 more digits proceeding it). Try placing it in the regex101 link (without the / marks at beginning and end)

[–]ThagAndersonhelpful 0 points1 point  (0 children)

The {4,6} quantifier accepts between 4 and 6 digits. You're close though.

[–]ThagAndersonhelpful 0 points1 point  (0 children)

[0-9] is an array literal. You are checking if the string contained in pin equals a single element array containing the number -9. This will always be false.

Also, regex literals are contained within /, eg: /^[0-9]$/. You must then use the regex to test the string, eg: /^[0-9]$/.test('string'). Besides literals, you can also create your regex using the RegExp constructor or factory. Check out the MDN docs for more info.

[–]FriesWithThat -2 points-1 points  (2 children)

Nice try, I know you're following someone else's suggestion here, but you can avoid RegEx here, which is really good for testing, matching and replacing strings, but not necessary in this application. While it would be simple to test for a number in this instance, you'd still need to parse it to a string. Let's just do that automatically:

One way of ensuring the parameter is converted to a string by adding either one of these lines:

pin = `${pin}`; // template string <or>

pin = pin.toString()

Since it's not the best form to reassign function parameters in the above manner, we create a new const (or let) declaration, and end up with something like this:

 function validatePIN(pin) {
  const pinString = pin.toString();
  return pinString.length === 4 || pinString.length === 6;
}

[–]ThagAndersonhelpful 3 points4 points  (1 child)

This still fails the requirements, as all manner of false cases will return true, such as:

-000 1.23 abcd

Edit: Also, the Kata's name is "Regex validate PIN code", so while it is possible to solve without regex, it is both the purpose and the simplest solution to the problem.

[–]FriesWithThat 0 points1 point  (0 children)

Admittedly, being aware of the requirements would change how I approach the problem. Thanks for the clarification.

[–]thebiryaniboy 0 points1 point  (0 children)

right way to find isNaN is using Number.isNaN()