Arcade Expression Symbology Difficulties

1431
5
Jump to solution
03-10-2023 01:41 PM
Labels (2)
VaneiriPatt
New Contributor II

Hello,

I am trying to figure out a meaningful symbology for my data. 

I have a submission that has 3 stages on which they either pass or fail. I want to be able to symbolize based on the main two stages and the third would only be if first two stages pass. 

These are the variations I want to achieve when symbolizing:

Stage 1 & Stage 2 Pass

Stage 1 Pass & Stage 2 Fail

Stage 1 Fail & Stage 2 Pass

Stage 1 , 2, 3 Pass. 

This is the sample expression I have written but it doesn't show what I need. 

var Stage1P= $feature.inspectionresult
if (Stage1P=="Pass")
return "Stage 1 Pass";

var Stage1F= $feature.inspectionresult
if (Stage1F=="Fail")
return "Stage 1 Fail";

var Stage2P= $feature.installationresults
if (Stage2P=="Pass")
return "Stage 2 Pass";

var Stage2F= $feature.installationresults
if (Stage2F=="Fail")
return "Stage 2 Fail";

var Stage3P=$feature["ns_serviceentrance"]
if (Stage3P=="Pass")
return "Stage 3 Pass";

var Stage3F=$feature["ns_serviceentrance"]
if (Stage3F=="Fail")
return "Stage 3 Fail"


if (Stage1F=="Fail" && Stage2P=="Pass")
return "Stage 1 Fail & Stage 2 Pass"

if (Stage1P=="Pass" && Stage2F=="Fail")
return "Stage 1 Pass & Stage 2 Fail"

if (Stage1P=="Pass" && Stage2P=="Pass" && Stage3P=="Pass")
return "Stage 1-2-3 Pass"

Appreciate any help on this. 

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

You could use IsEmpty(Stage3), which will return true for null and "" (and some other values). But if if Stage3 is dependent on both previous stages passing, you can just leave it out of those conditions:

 

var Stage1= $feature.inspectionresult
var Stage2= $feature.installationresults
var Stage3= $feature["ns_serviceentrance"]

return When(
    Stage1=="Pass" && Stage2=="Fail", "Stage 1 Pass Stage 2 Fail",
    Stage1=="Fail" && Stage2=="Pass", "Stage 1 Fail Stage 2 Pass",
    Stage1=="Fail" && Stage2=="Fail", "Stage 1-2 Fail",
    Stage1=="Pass" && Stage2=="Pass" && Stage3=="Pass", "Stage 1-2-3 Pass",
    Stage1=="Pass" && Stage2=="Pass" && Stage3=="Fail", "Stage 1-2 Pass Stage 3 Fail",
    "You missed a condition!"
)

 

 


Have a great day!
Johannes

View solution in original post

5 Replies
DavidPike
MVP Frequent Contributor

Looks like your code logic doesn't really work.  If inspectionResult is always either pass or fail, then only the first 2 if statements would ever be evaluated since a return breaks any subsequent evaluations (also consider using 'else if' to make the code more efficient.  

you need some more detailed logic such as 

 

 

//8 possible permutations (2^3) (ermmmm I think - a while since my statistics classses!)
var Stage1= $feature.inspectionresult
var Stage2= $feature.installationresults
var Stage3= $feature.ns_serviceentrance

if (Stage1=="Pass" && Stage2=="Fail" && Stage3=="Fail")
return "Stage 1 Pass Stage 2-3 Fail"

else if (Stage1=="Pass" && Stage2=="Pass" && Stage3=="Fail")
return "Stage 1-2 Pass Stage 3 Fail"

else if (Stage1=="Pass" && Stage2=="Fail" && Stage3=="Pass")
return "Stage 1-3 Pass Stage 2 Fail"

else if (Stage1=="Pass" && Stage2=="Pass" && Stage3=="Pass")
return "Stage 1-2-3 Pass"

else if (Stage1=="Fail" && Stage2=="Pass" && Stage3=="Pass")
return "Stage 1 Fail Stage 2-3 pass"

else if (Stage1=="Fail" && Stage2=="Fail" && Stage3=="Pass")
return "Stage 1-2 Fail Stage 3 pass"

else if (Stage1=="Fail" && Stage2=="Pass" && Stage3=="Fail")
return "Stage 1-3 Fail Stage 2 pass"

else if (Stage1=="Fail" && Stage2=="Fail" && Stage3=="Fail")
return "Stage 1-2-3 Fail"

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

consider using 'else if' to make the code more efficient

If I'm not mistaken, that won't do anything here. If the condition is evaluated to be false, the following block is skipped, and the next condition is evaluated, regardless of if you use "if " or "else if". And if the condition evaluates to true, then the following block will be entered, and then the expression returns, skipping everything after that (as you said).

