# Conditional Scripting/Expressions

**URL:** <https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140>\
**Category:** Ignition\
**Created:** [June 23, 2022, 11:33pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140 "2022-06-23T23:33:50Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Casey\_Roman](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@Casey\_Roman](https://forum.inductiveautomation.com/u/Casey_Roman)\
**Post date:** [June 23, 2022, 11:33pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/1 "2022-06-23T23:33:50Z")

</div>

Hi guys, looking for opinions if you’d be so kind! I’m trying to figure out the best way to write an expression that would produce a string value based on the following dataset of conditions:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/d/0/d09b2ba01ce21fd609ba063cc435c9212138e16c.png)

Based on the conditions from the first four columns on the left, I want to produce the “Selected Option” displayed in the same row on the far right.

I started on a huge string of if statements but the complexity of the “ifs” is leading me to believe there is much simpler way to do this that I just haven’t discovered yet.

What would you guys do?

---

<div class="post-metadata">

**Author:** ![josborn](https://avatars.discourse-cdn.com/v4/letter/j/4bbf92/32.png) [@josborn](https://forum.inductiveautomation.com/u/josborn)\
**Post date:** [June 23, 2022, 11:37pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/2 "2022-06-23T23:37:18Z")

</div>

A [case statement](https://docs.inductiveautomation.com/display/DOC81/case) would be easier than going with ifs.

Edit: Actually that might not work for your use.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [June 24, 2022, 12:06am UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/3 "2022-06-24T00:06:00Z")

</div>

When I set up scenarios for similar situations I have a somewhat complicated solution I fall back to because it works.

It looks like you have the wonderful luck of having four columns with binary values (`0`/`1`, and “Good”/“Bad”). Mentally convert all of those values to actual binary bits:

```auto
0 -> 0
1 -> 1
"Bad" -> 0
"Good" -> 1

```

Now you can represent each row as a four-bit binary value, ie row `0` becomes `0101`.

Now, instead of having to do conditionals to determine the what to do for each branch you can indeed fall back to a switch statement, or you could just use a Python dictionary:

```auto
tags = system.tag.readBlocking(["pathOne.value", "pathOne.quality", "pathTwo.value", "pathTwo.quality"])
opt_1_val = tags[0]
opt_1_qual = tags[1]
opt_2_val = tags[2]
opt_2_qual = tags[3]
converted = "".join([str(opt_1_val), "1" if opt_1_qual == "Good" else "0", str(opt_2_val), "1" if opt_2_qual == "Good" else "0"])
value_map = {
    "0101": "Option 1",
    "1111": "Option 2",
    "0110": "Option 1"
} # and include the rest of the valid options
return value_map.get(converted, None) # None if map contains no match

```

The downside is the map requires maintenance when requirements change (like added return values or changes to what each four-bit value represents), but it prevents long, branching if statements.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 24, 2022, 12:47am UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/4 "2022-06-24T00:47:30Z")

</div>

> [@cmallonee](#):
>
> ```auto
> opt_1_val = tags[0]
> opt_1_qual = tags[1]
> opt_2_val = tags[2]
> opt_2_qual = tags[3]
> 
> ```

I would move the boolean logic into here instead of into the join. I think you also still need the `.value` as well, so I would instead just read the 2 tags:

```auto
from com.inductiveautomation.ignition.common.model.values import QualityCode
tags = system.tag.readBlocking(["pathOne", "pathTwo"])
options = []
for tag in tags:
   options.append(tag.value)
   options.append(tag.quality.level == QualityCode.Level.Good))

converted = "".join({True: '1', False: '0'}.get(option, '0') for option in options)

```

Maybe using QualityCode here is overkill...

---

<div class="post-metadata">

**Author:** ![Casey\_Roman](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@Casey\_Roman](https://forum.inductiveautomation.com/u/Casey_Roman)\
**Post date:** [June 24, 2022, 2:29pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/5 "2022-06-24T14:29:24Z")

</div>

Great thinking! I’m going to give that a shot today. Thanks so much!

---

<div class="post-metadata">

**Author:** ![Casey\_Roman](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@Casey\_Roman](https://forum.inductiveautomation.com/u/Casey_Roman)\
**Post date:** [June 24, 2022, 2:30pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/6 "2022-06-24T14:30:18Z")

</div>

Very cool idea! I will look into this today as well! Thanks @nminchin !

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 24, 2022, 2:31pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/7 "2022-06-24T14:31:15Z")

</div>

> [@nminchin](#):
>
> `options.append(tag.quality.level == QualityCode.Level.Good))`

I would just use

```auto
options.append(tag.quality.good)

```

---

<div class="post-metadata">

**Author:** ![Casey\_Roman](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@Casey\_Roman](https://forum.inductiveautomation.com/u/Casey_Roman)\
**Post date:** [June 24, 2022, 2:32pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/8 "2022-06-24T14:32:06Z")

</div>

@josborn I looked at using a case statement as well but it seemed equally as cumbersome as the if statement scenario! Thanks for the reply!

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [June 24, 2022, 2:46pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/9 "2022-06-24T14:46:50Z")

</div>

A switch statement is actually a lot cleaner than even the map because you can fall through similar cases, so you’d actually only need four or five definitions.

```auto
# not perfect syntax, but the gist is this:
switch (converted): {
    case "0101":
    case "0110":
    case "0111":
    case "1001":
        return "Option 1"
    case "1111":
    case "0011":
    case "1101":
    case "1100":
        return "Option 2"
    case "0011":
    case "1000":
        return "Lad Good Option"
    default:
        return "option not mapped"
}

```

Edit: I’m not really sure the correct Jython syntax. Python doesn’t support switch statements - they’re a Java concept - but Jython doesn’t require semi-colons, so… maybe this will work as-is? And since we’re returning we don’t need `break`.

---

<div class="post-metadata">

**Author:** ![Casey\_Roman](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@Casey\_Roman](https://forum.inductiveautomation.com/u/Casey_Roman)\
**Post date:** [June 24, 2022, 2:50pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/10 "2022-06-24T14:50:33Z")

</div>

@cmallonee Nice!!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 24, 2022, 3:06pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/11 "2022-06-24T15:06:13Z")

</div>

> [@cmallonee](#):
>
> maybe this will work as-is?

No, it won't. The pythonic structure is `if-elif-elif-else`.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [June 24, 2022, 3:13pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/12 "2022-06-24T15:13:28Z")

</div>

You could always use a dictionary with a `.get()` but since there’s so many cases with the same output I think the easiest way would be

```auto
# assume we have converted variable that is the 4 digit string
case_1 = converted in ["0101", "0110", "0111", "1001"]
case_2 = converted in ["1111","0011","1101","1100"]
case_3 = converted in ["0011","1000"]

if case_1:
    return "option 1"
elif case_2:
    return "option 2";
elif case_3:
    return "option 3"
else:
    return 'option not mapped'

```

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [June 24, 2022, 3:13pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/13 "2022-06-24T15:13:43Z")

</div>

Ah, so Jython doesn’t support switch statements at all? That’s too bad.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [June 24, 2022, 3:14pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/14 "2022-06-24T15:14:38Z")

</div>

The python equivalent to switch statements, Match statements, were only just introduced to python 3.10 IIRC

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [June 24, 2022, 3:17pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/15 "2022-06-24T15:17:23Z")

</div>

Here’s a [link](https://www.udacity.com/blog/2021/10/python-match-case-statement-example-alternatives.html) to all of the alternatives we’ve covered here. As @bkarabinchak.psi pointed out, the match case is not available in Ignition because we’re not using Python 3.10.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 24, 2022, 3:22pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/16 "2022-06-24T15:22:59Z")

</div>

I would not compute case\_1, case\_2, and case\_3 ahead of the if-elif-elif-else block. Compute in the `if` block. Put the most likely condition first. The other computations will be skipped.

---

<div class="post-metadata">

**Author:** ![Casey\_Roman](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@Casey\_Roman](https://forum.inductiveautomation.com/u/Casey_Roman)\
**Post date:** [June 24, 2022, 4:17pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/17 "2022-06-24T16:17:06Z")

</div>

I was trying to put all of this in an expression tag, but haven’t had luck making it work yet with all of your great suggestions… Should I maybe be trying to place all of this somewhere else? Would all of this be better suited as a script instead of an expression?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 24, 2022, 4:25pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/18 "2022-06-24T16:25:22Z")

</div>

All of the examples given so far use scripting. You could use [`binEnc`](https://docs.inductiveautomation.com/display/DOC81/binEnc) and `case` to do something similar entirely with expressions, but the logic becomes (arguably) more difficult to reason about:

```auto

case(
	binEnc(
		{Tag1},
		isBad({Tag1}),
		{Tag2},
		isBad({Tag2})
	),
	0, "Option 1", // 0000
	1, "Option 2", // 0001
	2, "Option 1",
	"Fallback"
)

```

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [June 24, 2022, 4:59pm UTC](https://forum.inductiveautomation.com/t/conditional-scripting-expressions/61140/19 "2022-06-24T16:59:05Z")

</div>

I would probably put the binEnc into another tag, so that you can see the intermediate value.
