Google Sheet double TRUE giving a FALSE - excel

I got a weird case of 2 TRUE giving a FALSE.
I got this formula (I reduced it to only have the case that interest me for debugging purpose.:
=ARRAYFORMULA(
IF(ROW(JS7:JS)=7,JR7+1,
SWITCH($F7:$F,
"M",1,
"D",2,
"W",3,
"B",IF(AND(JS$7 >= 'A 2021'!$E7:$E,mod(('A 2021'!$E7:$E-JS$7),14)=0),$D7:$D,4),
"A",5,
"O",6,
0)
)
)
Basically this formula check if the row is the 7th, if yes, add 1 to the previous date to get the next day (this part is fine), else it goes into the Switch to return a value (0 to 6) based on other columns (in my case it is the "B" and should return 4).
This part in the formula return a FALSE:
AND(JS$7 >= 'A 2021'!$E7:$E,mod(('A 2021'!$E7:$E-JS$7),14)=0
yet JS$7 >= 'A 2021'!$E7:$E (checking if we are past the current date) is TRUE and mod(('A 2021'!$E7:$E-JS$7),14)=0 (using modulo to check if we are every 2 weeks) is also TRUE
I tried to replace the returned value of 4 by JS$7 >= 'A 2021'!$E7:$E to see its value and it was TRUE, same thing for the mod(). But when I tried with the AND(), it returned FALSE, yet, that AND() is made of previous parts that both returned TRUE.
Am I doing an obvious mistake here or something is fishy?

AND is not supported under ARRAYFORMULA. try:
=ARRAYFORMULA(
IF(ROW(JS7:JS)=7,JR7+1,
SWITCH($F7:$F,
"M",1,
"D",2,
"W",3,
"B",IF((JS$7 >= 'A 2021'!$E7:$E)*(MOD(('A 2021'!$E7:$E-JS$7),14)=0),$D7:$D,4),
"A",5,
"O",6,0)))

Related

Excel returning a False response

=IF(B12<>"",(IF(U12="Subscription","Subscribe",IF(U12="T.E.H.","Subscribe",IF(U12="ESA","Subscribe",IF(U12="Perpetual","Buy",IF(U12=" "," ")))))))
I get a "False" value in the cell with this formula in it when the value in U12 is not one of the options and I want to get a blank
Appreciate any help
Thanks
Change this: IF(U12=" ", " ") to this: IF(U12=" ", " ", ""). Here's a demo in Google Sheets, but the formulas are the same.
https://docs.google.com/spreadsheets/d/10iFqq0PNt9VhGKMPLCxsI1df0x4nDSxCaCGSdEEktO8/edit#gid=0
However, I don't think this is exactly right. For one thing, it looks like this clause:
IF(U12=" ", " ")
is only there to try to generate the blank you are looking for. If that's the case, then change it to:
IF(U12=" ", " ", "")
However, I think I would probably use some array constants, something like this:
=IF(B12<>"", CHOOSE(SUM(--(U12={"Subscription","T.E.H","ESA"})) + IF(U12="Perpetual", 2) +1, "", "Subscribe", "Buy"))
To break this down a little, let me reformat so it's easier to see:
=IF(
B12 <> "",
CHOOSE(
SUM(--(U12={"Subscription","T.E.H","ESA"})) +
IF(U12="Perpetual", 2) + 1
"", "Subscribe", "Buy"
)
)
I'm going to use CHOOSE, which takes an index number N and a list of choices, and it returns the Nth element in the choice list. To generate the index, I'm going to use a couple of techniques. First look at this:
U12 = {"Subscription", "T.E.H", "ESA"})
This is going to test U12 against all of the choices in the list, and return an array of TRUE/FALSE values. If U12 matches any of the elements in the array constant, then one of those values will be TRUE. We use -- to coerce that array from TRUE/FALSE to 0/1, and then we use SUM to get the array into a single value. It will either be 0 if U12 doesn't match any of the options, or 1 if it does.
Then I'm going to use a standard IF to check if U12 = Perpetual, and return 2 if it does. Adding that result to the previous sum will give us a final number that is either 0, 1 or 2.
CHOOSE is 1 indexed, meaning that it expects the index to be 1 or greater, so we add 1 to the number we just generated and pass it to CHOOSE along with a list of options.
The advantage here is that if the Subscribe options change you can just change the list, instead of having to alter a bunch of nested IFs. Also, if you need to support multiple buy options, you can do it with a similar construction:
SUM(--(U12 = {"Subscription", "T.E.H", "ESA"})) +
IF(SUM(--(U12 = {"Perpetual", "Buy Now"})), 2) + 1
and if you needed to add return values just keep extending:
CHOOSE(
SUM(--(U12 = {"Subscription", "T.E.H", "ESA"})) +
IF(SUM(--(U12 = {"Perpetual", "Buy Now"})), 2) +
IF(SUM(--(U12 = {"Release", "Dropping"})), 3) + 1,
"", "Subscribe", "Buy", "Sell"
)
If you think this is something that might need to be maintained or the options might change, I would set it up like this, as opposed to nested IFs.
Is this a little clearer?
=IF(B12=""," ",IfError(VLookup(U12,{"ESA","Subscribe";"Perpetual","Buy";"Subscription",Subscribe";"T.E.H.","Subscribe"},2,false)," "))
This is really just a table lookup, hence the use of VLookup. The lookup array is a two dimensional array in curly brackets - the commas and semicolons are very important for defining a 2x4 array for VLookup. The IFError function tells how to return your desired " " result if the lookup fails.

Why I am getting FALSE for "=FALSE<=100" in excel

Hi I am Priya from India,
I am trying to get the logic in excel formula
=FALSE<=100
False will be considered as 0. if it is 0<=100 then expected output is TRUE.
But we are getting FALSE in the Microsoft Excel.
Why I am not getting True?
TRUE and FALSE can't be treated directly as numbers on Excel. However, they can be implicitly converted to numbers:
=(FALSE + 0) <= 100
Adding 0 to them does it.
The formula you mentioned in the comment, even though it seems to return a correct result - (10> = 50 AND 10 = <- 100) == FALSE, is basically incorrect, because excel calculates it as follows:
=(10>=50 & 10<=100)
=(10>="5010"<=100)
=(FALSE<=100)
= FALSE
If you want the numbers to be compared, you can use the following options:
Use the AND function:
=AND((10>=50),(10<=100))
Multiply the comparisons and check if the result is greater than zero
=(10>=50)*(10<=100)>0

Cant figure out why this code is failing a single test

I'm trying to learn python more by solving the hacker rank puzzles and I can't understand why it is failing
This code is supposed to determine whether or not a year that is or above 1900 is, in fact, a leap year, the website says it passes 5 of 6 tests. For the input
2100 it's returning true instead of false.
def is_leap(year):
leap = False
if year%4==0:
return True
elif year%100==0:
return False
elif year%400==0:
return True
return leap
year = int(input())
print(is_leap(year))
I expect it to return false if the year is not divisible by 100 and return true if it is divisible by 4 or 400.
Let's see what happens if the year is, e.g. 1900, a year that was not a leap year:
Since year % 4 is 0, we return True immediately, which is of course wrong. In fact, any number that is divisible by 100 or 400 must also be divisible by 4, meaning that we never even get to the bottom two conditions.
So the solution is to reorder your conditions from most to least specific:
if year % 400 == 0:
return True
elif year % 100 == 0:
return False
elif year % 4 == 0:
return True
Your second misunderstanding has to do with return: A return statement doesn't somehow "mark" a value to be the return value at the end of the function, it immediately exits the function, returning that value. For better consistency, I would remove the leap variable, and just return False at the end of the function. Alternatively, you could assign to leap inside the conditions instead of returning there.
Your if statement is not changing the variable leap.
Try changing the variable leap like below.
def is_leap(year):
leap = False
if year%4==0:
leap = True
elif year%100==0:
leap = False
elif year%400==0:
leap = True
return leap
year = int(input())
print(is_leap(year))
def foo(year: int) -> bool:
"find a year is leapyear or not"
if year % 4 == 0 and year % 100 != 0:
return True
return year % 4 == 0 and year % 100 == 0 and year % 400 == 0
The function takes an integer as argument for the year parameter and returns True if the year is a leap year and False for the opposite. A year needs to be divisible by 4 and not by 100 to be a confirmed leap year. So, the conditional statement checks for that. If the condition's met it returns True else that function does not return anything and continues downward. Then, if the number is divisible by 4 and 100 and 400 as this case also means the year is a confirmed leap year, it returns True. We have done all checks and still if that's not True then certainly the years not a leap year.

Use IF and IF AND in the same formula

I believe my sytanx is right but I cannot use IF and AND IF statements in the same formula. Do you know what the issue might be?
=IF(K47>170,"BAD",IF(K47<100,"GOOD"),IF(AND(J47=0,I47>160,"BAD")
In excel If is (boolean statement, true result, false result)
And just returns true or false. You can't have a string value.
so And should be throwing an error because "BAD" can't be evaluated as true or false
and the last if should throw an error because there are enough arguments (it needs three).
In addition, you don't have enough to bound the formula.
So you should have something like
=if(K47>170, "Bad", if(k47< 100, "Good", if(AND(J47=0,I47>160), "BAD", "SOMETHING")))
Break it down into smaller blocks to isolate the problem. Not tested because I don't have excel but writing the formula as follows
=IF(
K47>170,
"BAD",
IF(
K47<100,
"GOOD")
^^ looks like you're missing something here because the else part of the innermost if here isn't specified and the statement should be closed with a ) here, meaning excel can't figure out what to do with the rest (below).
,IF(AND(J47=0,I47>160,"BAD")
This part also has a pretty strange condition. It seems like you want to say " if j47 equals 0 and I47 is greater than 160 ".
In pseudo code, if you want
if k47 > 170
bad
else
if k47 < 100
good
else
if j47 = 0 and I47 > 160
bad
else
good
end
end
Then you can write it with excel with something like
=IF(
K47 > 170,
"BAD",
IF(
K47 < 100,
"GOOD",
IF(
AND(
J47 = 0,
I47 > 160
),
"BAD",
"GOOD"
)
)
)
Give it a try and look at the excel formula guide as you go, solving one piece at a time.

Recognize relevant string information by checking the first characters

I have a table with 2 columns. In column 1, I have a string information, in column 2, I have a logical index
%% Tables and their use
T={'A2P3';'A2P3';'A2P3';'A2P3 with (extra1)';'A2P3 with (extra1) and (extra 2)';'A2P3 with (extra1)';'B2P3';'B2P3';'B2P3';'B2P3 with (extra 1)';'A2P3'};
a={1 1 0 1 1 0 1 1 0 1 1 }
T(:,2)=num2cell(1);
T(3,2)=num2cell(0);
T(6,2)=num2cell(0);
T(9,2)=num2cell(0);
T=table(T(:,1),T(:,2));
class(T.Var1);
class(T.Var2);
T.Var1=categorical(T.Var1)
T.Var2=cell2mat(T.Var2)
class(T.Var1);
class(T.Var2);
if T.Var1=='A2P3' & T.Var2==1
disp 'go on'
else
disp 'change something'
end
UPDATES:
I will update this section as soon as I know how to copy my workspace into a code format
** still don't know how to do that but here it goes
*** why working with tables is a double edged sword (but still cool): I have to be very aware of the class inside the table to refer to it in an if else construct, here I had to convert two columns to categorical and to double from cell to make it work...
Here is what my data looks like:
I want to have this:
if T.Var1=='A2P3*************************' & T.Var2==1
disp 'go on'
else
disp 'change something'
end
I manage to tell matlab to do as i wish, but the whole point of this post is: how do i tell matlab to ignore what comes after A2P3 in the string, where the string length is variable? because otherwise it would be very tiring to look up every single piece of string information left on A2P3 (and on B2P3 etc) just to say thay.
How do I do that?
Assuming you are working with T (cell array) as listed in your code, you may use this code to detect the successful matches -
%%// Slightly different than yours
T={'A2P3';'NotA2P3';'A2P3';'A2P3 with (extra1)';'A2P3 with (extra1) and (extra 2)';'A2P3 with (extra1)';'B2P3';'B2P3';'NotA2P3';'B2P3 with (extra 1)';'A2P3'};
a={1 1 0 1 1 0 1 1 0 1 1 }
T(:,2)=num2cell(1);
T(3,2)=num2cell(0);
T(6,2)=num2cell(0);
T(9,2)=num2cell(0);
%%// Get the comparison results
col1_comps = ismember(char(T(:,1)),'A2P3') | ismember(char(T(:,1)),'B2P3');
comparisons = ismember(col1_comps(:,1:4),[1 1 1 1],'rows').*cell2mat(T(:,2))
One quick solution would be to make a function that takes 2 strings and checks whether the first one starts with the second one.
Later Edit:
The function will look like this:
for i = 0, i < second string's length, i = i + 1
if the first string's character at index i doesn't equal the second string's character at index i
return false
after the for, return true
This assuming the second character's lenght is always smaller the first's. Otherwise, return the function with the arguments swapped.

Resources