Neither is switch/case to a someone who’s never used it before. Scripts are not a “workaround” any more than a subroutine or function is a “workaround” in other languages.
Anyway, if you believe you know of an easier way it should be done, please present an example of the syntax you would prefer to see for, say, a choice of three possible options. You can modify the following example to show how it could be simplified with different syntax:
FWIW, I believe pnbruckner is also working on a simplification of how conditions are presented when using the template platform. I’ve seen an example and it’s more streamlined than how it’s currently done.
BTW, I did use the adjective “optional” when describing default. Maybe you missed it.
You can use multiple choose in your script sequence or automation action
So
- service: #whatever you use to turn receiver on
- choose:
- conditions:
#Your condition to check quiet mode
sequence:
# your actions to set volume
- service: # service to turn TV on
- service: # service to turn playstation on
- choose:
- conditions:
#check if it's night- time
sequence:
# apply your theme
The choose action was a compromise. It was discussed at length in an architecture issue. A more straightforward if - elif - else construct would have been preferable, but YAML constraints made it difficult. So, yeah, I agree, choose is neither optimal nor intuitive, but it was the best that could be suggested at the time.
Maybe it is because I have a little programming experience, but I think it would still be clearer (easier to understand) to just call it ‘if/else if’ instead of 'choose" and ‘else’ instead of ‘default’.
Nothing inherently wrong with the term choose. Other languages use different names, for example, this is from VB:
Select [ Case ] testexpression
[ Case expressionlist
[ statements ] ]
[ Case Else
[ elsestatements ] ]
End Select
It uses the word ‘select’ instead of choose, each selection begins with the word ‘case’ and the equivalent of ‘default’ is ‘case else’.
In C++, switch is the equivalent word for choose, each choice begins with case and it uses the word default in the same way VB uses case else.
In perl 5, it’s given, when, and default, respectively. Prior to version 5 it was switch case.
When learning python, it was surprising to discover there’s no equivalent statement for switch/choose/select/given (or, for that matter, do while). Nevertheless, an old-school chain of if-elif's can achieve the same thing (it just looks kind of lame when you’re accustomed to using switch or select).
I’m beginning to believe that the choose construct was a mistake. It seems to confuse everyone.
I think this would be better (and now that I’ve had a chance to think about it more, it wouldn’t really be any more difficult to implement than choose was):
That was another option, but then it would quickly lead to ridiculous indentation with nested if’s. I prefer something with elif to keep things reasonable.
Unless I’m mistaken, I believe choose was suggested in the Architecture discussion and inspired by XSL. However, what was lost in translation is that XSL’s choose includes other key words to clarify its usage:
<xsl:choose>
<xsl:when test="expression">
... some output ...
</xsl:when>
<xsl:otherwise>
... some output ....
</xsl:otherwise>
</xsl:choose>
The key word otherwise became default and when effectively disappeared and simply inferred by condition.
I don’t have a problem with understanding the new choose option’s structure. Frankly, I dislike the if-then-elif-then-else example (shown above) because it contains more key words to achieve what can already be done with less.
While all the suggestions are valid here and I appreciate @pnbruckner’s continued contributions to make this easier still, I feel like the author’s original point is still valid - why doesn’t execution continue after a conditional? I feel like whether or not to continue execution after should be a decision users can make regardless of the conditional construct or whether or not a default is present.
To give an example, when someone arrives home at my house I conditionally turn lights on downstairs based on current light levels in those rooms. Then I always turn the outlets on regardless of which lights turned on since those are for two devices with screens, light level doesn’t matter to them. Today I would need to do the following to make that work:
Remember to do the outlets first since those are always and once conditionals start the script ends
Move all but one of the conditionals into a separate script since logic cannot proceed within this script past a conditional
Move that one remaining conditional to the end (or just put them all in separate scripts because this is kind of a hassle)
I don’t mind that its possible for script execution to end after a conditional but I do feel like that should be an option rather then a requirement.
There are two different action types being discussed: condition and choose. The former’s whole purpose in life is to provide a conditional “exit” type statement. The latter allows a “do something only if something else is true” type statement. So basically, don’t use the first when the second is more appropriate. I believe that was the suggestion in the first reply.
The discussion, though, has lately turned into “WTH is an exit statement called condition, and why is an if statement called choose”.
How is the then keyword not required? And which one? The one with “if” or the one with “elif” or both? How are the conditions differentiated/separated from the actions otherwise? YAML is still YAML.
In my proposal, “if” and “elif” are actions that each contain a list of conditions and a list of actions. The “if”/“elif” contains the conditions, and the “then” contains the actions. For the “else”, there are no conditions, so the “else” just contains the actions.
Your existing implementation of choose doesn’t need an explicit then key word. I like how then is inferred (and not explicitly stated) in the current implementation. That’s what I’ve been describing as being the difference with the example you posted using if-then-elif-etc.
The key word then is also inferred in python.
if x > 50:
#do something
else:
#do something else
as opposed to VB where the key word then is required (plus a terminating end if).
If count = 0 Then
message = "There are no items."
ElseIf count = 1 Then
message = "There is 1 item."
Else
message = $"There are {count} items."
End If
- choose: <== extra line that if doesn't need
- conditions: <== equivalent to if
<conditions>
sequence: <== equivalent to then
<actions>
- conditions: <== equivalent to elif
<conditions>
sequence: <== equivalent to then
<actions>
default: <== equivalent to else
<actions>
except that the “if” version uses smaller words and one less line / level of indentation.
Hmm, kind of see what you’re trying to say there but I never considered the word sequence to be the literal equivalent of then. It’s what Home Assistant has adopted to indicate the beginning of a (literal) sequence of script actions. In fact, it sits at the top of a script where it certainly has never meant then.
But, if all we’re doing is counting key words, I think it may be a tie. Looking at your annotated example, conditions substitutes for both if and elif but the choose version also needs the choose key word itself (i.e. like select, switch, and given, the word is used just once). Six of one, half a dozen of the other.
I still prefer the current implementation over if-then-elif-else.