So I had this bit of code in an if statement as follows
if (!inTime || !moment(inTime).format('m') % 15 === 0) {
doSomething();
}
The inTime getting passed in was 2018-10-11T20:00:25Z. for some reason that condition was met and the code in the if block was being called. After some tooling around I found two fixes for the issue as follows
if (!inTime || !(moment(inTime).format('m') % 15 === 0)) {
doSomething();
}
*note the parens after the bang and after the 0
or I could do this
if (!inTime || !moment(inTime).minute() % 15 === 0) {
doSomething();
}
I was curious to know if anyone knows why this happens?
The expression
!moment(inTime).format('m') % 15 === 0
is interpreted as if it were written
((!moment(inTime).format('m')) % 15) === 0
So its evaluation proceeds as
moment(inTime).format('m') gives the string "0"
!moment(inTime).format('m') gives boolean false, because "0" is truthy
((!moment(inTime).format('m')) % 15) gives the number 0, after false is converted to a number (0) and the modulus is computed
((!moment(inTime).format('m')) % 15) === 0 gives true
tl;dr the ! binds very tightly.
Since you've got an ISO date string, it might be simpler to just use the native Date API:
if (!inTime || new Date(inTime).getMinutes() % 15 !== 0)
Related
I am doing an exercise, the problem is that my if/else structure does not work properly and I do not know why.
Here is the exercise statement and my code
Your task is to write a function, fizzBuzz, that accepts a number and returns a string:
'fizz' if the number is divisible by 3;
'buzz' if the number is divisible by 5;
'fizzbuzz' if the number is divisible by both 3 and 5.
'{number}' if the number doesn't fulfil any of the above conditions.
function fizzBuzz(number) {
if (number % 3 === 0) {
return "fizz"
};
if (number % 5 === 0) {
return "buzz"
};
if (number % 3 === 0 && number % 5 === 0) {
return "fizzbuz"
};
else return number
}
Try a little mental debugging. Look at your code and run different values through it in your mind:
What happens if you run the value 6 through it?
What happens if you run the value 10 through it?
What happens if you run the value 15 through it?
Ask yourself, "How could I fix this?" (hint: order of operations is important).
Something like this would do what you expect:
function fizzBuzz(n) {
const fizz = n % 3 ? '' : 'fizz' ;
const buzz = n % 5 ? '' : 'buzz' ;
return !fizz && !buzz ? '{number}' : `${fizz}${buzz}` ;
}
or this:
function fizzBuzz( n ) {
let s;
if ( n % 3 === 0 ) {
s = 'fizz' ;
if ( n % 5 === 0 ) {
s = 'fizzbuzz' ;
}
} else if ( n % 5 == 0 ) {
s = 'buzz' ;
} else {
s = '{number}' ;
}
return s;
}
This does [at most] 2 divisions and 2 comparisions.
The former does 2 divisions and 3-4 comparisons, so it is nominally less efficient.
But I know which version I'd rather look at.
The problem is, if a number is divisible by 5 and 3 (ex 15) "fizz" would only be returned (as a factor of 3) because every block {...} terminates the function with a return (this technique is called a "short-circuit", which isn't a bad practice). So you need to put the 5 and 3 condition first. Also that condition had an undefined variable called solution so that would've been the first error. One minor thing is that each block {...} was suffixed with a semi-colon: ; which is just bad formatting but it doesn't affect functionality.
function fB(number) {
if (number % 3 === 0 && number % 5 === 0) {
return "fizzbizz";
}
if (number % 3 === 0) {
return "fizz";
}
if (number % 5 === 0) {
return "bizz";
}
return number;
}
console.log(fB(15));
console.log(fB(575));
console.log(fB(49));
console.log(fB(51));
console.log(fB(80));
console.log(fB(375));
console.log(fB(99));
console.log(fB(Infinity));
I got stuck on this exercise. I don't understand why they need to have the first condition. Can I ignore that part?
The exercise is from https://www.w3resource.com/javascript-exercises/javascript-basic-exercise-46.php:
Write a JavaScript program to check two given non-negative integers that whether one of the number (not both) is multiple of 7 or 11.
function valCheck(a, b) {
if (!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
} else
return false;
}
console.log(valCheck(14, 21));
console.log(valCheck(14, 20));
console.log(valCheck(16, 20));
TL;DR – No, it's not redundant!
Write a JavaScript program to check whether exactly one of the two given non-negative integer numbers is a multiple of 7 or 11.
To explain why it's not redundant, let's break this solution function down.
function valCheck(a, b) {
if (!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
} else
return false;
}
First Conditional
The first condition is !((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0)). The x % n == 0 expressions are checking whether the given x is divisible by (a multiple of) either 7 or 11, but the expression is written in an overly verbose way that makes it a little difficult to understand.
Using De Morgan's law, we can rewrite it:
!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))
⇔
!(a % 7 == 0 || a % 11 == 0) || !(b % 7 == 0 || b % 11 == 0)
⇔
(a % 7 != 0 && a % 11 != 0) || (b % 7 != 0 && b % 11 != 0)
Now, we can tell that this condition is checking for the case where either a or b isn't divisible by 7 nor 11.
When this condition is true, we return the result of a second condition. If it is false, then we know neither input is a multiple of 7 or 11, so we return false outright.
Second Conditional
The second condition is:
(a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0)
This one is much less opaque than the first, and checks whether any of the 4 sub-conditions are true (the parenthesis are irrelevant here, since they're all "or" || operators).
Since we already know from the first condition that at least one of the inputs isn't a multiple of 7 or 11, we can now simply return whether at least of the inputs is. Put another way, if we know that this second condition is true, then we can be certain that exactly one of the numbers is a multiple of 7 or 11.
Are the Conditions Redundant?
So to answer your question, no, the first conditional isn't redundant, since it checks for whether at least one of the inputs isn't a multiple or 7 or 11. We need both of the conditional expressions to properly check that exactly one of the inputs is a proper multiple or 7 or 11.
If the "but not both" clause wasn't there, then we could use just the second conditional expression, but since it is, we need both pieces of information.
Wanted to note, I lied a little in saying we need both expressions, since it is indeed possible to solve this exercise with a single expression!
function valCheck(a, b) {
return (a % 7 == 0 || a % 11 == 0) != (b % 7 == 0 || b % 11 == 0);
}
console.log(valCheck(14, 21)); // false
console.log(valCheck(14, 20)); // true
console.log(valCheck(16, 20)); // false
I'll leave it to the reader to figure out why this works!
There are many repeating functions, let's refactor for clarity:
function isMultipleOf7Or11(num) {
return num % 7 == 0 || num % 11 == 0;
}
function valCheck(a, b) {
var isAVarMultiple = isMultipleOf7Or11(a);
var isBVarMultiple = isMultipleOf7Or11(b);
if(!(isAVarMultiple && isBVarMultiple) {
return isAVarMultiple || isBVarMultiple;
else
return false;
}
}
Now to simplify the condition:
!(isAVarMultiple && isBVarMultiple) is also equal to !isAVarMultiple || !isBVarMultiple according to De Morgan's negation of a conjuction, which returns true if at least one of them is not a multiple of 7 or 11
and in the return value the condition isAVarMultiple || isBVarMultiple returns true if at least one of them is a multiple of 7 or 11
We can conclude that it is a XOR operation on two values, which would return true only if one and only one of the variables is a multiple of 7 or 11
Outputs:
console.log(valCheck(14, 21));
returns false
console.log(valCheck(14, 20));
returns true
console.log(valCheck(16, 20));
returns false
I recommend you look at the code by the debugger, not for this example only, but when you will be stuck in difficult situations, you can split your code in a small and readable pieces and see what is happening in there.
For example this can be transformed to this
Not Sure If I can make this more readable :)
function valCheck (a, b) {
debugger;
const canADividedTo7 = a % 7 == 0;
const canADividedTo11 = a % 11 == 0;
const canADividedTo7Or11 = canADividedTo7 || canADividedTo11;
const canBDividedTo7 = b % 7 == 0;
const canBDividedTo11 = b % 11 == 0;
const canBDividedTo7Or11 = canBDividedTo7 || canBDividedTo11;
// true when both both side of expression are true
const canAAndBDividedTo7Or11 = canADividedTo7Or11 && canBDividedTo7Or11;
// true when at least one of the expression is true
const canAOrBDividedTo7Or11 = canADividedTo7Or11 || canBDividedTo7Or11;
//
if (!canAAndBDividedTo7Or11) {
return canAOrBDividedTo7Or11;
} else {
return false;
}
}
console.log(valCheck(14, 21));
console.log(valCheck(14, 20));
console.log(valCheck(16, 20));
Who would write anything that inane and complicated?
Let's take this mess:
function valCheck(a, b) {
if (!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
} else
return false;
}
and refactor it into something readable:
function valChec( a, b ) {
const aIsDivisible = a % 7 === 0 || a % 11 === 0 ;
const bIsDivisible = b % 7 === 0 || b % 11 === 0 ;
return aIsDivisible ? !bIsDivisible : bIsDivisible;
}
You could even make it a one-liner with a ternary expression (at the expense of a few more division ops... but given the original code, that's not an issue):
const isMagic = x => x % 7 === 0 || x % 11 === 0;
const valCheck = (a,b) => isMagic(a) ? !isMagic(b) : isMagic(b);
Yes, you're right in finding the answer to that question redundant; also, I believe the ! is incorrect and makes the code always return false.
A more reasonable solution to the problem would be to just return the boolean expression:
function valCheck(a, b) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
}
Alternatively, if you really wanted to use an if/else construct, it would be better to just return true in the first case:
function valCheck(a, b) {
if ((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))
return true;
else
return false;
}
Hope this helps with your understanding of JavaScript! But as suggested in the comments, you might want to learn JavaScript from other sources.
I'm starting to learn javascript for front-end programming, being python my first language to learn completely.
So I'm trying to solve a while loop excersise that console-logs every number from 50-300 that is divisble by 5 and 3.
So in python i would do this:
i = 50
while i < 301:
if i % 5 == i % 3 == 0:
print(i)
i += 1
And works flawlessly. I know you could use and and operator but the whole point of this question is to avoid using it.
So I try the same thing in javascript
var i = 50;
while (i < 301){
if (i % 5 === i % 3 === 0){
console.log(i);
}
i ++;
}
And somehow that wont work. However, with an && operator it does. Are double equalities in javascript not allowed? If they are, what am I missing?
It's allowed, and it does exactly what you told it to do -- it's just that that's not the same as what you want it to do. i % 5 === i % 3 === 0 is the same as (i % 5 === i % 3) === 0 (because === is left-associative). (i % 5 === i % 3) evaluates to either true or false depending on the value of i, and true === 0 and false === 0 are both false, so the condition will always be false.
I attached an example with two if conditions. The first if condition works as expected. The second if condition returns 11, but why? I know that the second if condition is wrong, but I would like to understand why Javascript returns in that case 11.
function exception(number) {
// if(number === 10 || number === 11) { // Working as expected
if(number === 10 || 11) { // Why 11?
console.log(number);
}
}
function loop(f) {
for (i = 0; i <= 100; i++) {
f(i);
}
}
loop(exception);
from this question.
(expr1 || expr2)
"Returns expr1 if it can be converted to true; otherwise, returns
expr2."
source
So when expr1 is (or evaluates to) one of these 0,"",false,null,undefined,NaN, then expr2 is returned, otherwise expr1 is returned
Some Information about what you where trying to achieve:
number === 10 || number === 11 is the same as (number === 10) || (number === 11)
number === 10 || 11 is the same as (number === 10) || (11) it does not compare 11 to number here
Now let's have a closer look atnumber === 10 || 11 :
number === 10 will be true if number is of type number and equal to 10
if the first was false, it will evaluate the boolean value of the next statement: 11 (wich is accepted as true, for beeing a number not equal to 0)
because Boolean(11) is true (try on your console)
so even if first condition is not true (if the number is not 10), then second condition will be true always
I have the following rather verbose conditional, I'm trying to wrap my head around a simpler version but I'm not getting anywhere.
if( agent % $.settings.gridSize === 0 && value % $.settings.gridSize == 1 ){
// Dud
}else if(agent % $.settings.gridSize == 1 && value % $.settings.gridSize === 0){
// Dud
}else{
freeCells.push(value);
}
Is there a way I can achieve the same condition with a single if statement, rather than using the throw-away if else?
Something like:
if(!(a && b) && !(x && y)){
// Do stuff
}
Yes, it's possible and you've (almost) answered your question yourself.
You can do the following:
var gS = $.settings.gridSize;
if(!(agent % gS === 0 && value % gS == 1) && !(agent % gS == 1 && value % gS === 0)) {
freeCells.push(value);
}
Depending on the possible values of $.settings.gridSize etc., it's possible that what you are looking for is:
if (agent % $.settings.gridSize !== value % $.settings.gridSize) {
// Dud
} else {
which also makes the semantics clearer: the modulo involving agent should be "different" (in the 0/1 sense) from the module involving value.
if (
agent % $.settings.gridSize > 1
||
(agent + value) % $.settings.gridSize !== 1
) {
freeCells.push(value);
}
I think it's pretty self-explaining.
Edit
Seems like it isn't that self-explaining actually.
I made a few assumptions for the transformation.
// Dud means to do nothing.
$.settings.gridSize is a positive integer, henceforth referred to as gridSize.
agent and value are non-negative integers.
For a value not to be pushed agent % gridSize has to be either 0 or 1. Since there are no negative numbers or fractional parts involved this means the same as agent % gridSize <= 1. So if the remainder is greater than 1 then value gets pushed.
Otherwise agent % gridSize is either 0 or 1. And for the value not to be pushed value % gridSize has to take on the respective other value. In total this would mean that (agent + value) % gridSize === 1. So if it's not 1 then value gets pushed.