Apples, oranges, *and* bananas

Objective

The last item in a comma-separated list should be prefaced with the word “and” as opposed to a comma.

Example

Convert this:

Front, Garage, Patio, Yard

to this:

Front, Garage, Patio and Yard

Applications

Useful for creating more natural-sounding phrases for speech synthesis. For example:

Front and Garage doors are open.

as opposed to

Front, Garage doors are open.

Method

Paste this into the Template Editor and experiment with it:

{% set doors = 'Front, Garage, Patio, Yard' %}
{{' and '.join(doors.rsplit(', ', 1))}}

Screenshot from 2020-10-11 11-56-12

Real-World Example

This is used to report any doors left open.

{% set pause = '<silence msec="750"/>' %}
{% set qty = states('sensor.all_doors')|int %}
{% set plural = 's' if qty > 1 else '' %}
{% set prep = 'are' if qty > 1 else 'is' %}
Attention! {{pause}} There {{prep}} {{qty}} door{{plural}} left open. 
{{pause}} {{' and '.join(states('sensor.open_doors').rsplit(', ', 1))}} door{{plural}} 
{{pause}} {{prep}} open.

25 Likes

Thumbs up :slight_smile:
Thanks…

Wow! that is so useful in A LOT of announcement automations. Thanks

Damn, son! I mean, DAMN!!! That is awesome!

I beg to differ. Perhaps you might consider the Oxford Comma?

4 Likes

:musical_note:
Check your passport, it’s no trick
Take the Chapstick, put it on your lips
Crack a smile, adjust my tie
Know your butler, unlike other guys
:musical_note:

1 Like

I love it!

But then again, I’m a bit pedantic about language.

Now, if we could only get all those Unix folks to start using upper-case letters once in a while…

Came for the Oxford comma. Leaving satisfied.

Quick and dirty method is to insert a comma here:

', and '

However, that will cause a comma to be used even if there are only two items in the list. To respect the ‘three items or more’ rule would require a slightly more elaborate template. It would use an Oxford comma only if there are three or more items.

It’s not difficult to implement it but would complicate the original example (I wanted to keep it simple).

{% set doors = 'Front, Garage, Patio, Yard' %}
{% set x = ', and ' if doors.split(', ') | count > 2 else ' and ' %}
{{x.join(doors.rsplit(', ', 1))}}

1 Like

ha nice,

will see if this is now defunct:

            {%- set ns = namespace(not_off=[]) %}
            {%- for s in expand('group.iungo_switches_actueel')
              if  s.object_id.split('_actueel')[0] not in
                    ['inductieplaat','patchboard_zolder'] and
                  states(s.entity_id) != '0' and
                  states('switch.' + s.object_id.split('_actueel')[0]) == 'off' %}

            {%- set ns.not_off = ns.not_off + [s.name+ ': ' + s.state + ' watt'] %}
            {%- endfor %}
            {% set count_not_off = ns.not_off|count %}
            {% set list = ns.not_off %}
            {% if count_not_off == 0 %} All fine
            {%- elif count_not_off == 1 %}
                {{list[0]}} is still using power!
            {%- elif count_not_off == 2 %}
                {{list|join(' and ')}} are still using power!
              {%- else %}
                {{list[:-1]|join(', ')}}, and {{list[-1]}} are still using power!
              {%- endif %}