You cannot break for loops. You are extremely limited with for loops in jinja. What is your overall goal? There may be a better way to handle this. With Jinja, you need to be very crafty with its limitations.
Yeah, thats not possible with jinja. You need to use filters to remove items from your for loop. I avoid for loops if I can because of this limitation. If the value_template requires a single item, using a for loop will not give you the results you expect. In your example above, you could do something like this:
{% set items = range(0,10) | reject("<", 4) | list %}
{{ items | length > 0 }}
That will return true if the list has items after rejecting everything that is less than 4. It will return false if the list rejected everything.
Like I said, if you know what you want to do in the end, I can help you with the code to get something that works.
EDIT: Just saw the i+2 > 6, changed the syntax to be equivalent by making it < 4 which is equivalent to i+2
My aim is to understand a sentence sent from Telegram.
To do this, I defined 2 (or more) lists of words.
After I’m watching word by word to see if the sentence contains a word of each list.
I tried with a very simple sentence:
- alias: 'good night'
initial_state: 'on'
trigger:
- platform: event
event_type: telegram_text
condition:
- condition: template
value_template: >-
{%- set text = trigger.event.data.text|lower -%}
{%- set text = text.split(' ') -%}
{%- set liste_1 = ["good","well"] -%}
{%- set liste_2 = ["night","nights", "dream", "dreams"] -%}
{% for i in range(0, 10) %}
{% if (text[i] == liste_1[0] or text[i] == liste_1[1] or text[i] == liste_2[0] or text[i] == liste_2[1] or text[i] == liste_2[2] or text[i] == liste_2[3]) %}
{% for j in range(i+1, 11) %}
{% if (text[j] == liste_1[0] or text[j] == liste_1[1] or text[j] == liste_2[0] or text[j] == liste_2[1] or text[j] == liste_2[2] or text[j] == liste_2[3]) %}
true
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
action:
- service: telegram_bot.send_message
data_template:
message: 'Good night!'
title: ''
target: '{{ trigger.event.data.chat_id }}'
With this solution, we can write:
good night,
have a good night
good night to you…
Well it becomes really easy, and every sentence with words in lists are well understand !!
My problem is with this part: {% if (text[j] == liste_1[0] or text[j] == liste_1[1] or text[j] == liste_2[0] or text[j] == liste_2[1] or text[j] == liste_2[2] or text[j] == liste_2[3]) %}
I would like to have a loop here to don’t be obliged to write by hand, and just have to fill in the lists !
So I need to stop the loop immediately if a second word is find !
{% set text = trigger.event.data.text | lower %}
{% set text = text | replace('good', '*') %}
{% set text = text | replace('well', '*') %}
{% set text = text | replace('nights', '*') %}
{% set text = text | replace('night', '*') %}
{% set text = text | replace('dreams', '*') %}
{% set text = text | replace('dream', '*') %}
{{ text | reject("!=", "*") | list | length == 2 }}
This should work. It basically replaces everything in the sentence with your word, if you get 2 of them it passes, any more it fails. You can adjust to your liking.
If you use this method, make sure you replace plural words before non-plural, otherwise it won’t work.
You’d need to use regex to get around that. That is why you should search for plurals first. You’re welcome to learn regex, but from what I’ve seen there is little to no information about the regex formatting used in templating. I haven’t looked hard though.
You would be better served searching for weather.get_forecasts or starting a new thread than necro-ing a 6 year old post with a completely unrelated question.