amr125 - 6 months ago 30

Python Question

I am making a python program in which random values are generated *n* times, to be used as parameter values for model simulation.

I have a dictionary defining the boundaries for each parameter, for example:

`parameters = {'A': random.uniform(1,10), 'B': random.uniform(20,40)}`

I want to add some parameters the sum of which has to be 1, something like:

`params = {'C1': random.uniform(0.0,1.0), 'C2': 1 - params['C1']}`

This latter obviously doesn't work producing the

`KeyError: 'C1'`

I also tried something like:

`params = {'A': random.uniform(1,10), 'B': random.uniform(20,40), 'C': {'C1': None,'C2': None}}`

def class_fractions():

for key in params['C']:

if key == 'C1':

params['C'][key] = random.uniform(0.0,1.0)

if key == 'C2':

params['C'][key] = 1.0 - params['C'][key]

but after calling the function I get the TypeError

`TypeError: unsupported operand type(s) for -: 'float' and 'NoneType'`

Any suggestion?

Answer

From your use of the `for`

loop it looks like you may really have many more parameters than just two. In that case you can generate a list of values filled with random numbers, and *then* scale it to sum to one, as described in this other answer. Then iterate over a zipped view of your dictionary keys and the list items and assign the items to the dictionary.

Or, operating directly on the dictionary:

```
params = {k: random.uniform(0, 1) for k in ('C1', 'C2', 'C3')}
total = sum(params.values())
params = {k: (v / total) for k, v in params.items()}
```