Skip to content

Commit 5c3a323

Browse files
Merge pull request #398 from SDXorg/dev-3.9.0
v3.9.0
2 parents a68fa44 + 7e13cf6 commit 5c3a323

File tree

23 files changed

+506
-78
lines changed

23 files changed

+506
-78
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ For standard methods for data analysis with SD models, see the [PySD Cookbook](
3333

3434
## Why create a new SD simulation engine?
3535

36-
There are a number of great SD programs out there ([Vensim](http://vensim.com/), [iThink](http://www.iseesystems.com/Softwares/Business/ithinkSoftware.aspx), [AnyLogic](http://www.anylogic.com/system-dynamics), [Insight Maker](http://insightmaker.com/), and [others](http://en.wikipedia.org/wiki/List_of_system_dynamics_software)). In order not to waste our effort, or fall victim to the [Not-Invented-Here](http://en.wikipedia.org/wiki/Not_invented_here) fallacy, we should have a very good reason for starting a new project.
36+
There are a number of great SD programs out there ([Vensim](http://vensim.com/), [iThink](http://www.iseesystems.com/Softwares/Business/ithinkSoftware.aspx), [AnyLogic](http://www.anylogic.com/system-dynamics), [Insight Maker](http://insightmaker.com/), and [others](https://en.wikipedia.org/wiki/Comparison_of_system_dynamics_software)). In order not to waste our effort, or fall victim to the [Not-Invented-Here](http://en.wikipedia.org/wiki/Not_invented_here) fallacy, we should have a very good reason for starting a new project.
3737

3838
That reason is this: There is a whole world of computational tools being developed in the larger data science community. **System dynamicists should directly use the tools that other people are building, instead of replicating their functionality in SD specific software.** The best way to do this is to bring specific SD functionality to the domain where those other tools are being developed.
3939

docs/command_line_usage.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,15 @@ In order to split the Vensim model views in different files, as explained in :do
5858

5959
.. code-block:: text
6060
61-
python -m pysd --split-views many_views_model.mdl
61+
python -m pysd many_views_model.mdl --split-views
62+
63+
The previous code will put each model view in a separate Python module. Additionally, if the names of the views include the concepts of subsubmodules (e.g., ENERGY-transformation.efficiency_improvement), the *--subview-sep* (subview separators) argument may be used to further classify the model equations:
64+
65+
.. code-block:: text
66+
67+
python -m pysd many_views_and_subviews_model.mdl --split-views --subview-sep - .
68+
69+
Note that passing any positional argument right after the *--subview-sep* argument will raise an error, so it is recommended to pass this argument as the last one.
6270

6371

6472
Outputting various run information
@@ -102,7 +110,7 @@ modified using the *-I/--initial_time*, *-F/--final-time*, *-T/--time-step* and
102110

103111
.. code-block:: text
104112
105-
python -m pysd -I 2005 --final-time=2010 --time-step=1 Teacup.mdl
113+
python -m pysd -I=2005 --final-time=2010 --time-step=1 Teacup.mdl
106114
107115
will set the initial time to 2005, the final time to 2010 and the time step to 1.
108116

docs/development/adding_functions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Adding new functions
22
====================
3-
In this section you may found some helpful examples for adding a new function to the PySD Python builder. Before starting adding any new feature or fuction, please, make sure that no one is working on it. Search if any open issue exists with the feature you want to work on or open a new one if it does not exist. Then, claim that you are working on it.
3+
In this section you may find some helpful examples for adding a new function to the PySD Python builder. Before starting adding any new feature or function, please, make sure that no one is working on it. Search if any open issue exists with the feature you want to work on or open a new one if it does not exist. Then, claim that you are working on it.
44

55
Adding a hardcoded function
66
---------------------------

docs/structure/structure_index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ While something like :py:data:`1<5 and 5>3`::
3333

3434
LogicStructure(operators=[':AND:'], arguments=(LogicStructure(operators=['<'], arguments=(1, 5)), LogicStructure(operators=['>'], arguments=(5, 3))))
3535

36-
The parenthesis also affects same order operatos, for example :py:data:`1+2-3` is translated to::
36+
The parenthesis also affects same order operators, for example :py:data:`1+2-3` is translated to::
3737

3838
ArithmeticStructure(operators=['+', '-'], arguments=(1, 2, 3))
3939

docs/whats_new.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
11
What's New
22
==========
3+
v3.9.0 (2022/12/15)
4+
-------------------
5+
6+
New Features
7+
~~~~~~~~~~~~
8+
- Parses and ignores reality check functions during translation of Vensim models. (`@rogersamso <https://github.com/rogersamso>`_)
9+
10+
Breaking changes
11+
~~~~~~~~~~~~~~~~
12+
13+
Deprecations
14+
~~~~~~~~~~~~
15+
16+
Bug fixes
17+
~~~~~~~~~
18+
- Fix issue with the classification of variables in modules and submodules (:issue:`388`). When a model had a view with 3 sublevels (e.g. energy-transformation.losses) but another view was defined with only two of them (e.g. energy-transformation), the variables in the second view were placed in the main model file. Now, if this happens, the variables in the second view will be placed in a main.py file (i.e. energy/transformation/main.py). (`@rogersamso <https://github.com/rogersamso>`_)
19+
- Fix bug on the CLI when passing a hyphen as first value to the *--subview-sep* argument (:issue:`388`). (`@rogersamso <https://github.com/rogersamso>`_)
20+
- Fix bug on the CLI when parsing initial conditions (:issue:`395`). (`@rogersamso <https://github.com/rogersamso>`_)
21+
22+
Documentation
23+
~~~~~~~~~~~~~
24+
- The `Splitting Vensim views in different files` section in :doc:`command_line_usage` has been updated to include an example of the usage of the *--subview-sep* CLI argument. (`@rogersamso <https://github.com/rogersamso>`_)
25+
26+
Performance
27+
~~~~~~~~~~~
28+
29+
Internal Changes
30+
~~~~~~~~~~~~~~~~
31+
- The :py:meth:`_merge_nested_dicts` method from the :py:class:`pysd.translators.vensim.vensim_file.VensimFile` class has been made a static method, as it does not need to access any attribute of the instance, and it does facilitate unit testing. (`@rogersamso <https://github.com/rogersamso>`_)
32+
- The `pysd/translators/vensim/parsing_grammars/element_object.peg` grammar has been modified to be able to parse reality check elements. (`@rogersamso <https://github.com/rogersamso>`_)
33+
- :py:class:`pysd.translators.vensim.vensim_element.Constraint` and :py:class:`pysd.translators.vensim.vensim_element.TestInputs` classes have been added, which inherit from the also newly created :py:class:`pysd.translators.vensim.vensim_element.GenericComponent`, which include the :py:meth:`parse` and :py:meth:`get_abstract_component` methods. (`@rogersamso <https://github.com/rogersamso>`_ and `@enekomartinmartinez <https://github.com/enekomartinmartinez>`_)
34+
- The :py:class:`pysd.translators.structures.abstract_model.AbstractSection` class now has two extra attributes (:py:data:`constraints` and :py:data:`input_tests`), which hold the :py:class:`pysd.translators.structures.abstract_model.AbstractConstraint` and :py:class:`pysd.translators.structures.abstract_model.AbstractTestInputs` objects. (`@rogersamso <https://github.com/rogersamso>`_)
35+
336
v3.8.0 (2022/11/03)
437
-------------------
538

pysd/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.8.0"
1+
__version__ = "3.9.0"

pysd/builders/python/python_expressions_builder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def reshape(self, subscripts: SubscriptManager,
130130
def lower_order(self, new_order: int) -> None:
131131
"""
132132
Lower the order to maintain the correct order in arithmetic
133-
operations. If the requestes order is smaller than the current
133+
operations. If the requested order is smaller than the current
134134
order parenthesis will be added to the expression to lower its
135135
order to 0.
136136
@@ -411,7 +411,7 @@ def build(self, arguments: dict) -> BuildAST:
411411
412412
"""
413413
# Game calls are ignored as we have no support for a similar
414-
# feature, we simpli return the content inside the GAME call
414+
# feature, we simply return the content inside the GAME call
415415
return arguments["expr"]
416416

417417

pysd/cli/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from .parser import parser
1414

15+
1516
def main(args):
1617
"""
1718
Main function. Reads user arguments, loads the models,

pysd/cli/parser.py

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
cmdline parser
33
"""
44
import os
5+
import re
56
from ast import literal_eval
67
import numpy as np
78
import pandas as pd
@@ -113,15 +114,6 @@ def split_timestamps(string):
113114
f'See {docs} for examples.')
114115

115116

116-
def split_subview_sep(string):
117-
"""
118-
Splits the subview separators
119-
--subview-sep ' - ,.' -> [' - ', '.']
120-
121-
"""
122-
return string.split(",")
123-
124-
125117
def split_vars(string):
126118
"""
127119
Splits the arguments from new_values.
@@ -141,8 +133,8 @@ def split_vars(string):
141133
var, value = string.split(':')
142134
type = 'initial'
143135

144-
if value.strip().isnumeric():
145-
# value is float
136+
if re.match(r"^[+-]?(\d*\.)?\d+$", value.strip()):
137+
# value is a number
146138
return {var.strip(): (type, float(value))}
147139

148140
# value is series
@@ -193,7 +185,7 @@ def __call__(self, parser, namespace, values, option_string=None):
193185
parser.add_argument(
194186
'-o', '--output-file', dest='output_file',
195187
type=check_output, metavar='FILE',
196-
help='output file to save run outputs (.tab or .csv)')
188+
help='output file to save run outputs (.tab, .csv or .nc)')
197189

198190
parser.add_argument(
199191
'-p', '--progress', dest='progress',
@@ -282,11 +274,12 @@ def __call__(self, parser, namespace, values, option_string=None):
282274

283275
trans_arguments.add_argument(
284276
'--subview-sep', dest='subview_sep',
285-
action='store', type=split_subview_sep, default=[],
286-
metavar='\'STRING1,STRING2,..,STRINGN\'',
287-
help='further division of views split in subviews, by identifying the'
277+
action='store', nargs="*", default=[],
278+
metavar='separator_1 separator_2 ... separator_n',
279+
help='further division of views into subviews, by identifying the '
288280
'separator string in the view name, only availabe if --split-views'
289-
' is used')
281+
' is used. Passing positional arguments after this argument will'
282+
' not work')
290283

291284

292285
#######################
@@ -316,17 +309,17 @@ def __call__(self, parser, namespace, values, option_string=None):
316309
parser.add_argument('new_values',
317310
metavar='variable=new_value', type=split_vars,
318311
nargs='*', action=SplitVarsAction,
319-
help='redefine the value of variable with new value.'
320-
'variable must be a model component, new_value can be a '
321-
'float or a a list of two list')
312+
help='redefine the value of variable with new value. '
313+
'variable must be a model component, new_value may be a '
314+
'float or a list of two lists')
322315

323-
# The destionation new_values2 will never used as the previous argument
316+
# The destination new_values2 will never be used as the previous argument
324317
# is given also with nargs='*'. Nevertheless, the following variable
325318
# is declared for documentation
326319
parser.add_argument('new_values2',
327320
metavar='variable:initial_value', type=split_vars,
328321
nargs='*', action=SplitVarsAction,
329-
help='redefine the initial value of variable.'
322+
help='redefine the initial value of variable. '
330323
'variable must be a model stateful element, initial_value'
331324
' must be a float')
332325

pysd/py_backend/allocation.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -682,13 +682,11 @@ def allocate_by_priority(request, priority, width, supply):
682682

683683
if np.any(width <= 0):
684684
raise ValueError(
685-
f"width={width} is not allowed. width should be greater than 0."
686-
)
685+
f"width={width} \n is not allowed. width must be greater than 0.")
687686

688687
if np.any(supply < 0):
689688
raise ValueError(
690-
f"supply={supply} is not allowed. supply should be non-negative."
691-
)
689+
f"supply={supply} \n is not allowed. supply must not be negative.")
692690

693691
if len(request.shape) == 1:
694692
# NUMPY: avoid '.values' and return directly the result of the

0 commit comments

Comments
 (0)