Skip to content

Commit

Permalink
Return parameters as dictionary instead of list of named tuples.
Browse files Browse the repository at this point in the history
This is a breaking API change. It is noted as such in the docs,
specifically in the doc-string of `Model.parameters()`. The method
is more commonly used for interactive inspection at the Python
prompt, so this change will probably not break much in terms of
application code. The dictionary as the new return type is in line
with other new methods, such as `Model.properties()`.
  • Loading branch information
john-hen committed Apr 9, 2021
1 parent ef3de57 commit f2b1065
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 37 deletions.
28 changes: 16 additions & 12 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,25 @@ Or we could remove all models at once — restart from a clean slate.

## Inspecting models

Let's have a look at the parameters defined in the model.
Let's have a look at the parameters defined in the model:
```python
>>> for parameter in model.parameters():
... print(parameter)
>>> model.parameters()
{'U': '1[V]', 'd': '2[mm]', 'l': '10[mm]', 'w': '2[mm]'}
```

With a little more typing we can include the parameter descriptions:
```python
>>> for (name, value) in model.parameters().items():
... description = model.description(name)
... print(f'{description:20} {name} = {value}')
...
parameter(name='U', value='1[V]', description='applied voltage')
parameter(name='d', value='2[mm]', description='electrode spacing')
parameter(name='l', value='10[mm]', description='plate length')
parameter(name='w', value='2[mm]', description='plate width')
applied voltage U = 1[V]
electrode spacing d = 2[mm]
plate length l = 10[mm]
plate width w = 2[mm]
```

Or the materials for that matter.
Two custom materials are defined:
```python
>>> model.materials()
['medium 1', 'medium 2']
Expand Down Expand Up @@ -281,10 +288,7 @@ well run the time-dependent study a number of times and change the
parameter value from one run to the next. General parameter sweeps
can get quite complicated in terms of how they map to indices as
soon as combinations of parameters are allowed. Support for this may
therefore be dropped in a future release — while the API is still
considered unstable, which it is for as long as the version number
of this library does not start with a 1 —, just to keep things simple
and clean.
therefore be limited.


## Saving results
Expand Down
46 changes: 27 additions & 19 deletions mph/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
########################################
import numpy # fast numerics
from numpy import array # numerical array
from collections import namedtuple # named tuples
import jpype.types as jtypes # Java data types
from pathlib import Path # file-system paths
from warnings import warn # user warning
Expand Down Expand Up @@ -502,8 +501,8 @@ def parameter(self, name, value=None, evaluate=False,
"""
Returns or sets the parameter of the given name.
If no `value` is given, returns the value of parameter `name`.
Otherwise sets it.
Returns the value of parameter `name` if no `value` is given.
Otherwise sets the value.
Values are accepted as expressions (strings, possibly including
the unit inside square brackets) or as numerical values
Expand All @@ -516,9 +515,9 @@ def parameter(self, name, value=None, evaluate=False,
is returned.
*Warning*: The optional arguments `unit` and `description` are
deprecated and will be removed in a future release. Add the unit
to the value string inside square brackets and call the
`description()` method to change a parameter description.
deprecated and will be removed in a future release. Include the
unit in the value expression and call the `description()` method
to change a parameter description.
"""
if unit is not None:
warn('Argument "unit" to Model.parameter() is deprecated. '
Expand All @@ -537,21 +536,31 @@ def parameter(self, name, value=None, evaluate=False,
else:
self.java.param().set(name, value)

def parameters(self):
def parameters(self, evaluate=False):
"""
Returns the global model parameters.
The parameters are returned as a list of tuples holding name,
value, and description for each of them.
The parameters are returned as a dictionary indexed by the
parameter names and mapping to the parameter values.
Value are returned as string expressions, i.e. as entered by
the user, unless `evaluate` is set to `True`, in which case
the expressions are evaluated and the corresponding numbers
are returned.
*Warning*: Prior to version 1.0, this method would return
a list of named tuples holding name, value, and description.
It now returns a dictionary, which is a breaking change that
may require application code to be adapted. The descriptions
can be retrieved by additionally calling `.description()` or
`.descriptions()`.
"""
Parameter = namedtuple('parameter', ('name', 'value', 'description'))
parameters = []
for name in self.java.param().varnames():
name = str(name)
value = str(self.java.param().get(name))
descr = str(self.java.param().descr(name))
parameters.append(Parameter(name, value, descr))
return parameters
if not evaluate:
return {str(name): str(self.java.param().get(name))
for name in self.java.param().varnames()}
else:
return {str(name): str(self.java.param().evaluate(name))
for name in self.java.param().varnames()}

def description(self, name, text=None):
"""
Expand All @@ -568,8 +577,7 @@ def description(self, name, text=None):

def descriptions(self):
"""Returns all parameter descriptions as a dictionary."""
names = [name for (name, value, description) in self.parameters()]
return {name: self.description(name) for name in names}
return {name: self.description(name) for name in self.parameters()}

def property(self, node, name, value=None):
"""
Expand Down
10 changes: 4 additions & 6 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,10 @@ def test_parameter():


def test_parameters():
parameters = model.parameters()
names = [parameter.name for parameter in parameters]
assert 'U' in names
assert 'd' in names
assert 'l' in names
assert 'w' in names
assert 'U' in model.parameters()
assert 'U' in model.parameters().keys()
assert '1[V]' in model.parameters().values()
assert ('U', '1[V]') in model.parameters().items()


def test_description():
Expand Down

0 comments on commit f2b1065

Please sign in to comment.