Nested If statements in Google sheets not working properly - google-sheets

I am trying to sort some salary expectations to different levels of jobs in google sheets and have created the formula below. I am expecting it to print entry-level, Mid Level, Senior Level and Blank in the ranges I have defined below.
However, it is only printing Senior Level where the cell values are over 50000 or blank.
What's wrong with my formula?
=IFS(
0> $J2 < 30000, "Entry Level",
30000 >= $J2 < 50000 ,"Mid Level",
$J2 >= 50000, "Senior Level",
ISBLANK($J2),"Blank")

You can't write 30000 >= $J2 < 50000, write instead and( $J2 >= 30000 , $J2 < 50000 )
complete formula
=if(isblank($J2),"Blank",if($J2<30000,"Entry level",if($J2<50000,"Mid level","Senior level")))

use:
=IF((J2 > 0) *(J2 < 30000), "Entry Level",
IF((J2 >= 30000)*(J2 < 50000), "Mid Level",
IF( J2 >= 50000), "Senior Level",
IF(ISBLANK(J2), "Blank", ))))
see: https://webapps.stackexchange.com/q/123729/186471
try:
=IF(J2="", "Blank", VLOOKUP(J2,
{0, "Entry Level";
30000, "Mid Level";
50000, "Senior Level"}, 2, 1))

Related

Google Sheets: Adjusting an array formula to auto-appear in every row

