How to update a Dictionary-Variable?

hi, I only know a little python to play with klipper but until now I found what I needed

now I need a dictionary to store a list of keys and values and like to update the items by a macro

here I have my dictionary
[gcode_macro _test_variables]
variable_feature_hops: {“feature1”: 1.0, “feature2”: 1.5}
gcode:
M115 ; must provide something

here I try to update it
[gcode_macro _set_feature_retraction_zhop]
gcode:
{% set feature_hops = printer[“gcode_macro _test_variables”].feature_hops %}
{% set feature = params.FEATURE|default(“”)|string %}
{% set distance = params.DISTANCE|default(0.0)|float %}

{% if feature != “” and distance >= 0 %}

#each of this lines results in an error
#{% set feature_hops |= {feature: distance} %}
#{% set feature_hops = {feature_hops, feature: distance} %}
#feature_hops.update(feature = distance)
#feature_hops[feature] = distance;    

#while this works
#{% set feature_hops = {feature: distance} %}

#saving the dict back to the macro-variable is not working also
#SET_GCODE_VARIABLE MACRO=_test_variables VARIABLE=feature_hops VALUE={feature_hops}

{action_respond_info('feature_test_zhops: {}'.format(feature_hops))}

{% endif %}

is it possible to read and update dictionary-items or do I have to find another solution?

Try something like:

SET_GCODE_VARIABLE MACRO=_test_variables VARIABLE=feature_hops VALUE='{"mykey": 123.4}'

-Kevin

thanks, result sadly is
Error loading template ‘gcode_macro _set_feature_retraction_zhop:gcode’: jinja2.exceptions.TemplateSyntaxError: expected token ‘end of print statement’, got ‘:’
same result without ‘’

{% set dummy = feature_hops.__setitem__(feature, distance) %}

1 Like

thanks @theophile
this really works to add an item to the dict :slight_smile:
now how do I write the new dictionary back to the other macro’s variable?

SET_GCODE_VARIABLE MACRO=_retraction_variables VARIABLE=feature_hops VALUE={feature_hops}
returns Malformed command ‘SET_GCODE_VARIABLE MACRO=_retraction_variables VARIABLE=feature_hops VALUE={‘featureName’: 1.0, ‘xx1’: 3.0}’
while I think

using VALUE=‘{feature_hops}’ returns Unable to parse ‘{featureName: 1.0, xx1: 3.0}’ as a literal

I feel so near and so far at same time :smiley:
and I’ll have a deeper look into this python stuff

For that, I will refer you to this excellent post by @garethky:

2 Likes

awsome it works
_set_feature_retraction_zhop feature=lala distance=5

feature_retraction_zhops: {‘featureName’: 1.0, ‘lala’: 5.0}
_set_feature_retraction_zhop feature=lulu distance=3
feature_retraction_zhops: {‘featureName’: 1.0, ‘lala’: 5.0, ‘lulu’: 3.0}

using getitem to get an item is the best way also? it works fine, just the first time seems to be slow

foll code for solution:

[gcode_macro _retraction_variables]
variable_feature_hops: {“featureName”: 1.0}

[gcode_macro _set_feature_retraction_zhop]
description: set z-hop distance by feature
gcode:
{% set feature_hops = printer[“gcode_macro _retraction_variables”].feature_hops %}
{% set feature = params.FEATURE|default(“”)|string %}
{% set distance = params.DISTANCE|default(0.0)|float %}

{% if feature != “” and distance >= 0 %}

{% set dummy = feature_hops.__setitem__(feature, distance) %}
SET_GCODE_VARIABLE MACRO=_retraction_variables VARIABLE=feature_hops VALUE="{feature_hops | pprint | replace("\n", "") | replace("\"", "\\\"")}"

{action_respond_info('feature_retraction_zhops: {}'.format(feature_hops))}

{% endif %}

[gcode_macro _get_feature_retraction_zhop]
description: set z-hop distance by feature
gcode:
{% set feature_hops = printer[“gcode_macro _retraction_variables”].feature_hops %}
{% set feature = params.FEATURE|default(“”)|string %}

{% if feature != “” %}
{action_respond_info(‘feature_retraction_zhops: ‘+feature+’={}’.format(feature_hops.__ getitem__(feature)))}
{% endif %}

Yes, __getitem__ works well, and has the benefit of returning None instead of an error if the specified key isn’t in the dictionary for some reason. I don’t think it’s any slower than trying to access the value directly.