33

I have the following code in my template:

data: [{% for deet in deets %} {{ deet.value*100|round(1) }}{% if not loop.last %},{% endif %} {% endfor %}]

I am expecting data rounded to 1 decimal place. However, when I view the page or source, this is the output I'm getting:

data: [ 44.2765833818,  44.2765833818,  44.2765833818,  44.2765833818,  44.2765833818,  44.2765833818,  44.2765833818,  44.2765833818,  44.2765833818,  44.2765833818 ]

This is not rounded to 1 decimal place. It runs without a template error or anything, but produces incorrect output. My understanding from the documentation, and even a related stack overflow question, are that my format should work. What am I missing or doing wrong?

Community
  • 1
  • 1
Mittenchops
  • 18,633
  • 33
  • 128
  • 246
  • 1
    It looks like your code is rounding `100` instead of the **product** of `deet.value*100`. You should probably prefer to do the multiplication in your code, and not in the template. – mechanical_meat Jul 30 '13 at 21:19
  • Gotcha, I take your point, but I switched to 100*deet.value | round(3) and that solved it for me. Thanks! – Mittenchops Jul 30 '13 at 21:23

5 Answers5

52

You can put parens around the value that you want to round. (This works for division as well, contrary to what @sobri wrote.)

{{ (deet.value/100)|round }}

NOTE: round returns a float so if you really want the int you have to pass the value through that filter as well.

{{ (deet.value/100)|round|int }}
Community
  • 1
  • 1
John R
  • 683
  • 4
  • 7
40

Didn't realize the filter operator had precedence over multiplication!

Following up on bernie's comment, I switched

{{ deet.value*100|round(1) }}

to

{{ 100*deet.value|round(1) }}

which solved the problem. I agree the processing should happen in the code elsewhere, and that would be better practice.

Mittenchops
  • 18,633
  • 33
  • 128
  • 246
  • This obviously doesn't work for division. In that case, Jinja is incapable of rounding the result. I'm not in agreement with the idea that the maths should be done in a controller rather than view. That's a bad smell masked as a good smell. – sobri Aug 16 '13 at 10:45
  • For a division, put parenthesis around: `{{ (deet.value / 2) | round() }}`. See also: https://stackoverflow.com/questions/66802920/ansible-strange-rounding-behaviour – 4wk_ May 26 '23 at 08:53
6

Try this

{{ (deet.value*100)|round(1) }}

If we didn't put parenthesis, round will do only to 100 not to the result.

Dixon MD
  • 168
  • 2
  • 11
3

I ran across this... needed int(mem_total / 4) in jinja. I solved it by making it two operations:

{% set LS_HEAP_SIZE = grains['mem_total'] / 4 %}
{% set LS_HEAP_SIZE = LS_HEAP_SIZE | round | int %}
Dan Garthwaite
  • 3,436
  • 4
  • 22
  • 32
2

If filter operator has precedence, then you should use round(3) instead of round(1) in "{{ 100*deet.value|round(1) }}"