0

I want to setup an environment in a Jupyter notebook where parameters are stored in a dictionary parValue and where you can change values of one or several parameters with a function par(), while letting the actual dictionary parValue stay "under the hood", i.e not directly used by the user. The following setup script` partest.py does that:

global parValue; parValue = {}

parValue['a'] = 1
parValue['b'] = 2

def par(parValue=parValue, *x, **x_kwarg):
   x_kwarg.update(*x)
   x_temp = {}
   for key in x_kwarg.keys():
       if key in parValue.keys():
          x_temp.update({key: x_kwarg[key]})
       else:
          print('Error')
    parValue.update(x_temp)

In a Jupyter notebook I can then write:

run -i partest.py

# Change a single parameter
par(a=1.5)

# Change two parameters
par(a=1.1, b=2.1)

However, I also want to be able to change the entire dictionary parValue to, say, parValue2 with a similar command:

parValue2 = {'a':1.2, 'b':2.2}

par(parValue2)

But that does not work. I do not get any error message, but parValue2 does not propagate to parValue.

How could the function par() above be modified to handle this?

I know that in the notebook I could have the command:

parValue.update(parValue2) 

but I want the dictionary parValue to be "hidden" for the person who uses the notebook.

8
  • See this post stackoverflow.com/questions/67738000/… Commented Nov 4 at 10:21
  • what means "does not work"? Do you get error? if yes then show it in question (not in comments) Commented Nov 4 at 10:23
  • I do not get any error but values of parValue2 does not go through to the underlying dictionary in the script parValue. Commented Nov 4 at 10:25
  • 1
    Seems par(**parValue2) does the work. I will check it more in a few hours. Other ideas still welcome. Commented Nov 4 at 10:30
  • 2
    Why does the function have the parValue parameter at all? Commented Nov 4 at 10:57

1 Answer 1

1

Adding a print statement to your function shows the problem:

def par(parValue=parValue, *x, **x_kwarg):
   print(f"{parValue = } / {x = } / {x_kwarg = }")
   x_kwarg.update(*x)
   x_temp = {}
   for key in x_kwarg.keys():
       if key in parValue.keys():
          x_temp.update({key: x_kwarg[key]})
       else:
          print('Error')
       parValue.update(x_temp)


par(parValue2)
parValue = {'a': 1.2, 'b': 2.2} / x = () / x_kwarg = {}

As you can see, parValue2 is assigned to the 1st parameter, which is parValue.

You can fix this by moving the *x parameter:

def par(*x, parValue=parValue, **x_kwarg):
   print(f"{parValue = } / {x = } / {x_kwarg = }")
   x_kwarg.update(*x)
   for key in x_kwarg.keys():
       if key in parValue.keys():
          x_temp.update({key: x_kwarg[key]})
       else:
          print('Error')
       parValue.update(x_temp)


print(parValue)
{'a': 1, 'b': 2}

par(parValue2)
parValue = {'a': 1, 'b': 2} / x = ({'a': 1.2, 'b': 2.2},) / x_kwarg = {}

print(parValue)
{'a': 1.2, 'b': 2.2}
  • As as been stated, you can also call par(**parValue2) : then parValue2 will be unpacked, and repacked as x_kwarg.

  • You might also want to remove parValue as a default parameter. [and instead add global parValue as the first statement in your function] -> not necessary since parValue is mutable and used as such.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.