DiODeProject / MuMoT

Multiscale Modelling Tool - mathematical modelling without the maths
https://mumot.readthedocs.io/
GNU General Public License v3.0
21 stars 5 forks source link

Allow for creating models from Python strings #156

Open willfurnass opened 6 years ago

willfurnass commented 6 years ago

Following on from #67 I I think it would be a very good thing if MuMoT models could be created and referenced in Notebooks without using Notebook cell execution numbers. At present the example Notebooks contain cells like:

%%model
$
U -> A : g_A
U -> B : g_B
A -> U : a_A
B -> U : a_B 
A + U -> A + A : r_A
B + U -> B + B : r_B
A + B -> A + U : s
A + B -> B + U : s
$

then

model1 = mumot.parseModel(In[2])

This approach causes problems for the user if they want to re-run a given cell as then calls like mumot.parseModel(In[X}) in subsequent cells won't work without manual editing of the cell execution number.

I suggest that what's needed is a Python function to generate a model from a multi-line string:

model_1 = mumot.model_from_latex("""
U -> A : g_A
U -> B : g_B
A -> U : a_A
B -> U : a_B 
A + U -> A + A : r_A
B + U -> B + B : r_B
A + B -> A + U : s
A + B -> B + U : s
""")

This is almost as readable as the but should allow Notebooks to be run more flexibly and robustly. You'd loose the LaTeX rendering beneath the %%model magic cells but that seems redundant given that MuMoTmodel.show() produces a more attractive rendering of that information.

Another advantage of allowing models to be generated by parsing a Python string is that it would make it easier to create models for unit testing outside Notebooks.

jarmarshall commented 6 years ago

If this is necessary to close issue #157 I should be able to do something quick in a few days - the existing functionality is probably nicer for a user though - it separates describing the model from writing the function call to parse the model.

willfurnass commented 6 years ago

NB this can currently be done with e.g.

model1 = mumot.parseModel("""
U -> A : g_1
U -> B : g_2
A -> U : a_1
B -> U : a_2
A + U -> A + A : r_1
B + U -> B + B : r_2
A + B -> A + U : s
A + B -> B + U : s
""".replace('\n', '\\n'))

Some extra logic in parseModel would allow .replace('\n', '\\n') to be omitted in the above.

jarmarshall commented 6 years ago

You mean it already works as described @willfurnass (I'd be surprised unless you changed something) or it would be straightforward to make it work (I agree, was thinking the same, and could make the change quickly)?

willfurnass commented 6 years ago

The snipped of code in https://github.com/DiODeProject/MuMoT/issues/156#issuecomment-428546922 works for me. I tried something like this a while ago but think I was missing the .replace('\n', '\\n').

jarmarshall commented 6 years ago

Great, on reflection I can see why this would work - since this is a satisfactory workaround for testing purposes I can focus now on #158

jarmarshall commented 6 years ago

Feel free to add some pre-processing to the input string within the parseModel(...) method though, and close