omry / omegaconf

Flexible Python configuration system. The last one you will ever need.
BSD 3-Clause "New" or "Revised" License
1.91k stars 104 forks source link

Interpolation order problem #1105

Closed ccpocker closed 1 year ago

ccpocker commented 1 year ago

I am using omegaconf to implement some complex logic using a YAML file with interpolation. To achieve this, I registered some new resolvers as follows:

OmegaConf.register_new_resolver(
    "eval", eval
)
OmegaConf.register_new_resolver(
    "select", lambda *x: random.choice(x),use_cache=True
)
OmegaConf.register_new_resolver(
    "sample", lambda x, y: random.uniform(x, y),use_cache=True
)
OmegaConf.register_new_resolver(
    "exclude", lambda x, y, z: x if x != z else y,use_cache=True
)

My yaml file looks like this:

uid: 004
name: split_image_left_right
canvas_width: 1200
canvas_height: 1200
h_safe_padding_ratio: ${sample:0.025,0.6}
w_safe_padding_ratio: ${h_safe_padding_ratio}
layout:
  image0:
    x: ${select:0,${eval:'1-${layout.image0.width}'}}
    y: 1
    width: ${select:0.5,0.6,0.7}
    height: 1
  text0:
    x: ${exclude:0,${eval:'1-${layout.image0.width}'},${layout.image0.x}}
    y: 1
    width: ${eval:'1-${layout.image0.width}'}
    height: 1

However, after resolving the YAML file, the output is not as expected. It seems there is a floating point precision issue, and image0 and text0 are overlapping instead of filling up the image. The resulting output is as follows:

{'uid': 4, 'name': 'split_image_left_right', 'canvas_width': 1200, 'canvas_height': 1200, 'h_safe_padding_ratio': 0.4585672326232832, 'w_safe_padding_ratio': 0.4585672326232832, 'layout': {'image0': {'x': 0, 'y': 1, 'width': 0.7, 'height': 1}, 'text0': {'x': 0.30000000000000004, 'y': 1, 'width': 0.30000000000000004, 'height': 1}}}

My expected output should look like this:

{'uid': 4, 'name': 'split_image_left_right', 'canvas_width': 1200, 'canvas_height': 1200, 'h_safe_padding_ratio': 0.4585672326232832, 'w_safe_padding_ratio': 0.4585672326232832, 'layout': {'image0': {'x': 0, 'y': 1, 'width': 0.7, 'height': 1}, 'text0': {'x': 0.7, 'y': 1, 'width': 0.3, 'height': 1}}}
Jasha10 commented 1 year ago

When you call eval on the expression 1 - 0.7, you get 0.30000000000000004.

>>> 1 - 0.7
0.30000000000000004
>>> eval("1 - 0.7")
0.30000000000000004

I am going to migrate this issue to a discussion as this is not an omegaconf bug.