I have a dict with which I'm doing simple arithmetic operations. That is fine, but when I print result I just get the result for the last key-value pair, not for all of them.
Thanks.
- hosts: localhost
gather_facts: false
vars:
dict1: [{x: 1, y: 2},{x: 3, y: 4},{x: 5, y: 6}]
tasks:
- set_fact:
percentage: "{{ item.x / item.y * 100}}"
with_items: "{{dict1}}"
>ok: [localhost] => (item={'x': 1, 'y': 2}) => {
"ansible_facts": {
"percentage": "50.0"
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"x": 1,
"y": 2
}
}
>ok: [localhost] => (item={'x': 3, 'y': 4}) => {
"ansible_facts": {
"percentage": "75.0"
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"x": 3,
"y": 4
}
}
>ok: [localhost] => (item={'x': 5, 'y': 6}) => {
"ansible_facts": {
"percentage": "83.33333333333334"
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"x": 5,
"y": 6
}
}
Result when I print it:
debug:
msg: "{{ percentage }}"
It's only the last value:
ok: [localhost] => { "msg": "83.33333333333334" }
UPDATE (WITH REGISTER):
- name: Show percentage
debug:
msg: "{{ item.x / item.y * 100}}"
with_items: "{{ dict1 }}"
register: percentage
- name: Show result
debug:
var: percentage # dict
- name: Show result
debug:
var: percentage.results # list
RESULT (with not only results, but also item, loop and other informational things I don't need):
>ok: [localhost] => {
"percentage.results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": {
"x": 1,
"y": 2
},
"msg": "50.0"
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": {
"x": 3,
"y": 4
},
"msg": "75.0"
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": {
"x": 5,
"y": 6
},
"msg": "83.33333333333334"
}
]
}
CodePudding user response:
"I just get the result for the last key-value pair, not for all of them."
That is the expected behavior for the shown set_fact
loop since it is registering every loop run the value new.
You may let run the following example
- name: Show percentage
debug:
msg: "{{ item.x / item.y * 100}}"
with_items: "{{ dict1 }}"
register: percentage
- name: Show result
debug:
var: percentage # dict
to get familiar with Registering variables and the returned data structure for loop.
When you register a variable in a task with a loop, the registered variable contains a value for each item in the loop. The data structure placed in the variable during the loop will contain a
results
attribute, that is a list of all responses from the module.
After first test and regarding
Yes, but I get all other info that I don't need need i.e. ansible_loop_var': 'item'}, {'ansible_facts' ... or failed': False, 'changed': False, 'item':.. I need just a list with pure results, without that additional info.
to narrow down you could do further runs with
- name: Show result
debug:
var: percentage.results # list
resulting into an output of
ok: [localhost] =>
msg:
- ansible_loop_var: item
changed: false
failed: false
item:
x: 1
y: 2
msg: '50.0'
- ansible_loop_var: item
changed: false
failed: false
item:
x: 3
y: 4
msg: '75.0'
- ansible_loop_var: item
changed: false
failed: false
item:
x: 5
y: 6
msg: '83.3333333333'
That is one possible approach for creating a result list.
Follow Up
It seems that you like to have the percentage results only. Therefore it will be necessary to work further on the list to get the values of the msg
element out.
A very simple approach and which isn't mentioned for further data processing
- name: Show result
debug:
msg: "{{ item.msg }}"
loop: "{{ percentage.results }}"
loop_control:
label: "{{ item.item }}"
will result into an output of
TASK [Show result] ****************************
ok: [localhost] => (item={u'y': 2, u'x': 1}) =>
msg: '50.0'
ok: [localhost] => (item={u'y': 4, u'x': 3}) =>
msg: '75.0'
ok: [localhost] => (item={u'y': 6, u'x': 5}) =>
msg: '83.3333333333'
CodePudding user response:
Use Jinja to create the list. For example,
percentage: |
[
{% for i in dict1 %}
{{ i.x / i.y }},
{% endfor %}
]
gives
percentage:
- 0.5
- 0.75
- 0.8333333333333334
Example of a complete playbook for testing
- hosts: localhost
vars:
dict1: [{x: 1, y: 2},{x: 3, y: 4},{x: 5, y: 6}]
percentage: |
[
{% for i in dict1 %}
{{ i.x / i.y }},
{% endfor %}
]
tasks:
- debug:
var: percentage|type_debug
- debug:
var: percentage