Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialamirbizimana
9,639 PointsIssue with my conditional statements
Im trying to write an fake ATM program machine program that allow 4 or 6 digits pin codes strictly, not 5 not >6 or <4 strictly 4 and 6, Such as the following conditions scenarios apply validatePIN("1234") === true validatePIN("12345") === false validatePIN("a234") === false
function validatePIN (pin){
var pin = "";
if (pin.length !=4 || pin.length !=6) {
return false;
}
else {
return true;
}
}
when i test the function the program returns "false" correctly as it should for scenarios with pins that are not 4 or 6 digits exactly. However it keeps on returning false for any other scenarios that are still within the 4 or 6 digit limit like ("1234"), ("123456") or ("1111") etc... It seems as though my second conditional statement is not considered at all regardless of what condition if pass through.
Any feedback appreciated.
4 Answers
andren
28,558 PointsThe first line of your program sets the pin variable to an empty string, so everything you pass into the function will be ignored. But that is not actually the main issue with your code.
The main issue occurs because you use the || (OR) operator within the if statement. The OR operator will look at the conditions and return true as long as one of the conditions evaluates to true. If you enter 4 then the condition that the number is not 6 is true, if you enter 6 then the condition that the number is not 4 is true.
The reason all numbers fail is that it's impossible for a number to be both 4 and 6 at the same time, which is technically what needs to happen for the if statement not to run.
You can fix this issue by using the && (AND) operator instead. That looks at both conditions and only returns true if both of them are true. So unless the number is not 4 and not 6 it won't run, which is of curse your intended behavior.
Edit:
Also your code currently only deals with the length of the pin, it does nothing to check whether the pin entirely consists of numbers, I assume you are aware of that and intend to work on that yourself once this issue has been resolved. But if you need help with that too then I can provide a solution for it.
Benjamin Larson
34,055 PointsThere's a couple issues with your code preventing this. The first one is that, within the function you are declaring the var pin and assigning it an empty string. This is effectively overwriting any argument you pass into it, so it will always evaluate an empty string, and therefore, always be false.
The second problem is the logic in your conditional if statement. I understand the logic you are using but it's not the way it's actually being evaluated. You were right that it never seems to evaluate the second half of the expression. The way a conditional || (OR) statement works, is that it looks at each condition and if either of them evaluates to true, then the conclusion is true. Conditional OR statements also short-circuit, meaning that if the first case is TRUE, then there's no point in checking the second case, because it will evaluate to TRUE in either case.
In your case: IF EITHER (pin.length != 4) OR (pin.length ! =6) is TRUE, then the result is TRUE.
Think carefully about your code now. If it receives any length other than 4, the first half will evaluate to TRUE and it won't even check if pin.length !=6.
It's also not easy to spot, because when the IF condition evaluates to TRUE, you then have it return FALSE. This is valid and sometimes useful, but often confusing.
Here is one way you might solve this:
function validatePIN(pin) {
if (pin.length === 4 || pin.length === 6) {
return true;
} else {
return false;
}
}
amirbizimana
9,639 PointsThanks for the feedback guys. Benjamin Larson that explanation makes a lot of sense. I was overthinking because initially i thought about starting the condition with if (pin.length === 4 || pin.length === 6)
and have it return true but once i noticed the program didn't seem to consider the second conditional statement i figured id start with something false so that the program could keep looking through the conditional until it returned true.
andren
Taking into consideration both of you guys feedback this is what i came with to finalize it and also address the fact that the program needs to check whether the pin entirely consists of numbers
However when i type a pin that contains characters other than digits like ('a234') or ('.234') it returns true instead of false for these scenarios. Any thoughts ?
function validatePIN(pin){
if (pin.length === 4 || pin.length === 6) {
return true;
}
else if( isNaN(pin)===true) {
return false;
}
else {
return false;
}
}
andren
28,558 PointsAmir Bizimana
If
statements are evaluated from top to bottom, and else if
and else
statements only run if the first if
statement evaluates to false.
Since "a234" does have a length of 4 the first if
statement will run, which means that the else if
is not executed at all. And even if that was not the case, once you return a value the method stops executing, so even if you didn't use if/else if statements the method would stop once the if
statement ran anyway.
The solution to that issue is pretty simple, move the isNaN
check to the top. Like this
function validatePIN(pin){
if(isNaN(pin)) {
return false;
}
else if (pin.length === 4 || pin.length === 6) {
return true;
}
else {
return false;
}
}
Also since isNaN
returns true
of false
on its own you don't need to compare it to true
, that is redundant. So I removed that comparison.
Edit:
You could also make the if
statement more compact by combining the if
and else if
into one check like this:
function validatePIN(pin){
if ((pin.length === 4 || pin.length === 6) && !isNaN(pin)) {
return true;
}
else {
return false;
}
}
That is a bit more complicated to read, but it essentially says "if pin
is 4 or 6 and it's not not a number then return true". I had to wrap the first two conditionals in parentheses to make sure they are evaluated first.
Benjamin Larson
34,055 PointsI do most of my programming in C#, Java and PHP so I'll have to think about this one, but even with andren's improved function, there are still exceptions such as:
validatePIN("1.23");
Are there any other JavaScript functions that could check this without using Regular Expressions? +1 to strongly typed languages that don't have this problem haha
andren
28,558 PointsBenjamin Larson
Ops, you are right. I forgot to use .
when testing the code. The simplest (but somewhat lazy and hacky) way to solve that issue would just be to explicitly check for the dot like this:
function validatePIN(pin){
if ((pin.length === 4 || pin.length === 6) && !isNaN(pin) && !pin.includes(".")) {
return true;
}
else {
return false;
}
}
That works, but it's admittedly not very elegant. I spend a decent amount of time coding in JavaScript (though I prefer to use TypeScript whenever i can get away with it) but I can't say I deal with number input validation all that often, so I don't have any good elegant solution I can think of at the top of my head.
I also tend to prefer strongly typed languages. Auto conversions might be nice for people just starting out with programming but they become a pain to deal with later.
Benjamin Larson
34,055 PointsYeah, I tried a different way, which requires the input be entered as an integer and not a string.
function validatePIN(pin){
if (Number.isInteger(pin) && (pin.toString().length === 4 || pin.toString().length === 6)) {
return true;
}
else {
return false;
}
}
Searching for the "." is better than mine because Number.isInteger() isn't supported in older versions of IE. There's probably validation packages out there that do this much better and if you're really ambitious Amir, you can learn Regular Expressions to have a lot more control in these situations.
Sam Donald
36,305 PointsAmir Bizimana - Benjamin Larson - andren
Use RegExp
function validatePIN(pin)
{
var expression = new RegExp(/^\d{4}$|^\d{6}$/);
return expression.test(pin);
}
- The regular expression
/^\d{4}$|^\d{6}&/
will only match a pin with exactly 4 or 6 digits. - The
.test()
method takespin
and evaluates it against our expression. Returningtrue
orfalse
See
amirbizimana
9,639 PointsIm gonna get some learning done on those. Thanks for posting the MDN resources !
amirbizimana
9,639 PointsThanks again for the feedback andren and Benjamin Larson ! Guess i need to review the rules surrounding conditional statements. I've made a slight modification to the to the first conditional and added a parseInt() method to the pin because it was still returning true for (".234"). I realized that with (".234") or ("1.23") the isNaN() would evaluate it to false because it seems to overlook the dot and focus on the numbers instead. By strictly parsing the pin for integers with the parseInt() the program will recognize that there is a little intruder in strings like (".234") or ("1.23").
Thank you for the help !
function validatePIN(pin){
if( isNaN(parseInt(pin))) {
return false;
}
else if (pin.length === 4 || pin.length === 6) {
return true;
}
else {
return false;
}
}
Benjamin Larson
34,055 PointsI hate to be "that guy", but I can technically break that one with:
validatePIN("1234.0")
Sorry...lol
Benjamin Larson
34,055 PointsBenjamin Larson
34,055 PointsBeat me too it, I should refresh my old browser tabs before answering questions haha. But good example that there's always more than one way to solve a problem.
andren
28,558 Pointsandren
28,558 PointsDon't worry, I've certainly made my share of lengthy answers that ends up being posted a while after the question was answered as well .
And yeah there definitively are many varied ways of solving the same issue. That's part of the reason why I personally don't mind it when multiple people end up answering the same question. Different people often come up with slightly different solutions, and that can be helpful and educational on it's own.