In terms of writing efficiency, you could do this a little easier with When():

return When(
  Stage1=="Pass" && Stage2=="Fail" && Stage3=="Fail", "Stage 1 Pass Stage 2-3 Fail",
  Stage1=="Pass" && Stage2=="Pass" && Stage3=="Fail", "Stage 1-2 Pass Stage 3 Fail",
  Stage1=="Pass" && Stage2=="Fail" && Stage3=="Pass", "Stage 1-3 Pass Stage 2 Fail",
  Stage1=="Pass" && Stage2=="Pass" && Stage3=="Pass", "Stage 1-2-3 Pass",
  Stage1=="Fail" && Stage2=="Pass" && Stage3=="Pass", "Stage 1 Fail Stage 2-3 pass",
  Stage1=="Fail" && Stage2=="Fail" && Stage3=="Pass", "Stage 1-2 Fail Stage 3 pass",
  Stage1=="Fail" && Stage2=="Pass" && Stage3=="Fail", "Stage 1-3 Fail Stage 2 pass",
  Stage1=="Fail" && Stage2=="Fail" && Stage3=="Fail", "Stage 1-2-3 Fail",
  "SomeDefaultValue"
)

 

 

And if we go down the path of writing efficiency, this is still quite bad.

For the 8 permutations in this case, writing out all of them is still feasible. But imagine you'd need to add a fourth stage or another possible evaluation result (eg "undetermined"). Then we have 16 (4^2) or 27 (3^3) possible permutations. It quickly becomes unfeasible to write them all out.

In these cases, it's much more effcient (at least in terms of writing the expression, no idea about execution), to work with arrays/dictionaries:

var stages = [
    $feature.inspectionresult,
    $feature.installationresults,
    $feature.ns_serviceentrance,
]
var possible = ["Pass", "Fail"]

var values = Dictionary()
for(var i in stages) {
    var v = stages[i]
    Console(v)
    if(HasKey(values, v)) { Push(values[v], i + 1) }
    else { values[v] = [i + 1] }
}
var parts = []
for(var i in possible) {
    var v = possible[i]
    if(!HasKey(values, v)) { continue }
    Push(parts, "Stage " + Concatenate(values[v], "-") + " " + v)
}
return Concatenate(parts, " & ")

 

Now, if we want to add another stage and/or another possible result, we just have to edit the two variables:

JohannesLindner_0-1678537975952.png

 


Have a great day!
Johannes
DavidPike
MVP Frequent Contributor

Impressive stuff there.  Yes on looking back, 'else if' makes no difference since a return statement is used each time.  'When' is certainly more readable also.

0 Kudos
VaneiriPatt
New Contributor II

@JohannesLindner , thanks for the feedback. I forgot to mention that Stage 3 will be empty if either Stage 1 Fails and Stage 2 Fails. This stage 3 will be "Pass" only if both Stage 1 and Stage 2 pass. Otherwise, it will be empty. 

I tried to re-write the expression by leaving it empty in the quotations but it returns "SomeDefaultValue" rather than the variations I state.  

var Stage1= $feature.inspectionresult
var Stage2= $feature.installationresults
var Stage3= $feature["ns_serviceentrance"]

return When(
Stage1=="Pass" && Stage2=="Fail" && Stage3==" ", "Stage 1 Pass Stage 2 Fail",
Stage1=="Pass" && Stage2=="Pass" && Stage3=="Pass", "Stage 1-2-3 Pass",
Stage1=="Fail" && Stage2=="Pass" && Stage3==" ", "Stage 1 Fail Stage 2 Pass",
Stage1=="Fail" && Stage2=="Fail" && Stage3==" ", "Stage 1-2 Fail",

"SomeDefaultValue"
)

I also tried entering "NULL" and still got the breakdown as on image. 

2023-03-13_15-58-05.png

0 Kudos
JohannesLindner
MVP Frequent Contributor

You could use IsEmpty(Stage3), which will return true for null and "" (and some other values). But if if Stage3 is dependent on both previous stages passing, you can just leave it out of those conditions:

 

var Stage1= $feature.inspectionresult
var Stage2= $feature.installationresults
var Stage3= $feature["ns_serviceentrance"]

return When(
    Stage1=="Pass" && Stage2=="Fail", "Stage 1 Pass Stage 2 Fail",
    Stage1=="Fail" && Stage2=="Pass", "Stage 1 Fail Stage 2 Pass",
    Stage1=="Fail" && Stage2=="Fail", "Stage 1-2 Fail",
    Stage1=="Pass" && Stage2=="Pass" && Stage3=="Pass", "Stage 1-2-3 Pass",
    Stage1=="Pass" && Stage2=="Pass" && Stage3=="Fail", "Stage 1-2 Pass Stage 3 Fail",
    "You missed a condition!"
)

 

 


Have a great day!
Johannes