The formula in question is =IF (ISBLANK(H2),"", ARRAY_CONSTRAIN(ARRAYFORMULA(IF( (MOD(SUM(INT(MID(REPT("0",20-LEN(H2))&H2,ROW($1:$31),1)*(MOD(ROW($1:$31),2)+1)/10)+MOD(MID(REPT("0",20-LEN(H2))&H2,ROW($1:$31),1)*(MOD(ROW($1:$31),2)+1),10)),10)=0), "✔", "❌")), 1, 1))
In English it checks if H2 contains a valid credit card (passing Luhn's algorithm, discussion / sample data here). The expected output is valid = ✔; invalid = ❌; if blank then nothing.
I'm trying to adjust this to appear in every row, but can't seem to nail it down. (Using the trick like for a formula =LEFT(H2,4)&" "&MID(H2,5,6), if it's =arrayformula(LEFT(H2:H100,4)&" "&MID(H2:H100,5,6)) it appears in every row without having to manually refill it when a new row is inserted).
Sample google sheet.
Try this:
=ARRAYFORMULA(
IF(
H2:H = "",
"",
IF(
MOD(
MMULT(
MID(REPT("0", 20 - LEN(H2:H)) & H2:H, SEQUENCE(1, 10, 2, 2), 1)
+ MID(REPT("0", 20 - LEN(H2:H)) & H2:H, SEQUENCE(1, 10, 1, 2), 1) * 2
- (MID(REPT("0", 20 - LEN(H2:H)) & H2:H, SEQUENCE(1, 10, 1, 2), 1) * 2 > 9) * 9,
SEQUENCE(10, 1, 1, 0)
),
10
) = 0,
"✔",
"❌"
)
)
)
If you want a more general solution (for card numbers longer than 20 digits), replace 20 with MAX(LEN(H2:H)) + MOD(MAX(LEN(H2:H)), 2), and 10 with (MAX(LEN(H2:H)) + MOD(MAX(LEN(H2:H)), 2)) / 2.

Shortening a long if else statement

I have a long if else statement:
rnd = rand(1..1000)
if rnd >= 600
0
elsif rnd < 600 && rnd >= 350
1
elsif rnd < 350 && rnd >= 270
2
elsif rnd < 270 && rnd >= 200
3
elsif rnd < 200 && rnd >= 150
4
elsif rnd < 150 && rnd >= 100
5
elsif rnd < 100 && rnd >= 80
6
elsif rnd < 80 && rnd >= 50
7
elsif rnd < 50 && rnd >= 30
8
else
9
end
I would like to shorten it. Is it possible?
My rubocop swears at this long method.
I would start with something like this:
RANGES = {
(0...30) => 9,
(30...50) => 8,
(50...80) => 7,
# ...
(350...600) => 1,
(600...1000) => 0
}
rnd = rand(1..1000)
RANGES.find { |k, _| k.cover?(rnd) }.last
Great answers already! Just chiming in since I had a suspicion that ruby could handle this with a case statement, and it appears to be able to do so:
rnd = rand(1..1000)
case rnd
when 600.. then 0
when 350...600 then 1
when 270...350 then 2
...
else 9
end
Regardless of the approach taken, you're going to have to specify the ranges somewhere, so I think using something like a case statement is appropriate here (sorry! It doesn't shorten the code more than a few lines). Using a hash would also be a great approach (and might allow you to move the hash elsewhere), as other commenters have already shown.
It's worth mentioning, with ruby ranges, .. means that the range is inclusive and includes the last value (1..10 includes the number 10), and ... means the range is exclusive where it does not include the last value.
The top case 600.. is an endless range, which means it will match anything greater than 600. (That functionality was added in ruby 2.6)
You can simplify your conditions by using only the lower bound.
And you can avoid repeting elsif because it is cumbersome
rnd = rand(1..1000)
lower_bounds = {
600 => 0,
350 => 1,
270 => 2,
200 => 3,
150 => 4,
100 => 5,
80 => 6,
50 => 7,
30 => 8,
0 => 9,
}
lower_bounds.find { |k, _| k <= rnd }.last
MX = 1000
LIMITS = [600, 350, 270, 200, 150, 100, 80, 50, 30, 0]
The required index can be computed as follows.
def doit
rnd = rand(1..MX)
LIMITS.index { |n| n <= rnd }
end
doit
#=> 5
In this example rnd #=> 117.
If this must be repeated many times, and speed is paramount, you could do the following.
LOOK_UP = (1..MX).each_with_object({}) do |m,h|
h[m] = LIMITS.index { |n| n <= m }
end
#=> {1=>9, 2=>9,..., 29=>9,
# 30=>8, 31=>8,..., 49=>8,
# ...
# 600=>0, 601=>0,..., 1000=>0}
Then simply
def doit
LOOK_UP[rand(1..MX)]
end
doit
#=> 3
In this example rand(1..MX) #=> 262.
If speed were paramount but MX were so large that the previous approach would require excessive memory, you could use a binary search.
def doit
rnd = rand(1..MX)
LIMITS.bsearch_index { |n| n <= rnd }
end
doit
#=> 5
In this example rnd #=> 174.
See Array#bsearch_index. bsearch_index returns the correct index in O(log n), n being LIMITS.size). bsearch_index requires the array on which it operates to be ordered.

How to make 1-100 score out of two datasets in Google Sheets?

I have two datasets:
1) The number of days passed since the product was released
2) Total Number of Positive Reviews
What I am trying to archive is a 1-100 score, since the product that was released one year ago and has +1000 positive reviews is not the same with a product that was released a 1-2 month ago and already has +300 positive reviews. In a nutshell, depending on "days passed till now" - the value of "total amount of positive reviews" should drop giving 1-100 rating to filter out the most valuable products.
I'm not even sure how to approach this problem, please help me out.
There would be around 1000 products that I'd need to score, so I thought there might be a predefined formula for this in Google Sheets.
Example: https://docs.google.com/spreadsheets/d/1Y3q7URy5s8B5x3HVIzjaDzIZN3FRRvoduJAXobw1UOk/edit#gid=1382498268
this will filter out all products with:
1000+ reviews if older than 356 days
300+ reviews if not older than 60 days
={A1:D1; QUERY(
{IFERROR(QUERY(A2:D, "select * where D >= 1000 and C > 365", 0), {"","","",""});
IFERROR(QUERY(A2:D, "select * where D >= 300 and C < 60 ", 0), {"","","",""})},
"select * order by Col4 desc", 0)}
if you still want that "score" column use this:
=ARRAYFORMULA(IFERROR(VLOOKUP(A2:A,
{{QUERY(A2:D, "select A where C >= 365 order by D desc", 0),
ROW(INDIRECT("A1:A"&COUNTA(
QUERY(A2:D, "select A where C >= 365 order by D", 0))))};
{QUERY(A2:D, "select A where C < 365 and C > 0 order by D desc", 0),
ROW(INDIRECT("A1:A"&COUNTA(
QUERY(A2:D, "select A where C < 365 and C > 0 order by D", 0))))}},
2, 0), ))
if you want no more then 100 use:
=ARRAYFORMULA(IF(IFERROR(VLOOKUP(A2:A,
{{QUERY(A2:D, "select A where C >= 365 order by D desc", 0),
ROW(INDIRECT("A1:A"&COUNTA(
QUERY(A2:D, "select A where C >= 365 order by D", 0))))};
{QUERY(A2:D, "select A where C < 365 and C > 0 order by D desc", 0),
ROW(INDIRECT("A1:A"&COUNTA(
QUERY(A2:D, "select A where C < 365 and C > 0 order by D", 0))))}},
2, 0), )>100, ,
IFERROR(VLOOKUP(A2:A,
{{QUERY(A2:D, "select A where C >= 365 order by D desc", 0),
ROW(INDIRECT("A1:A"&COUNTA(
QUERY(A2:D, "select A where C >= 365 order by D", 0))))};
{QUERY(A2:D, "select A where C < 365 and C > 0 order by D desc", 0),
ROW(INDIRECT("A1:A"&COUNTA(
QUERY(A2:D, "select A where C < 365 and C > 0 order by D", 0))))}},
2, 0), )))

Geogebra plot range

I created this plot through the GeoGebra spreadsheet:
I would be interested in getting the same plot, but only in range between the first (1;3) and the last (3;4.5) point. How can I do this?
Thanks in advance
Ok this is my firs answer , you can type that in the input line below : If(1 < x < 3, f(x))
where f(x) is your function
For example, for f(x) = x^2, you can input like this: x² / (x < -1 ∨ x > 1)
(x < -1 ∨ x > 1) is a boolean value, True == 1, and False == 0. 0 as a denominator is meaningless, and this can be used to limit the display range in Geogebra.

Nested IF condition not working in google spreadsheet

This doesn't seems to be working in Google spreadsheet, can anyone help me out?
=IF(P70 <= 0, "NYS", IF(AND(P70 > 0, P70 <= 99), "WIP", IF(P70 >= 100, "COM")))
IF statement require 3 arguments: IF(condition, true_exp, false_exp).
You forgot the false_exp in the innermost IF.
It could be expressed more clearly like:
=IF(P70 <= 0, "NYS", IF(P70 <= 99, "WIP", "COM"))

Resources