From 655c61c0aa1a08c7673b71e75541aff9bad67a5d Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 09:18:10 -0700 Subject: [PATCH 01/26] Abstract the Book baseline test driver so we can re-use in online docs --- examples/pyomobook/test_book_examples.py | 631 +++++------------------ pyomo/common/unittest.py | 409 +++++++++++++++ 2 files changed, 528 insertions(+), 512 deletions(-) diff --git a/examples/pyomobook/test_book_examples.py b/examples/pyomobook/test_book_examples.py index 1aa2a3ed6b3..af7e9e33d20 100644 --- a/examples/pyomobook/test_book_examples.py +++ b/examples/pyomobook/test_book_examples.py @@ -10,34 +10,13 @@ # ___________________________________________________________________________ import pyomo.common.unittest as unittest -import filecmp import glob import os -import os.path -import re -import subprocess -import sys -from itertools import zip_longest -from pyomo.opt import check_available_solvers -from pyomo.common.dependencies import attempt_import, check_min_version -from pyomo.common.fileutils import this_file_dir, import_file -from pyomo.common.log import LoggingIntercept, pyomo_formatter -from pyomo.common.tee import capture_output +from pyomo.common.dependencies import attempt_import +from pyomo.common.fileutils import this_file_dir import pyomo.environ as pyo -def gurobi_fully_licensed(): - m = pyo.ConcreteModel() - m.x = pyo.Var(list(range(2001)), within=pyo.NonNegativeReals) - m.o = pyo.Objective(expr=sum(m.x.values())) - try: - results = pyo.SolverFactory('gurobi').solve(m, tee=True) - pyo.assert_optimal_termination(results) - return True - except: - return False - - parameterized, param_available = attempt_import('parameterized') if not param_available: raise unittest.SkipTest('Parameterized is not available.') @@ -47,504 +26,132 @@ def gurobi_fully_licensed(): bool(matplotlib_available) -# Find all *.txt files, and use them to define baseline tests currdir = this_file_dir() -datadir = currdir - -solver_dependencies = { - # abstract_ch - 'test_abstract_ch_wl_abstract_script': ['glpk'], - 'test_abstract_ch_pyomo_wl_abstract': ['glpk'], - 'test_abstract_ch_pyomo_solve1': ['glpk'], - 'test_abstract_ch_pyomo_solve2': ['glpk'], - 'test_abstract_ch_pyomo_solve3': ['glpk'], - 'test_abstract_ch_pyomo_solve4': ['glpk'], - 'test_abstract_ch_pyomo_solve5': ['glpk'], - 'test_abstract_ch_pyomo_diet1': ['glpk'], - 'test_abstract_ch_pyomo_buildactions_works': ['glpk'], - 'test_abstract_ch_pyomo_abstract5_ns1': ['glpk'], - 'test_abstract_ch_pyomo_abstract5_ns2': ['glpk'], - 'test_abstract_ch_pyomo_abstract5_ns3': ['glpk'], - 'test_abstract_ch_pyomo_abstract6': ['glpk'], - 'test_abstract_ch_pyomo_abstract7': ['glpk'], - 'test_abstract_ch_pyomo_AbstractH': ['ipopt'], - 'test_abstract_ch_AbstHLinScript': ['glpk'], - 'test_abstract_ch_pyomo_AbstractHLinear': ['glpk'], - # blocks_ch - 'test_blocks_ch_lotsizing': ['glpk'], - 'test_blocks_ch_blocks_lotsizing': ['glpk'], - # dae_ch - 'test_dae_ch_run_path_constraint_tester': ['ipopt'], - # gdp_ch - 'test_gdp_ch_pyomo_gdp_uc': ['glpk'], - 'test_gdp_ch_pyomo_scont': ['glpk'], - 'test_gdp_ch_pyomo_scont2': ['glpk'], - 'test_gdp_ch_scont_script': ['glpk'], - # intro_ch' - 'test_intro_ch_pyomo_concrete1_generic': ['glpk'], - 'test_intro_ch_pyomo_concrete1': ['glpk'], - 'test_intro_ch_pyomo_coloring_concrete': ['glpk'], - 'test_intro_ch_pyomo_abstract5': ['glpk'], - # mpec_ch - 'test_mpec_ch_path1': ['path'], - 'test_mpec_ch_nlp_ex1b': ['ipopt'], - 'test_mpec_ch_nlp_ex1c': ['ipopt'], - 'test_mpec_ch_nlp_ex1d': ['ipopt'], - 'test_mpec_ch_nlp_ex1e': ['ipopt'], - 'test_mpec_ch_nlp_ex2': ['ipopt'], - 'test_mpec_ch_nlp1': ['ipopt'], - 'test_mpec_ch_nlp2': ['ipopt'], - 'test_mpec_ch_nlp3': ['ipopt'], - 'test_mpec_ch_mip1': ['glpk'], - # nonlinear_ch - 'test_rosen_rosenbrock': ['ipopt'], - 'test_react_design_ReactorDesign': ['ipopt'], - 'test_react_design_ReactorDesignTable': ['ipopt'], - 'test_multimodal_multimodal_init1': ['ipopt'], - 'test_multimodal_multimodal_init2': ['ipopt'], - 'test_disease_est_disease_estimation': ['ipopt'], - 'test_deer_DeerProblem': ['ipopt'], - # scripts_ch - 'test_sudoku_sudoku_run': ['glpk'], - 'test_scripts_ch_warehouse_script': ['glpk'], - 'test_scripts_ch_warehouse_print': ['glpk'], - 'test_scripts_ch_warehouse_cuts': ['glpk'], - 'test_scripts_ch_prob_mod_ex': ['glpk'], - 'test_scripts_ch_attributes': ['glpk'], - # optimization_ch - 'test_optimization_ch_ConcHLinScript': ['glpk'], - # overview_ch - 'test_overview_ch_wl_mutable_excel': ['glpk'], - 'test_overview_ch_wl_excel': ['glpk'], - 'test_overview_ch_wl_concrete_script': ['glpk'], - 'test_overview_ch_wl_abstract_script': ['glpk'], - 'test_overview_ch_pyomo_wl_abstract': ['glpk'], - # performance_ch - 'test_performance_ch_wl': ['gurobi', 'gurobi_persistent', 'gurobi_license'], - 'test_performance_ch_persistent': ['gurobi_persistent'], -} -package_dependencies = { - # abstract_ch' - 'test_abstract_ch_pyomo_solve4': ['yaml'], - 'test_abstract_ch_pyomo_solve5': ['yaml'], - # gdp_ch - 'test_gdp_ch_pyomo_scont': ['yaml'], - 'test_gdp_ch_pyomo_scont2': ['yaml'], - 'test_gdp_ch_pyomo_gdp_uc': ['sympy'], - # overview_ch' - 'test_overview_ch_wl_excel': ['pandas', 'xlrd'], - 'test_overview_ch_wl_mutable_excel': ['pandas', 'xlrd'], - # scripts_ch' - 'test_scripts_ch_warehouse_cuts': ['matplotlib'], - # performance_ch' - 'test_performance_ch_wl': ['numpy', 'matplotlib'], -} - -# -# Initialize the availability data -# -solvers_used = set(sum(list(solver_dependencies.values()), [])) -available_solvers = check_available_solvers(*solvers_used) -if gurobi_fully_licensed(): - available_solvers.append('gurobi_license') -solver_available = {solver_: (solver_ in available_solvers) for solver_ in solvers_used} - -package_available = {} -package_modules = {} -packages_used = set(sum(list(package_dependencies.values()), [])) -for package_ in packages_used: - pack, pack_avail = attempt_import(package_) - package_available[package_] = pack_avail - package_modules[package_] = pack - - -def check_skip(name): - """ - Return a boolean if the test should be skipped - """ - - if name in solver_dependencies: - solvers_ = solver_dependencies[name] - if not all([solver_available[i] for i in solvers_]): - # Skip the test because a solver is not available - _missing = [] - for i in solvers_: - if not solver_available[i]: - _missing.append(i) - return "Solver%s %s %s not available" % ( - 's' if len(_missing) > 1 else '', - ", ".join(_missing), - 'are' if len(_missing) > 1 else 'is', - ) - - if name in package_dependencies: - packages_ = package_dependencies[name] - if not all([package_available[i] for i in packages_]): - # Skip the test because a package is not available - _missing = [] - for i in packages_: - if not package_available[i]: - _missing.append(i) - return "Package%s %s %s not available" % ( - 's' if len(_missing) > 1 else '', - ", ".join(_missing), - 'are' if len(_missing) > 1 else 'is', - ) - - # This is a hack, xlrd dropped support for .xlsx files in 2.0.1 which - # causes problems with older versions of Pandas<=1.1.5 so skipping - # tests requiring both these packages when incompatible versions are found - if ( - 'pandas' in package_dependencies[name] - and 'xlrd' in package_dependencies[name] - ): - if check_min_version( - package_modules['xlrd'], '2.0.1' - ) and not check_min_version(package_modules['pandas'], '1.1.6'): - return "Incompatible versions of xlrd and pandas" - - return False - -def filter(line): - """ - Ignore certain text when comparing output with baseline - """ - for field in ( - '[', - 'password:', - 'http:', - 'Job ', - 'Importing module', - 'Function', - 'File', - 'Matplotlib', - '-------', - '=======', - ' ^', - ): - if line.startswith(field): - return True - for field in ( - 'Total CPU', - 'Ipopt', - 'license', - 'Status: optimal', - 'Status: feasible', - 'time:', - 'Time:', - 'with format cpxlp', - 'usermodel = 1 else '', + ", ".join(_missing), + 'are' if len(_missing) > 1 else 'is', + ) + + if name in self.package_dependencies: + packages_ = self.package_dependencies[name] + if not all([self.package_available[i] for i in packages_]): + # Skip the test because a package is not available + _missing = [] + for i in packages_: + if not self.package_available[i]: + _missing.append(i) + return "Package%s %s %s not available" % ( + 's' if len(_missing) > 1 else '', + ", ".join(_missing), + 'are' if len(_missing) > 1 else 'is', + ) + + # This is a hack, xlrd dropped support for .xlsx files in 2.0.1 which + # causes problems with older versions of Pandas<=1.1.5 so skipping + # tests requiring both these packages when incompatible versions are found + if ( + 'pandas' in self.package_dependencies[name] + and 'xlrd' in self.package_dependencies[name] + ): + if check_min_version( + self.package_modules['xlrd'], '2.0.1' + ) and not check_min_version(self.package_modules['pandas'], '1.1.6'): + return "Incompatible versions of xlrd and pandas" + + return False + + def filter_fcn(self, line): + """ + Ignore certain text when comparing output with baseline + """ + for field in ( + '[', + 'password:', + 'http:', + 'Job ', + 'Importing module', + 'Function', + 'File', + 'Matplotlib', + '-------', + '=======', + ' ^', + ): + if line.startswith(field): + return True + for field in ( + 'Total CPU', + 'Ipopt', + 'license', + 'Status: optimal', + 'Status: feasible', + 'time:', + 'Time:', + 'with format cpxlp', + 'usermodel = Date: Tue, 9 Jan 2024 09:22:18 -0700 Subject: [PATCH 02/26] Update OnlineDocs test driver to use the standard baseline driver --- doc/OnlineDocs/tests/test_examples.py | 299 +++++--------------------- 1 file changed, 48 insertions(+), 251 deletions(-) diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/tests/test_examples.py index 0ee6a249c38..89b95fff843 100644 --- a/doc/OnlineDocs/tests/test_examples.py +++ b/doc/OnlineDocs/tests/test_examples.py @@ -1,269 +1,66 @@ -# Imports +# ___________________________________________________________________________ +# +# Pyomo: Python Optimization Modeling Objects +# Copyright (c) 2008-2022 +# National Technology and Engineering Solutions of Sandia, LLC +# Under the terms of Contract DE-NA0003525 with National Technology and +# Engineering Solutions of Sandia, LLC, the U.S. Government retains certain +# rights in this software. +# This software is distributed under the 3-clause BSD License. +# ___________________________________________________________________________ + import pyomo.common.unittest as unittest import glob import os -import os.path -import sys -import pyomo.environ +from pyomo.common.dependencies import attempt_import +from pyomo.common.fileutils import this_file_dir +import pyomo.environ as pyo + + +parameterized, param_available = attempt_import('parameterized') +if not param_available: + raise unittest.SkipTest('Parameterized is not available.') + +# Needed for testing (switches the matplotlib backend): +from pyomo.common.dependencies import matplotlib_available + +bool(matplotlib_available) -try: - import yaml +currdir = this_file_dir() - yaml_available = True -except: - yaml_available = False -# Find all *.txt files, and use them to define baseline tests -currdir = os.path.dirname(os.path.abspath(__file__)) -datadir = currdir -testdirs = [currdir] +class TestOnlineDocExamples(unittest.BaseLineTestDriver, unittest.TestCase): + # Only test files in directories ending in -ch. These directories + # contain the updated python and scripting files corresponding to + # each chapter in the book. + py_tests, sh_tests = unittest.BaseLineTestDriver.gather_tests( + list(filter(os.path.isdir, glob.glob(os.path.join(currdir, '*')))) + ) -solver_dependencies = { - 'Test_nonlinear_ch': { - 'test_rosen_pyomo_rosen': 'ipopt', - 'test_react_design_run_pyomo_reactor_table': 'ipopt', - 'test_react_design_run_pyomo_reactor': 'ipopt', - 'test_multimodal_pyomo_multimodal_init1': 'ipopt', - 'test_multimodal_pyomo_multimodal_init2': 'ipopt', - 'test_disease_est_run_disease_summary': 'ipopt', - 'test_disease_est_run_disease_callback': 'ipopt', - 'test_deer_run_deer': 'ipopt', - }, - 'Test_mpec_ch': {'test_mpec_ch_path1': 'path'}, - 'Test_dae_ch': {'test_run_path_constraint_tester': 'ipopt'}, -} -package_dependencies = { - 'Test_data': { + solver_dependencies = {} + package_dependencies = { + # data 'test_data_ABCD9': ['pyodbc'], 'test_data_ABCD8': ['pyodbc'], 'test_data_ABCD7': ['win32com'], - }, - 'Test_dataportal': { - 'test_dataportal_dataportal_tab': ['xlrd'], + # dataportal + 'test_dataportal_dataportal_tab': ['xlrd', 'pyutilib'], 'test_dataportal_set_initialization': ['numpy'], 'test_dataportal_param_initialization': ['numpy'], - }, -} -solver_available = {} -package_available = {} - -only_book_tests = set(['Test_nonlinear_ch', 'Test_scripts_ch']) - - -def _check_available(name): - from pyomo.opt.base.solvers import check_available_solvers - - return bool(check_available_solvers(name)) - - -def check_skip(tfname_, name): - # - # Skip if YAML isn't installed - # - if not yaml_available: - return "YAML is not available" - # - # Initialize the availability data - # - if len(solver_available) == 0: - for tf_ in solver_dependencies: - for n_ in solver_dependencies[tf_]: - solver_ = solver_dependencies[tf_][n_] - if not solver_ in solver_available: - solver_available[solver_] = _check_available(solver_) - for tf_ in package_dependencies: - for n_ in package_dependencies[tf_]: - packages_ = package_dependencies[tf_][n_] - for package_ in packages_: - if not package_ in package_available: - try: - __import__(package_) - package_available[package_] = True - except: - package_available[package_] = False - # - # Return a boolean if the test should be skipped - # - if tfname_ in solver_dependencies: - if ( - name in solver_dependencies[tfname_] - and not solver_available[solver_dependencies[tfname_][name]] - ): - # Skip the test because a solver is not available - # print('Skipping %s because of missing solver' %(name)) - return 'Solver "%s" is not available' % ( - solver_dependencies[tfname_][name], - ) - if tfname_ in package_dependencies: - if name in package_dependencies[tfname_]: - packages_ = package_dependencies[tfname_][name] - if not all([package_available[i] for i in packages_]): - # Skip the test because a package is not available - # print('Skipping %s because of missing package' %(name)) - _missing = [] - for i in packages_: - if not package_available[i]: - _missing.append(i) - return "Package%s %s %s not available" % ( - 's' if len(_missing) > 1 else '', - ", ".join(_missing), - 'are' if len(_missing) > 1 else 'is', - ) - return False - - -def filter(line): - # Ignore certain text when comparing output with baseline - - # Ipopt 3.12.4 puts BACKSPACE (chr(8) / ^H) into the output. - line = line.strip(" \n\t" + chr(8)) - - if not line: - return True - for field in ( - '[', - 'password:', - 'http:', - 'Job ', - 'Importing module', - 'Function', - 'File', - ): - if line.startswith(field): - return True - for field in ( - 'Total CPU', - 'Ipopt', - 'Status: optimal', - 'Status: feasible', - 'time:', - 'Time:', - 'with format cpxlp', - 'usermodel = Date: Tue, 9 Jan 2024 09:28:24 -0700 Subject: [PATCH 03/26] Update baselines to track changes to LP writer --- doc/OnlineDocs/tests/data/pyomo.diet1.txt | 16 ++++++++-------- doc/OnlineDocs/tests/data/pyomo.diet2.txt | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/OnlineDocs/tests/data/pyomo.diet1.txt b/doc/OnlineDocs/tests/data/pyomo.diet1.txt index 4b67e92c80c..fd8c87d51d9 100644 --- a/doc/OnlineDocs/tests/data/pyomo.diet1.txt +++ b/doc/OnlineDocs/tests/data/pyomo.diet1.txt @@ -1,16 +1,16 @@ [ 0.00] Setting up Pyomo environment [ 0.00] Applying Pyomo preprocessing actions [ 0.00] Creating model -[ 0.02] Applying solver -[ 0.03] Processing results +[ 0.01] Applying solver +[ 0.02] Processing results Number of solutions: 1 Solution Information Gap: 0.0 Status: optimal Function Value: 2.81 Solver results file: results.yml -[ 0.04] Applying Pyomo postprocessing actions -[ 0.04] Pyomo Finished +[ 0.02] Applying Pyomo postprocessing actions +[ 0.02] Pyomo Finished # ========================================================== # = Solver Results = # ========================================================== @@ -22,9 +22,9 @@ Problem: Lower bound: 2.81 Upper bound: 2.81 Number of objectives: 1 - Number of constraints: 4 - Number of variables: 10 - Number of nonzeros: 10 + Number of constraints: 3 + Number of variables: 9 + Number of nonzeros: 9 Sense: minimize # ---------------------------------------------------------- # Solver Information @@ -37,7 +37,7 @@ Solver: Number of bounded subproblems: 1 Number of created subproblems: 1 Error rc: 0 - Time: 0.00816035270690918 + Time: 0.002644062042236328 # ---------------------------------------------------------- # Solution Information # ---------------------------------------------------------- diff --git a/doc/OnlineDocs/tests/data/pyomo.diet2.txt b/doc/OnlineDocs/tests/data/pyomo.diet2.txt index 00405216fe1..7ed879d500f 100644 --- a/doc/OnlineDocs/tests/data/pyomo.diet2.txt +++ b/doc/OnlineDocs/tests/data/pyomo.diet2.txt @@ -1,16 +1,16 @@ [ 0.00] Setting up Pyomo environment [ 0.00] Applying Pyomo preprocessing actions [ 0.00] Creating model -[ 0.03] Applying solver -[ 0.05] Processing results +[ 0.01] Applying solver +[ 0.01] Processing results Number of solutions: 1 Solution Information Gap: 0.0 Status: optimal Function Value: 2.81 Solver results file: results.yml -[ 0.05] Applying Pyomo postprocessing actions -[ 0.05] Pyomo Finished +[ 0.01] Applying Pyomo postprocessing actions +[ 0.01] Pyomo Finished # ========================================================== # = Solver Results = # ========================================================== @@ -22,9 +22,9 @@ Problem: Lower bound: 2.81 Upper bound: 2.81 Number of objectives: 1 - Number of constraints: 4 - Number of variables: 10 - Number of nonzeros: 10 + Number of constraints: 3 + Number of variables: 9 + Number of nonzeros: 9 Sense: minimize # ---------------------------------------------------------- # Solver Information @@ -37,7 +37,7 @@ Solver: Number of bounded subproblems: 1 Number of created subproblems: 1 Error rc: 0 - Time: 0.006503582000732422 + Time: 0.0018515586853027344 # ---------------------------------------------------------- # Solution Information # ---------------------------------------------------------- From 92a5bb60f02c053c678b6c0d15b695a7e608f472 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 09:29:22 -0700 Subject: [PATCH 04/26] Update baselines to track changes in Set pprint --- doc/OnlineDocs/tests/data/table0.txt | 5 +- doc/OnlineDocs/tests/data/table0.ul.txt | 5 +- doc/OnlineDocs/tests/data/table1.txt | 5 +- doc/OnlineDocs/tests/data/table2.txt | 15 +- doc/OnlineDocs/tests/data/table3.txt | 20 ++- doc/OnlineDocs/tests/data/table3.ul.txt | 20 ++- doc/OnlineDocs/tests/data/table4.txt | 10 +- doc/OnlineDocs/tests/data/table4.ul.txt | 10 +- doc/OnlineDocs/tests/data/table5.txt | 10 +- doc/OnlineDocs/tests/data/table7.txt | 10 +- .../tests/dataportal/dataportal_tab.txt | 161 ++++++++++------- .../tests/dataportal/param_initialization.txt | 10 +- .../tests/dataportal/set_initialization.txt | 52 +++--- doc/OnlineDocs/tests/kernel/examples.txt | 162 ++++++++++-------- 14 files changed, 284 insertions(+), 211 deletions(-) diff --git a/doc/OnlineDocs/tests/data/table0.txt b/doc/OnlineDocs/tests/data/table0.txt index ecd2417333d..c2e75dd97a6 100644 --- a/doc/OnlineDocs/tests/data/table0.txt +++ b/doc/OnlineDocs/tests/data/table0.txt @@ -1,6 +1,7 @@ 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table0.ul.txt b/doc/OnlineDocs/tests/data/table0.ul.txt index ecd2417333d..c2e75dd97a6 100644 --- a/doc/OnlineDocs/tests/data/table0.ul.txt +++ b/doc/OnlineDocs/tests/data/table0.ul.txt @@ -1,6 +1,7 @@ 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table1.txt b/doc/OnlineDocs/tests/data/table1.txt index ecd2417333d..c2e75dd97a6 100644 --- a/doc/OnlineDocs/tests/data/table1.txt +++ b/doc/OnlineDocs/tests/data/table1.txt @@ -1,6 +1,7 @@ 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table2.txt b/doc/OnlineDocs/tests/data/table2.txt index 6621e27f70c..60eb55aab4a 100644 --- a/doc/OnlineDocs/tests/data/table2.txt +++ b/doc/OnlineDocs/tests/data/table2.txt @@ -1,10 +1,13 @@ 3 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - B : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['B1', 'B2', 'B3'] - N_index : Dim=0, Dimen=2, Size=9, Domain=None, Ordered=False, Bounds=None - Virtual + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + B : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'B1', 'B2', 'B3'} + N_index : Size=1, Index=None, Ordered=True + Key : Dimen : Domain : Size : Members + None : 2 : A*B : 9 : {('A1', 'B1'), ('A1', 'B2'), ('A1', 'B3'), ('A2', 'B1'), ('A2', 'B2'), ('A2', 'B3'), ('A3', 'B1'), ('A3', 'B2'), ('A3', 'B3')} 2 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table3.txt b/doc/OnlineDocs/tests/data/table3.txt index e4194f6790d..cb5e63b30d4 100644 --- a/doc/OnlineDocs/tests/data/table3.txt +++ b/doc/OnlineDocs/tests/data/table3.txt @@ -1,12 +1,16 @@ 4 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - B : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['B1', 'B2', 'B3'] - N_index : Dim=0, Dimen=2, Size=9, Domain=None, Ordered=False, Bounds=None - Virtual - Z : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + B : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'B1', 'B2', 'B3'} + N_index : Size=1, Index=None, Ordered=True + Key : Dimen : Domain : Size : Members + None : 2 : A*B : 9 : {('A1', 'B1'), ('A1', 'B2'), ('A1', 'B3'), ('A2', 'B1'), ('A2', 'B2'), ('A2', 'B3'), ('A3', 'B1'), ('A3', 'B2'), ('A3', 'B3')} + Z : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 2 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table3.ul.txt b/doc/OnlineDocs/tests/data/table3.ul.txt index e4194f6790d..cb5e63b30d4 100644 --- a/doc/OnlineDocs/tests/data/table3.ul.txt +++ b/doc/OnlineDocs/tests/data/table3.ul.txt @@ -1,12 +1,16 @@ 4 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - B : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['B1', 'B2', 'B3'] - N_index : Dim=0, Dimen=2, Size=9, Domain=None, Ordered=False, Bounds=None - Virtual - Z : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + B : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'B1', 'B2', 'B3'} + N_index : Size=1, Index=None, Ordered=True + Key : Dimen : Domain : Size : Members + None : 2 : A*B : 9 : {('A1', 'B1'), ('A1', 'B2'), ('A1', 'B3'), ('A2', 'B1'), ('A2', 'B2'), ('A2', 'B3'), ('A3', 'B1'), ('A3', 'B2'), ('A3', 'B3')} + Z : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 2 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table4.txt b/doc/OnlineDocs/tests/data/table4.txt index eb49be14de2..f86004c342a 100644 --- a/doc/OnlineDocs/tests/data/table4.txt +++ b/doc/OnlineDocs/tests/data/table4.txt @@ -1,8 +1,10 @@ 2 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - Z : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + Z : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 2 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table4.ul.txt b/doc/OnlineDocs/tests/data/table4.ul.txt index eb49be14de2..f86004c342a 100644 --- a/doc/OnlineDocs/tests/data/table4.ul.txt +++ b/doc/OnlineDocs/tests/data/table4.ul.txt @@ -1,8 +1,10 @@ 2 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - Z : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + Z : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 2 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/data/table5.txt b/doc/OnlineDocs/tests/data/table5.txt index 76d8c59010f..084757b781b 100644 --- a/doc/OnlineDocs/tests/data/table5.txt +++ b/doc/OnlineDocs/tests/data/table5.txt @@ -1,7 +1,9 @@ 2 Set Declarations - Y : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [(4.3, 5.3), (4.4, 5.4), (4.5, 5.5)] - Z : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + Y : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {(4.3, 5.3), (4.4, 5.4), (4.5, 5.5)} + Z : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 2 Declarations: Z Y diff --git a/doc/OnlineDocs/tests/data/table7.txt b/doc/OnlineDocs/tests/data/table7.txt index 275e8543528..8ddbfde38be 100644 --- a/doc/OnlineDocs/tests/data/table7.txt +++ b/doc/OnlineDocs/tests/data/table7.txt @@ -1,8 +1,10 @@ 2 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - Z : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + Z : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 1 Param Declarations M : Size=3, Index=A, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/dataportal/dataportal_tab.txt b/doc/OnlineDocs/tests/dataportal/dataportal_tab.txt index a3fa2bd8067..2e507971157 100644 --- a/doc/OnlineDocs/tests/dataportal/dataportal_tab.txt +++ b/doc/OnlineDocs/tests/dataportal/dataportal_tab.txt @@ -1,21 +1,25 @@ 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Declarations: A 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Declarations: A 1 Set Declarations - C : Dim=0, Dimen=2, Size=9, Domain=None, Ordered=False, Bounds=None - [('A1', 1), ('A1', 2), ('A1', 3), ('A2', 1), ('A2', 2), ('A2', 3), ('A3', 1), ('A3', 2), ('A3', 3)] + C : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 9 : {('A1', 1), ('A1', 2), ('A1', 3), ('A2', 1), ('A2', 2), ('A2', 3), ('A3', 1), ('A3', 2), ('A3', 3)} 1 Declarations: C 1 Set Declarations - D : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 1), ('A2', 2), ('A3', 3)] + D : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 1), ('A2', 2), ('A3', 3)} 1 Declarations: D 1 Param Declarations @@ -25,8 +29,9 @@ 1 Declarations: z 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations y : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -37,8 +42,9 @@ 2 Declarations: A y 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 2 Param Declarations w : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -54,8 +60,9 @@ 3 Declarations: A x w 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations y : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -66,8 +73,9 @@ 2 Declarations: A y 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations w : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -78,12 +86,15 @@ 2 Declarations: A w 3 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - I : Dim=0, Dimen=1, Size=4, Domain=None, Ordered=False, Bounds=None - ['I1', 'I2', 'I3', 'I4'] - u_index : Dim=0, Dimen=2, Size=12, Domain=None, Ordered=False, Bounds=None - Virtual + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + I : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 4 : {'I1', 'I2', 'I3', 'I4'} + u_index : Size=1, Index=None, Ordered=True + Key : Dimen : Domain : Size : Members + None : 2 : I*A : 12 : {('I1', 'A1'), ('I1', 'A2'), ('I1', 'A3'), ('I2', 'A1'), ('I2', 'A2'), ('I2', 'A3'), ('I3', 'A1'), ('I3', 'A2'), ('I3', 'A3'), ('I4', 'A1'), ('I4', 'A2'), ('I4', 'A3')} 1 Param Declarations u : Size=12, Index=u_index, Domain=Any, Default=None, Mutable=False @@ -103,12 +114,15 @@ 4 Declarations: A I u_index u 3 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - I : Dim=0, Dimen=1, Size=4, Domain=None, Ordered=False, Bounds=None - ['I1', 'I2', 'I3', 'I4'] - t_index : Dim=0, Dimen=2, Size=12, Domain=None, Ordered=False, Bounds=None - Virtual + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + I : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 4 : {'I1', 'I2', 'I3', 'I4'} + t_index : Size=1, Index=None, Ordered=True + Key : Dimen : Domain : Size : Members + None : 2 : A*I : 12 : {('A1', 'I1'), ('A1', 'I2'), ('A1', 'I3'), ('A1', 'I4'), ('A2', 'I1'), ('A2', 'I2'), ('A2', 'I3'), ('A2', 'I4'), ('A3', 'I1'), ('A3', 'I2'), ('A3', 'I3'), ('A3', 'I4')} 1 Param Declarations t : Size=12, Index=t_index, Domain=Any, Default=None, Mutable=False @@ -128,8 +142,9 @@ 4 Declarations: A I t_index t 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations s : Size=2, Index=A, Domain=Any, Default=None, Mutable=False @@ -139,8 +154,9 @@ 2 Declarations: A s 1 Set Declarations - A : Dim=0, Dimen=1, Size=4, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3', 'A4'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 4 : {'A1', 'A2', 'A3', 'A4'} 1 Param Declarations y : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -151,8 +167,9 @@ 2 Declarations: A y 1 Set Declarations - A : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 1 Param Declarations p : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -163,13 +180,15 @@ 2 Declarations: A p 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Declarations: A 1 Set Declarations - y_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + y_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 2 Param Declarations y : Size=3, Index=y_index, Domain=Any, Default=None, Mutable=False @@ -188,8 +207,9 @@ A1 3.3 A2 3.4 A3 3.5 1 Set Declarations - A : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 1 Param Declarations p : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -200,8 +220,9 @@ A3 3.5 2 Declarations: A p 1 Set Declarations - A : Dim=0, Dimen=2, Size=0, Domain=None, Ordered=False, Bounds=None - [] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 0 : {} 1 Param Declarations p : Size=0, Index=A, Domain=Any, Default=None, Mutable=False @@ -209,8 +230,9 @@ A3 3.5 2 Declarations: A p 1 Set Declarations - A : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')} 1 Param Declarations p : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -221,8 +243,9 @@ A3 3.5 2 Declarations: A p 1 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} 1 Param Declarations p : Size=3, Index=A, Domain=Any, Default=None, Mutable=False @@ -233,14 +256,16 @@ A3 3.5 2 Declarations: A p 3 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - B : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [(1, 'B1'), (2, 'B2'), (3, 'B3')] - C : Dim=1, Dimen=1, Size=6, Domain=None, ArraySize=2, Ordered=False, Bounds=None - Key : Members - A1 : [1, 2, 3] - A3 : [10, 20, 30] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + B : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {(1, 'B1'), (2, 'B2'), (3, 'B3')} + C : Size=2, Index=A, Ordered=Insertion + Key : Dimen : Domain : Size : Members + A1 : 1 : Any : 3 : {1, 2, 3} + A3 : 1 : Any : 3 : {10, 20, 30} 3 Param Declarations p : Size=1, Index=None, Domain=Any, Default=None, Mutable=False @@ -259,14 +284,16 @@ A3 3.5 6 Declarations: A B C p q r 3 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - ['A1', 'A2', 'A3'] - B : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [(1, 'B1'), (2, 'B2'), (3, 'B3')] - C : Dim=1, Dimen=1, Size=6, Domain=None, ArraySize=2, Ordered=False, Bounds=None - Key : Members - A1 : [1, 2, 3] - A3 : [10, 20, 30] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {'A1', 'A2', 'A3'} + B : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {(1, 'B1'), (2, 'B2'), (3, 'B3')} + C : Size=2, Index=A, Ordered=Insertion + Key : Dimen : Domain : Size : Members + A1 : 1 : Any : 3 : {1, 2, 3} + A3 : 1 : Any : 3 : {10, 20, 30} 3 Param Declarations p : Size=1, Index=None, Domain=Any, Default=None, Mutable=False @@ -285,12 +312,14 @@ A3 3.5 6 Declarations: A B C p q r 1 Set Declarations - C : Dim=0, Dimen=2, Size=9, Domain=None, Ordered=False, Bounds=None - [('A1', 1), ('A1', 2), ('A1', 3), ('A2', 1), ('A2', 2), ('A2', 3), ('A3', 1), ('A3', 2), ('A3', 3)] + C : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 9 : {('A1', 1), ('A1', 2), ('A1', 3), ('A2', 1), ('A2', 2), ('A2', 3), ('A3', 1), ('A3', 2), ('A3', 3)} 1 Declarations: C 1 Set Declarations - C : Dim=0, Dimen=2, Size=3, Domain=None, Ordered=False, Bounds=None - [('A1', 1), ('A2', 2), ('A3', 3)] + C : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 2 : Any : 3 : {('A1', 1), ('A2', 2), ('A3', 3)} 1 Declarations: C diff --git a/doc/OnlineDocs/tests/dataportal/param_initialization.txt b/doc/OnlineDocs/tests/dataportal/param_initialization.txt index baf24eac293..fec8a06a84a 100644 --- a/doc/OnlineDocs/tests/dataportal/param_initialization.txt +++ b/doc/OnlineDocs/tests/dataportal/param_initialization.txt @@ -1,8 +1,10 @@ 2 Set Declarations - b_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(1, 3) - [1, 2, 3] - c_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(1, 3) - [1, 2, 3] + b_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {1, 2, 3} + c_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {1, 2, 3} 3 Param Declarations a : Size=1, Index=None, Domain=Any, Default=None, Mutable=False diff --git a/doc/OnlineDocs/tests/dataportal/set_initialization.txt b/doc/OnlineDocs/tests/dataportal/set_initialization.txt index 3bfbdad1cdc..c6be448eba9 100644 --- a/doc/OnlineDocs/tests/dataportal/set_initialization.txt +++ b/doc/OnlineDocs/tests/dataportal/set_initialization.txt @@ -1,24 +1,34 @@ +WARNING: Initializing ordered Set B with a fundamentally unordered data source +(type: set). This WILL potentially lead to nondeterministic behavior in Pyomo 9 Set Declarations - A : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 5) - [2, 3, 5] - B : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 5) - [2, 3, 5] - C : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 5) - [2, 3, 5] - D : Dim=0, Dimen=1, Size=9, Domain=None, Ordered=False, Bounds=(0, 8) - [0, 1, 2, 3, 4, 5, 6, 7, 8] - E : Dim=0, Dimen=1, Size=1, Domain=None, Ordered=False, Bounds=(2, 2) - [2] - F : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 5) - [2, 3, 5] - G : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 5) - [2, 3, 5] - H : Dim=1, Dimen=1, Size=9, Domain=None, ArraySize=3, Ordered=False, Bounds=None - Key : Members - 2 : [1, 3, 5] - 3 : [2, 4, 6] - 4 : [3, 5, 7] - H_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 4) - [2, 3, 4] + A : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {2, 3, 5} + B : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {2, 3, 5} + C : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {2, 3, 5} + D : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 9 : {0, 1, 2, 3, 4, 5, 6, 7, 8} + E : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 1 : {2,} + F : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {2, 3, 5} + G : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {2, 3, 5} + H : Size=3, Index=H_index, Ordered=Insertion + Key : Dimen : Domain : Size : Members + 2 : 1 : Any : 3 : {1, 3, 5} + 3 : 1 : Any : 3 : {2, 4, 6} + 4 : 1 : Any : 3 : {3, 5, 7} + H_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {2, 3, 4} 9 Declarations: A B C D E F G H_index H diff --git a/doc/OnlineDocs/tests/kernel/examples.txt b/doc/OnlineDocs/tests/kernel/examples.txt index c8a0cde2e36..4b13e25c157 100644 --- a/doc/OnlineDocs/tests/kernel/examples.txt +++ b/doc/OnlineDocs/tests/kernel/examples.txt @@ -1,20 +1,27 @@ 6 Set Declarations - cd_index : Dim=0, Dimen=2, Size=6, Domain=None, Ordered=True, Bounds=None - Virtual - cl_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - [1, 2, 3] - ol_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - [1, 2, 3] - s : Dim=0, Dimen=1, Size=2, Domain=None, Ordered=Insertion, Bounds=(1, 2) - [1, 2] - sd_index : Dim=0, Dimen=1, Size=2, Domain=None, Ordered=False, Bounds=(1, 2) - [1, 2] - vl_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - [1, 2, 3] + cd_index : Size=1, Index=None, Ordered=True + Key : Dimen : Domain : Size : Members + None : 2 : s*q : 6 : {(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)} + cl_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {1, 2, 3} + ol_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {1, 2, 3} + s : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 2 : {1, 2} + sd_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 2 : {1, 2} + vl_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {1, 2, 3} 1 RangeSet Declarations - q : Dim=0, Dimen=1, Size=3, Domain=Integers, Ordered=True, Bounds=(1, 3) - Virtual + q : Dimen=1, Size=3, Bounds=(1, 3) + Key : Finite : Members + None : True : [1:3] 2 Param Declarations p : Size=1, Index=None, Domain=Any, Default=None, Mutable=True @@ -84,64 +91,67 @@ 3 : -5.0 : vl[3] - v : 5.0 : True 3 SOSConstraint Declarations - sd : Size=2 Index= sd_index - 1 - Type=1 - Weight : Variable - 1 : vd[1] - 2 : vd[2] - 2 - Type=1 - Weight : Variable - 1 : vl[1] - 2 : vl[2] - 3 : vl[3] - sos1 : Size=1 - Type=1 - Weight : Variable - 1 : vl[1] - 2 : vl[2] - 3 : vl[3] - sos2 : Size=1 - Type=2 - Weight : Variable - 1 : vd[1] - 2 : vd[2] + sd : Size=2 Index= sd_index + 1 + Type=1 + Weight : Variable + 1 : vd[1] + 2 : vd[2] + 2 + Type=1 + Weight : Variable + 1 : vl[1] + 2 : vl[2] + 3 : vl[3] + sos1 : Size=1 + Type=1 + Weight : Variable + 1 : vl[1] + 2 : vl[2] + 3 : vl[3] + sos2 : Size=1 + Type=2 + Weight : Variable + 1 : vd[1] + 2 : vd[2] 2 Block Declarations b : Size=1, Index=None, Active=True 0 Declarations: - 2 Set Declarations - SOS2_constraint_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None - [1, 2, 3] - SOS2_y_index : Dim=0, Dimen=1, Size=4, Domain=None, Ordered=False, Bounds=(0, 3) - [0, 1, 2, 3] + pw : Size=1, Index=None, Active=True + 2 Set Declarations + SOS2_constraint_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 3 : {1, 2, 3} + SOS2_y_index : Size=1, Index=None, Ordered=Insertion + Key : Dimen : Domain : Size : Members + None : 1 : Any : 4 : {0, 1, 2, 3} - 1 Var Declarations - SOS2_y : Size=4, Index=pw.SOS2_y_index - Key : Lower : Value : Upper : Fixed : Stale : Domain - 0 : 0 : None : None : False : True : NonNegativeReals - 1 : 0 : None : None : False : True : NonNegativeReals - 2 : 0 : None : None : False : True : NonNegativeReals - 3 : 0 : None : None : False : True : NonNegativeReals + 1 Var Declarations + SOS2_y : Size=4, Index=pw.SOS2_y_index + Key : Lower : Value : Upper : Fixed : Stale : Domain + 0 : 0 : None : None : False : True : NonNegativeReals + 1 : 0 : None : None : False : True : NonNegativeReals + 2 : 0 : None : None : False : True : NonNegativeReals + 3 : 0 : None : None : False : True : NonNegativeReals - 1 Constraint Declarations - SOS2_constraint : Size=3, Index=pw.SOS2_constraint_index, Active=True - Key : Lower : Body : Upper : Active - 1 : 0.0 : v - (pw.SOS2_y[0] + 2*pw.SOS2_y[1] + 3*pw.SOS2_y[2] + 4*pw.SOS2_y[3]) : 0.0 : True - 2 : 0.0 : f - (pw.SOS2_y[0] + 2*pw.SOS2_y[1] + pw.SOS2_y[2] + 2*pw.SOS2_y[3]) : 0.0 : True - 3 : 1.0 : pw.SOS2_y[0] + pw.SOS2_y[1] + pw.SOS2_y[2] + pw.SOS2_y[3] : 1.0 : True + 1 Constraint Declarations + SOS2_constraint : Size=3, Index=pw.SOS2_constraint_index, Active=True + Key : Lower : Body : Upper : Active + 1 : 0.0 : v - (pw.SOS2_y[0] + 2*pw.SOS2_y[1] + 3*pw.SOS2_y[2] + 4*pw.SOS2_y[3]) : 0.0 : True + 2 : 0.0 : f - (pw.SOS2_y[0] + 2*pw.SOS2_y[1] + pw.SOS2_y[2] + 2*pw.SOS2_y[3]) : 0.0 : True + 3 : 1.0 : pw.SOS2_y[0] + pw.SOS2_y[1] + pw.SOS2_y[2] + pw.SOS2_y[3] : 1.0 : True - 1 SOSConstraint Declarations - SOS2_sosconstraint : Size=1 - Type=2 - Weight : Variable - 1 : pw.SOS2_y[0] - 2 : pw.SOS2_y[1] - 3 : pw.SOS2_y[2] - 4 : pw.SOS2_y[3] + 1 SOSConstraint Declarations + SOS2_sosconstraint : Size=1 + Type=2 + Weight : Variable + 1 : pw.SOS2_y[0] + 2 : pw.SOS2_y[1] + 3 : pw.SOS2_y[2] + 4 : pw.SOS2_y[3] - 5 Declarations: SOS2_y_index SOS2_y SOS2_constraint_index SOS2_constraint SOS2_sosconstraint + 5 Declarations: SOS2_y_index SOS2_y SOS2_constraint_index SOS2_constraint SOS2_sosconstraint 1 Suffix Declarations dual : Direction=Suffix.IMPORT, Datatype=Suffix.FLOAT @@ -166,14 +176,14 @@ - vl[0]: variable(active=True, value=None, bounds=(2,None), domain_type=RealSet, fixed=False, stale=True) - vl[1]: variable(active=True, value=None, bounds=(2,None), domain_type=RealSet, fixed=False, stale=True) - vl[2]: variable(active=True, value=None, bounds=(2,None), domain_type=RealSet, fixed=False, stale=True) - - c: constraint(active=True, expr=vd[1] + vd[2] <= 9.0) + - c: constraint(active=True, expr=vd[1] + vd[2] <= 9) - cd: constraint_dict(active=True, ctype=IConstraint) - - cd[(1, 0)]: constraint(active=True, expr=vd[1] == 0.0) - - cd[(1, 1)]: constraint(active=True, expr=vd[1] == 1.0) - - cd[(1, 2)]: constraint(active=True, expr=vd[1] == 2.0) - - cd[(2, 0)]: constraint(active=True, expr=vd[2] == 0.0) - - cd[(2, 1)]: constraint(active=True, expr=vd[2] == 1.0) - - cd[(2, 2)]: constraint(active=True, expr=vd[2] == 2.0) + - cd[(1, 0)]: constraint(active=True, expr=vd[1] == 0) + - cd[(1, 1)]: constraint(active=True, expr=vd[1] == 1) + - cd[(1, 2)]: constraint(active=True, expr=vd[1] == 2) + - cd[(2, 0)]: constraint(active=True, expr=vd[2] == 0) + - cd[(2, 1)]: constraint(active=True, expr=vd[2] == 1) + - cd[(2, 2)]: constraint(active=True, expr=vd[2] == 2) - cl: constraint_list(active=True, ctype=IConstraint) - cl[0]: constraint(active=True, expr=-5 <= vl[0] - v <= 5) - cl[1]: constraint(active=True, expr=-5 <= vl[1] - v <= 5) @@ -216,9 +226,9 @@ - pw.v[2]: variable(active=True, value=None, bounds=(0,None), domain_type=RealSet, fixed=False, stale=True) - pw.v[3]: variable(active=True, value=None, bounds=(0,None), domain_type=RealSet, fixed=False, stale=True) - pw.c: constraint_list(active=True, ctype=IConstraint) - - pw.c[0]: linear_constraint(active=True, expr=pw.v[0] + 2*pw.v[1] + 3*pw.v[2] + 4*pw.v[3] - v == 0.0) - - pw.c[1]: linear_constraint(active=True, expr=pw.v[0] + 2*pw.v[1] + pw.v[2] + 2*pw.v[3] - f == 0.0) - - pw.c[2]: linear_constraint(active=True, expr=pw.v[0] + pw.v[1] + pw.v[2] + pw.v[3] == 1.0) + - pw.c[0]: linear_constraint(active=True, expr=pw.v[0] + 2*pw.v[1] + 3*pw.v[2] + 4*pw.v[3] - v == 0) + - pw.c[1]: linear_constraint(active=True, expr=pw.v[0] + 2*pw.v[1] + pw.v[2] + 2*pw.v[3] - f == 0) + - pw.c[2]: linear_constraint(active=True, expr=pw.v[0] + pw.v[1] + pw.v[2] + pw.v[3] == 1) - pw.s: sos(active=True, level=2, entries=['(pw.v[0],1)', '(pw.v[1],2)', '(pw.v[2],3)', '(pw.v[3],4)']) -2.0 KB -8.4 KB +1.9 KB +9.5 KB From 235c46608d826ab36ae76cb9920d44b4d2b27670 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 09:32:53 -0700 Subject: [PATCH 05/26] Update baseline to track changes in pyomo 6 expression system --- doc/OnlineDocs/tests/expr/performance.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/OnlineDocs/tests/expr/performance.txt b/doc/OnlineDocs/tests/expr/performance.txt index c1387a51ce4..6bfd0bd1d5a 100644 --- a/doc/OnlineDocs/tests/expr/performance.txt +++ b/doc/OnlineDocs/tests/expr/performance.txt @@ -10,5 +10,5 @@ x[0] + x[1]**2 + x[2]**2 + x[3]**2 + x[4]**2 x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8] + x[9] x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3] + x[4]*y[4] + x[5]*y[5] + x[6]*y[6] + x[7]*y[7] + x[8]*y[8] + x[9]*y[9] x[1]*y[1] + x[2]*y[2] + x[3]*y[3] + x[4]*y[4] + x[5]*y[5] -x[0]*(1/y[0]) + x[1]*(1/y[1]) + x[2]*(1/y[2]) + x[3]*(1/y[3]) + x[4]*(1/y[4]) + x[5]*(1/y[5]) + x[6]*(1/y[6]) + x[7]*(1/y[7]) + x[8]*(1/y[8]) + x[9]*(1/y[9]) -(1/(x[0]*y[0])) + (1/(x[1]*y[1])) + (1/(x[2]*y[2])) + (1/(x[3]*y[3])) + (1/(x[4]*y[4])) + (1/(x[5]*y[5])) + (1/(x[6]*y[6])) + (1/(x[7]*y[7])) + (1/(x[8]*y[8])) + (1/(x[9]*y[9])) +x[0]/y[0] + x[1]/y[1] + x[2]/y[2] + x[3]/y[3] + x[4]/y[4] + x[5]/y[5] + x[6]/y[6] + x[7]/y[7] + x[8]/y[8] + x[9]/y[9] +1/(x[0]*y[0]) + 1/(x[1]*y[1]) + 1/(x[2]*y[2]) + 1/(x[3]*y[3]) + 1/(x[4]*y[4]) + 1/(x[5]*y[5]) + 1/(x[6]*y[6]) + 1/(x[7]*y[7]) + 1/(x[8]*y[8]) + 1/(x[9]*y[9]) From efb836e345a9310eeb64d275174195d59b96fc8d Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 09:34:38 -0700 Subject: [PATCH 06/26] Update visitor documentation; remove errors and bugs --- .../expressions/managing.rst | 128 +++++++++--------- .../expressions/visitors.rst | 9 ++ doc/OnlineDocs/tests/expr/managing.py | 124 +++++++---------- doc/OnlineDocs/tests/expr/managing.txt | 8 +- pyomo/core/expr/visitor.py | 49 ++++--- 5 files changed, 158 insertions(+), 160 deletions(-) diff --git a/doc/OnlineDocs/developer_reference/expressions/managing.rst b/doc/OnlineDocs/developer_reference/expressions/managing.rst index 344d101074c..43c5ec34816 100644 --- a/doc/OnlineDocs/developer_reference/expressions/managing.rst +++ b/doc/OnlineDocs/developer_reference/expressions/managing.rst @@ -28,12 +28,14 @@ string representation that is a nested functional form. For example: Labeler and Symbol Map ~~~~~~~~~~~~~~~~~~~~~~ -The string representation used for variables in expression can be customized to -define different label formats. If the :data:`labeler` option is specified, then this -function (or class functor) is used to generate a string label used to represent the variable. Pyomo -defines a variety of labelers in the `pyomo.core.base.label` module. For example, the -:class:`NumericLabeler` defines a functor that can be used to sequentially generate -simple labels with a prefix followed by the variable count: +The string representation used for variables in expression can be +customized to define different label formats. If the :data:`labeler` +option is specified, then this function (or class functor) is used to +generate a string label used to represent the variable. Pyomo defines a +variety of labelers in the `pyomo.core.base.label` module. For example, +the :class:`NumericLabeler` defines a functor that can be used to +sequentially generate simple labels with a prefix followed by the +variable count: .. literalinclude:: ../../tests/expr/managing_ex2.spy @@ -46,44 +48,20 @@ variables in different expressions have a consistent label in their associated string representations. -Standardized String Representations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The :data:`standardize` option can be used to re-order the string -representation to print polynomial terms before nonlinear terms. By -default, :data:`standardize` is :const:`False`, and the string -representation reflects the order in which terms were combined to -form the expression. Pyomo does not guarantee that the string -representation exactly matches the Python expression order, since -some simplification and re-ordering of terms is done automatically to -improve the efficiency of expression generation. But in most cases -the string representation will closely correspond to the -Python expression order. - -If :data:`standardize` is :const:`True`, then the pyomo expression -is processed to identify polynomial terms, and the string representation -consists of the constant and linear terms followed by -an expression that contains other nonlinear terms. For example: - -.. literalinclude:: ../../tests/expr/managing_ex3.spy - Other Ways to Generate String Representations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are two other standard ways to generate string representations: -* Call the :func:`__str__` magic method (e.g. using the Python :func:`str()` function. This - calls :func:`expression_to_string ` with - the option :data:`standardize` equal to :const:`True` (see below). +* Call the :func:`__str__` magic method (e.g. using the Python + :func:`str()` function. This calls :func:`expression_to_string + `, using the default values for + all arguments. -* Call the :func:`to_string` method on the :class:`ExpressionBase ` class. - This defaults to calling :func:`expression_to_string ` with - the option :data:`standardize` equal to :const:`False` (see below). - -In practice, we expect at the :func:`__str__` magic method will be -used by most users, and the standardization of the output provides -a consistent ordering of terms that should make it easier to interpret -expressions. +* Call the :func:`to_string` method on the + :class:`ExpressionBase` class. This + calls :func:`expression_to_string + ` and accepts the same arguments. Evaluating Expressions @@ -108,7 +86,7 @@ raise an exception. This exception can be suppressed using the .. literalinclude:: ../../tests/expr/managing_ex7.spy -This option is useful in contexts where adding a try block is inconvenient +This option is useful in contexts where adding a try block is inconvenient in your modeling script. .. note:: @@ -127,7 +105,7 @@ Expression transformations sometimes need to find all nodes in an expression tree that are of a given type. Pyomo contains two utility functions that support this functionality. First, the :func:`identify_components ` -function is a generator function that walks the expression tree and yields all +function is a generator function that walks the expression tree and yields all nodes whose type is in a specified set of node types. For example: .. literalinclude:: ../../tests/expr/managing_ex8.spy @@ -152,8 +130,15 @@ is computed using the values of its children. Walking an expression tree can be tricky, and the code requires intimate knowledge of the design of the expression system. Pyomo includes -several classes that define so-called visitor patterns for walking -expression tree: +several classes that define visitor patterns for walking expression +tree: + +:class:`StreamBasedExpressionVisitor ` + The most general and extensible visitor class. This visitor + implements an event-based approach for walking the tree inspired by + the ``expat`` library for processing XML files. The visitor has + seven event callbacks that users can hook into, providing very + fine-grained control over the expression walker. :class:`SimpleExpressionVisitor ` A :func:`visitor` method is called for each node in the tree, @@ -173,33 +158,39 @@ expression tree: These classes define a variety of suitable tree search methods: -* :class:`SimpleExpressionVisitor ` +* :class:`StreamBasedExpressionVisitor ` - * **xbfs**: breadth-first search where leaf nodes are immediately visited - * **xbfs_yield_leaves**: breadth-first search where leaf nodes are immediately visited, and the visit method yields a value + * ``walk_expression``: depth-first traversal of the expression tree. -* :class:`ExpressionValueVisitor ` +* :class:`ExpressionReplacementVisitor ` - * **dfs_postorder_stack**: postorder depth-first search using a stack + * ``walk_expression``: depth-first traversal of the expression tree. -* :class:`ExpressionReplacementVisitor ` +* :class:`SimpleExpressionVisitor ` - * **dfs_postorder_stack**: postorder depth-first search using a stack + * ``xbfs``: breadth-first search where leaf nodes are immediately visited + * ``xbfs_yield_leaves``: breadth-first search where leaf nodes are + immediately visited, and the visit method yields a value -.. note:: +* :class:`ExpressionValueVisitor ` + + * ``dfs_postorder_stack``: postorder depth-first search using a + nonrecursive stack - The PyUtilib visitor classes define several other search methods - that could be used with Pyomo expressions. But these are the - only search methods currently used within Pyomo. -To implement a visitor object, a user creates a subclass of one of these -classes. Only one of a few methods will need to be defined to -implement the visitor: +To implement a visitor object, a user needs to provide specializations +for specific events. For legacy visitors based on the PyUtilib +visitor pattern (e.g., :class:`SimpleExpressionVisitor` and +:class:`ExpressionValueVisitor`), one must create a subclass of one of these +classes and override at least one of the following: :func:`visitor` Defines the operation that is performed when a node is visited. In - the :class:`ExpressionValueVisitor ` and :class:`ExpressionReplacementVisitor ` visitor classes, this - method returns a value that is used by its parent node. + the :class:`ExpressionValueVisitor + ` and + :class:`ExpressionReplacementVisitor + ` visitor classes, + this method returns a value that is used by its parent node. :func:`visiting_potential_leaf` Checks if the search should terminate with this node. If no, @@ -211,9 +202,17 @@ implement the visitor: class. :func:`finalize` - This method defines the final value that is returned from the + This method defines the final value that is returned from the visitor. This is not normally redefined. +For modern visitors based on the :class:`StreamBasedExpressionVisitor +`, one can either define a +subclass, pass the callbacks to an instance of the base class, or assign +the callbacks as attributes on an instance of the base class. The +:class:`StreamBasedExpressionVisitor +` provides seven +callbacks, which are documented in the class documentation. + Detailed documentation of the APIs for these methods is provided with the class documentation for these visitors. @@ -226,7 +225,7 @@ class: .. literalinclude:: ../../tests/expr/managing_visitor1.spy -The class constructor creates a counter, and the :func:`visit` method +The class constructor creates a counter, and the :func:`visit` method increments this counter for every node that is visited. The :func:`finalize` method returns the value of this counter after the tree has been walked. The following function illustrates this use of this visitor class: @@ -261,16 +260,13 @@ class: .. literalinclude:: ../../tests/expr/managing_visitor5.spy -No :func:`visit` method needs to be defined. The -:func:`visiting_potential_leaf` function identifies variable nodes +No other method need to be defined. The +:func:`beforeChild` method identifies variable nodes and returns a product expression that contains a mutable parameter. -The :class:`_LinearExpression` class has a different representation -that embeds variables. Hence, this class must be handled -in a separate condition that explicitly transforms this sub-expression. .. literalinclude:: ../../tests/expr/managing_visitor6.spy -The :func:`scale_expression` function is called with an expression and +The :func:`scale_expression` function is called with an expression and a dictionary, :attr:`scale`, that maps variable ID to model parameter. For example: .. literalinclude:: ../../tests/expr/managing_visitor7.spy diff --git a/doc/OnlineDocs/library_reference/expressions/visitors.rst b/doc/OnlineDocs/library_reference/expressions/visitors.rst index f91107a6e8d..77cffe7905f 100644 --- a/doc/OnlineDocs/library_reference/expressions/visitors.rst +++ b/doc/OnlineDocs/library_reference/expressions/visitors.rst @@ -2,10 +2,19 @@ Visitor Classes =============== +.. autoclass:: pyomo.core.expr.StreamBasedExpressionVisitor + :members: + :inherited-members: + .. autoclass:: pyomo.core.expr.SimpleExpressionVisitor :members: + :inherited-members: + .. autoclass:: pyomo.core.expr.ExpressionValueVisitor :members: + :inherited-members: + .. autoclass:: pyomo.core.expr.ExpressionReplacementVisitor :members: + :inherited-members: diff --git a/doc/OnlineDocs/tests/expr/managing.py b/doc/OnlineDocs/tests/expr/managing.py index 0a2709fe96f..0a59c13bc1b 100644 --- a/doc/OnlineDocs/tests/expr/managing.py +++ b/doc/OnlineDocs/tests/expr/managing.py @@ -5,7 +5,7 @@ # --------------------------------------------- # @ex1 -from pyomo.core.expr import current as EXPR +import pyomo.core.expr as EXPR M = ConcreteModel() M.x = Var() @@ -21,7 +21,7 @@ # --------------------------------------------- # @ex2 -from pyomo.core.expr import current as EXPR +import pyomo.core.expr as EXPR M = ConcreteModel() M.x = Var() @@ -33,35 +33,6 @@ print(EXPR.expression_to_string(e, labeler=NumericLabeler('x'))) # @ex2 -# --------------------------------------------- -# @ex3 -from pyomo.core.expr import current as EXPR - -M = ConcreteModel() -M.x = Var() -M.y = Var() - -e = sin(M.x) + 2 * M.y + M.x * M.y - 3 - -# -3 + 2*y + sin(x) + x*y -print(EXPR.expression_to_string(e, standardize=True)) -# @ex3 - -# --------------------------------------------- -# @ex4 -from pyomo.core.expr import current as EXPR - -M = ConcreteModel() -M.x = Var() - -with EXPR.clone_counter() as counter: - start = counter.count - e1 = sin(M.x) - e2 = e1.clone() - total = counter.count - start - assert total == 1 -# @ex4 - # --------------------------------------------- # @ex5 M = ConcreteModel() @@ -85,7 +56,7 @@ # --------------------------------------------- # @ex8 -from pyomo.core.expr import current as EXPR +import pyomo.core.expr as EXPR M = ConcreteModel() M.x = Var() @@ -98,7 +69,7 @@ # --------------------------------------------- # @ex9 -from pyomo.core.expr import current as EXPR +import pyomo.core.expr as EXPR M = ConcreteModel() M.x = Var() @@ -116,7 +87,7 @@ # --------------------------------------------- # @visitor1 -from pyomo.core.expr import current as EXPR +import pyomo.core.expr as EXPR class SizeofVisitor(EXPR.SimpleExpressionVisitor): @@ -129,8 +100,7 @@ def visit(self, node): def finalize(self): return self.counter - -# @visitor1 + # @visitor1 # --------------------------------------------- @@ -144,13 +114,12 @@ def sizeof_expression(expr): # Compute the value using the :func:`xbfs` search method. # return visitor.xbfs(expr) + # @visitor2 -# @visitor2 - # --------------------------------------------- # @visitor3 -from pyomo.core.expr import current as EXPR +import pyomo.core.expr as EXPR class CloneVisitor(EXPR.ExpressionValueVisitor): @@ -161,22 +130,17 @@ def visit(self, node, values): # # Clone the interior node # - return node.construct_clone(tuple(values), self.memo) + return node.create_node_with_local_data(values) def visiting_potential_leaf(self, node): # # Clone leaf nodes in the expression tree # - if ( - node.__class__ in native_numeric_types - or node.__class__ not in pyomo5_expression_types - ): + if node.__class__ in native_numeric_types or not node.is_expression_type(): return True, copy.deepcopy(node, self.memo) return False, None - - -# @visitor3 + # @visitor3 # --------------------------------------------- @@ -191,13 +155,29 @@ def clone_expression(expr): # search method. # return visitor.dfs_postorder_stack(expr) - - -# @visitor4 + # @visitor4 + + +# Test: +m = ConcreteModel() +m.x = Var(range(2)) +m.p = Param(range(5), mutable=True) +e = m.x[0] + 5 * m.x[1] +ce = clone_expression(e) +print(e is not ce) +# True +print(str(e)) +# x[0] + 5*x[1] +print(str(ce)) +# x[0] + 5*x[1] +print(e.arg(0) is not ce.arg(0)) +# True +print(e.arg(1) is not ce.arg(1)) +# True # --------------------------------------------- # @visitor5 -from pyomo.core.expr import current as EXPR +import pyomo.core.expr as EXPR class ScalingVisitor(EXPR.ExpressionReplacementVisitor): @@ -205,29 +185,24 @@ def __init__(self, scale): super(ScalingVisitor, self).__init__() self.scale = scale - def visiting_potential_leaf(self, node): + def beforeChild(self, node, child, child_idx): # - # Clone leaf nodes in the expression tree + # Native numeric types are terminal nodes; this also catches all + # nodes that do not conform to the ExpressionBase API (i.e., + # define is_variable_type) # - if node.__class__ in native_numeric_types: - return True, node - - if node.is_variable_type(): - return True, self.scale[id(node)] * node - - if isinstance(node, EXPR.LinearExpression): - node_ = copy.deepcopy(node) - node_.constant = node.constant - node_.linear_vars = copy.copy(node.linear_vars) - node_.linear_coefs = [] - for i, v in enumerate(node.linear_vars): - node_.linear_coefs.append(node.linear_coefs[i] * self.scale[id(v)]) - return True, node_ - - return False, None - - -# @visitor5 + if child.__class__ in native_numeric_types: + return False, child + # + # Replace leaf variables with scaled variables + # + if child.is_variable_type(): + return False, self.scale[id(child)] * child + # + # Everything else can be processed normally + # + return True, None + # @visitor5 # --------------------------------------------- @@ -241,11 +216,10 @@ def scale_expression(expr, scale): # Scale the expression using the :func:`dfs_postorder_stack` # search method. # - return visitor.dfs_postorder_stack(expr) + return visitor.walk_expression(expr) + # @visitor6 -# @visitor6 - # --------------------------------------------- # @visitor7 M = ConcreteModel() diff --git a/doc/OnlineDocs/tests/expr/managing.txt b/doc/OnlineDocs/tests/expr/managing.txt index 5a22c846a8b..d236c942d25 100644 --- a/doc/OnlineDocs/tests/expr/managing.txt +++ b/doc/OnlineDocs/tests/expr/managing.txt @@ -1,5 +1,9 @@ sin(x) + 2*x -sum(sin(x), prod(2, x)) +sum(sin(x), mon(2, x)) sin(x1) + 2*x2 --3 + 2*y + x*y + sin(x) +True +x[0] + 5*x[1] +x[0] + 5*x[1] +True +True p[0]*x[0] + p[1]*x[1] + p[2]*x[2] + p[3]*x[3] + p[4]*x[4] diff --git a/pyomo/core/expr/visitor.py b/pyomo/core/expr/visitor.py index c8f22ba1d3a..ca3a1c9e745 100644 --- a/pyomo/core/expr/visitor.py +++ b/pyomo/core/expr/visitor.py @@ -82,11 +82,13 @@ class RevertToNonrecursive(Exception): class StreamBasedExpressionVisitor(object): """This class implements a generic stream-based expression walker. - This visitor walks an expression tree using a depth-first strategy - and generates a full event stream similar to other tree visitors - (e.g., the expat XML parser). The following events are triggered - through callback functions as the traversal enters and leaves nodes - in the tree: + This visitor walks an expression tree using a depth-first strategy + and generates a full event stream similar to other tree visitors + (e.g., the expat XML parser). The following events are triggered + through callback functions as the traversal enters and leaves nodes + in the tree: + + :: initializeWalker(expr) -> walk, result enterNode(N1) -> args, data @@ -100,7 +102,7 @@ class StreamBasedExpressionVisitor(object): exitNode(N1, data) -> N1_result finalizeWalker(result) -> result - Individual event callbacks match the following signatures: + Individual event callbacks match the following signatures: walk, result = initializeWalker(self, expr): @@ -123,7 +125,7 @@ class StreamBasedExpressionVisitor(object): not defined, the default behavior is equivalent to returning (None, []). - node_result = exitNode(self, node, data): + node_result = exitNode(self, node, data): exitNode() is called after the node is completely processed (as the walker returns up the tree to the parent node). It is @@ -133,7 +135,7 @@ class StreamBasedExpressionVisitor(object): this node. If not specified, the default action is to return the data object from enterNode(). - descend, child_result = beforeChild(self, node, child, child_idx): + descend, child_result = beforeChild(self, node, child, child_idx): beforeChild() is called by a node for every child before entering the child node. The node, child node, and child index @@ -145,7 +147,7 @@ class StreamBasedExpressionVisitor(object): equivalent to (True, None). The default behavior if not specified is equivalent to (True, None). - data = acceptChildResult(self, node, data, child_result, child_idx): + data = acceptChildResult(self, node, data, child_result, child_idx): acceptChildResult() is called for each child result being returned to a node. This callback is responsible for recording @@ -156,7 +158,7 @@ class StreamBasedExpressionVisitor(object): returned. If acceptChildResult is not specified, it does nothing if data is None, otherwise it calls data.append(result). - afterChild(self, node, child, child_idx): + afterChild(self, node, child, child_idx): afterChild() is called by a node for every child node immediately after processing the node is complete before control @@ -165,7 +167,7 @@ class StreamBasedExpressionVisitor(object): are passed, and nothing is returned. If afterChild is not specified, no action takes place. - finalizeResult(self, result): + finalizeResult(self, result): finalizeResult() is called once after the entire expression tree has been walked. It is passed the result returned by the root @@ -173,10 +175,10 @@ class StreamBasedExpressionVisitor(object): the walker returns the result obtained from the exitNode callback on the root node. - Clients interact with this class by either deriving from it and - implementing the necessary callbacks (see above), assigning callable - functions to an instance of this class, or passing the callback - functions as arguments to this class' constructor. + Clients interact with this class by either deriving from it and + implementing the necessary callbacks (see above), assigning callable + functions to an instance of this class, or passing the callback + functions as arguments to this class' constructor. """ @@ -254,7 +256,14 @@ def wrapper(*args): ) def walk_expression(self, expr): - """Walk an expression, calling registered callbacks.""" + """Walk an expression, calling registered callbacks. + + This is the standard interface for running the visitor. It + defaults to using an efficient recursive implementation of the + visitor, falling back on :py:meth:`walk_expression_nonrecursive` + if the recursion stack gets too deep. + + """ if self.initializeWalker is not None: walk, root = self.initializeWalker(expr) if not walk: @@ -496,7 +505,13 @@ def _recursive_frame_to_nonrecursive_stack(self, local): ) def walk_expression_nonrecursive(self, expr): - """Walk an expression, calling registered callbacks.""" + """Nonrecursively walk an expression, calling registered callbacks. + + This routine is safer than the recursive walkers for deep (or + unbalanced) trees. It is, however, slightly slower than the + recursive implementations. + + """ # # This walker uses a linked list to store the stack (instead of # an array). The nodes of the linked list are 6-member tuples: From 85952ff702c836914f3099f1fc544a07bc69fbba Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 09:39:22 -0700 Subject: [PATCH 07/26] Add testing of OnlineDocs to Jenkins, GHA drivers --- .github/workflows/test_branches.yml | 2 +- .github/workflows/test_pr_and_main.yml | 2 +- .jenkins.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml index ff24c731d94..98954debde5 100644 --- a/.github/workflows/test_branches.yml +++ b/.github/workflows/test_branches.yml @@ -623,7 +623,7 @@ jobs: $PYTHON_EXE -m pytest -v \ -W ignore::Warning ${{matrix.category}} \ pyomo `pwd`/pyomo-model-libraries \ - `pwd`/examples/pyomobook --junitxml="TEST-pyomo.xml" + `pwd`/examples `pwd`/doc --junitxml="TEST-pyomo.xml" - name: Run Pyomo MPI tests if: matrix.mpi != 0 diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml index 6e5604bea47..3d7c2f58e2d 100644 --- a/.github/workflows/test_pr_and_main.yml +++ b/.github/workflows/test_pr_and_main.yml @@ -653,7 +653,7 @@ jobs: $PYTHON_EXE -m pytest -v \ -W ignore::Warning ${{matrix.category}} \ pyomo `pwd`/pyomo-model-libraries \ - `pwd`/examples/pyomobook --junitxml="TEST-pyomo.xml" + `pwd`/examples `pwd`/doc --junitxml="TEST-pyomo.xml" - name: Run Pyomo MPI tests if: matrix.mpi != 0 diff --git a/.jenkins.sh b/.jenkins.sh index 544cb549175..37be6113ed9 100644 --- a/.jenkins.sh +++ b/.jenkins.sh @@ -38,7 +38,7 @@ if test -z "$WORKSPACE"; then export WORKSPACE=`pwd` fi if test -z "$TEST_SUITES"; then - export TEST_SUITES="${WORKSPACE}/pyomo/pyomo ${WORKSPACE}/pyomo-model-libraries ${WORKSPACE}/pyomo/examples/pyomobook" + export TEST_SUITES="${WORKSPACE}/pyomo/pyomo ${WORKSPACE}/pyomo-model-libraries ${WORKSPACE}/pyomo/examples ${WORKSPACE}/pyomo/doc" fi if test -z "$SLIM"; then export VENV_SYSTEM_PACKAGES='--system-site-packages' From f933a3f020f86e2b7f3ab6ccbbd507f6435eb904 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 09:42:17 -0700 Subject: [PATCH 08/26] NFC: Apply black --- pyomo/common/unittest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index 785afcf6316..dcd1b87f398 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -908,7 +908,6 @@ def python_test_driver(self, tname, test_file, base_file): finally: os.chdir(cwd) - try: self.compare_baselines(OUT.getvalue(), baseline) except: From 749583a7e3f62e893ca96102d136f5aeb435f240 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 09:44:22 -0700 Subject: [PATCH 09/26] NFC: fix typo --- pyomo/common/unittest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index dcd1b87f398..b7d8973a186 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -597,7 +597,7 @@ def __init__(self, test): super().__init__(test) def initialize_dependencies(self): - # Note: aas a rule, pyomo.common is not allowed to import from + # Note: as a rule, pyomo.common is not allowed to import from # the rest of Pyomo. we permit it here because a) this is not # at module scope, and b) there is really no better / more # logical place in pyomo to put this code. From 240e3e86e37c9d219fa53b8927bbb1319fb5e727 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 10:38:00 -0700 Subject: [PATCH 10/26] Updating package dependencies for OnlineDOcs kernel test --- doc/OnlineDocs/tests/test_examples.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/tests/test_examples.py index 89b95fff843..3f9b05b4a3f 100644 --- a/doc/OnlineDocs/tests/test_examples.py +++ b/doc/OnlineDocs/tests/test_examples.py @@ -47,6 +47,8 @@ class TestOnlineDocExamples(unittest.BaseLineTestDriver, unittest.TestCase): 'test_dataportal_dataportal_tab': ['xlrd', 'pyutilib'], 'test_dataportal_set_initialization': ['numpy'], 'test_dataportal_param_initialization': ['numpy'], + # kernel + 'test_kernel_examples': ['pympler'], } @parameterized.parameterized.expand( From 698ac6146159a68f1f11af273907879387b9499a Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 11:30:17 -0700 Subject: [PATCH 11/26] Update package dependency for OnlineDocs data test --- doc/OnlineDocs/tests/test_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/tests/test_examples.py index 3f9b05b4a3f..caac8e36256 100644 --- a/doc/OnlineDocs/tests/test_examples.py +++ b/doc/OnlineDocs/tests/test_examples.py @@ -42,7 +42,7 @@ class TestOnlineDocExamples(unittest.BaseLineTestDriver, unittest.TestCase): # data 'test_data_ABCD9': ['pyodbc'], 'test_data_ABCD8': ['pyodbc'], - 'test_data_ABCD7': ['win32com'], + 'test_data_ABCD7': ['win32com', 'pyutilib'], # dataportal 'test_dataportal_dataportal_tab': ['xlrd', 'pyutilib'], 'test_dataportal_set_initialization': ['numpy'], From 3e3c8fd5cd76b0da9ef4e89bb03039ae30dc1a6b Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 15:48:43 -0700 Subject: [PATCH 12/26] Ignore memory usage reported in examples tests --- .../library_reference/kernel/examples/transformer.py | 4 ++-- doc/OnlineDocs/tests/kernel/examples.txt | 4 ++-- pyomo/common/unittest.py | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/OnlineDocs/library_reference/kernel/examples/transformer.py b/doc/OnlineDocs/library_reference/kernel/examples/transformer.py index 3d8449a191d..66893008cf9 100644 --- a/doc/OnlineDocs/library_reference/kernel/examples/transformer.py +++ b/doc/OnlineDocs/library_reference/kernel/examples/transformer.py @@ -37,7 +37,7 @@ def connect_v_out(self, v_out): # @kernel -print(_fmt(pympler.asizeof.asizeof(Transformer()))) +print("Memory:", _fmt(pympler.asizeof.asizeof(Transformer()))) # @aml @@ -52,4 +52,4 @@ def Transformer(): # @aml -print(_fmt(pympler.asizeof.asizeof(Transformer()))) +print("Memory:", _fmt(pympler.asizeof.asizeof(Transformer()))) diff --git a/doc/OnlineDocs/tests/kernel/examples.txt b/doc/OnlineDocs/tests/kernel/examples.txt index 4b13e25c157..306eff0e929 100644 --- a/doc/OnlineDocs/tests/kernel/examples.txt +++ b/doc/OnlineDocs/tests/kernel/examples.txt @@ -230,5 +230,5 @@ - pw.c[1]: linear_constraint(active=True, expr=pw.v[0] + 2*pw.v[1] + pw.v[2] + 2*pw.v[3] - f == 0) - pw.c[2]: linear_constraint(active=True, expr=pw.v[0] + pw.v[1] + pw.v[2] + pw.v[3] == 1) - pw.s: sos(active=True, level=2, entries=['(pw.v[0],1)', '(pw.v[1],2)', '(pw.v[2],3)', '(pw.v[3],4)']) -1.9 KB -9.5 KB +Memory: 1.9 KB +Memory: 9.5 KB diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index b7d8973a186..2c93a49e1ee 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -732,6 +732,7 @@ def filter_fcn(self, line): 'Function', 'File', 'Matplotlib', + 'Memory:', '-------', '=======', ' ^', From 88a62581232974b65df26fc8a190fc39f8736a61 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 15:49:16 -0700 Subject: [PATCH 13/26] Baseline update --- examples/pyomobook/performance-ch/wl.txt | 94 ++++++++++++------------ 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/examples/pyomobook/performance-ch/wl.txt b/examples/pyomobook/performance-ch/wl.txt index fbbd11fa32a..f7d2e0ada19 100644 --- a/examples/pyomobook/performance-ch/wl.txt +++ b/examples/pyomobook/performance-ch/wl.txt @@ -7,17 +7,17 @@ Building model 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total - 0.15 seconds to construct Var x; 40000 indices total + 0.02 seconds to construct Var x; 40000 indices total 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Var y; 200 indices total - 0.26 seconds to construct Objective obj; 1 index total + 0.13 seconds to construct Objective obj; 1 index total 0 seconds to construct Set OrderedScalarSet; 1 index total 0.13 seconds to construct Constraint demand; 200 indices total 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total - 0.82 seconds to construct Constraint warehouse_active; 40000 indices total + 0.48 seconds to construct Constraint warehouse_active; 40000 indices total 0 seconds to construct Constraint num_warehouses; 1 index total Building model with LinearExpression ------------------------------------ @@ -28,71 +28,69 @@ Building model with LinearExpression 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total - 0.08 seconds to construct Var x; 40000 indices total + 0.02 seconds to construct Var x; 40000 indices total 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Var y; 200 indices total - 0.33 seconds to construct Objective obj; 1 index total + 0.06 seconds to construct Objective obj; 1 index total 0 seconds to construct Set OrderedScalarSet; 1 index total - 0.13 seconds to construct Constraint demand; 200 indices total + 0.18 seconds to construct Constraint demand; 200 indices total 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Set OrderedScalarSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total 0 seconds to construct Set SetProduct_OrderedSet; 1 index total - 0.59 seconds to construct Constraint warehouse_active; 40000 indices total + 0.33 seconds to construct Constraint warehouse_active; 40000 indices total 0 seconds to construct Constraint num_warehouses; 1 index total [ 0.00] start -[+ 1.74] Built model -[+ 7.39] Wrote LP file and solved -[+ 11.36] finished parameter sweep - 14919301 function calls (14916699 primitive calls) in 15.948 seconds +[+ 0.79] Built model +[+ 2.56] Wrote LP file and solved +[+ 10.96] Finished parameter sweep + 7372057 function calls (7368345 primitive calls) in 13.627 seconds Ordered by: cumulative time - List reduced from 590 to 15 due to restriction <15> + List reduced from 673 to 15 due to restriction <15> ncalls tottime percall cumtime percall filename:lineno(function) - 1 0.002 0.002 15.948 15.948 /export/home/dlwoodruff/Documents/BookIII/trunk/pyomo/examples/doc/pyomobook/performance-ch/wl.py:112(solve_parametric) - 30 0.007 0.000 15.721 0.524 /export/home/dlwoodruff/software/pyomo/pyomo/opt/base/solvers.py:511(solve) - 30 0.001 0.000 9.150 0.305 /export/home/dlwoodruff/software/pyomo/pyomo/solvers/plugins/solvers/GUROBI.py:191(_presolve) - 30 0.001 0.000 9.149 0.305 /export/home/dlwoodruff/software/pyomo/pyomo/opt/solver/shellcmd.py:188(_presolve) - 30 0.001 0.000 9.134 0.304 /export/home/dlwoodruff/software/pyomo/pyomo/opt/base/solvers.py:651(_presolve) - 30 0.000 0.000 9.133 0.304 /export/home/dlwoodruff/software/pyomo/pyomo/opt/base/solvers.py:719(_convert_problem) - 30 0.002 0.000 9.133 0.304 /export/home/dlwoodruff/software/pyomo/pyomo/opt/base/convert.py:31(convert_problem) - 30 0.001 0.000 9.093 0.303 /export/home/dlwoodruff/software/pyomo/pyomo/solvers/plugins/converter/model.py:43(apply) - 30 0.001 0.000 9.080 0.303 /export/home/dlwoodruff/software/pyomo/pyomo/core/base/block.py:1756(write) - 30 0.008 0.000 9.077 0.303 /export/home/dlwoodruff/software/pyomo/pyomo/repn/plugins/cpxlp.py:81(__call__) - 30 1.308 0.044 9.065 0.302 /export/home/dlwoodruff/software/pyomo/pyomo/repn/plugins/cpxlp.py:377(_print_model_LP) - 30 0.002 0.000 5.016 0.167 /export/home/dlwoodruff/software/pyomo/pyomo/opt/solver/shellcmd.py:223(_apply_solver) - 30 0.002 0.000 5.013 0.167 /export/home/dlwoodruff/software/pyomo/pyomo/opt/solver/shellcmd.py:289(_execute_command) - 30 0.006 0.000 5.011 0.167 /export/home/dlwoodruff/software/pyutilib/pyutilib/subprocess/processmngr.py:433(run_command) - 30 0.001 0.000 4.388 0.146 /export/home/dlwoodruff/software/pyutilib/pyutilib/subprocess/processmngr.py:829(wait) + 1 0.001 0.001 13.627 13.627 /home/jdsiiro/Research/pyomo/examples/pyomobook/performance-ch/wl.py:132(solve_parametric) + 30 0.002 0.000 13.551 0.452 /home/jdsiiro/Research/pyomo/pyomo/opt/base/solvers.py:530(solve) + 30 0.001 0.000 10.383 0.346 /home/jdsiiro/Research/pyomo/pyomo/opt/solver/shellcmd.py:247(_apply_solver) + 30 0.002 0.000 10.381 0.346 /home/jdsiiro/Research/pyomo/pyomo/opt/solver/shellcmd.py:310(_execute_command) + 30 0.001 0.000 10.360 0.345 /projects/sems/install/rhel7-x86_64/pyomo/compiler/python/3.11.6/lib/python3.11/subprocess.py:506(run) + 30 0.000 0.000 10.288 0.343 /projects/sems/install/rhel7-x86_64/pyomo/compiler/python/3.11.6/lib/python3.11/subprocess.py:1165(communicate) + 60 0.000 0.000 10.287 0.171 /projects/sems/install/rhel7-x86_64/pyomo/compiler/python/3.11.6/lib/python3.11/subprocess.py:1259(wait) + 60 0.001 0.000 10.287 0.171 /projects/sems/install/rhel7-x86_64/pyomo/compiler/python/3.11.6/lib/python3.11/subprocess.py:2014(_wait) + 30 0.000 0.000 10.286 0.343 /projects/sems/install/rhel7-x86_64/pyomo/compiler/python/3.11.6/lib/python3.11/subprocess.py:2001(_try_wait) + 30 10.286 0.343 10.286 0.343 {built-in method posix.waitpid} + 30 0.000 0.000 2.123 0.071 /home/jdsiiro/Research/pyomo/pyomo/solvers/plugins/solvers/GUROBI.py:214(_presolve) + 30 0.000 0.000 2.122 0.071 /home/jdsiiro/Research/pyomo/pyomo/opt/solver/shellcmd.py:215(_presolve) + 30 0.000 0.000 2.114 0.070 /home/jdsiiro/Research/pyomo/pyomo/opt/base/solvers.py:687(_presolve) + 30 0.000 0.000 2.114 0.070 /home/jdsiiro/Research/pyomo/pyomo/opt/base/solvers.py:756(_convert_problem) + 30 0.001 0.000 2.114 0.070 /home/jdsiiro/Research/pyomo/pyomo/opt/base/convert.py:27(convert_problem) - 14919301 function calls (14916699 primitive calls) in 15.948 seconds + 7372057 function calls (7368345 primitive calls) in 13.627 seconds Ordered by: internal time - List reduced from 590 to 15 due to restriction <15> + List reduced from 673 to 15 due to restriction <15> ncalls tottime percall cumtime percall filename:lineno(function) - 30 4.381 0.146 4.381 0.146 {built-in method posix.waitpid} - 30 1.308 0.044 9.065 0.302 /export/home/dlwoodruff/software/pyomo/pyomo/repn/plugins/cpxlp.py:377(_print_model_LP) - 76560 0.703 0.000 1.165 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/repn/plugins/cpxlp.py:178(_print_expr_canonical) - 76560 0.682 0.000 0.858 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/repn/standard_repn.py:424(_collect_sum) - 30 0.544 0.018 0.791 0.026 /export/home/dlwoodruff/software/pyomo/pyomo/solvers/plugins/solvers/GUROBI.py:365(process_soln_file) - 76560 0.539 0.000 1.691 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/repn/standard_repn.py:973(_generate_standard_repn) - 306000 0.507 0.000 0.893 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/core/base/set.py:581(bounds) - 30 0.367 0.012 0.367 0.012 {built-in method posix.read} - 76560 0.323 0.000 2.291 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/repn/standard_repn.py:245(generate_standard_repn) - 76560 0.263 0.000 2.923 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/repn/plugins/cpxlp.py:569(constraint_generator) - 225090 0.262 0.000 0.336 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/core/base/constraint.py:228(has_ub) - 153060 0.249 0.000 0.422 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/core/expr/symbol_map.py:82(createSymbol) - 77220 0.220 0.000 0.457 0.000 {built-in method builtins.sorted} - 30 0.201 0.007 0.202 0.007 {built-in method _posixsubprocess.fork_exec} - 153000 0.185 0.000 0.690 0.000 /export/home/dlwoodruff/software/pyomo/pyomo/core/base/var.py:407(ub) + 30 10.286 0.343 10.286 0.343 {built-in method posix.waitpid} + 30 0.325 0.011 2.078 0.069 /home/jdsiiro/Research/pyomo/pyomo/repn/plugins/lp_writer.py:250(write) + 76560 0.278 0.000 0.668 0.000 /home/jdsiiro/Research/pyomo/pyomo/repn/plugins/lp_writer.py:576(write_expression) + 30 0.248 0.008 0.508 0.017 /home/jdsiiro/Research/pyomo/pyomo/solvers/plugins/solvers/GUROBI.py:394(process_soln_file) + 76560 0.221 0.000 0.395 0.000 /home/jdsiiro/Research/pyomo/pyomo/repn/linear.py:664(_before_linear) + 301530 0.131 0.000 0.178 0.000 /home/jdsiiro/Research/pyomo/pyomo/core/expr/symbol_map.py:133(getSymbol) + 30 0.119 0.004 0.192 0.006 /home/jdsiiro/Research/pyomo/pyomo/core/base/PyomoModel.py:461(select) + 77190 0.117 0.000 0.161 0.000 /home/jdsiiro/Research/pyomo/pyomo/solvers/plugins/solvers/GUROBI.py:451() + 30 0.116 0.004 0.285 0.010 /home/jdsiiro/Research/pyomo/pyomo/core/base/PyomoModel.py:337(add_solution) + 76530 0.080 0.000 0.106 0.000 /home/jdsiiro/Research/pyomo/pyomo/core/expr/symbol_map.py:63(addSymbol) + 239550 0.079 0.000 0.079 0.000 /home/jdsiiro/Research/pyomo/pyomo/core/base/indexed_component.py:611(__getitem__) + 1062450 0.078 0.000 0.078 0.000 {built-in method builtins.id} + 163050 0.074 0.000 0.128 0.000 /home/jdsiiro/Research/pyomo/pyomo/core/base/var.py:1045(__getitem__) + 76560 0.074 0.000 0.080 0.000 /home/jdsiiro/Research/pyomo/pyomo/repn/linear.py:834(finalizeResult) + 153150 0.073 0.000 0.191 0.000 /home/jdsiiro/Research/pyomo/pyomo/core/base/block.py:1505(_component_data_itervalues) -[ 36.46] Resetting the tic/toc delta timer -Using license file /export/home/dlwoodruff/software/gurobi900/linux64/../lic/gurobi.lic -Academic license - for non-commercial use only -[+ 1.21] finished parameter sweep with persistent interface +[ 0.00] Resetting the tic/toc delta timer +[+ 0.66] Finished parameter sweep with persistent interface From d34b50cb6a522df7f931f47986e4a74b54a0910e Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 15:49:35 -0700 Subject: [PATCH 14/26] Refine baseline test filter patterns --- pyomo/common/unittest.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index 2c93a49e1ee..a77c2d6bd56 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -743,8 +743,8 @@ def filter_fcn(self, line): 'Total CPU', 'Ipopt', 'license', - 'Status: optimal', - 'Status: feasible', + #'Status: optimal', + #'Status: feasible', 'time:', 'Time:', 'with format cpxlp', @@ -752,12 +752,13 @@ def filter_fcn(self, line): 'execution time=', 'Solver results file:', 'TokenServer', + # ignore entries in pstats reports: 'function calls', 'List reduced', '.py:', - '{built-in method', - '{method', - '{pyomo.core.expr.numvalue.as_numeric}', + ' {built-in method', + ' {method', + ' {pyomo.core.expr.numvalue.as_numeric}', ): if field in line: return True From 9c3d7610ccd47ff2cca14d0eb03c9aec5ac6e394 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Tue, 9 Jan 2024 17:23:28 -0700 Subject: [PATCH 15/26] Use a deep import when checking pyutilib availability (catches pyutilib's incompatibility with python 3.12) --- doc/OnlineDocs/tests/test_examples.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/tests/test_examples.py index caac8e36256..40d4127fd74 100644 --- a/doc/OnlineDocs/tests/test_examples.py +++ b/doc/OnlineDocs/tests/test_examples.py @@ -42,9 +42,9 @@ class TestOnlineDocExamples(unittest.BaseLineTestDriver, unittest.TestCase): # data 'test_data_ABCD9': ['pyodbc'], 'test_data_ABCD8': ['pyodbc'], - 'test_data_ABCD7': ['win32com', 'pyutilib'], + 'test_data_ABCD7': ['win32com', 'pyutilib.excel.spreadsheet'], # dataportal - 'test_dataportal_dataportal_tab': ['xlrd', 'pyutilib'], + 'test_dataportal_dataportal_tab': ['xlrd', 'pyutilib.excel.spreadsheet'], 'test_dataportal_set_initialization': ['numpy'], 'test_dataportal_param_initialization': ['numpy'], # kernel From 1c8e8044d83b83a0620fe81e43bc1d49b61ffa8a Mon Sep 17 00:00:00 2001 From: John Siirola Date: Wed, 10 Jan 2024 08:06:40 -0700 Subject: [PATCH 16/26] Fix: catch pyutilib errors on Python 3.12 --- doc/OnlineDocs/tests/test_examples.py | 9 +++++++-- pyomo/common/unittest.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/tests/test_examples.py index 40d4127fd74..46c258e91f4 100644 --- a/doc/OnlineDocs/tests/test_examples.py +++ b/doc/OnlineDocs/tests/test_examples.py @@ -38,13 +38,18 @@ class TestOnlineDocExamples(unittest.BaseLineTestDriver, unittest.TestCase): ) solver_dependencies = {} + # Note on package dependencies: two tests actually need + # pyutilib.excel.spreadsheet; however, the pyutilib importer is + # broken on Python>=3.12, so instead of checking for spreadsheet, we + # will check for pyutilib.component, which triggers the importer + # (and catches the error on 3.12) package_dependencies = { # data 'test_data_ABCD9': ['pyodbc'], 'test_data_ABCD8': ['pyodbc'], - 'test_data_ABCD7': ['win32com', 'pyutilib.excel.spreadsheet'], + 'test_data_ABCD7': ['win32com', 'pyutilib.component'], # dataportal - 'test_dataportal_dataportal_tab': ['xlrd', 'pyutilib.excel.spreadsheet'], + 'test_dataportal_dataportal_tab': ['xlrd', 'pyutilib.component'], 'test_dataportal_set_initialization': ['numpy'], 'test_dataportal_param_initialization': ['numpy'], # kernel diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index a77c2d6bd56..cd5f46d00f5 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -752,7 +752,7 @@ def filter_fcn(self, line): 'execution time=', 'Solver results file:', 'TokenServer', - # ignore entries in pstats reports: + # next 6 patterns ignore entries in pstats reports: 'function calls', 'List reduced', '.py:', From 679018282f7868e4babf5588ef5e6a88836e9fd9 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Thu, 11 Jan 2024 14:31:15 -0700 Subject: [PATCH 17/26] Simplify baseline tester to better leverage assertStructuredAlmostEqual --- pyomo/common/unittest.py | 63 ++++------------------------------------ 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index cd5f46d00f5..5173008c759 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -786,13 +786,9 @@ def filter_file_contents(self, lines): s = line.find("seconds") + 7 line = line[s:] + item_list = [] items = line.strip().split() for i in items: - if not i: - continue - if i.startswith('/') or i.startswith(":\\", 1): - continue - # A few substitutions to get tests passing on pypy3 if ".inf" in i: i = i.replace(".inf", "inf") @@ -800,9 +796,10 @@ def filter_file_contents(self, lines): i = i.replace("null", "None") try: - filtered.append(float(i)) + item_list.append(float(i)) except: - filtered.append(i) + item_list.append(i) + filtered.append(item_list) return filtered @@ -811,56 +808,6 @@ def compare_baselines(self, test_output, baseline, abstol=1e-6, reltol=None): out_filtered = self.filter_file_contents(test_output.strip().split('\n')) base_filtered = self.filter_file_contents(baseline.strip().split('\n')) - if len(out_filtered) != len(base_filtered): - # it is likely that a solver returned a (slightly) nonzero - # value for a variable that is normally 0. Try to look for - # sequences like "['varname:', 'Value:', 1e-9]" that appear - # in one result but not the other and remove them. - i = 0 - while i < min(len(out_filtered), len(base_filtered)): - try: - self.assertStructuredAlmostEqual( - out_filtered[i], - base_filtered[i], - abstol=abstol, - reltol=reltol, - allow_second_superset=False, - ) - i += 1 - continue - except self.failureException: - pass - - try: - index_of_out_i_in_base = base_filtered.index(out_filtered[i], i) - except ValueError: - index_of_out_i_in_base = float('inf') - try: - index_of_base_i_in_out = out_filtered.index(base_filtered[i], i) - except ValueError: - index_of_base_i_in_out = float('inf') - if index_of_out_i_in_base < index_of_base_i_in_out: - extra = base_filtered - n = index_of_out_i_in_base - else: - extra = out_filtered - n = index_of_base_i_in_out - if n == float('inf'): - n = None - extra_terms = extra[i:n] - try: - assert len(extra_terms) % 3 == 0 - assert all(str(_)[-1] == ":" for _ in extra_terms[0::3]) - assert all(str(_) == "Value:" for _ in extra_terms[1::3]) - assert all(abs(_) < abstol for _ in extra_terms[2::3]) - except: - # This does not match the pattern we are looking - # for: quit processing, and let the next - # assertStructuredAlmostEqual raise the appropriate - # failureException - break - extra[i:n] = [] - try: self.assertStructuredAlmostEqual( out_filtered, @@ -869,6 +816,7 @@ def compare_baselines(self, test_output, baseline, abstol=1e-6, reltol=None): reltol=reltol, allow_second_superset=False, ) + return True except self.failureException: # Print helpful information when file comparison fails print('---------------------------------') @@ -881,7 +829,6 @@ def compare_baselines(self, test_output, baseline, abstol=1e-6, reltol=None): print('---------------------------------') print(test_output) raise - return True def python_test_driver(self, tname, test_file, base_file): bname = os.path.basename(test_file) From a3981f43d1aeaa58fd98b1d7e57ca7cb62c24c0c Mon Sep 17 00:00:00 2001 From: John Siirola Date: Thu, 11 Jan 2024 14:31:46 -0700 Subject: [PATCH 18/26] Add option to bypass cleandoc in Pyomo's log formatter --- pyomo/common/log.py | 3 ++- pyomo/core/base/PyomoModel.py | 1 + pyomo/core/base/block.py | 3 ++- pyomo/scripting/util.py | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pyomo/common/log.py b/pyomo/common/log.py index bf2ae1e4c96..3097fe1c6de 100644 --- a/pyomo/common/log.py +++ b/pyomo/common/log.py @@ -139,7 +139,8 @@ def format(self, record): # # A standard approach is to use inspect.cleandoc, which # allows for the first line to have 0 indent. - msg = inspect.cleandoc(msg) + if getattr(record, 'cleandoc', True): + msg = inspect.cleandoc(msg) # Split the formatted log message (that currently has _flag in # lieu of the actual message content) into lines, then diff --git a/pyomo/core/base/PyomoModel.py b/pyomo/core/base/PyomoModel.py index 6aacabeb183..055f6f8450a 100644 --- a/pyomo/core/base/PyomoModel.py +++ b/pyomo/core/base/PyomoModel.py @@ -877,6 +877,7 @@ def _initialize_component( str(data).strip(), type(err).__name__, err, + extra={'cleandoc': False}, ) raise diff --git a/pyomo/core/base/block.py b/pyomo/core/base/block.py index fd5322ba686..d3950575435 100644 --- a/pyomo/core/base/block.py +++ b/pyomo/core/base/block.py @@ -1186,11 +1186,12 @@ def add_component(self, name, val): except: err = sys.exc_info()[1] logger.error( - "Constructing component '%s' from data=%s failed:\n%s: %s", + "Constructing component '%s' from data=%s failed:\n %s: %s", str(val.name), str(data).strip(), type(err).__name__, err, + extra={'cleandoc': False}, ) raise if generate_debug_messages: diff --git a/pyomo/scripting/util.py b/pyomo/scripting/util.py index 3ec0feccd66..5bc65eb35ae 100644 --- a/pyomo/scripting/util.py +++ b/pyomo/scripting/util.py @@ -146,7 +146,7 @@ def pyomo_excepthook(etype, value, tb): if valueStr[0] == valueStr[-1] and valueStr[0] in "\"'": valueStr = valueStr[1:-1] - logger.error(msg + valueStr) + logger.error(msg + valueStr, extra={'cleandoc': False}) tb_list = traceback.extract_tb(tb, None) i = 0 @@ -1129,7 +1129,7 @@ def _run_command_impl(command, parser, args, name, data, options): if type(err) == KeyError and errStr != "None": errStr = str(err).replace(r"\n", "\n")[1:-1] - logger.error(msg + errStr) + logger.error(msg + errStr, extra={'cleandoc': False}) errorcode = 1 return retval, errorcode From 3bea8fc6ce5909d30203b2c0a44a168fc366732a Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 01:13:33 -0700 Subject: [PATCH 19/26] Remove "values" from results when they are within abstol of 0 --- pyomo/common/unittest.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index 5173008c759..7af4ad99bda 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -764,7 +764,7 @@ def filter_fcn(self, line): return True return False - def filter_file_contents(self, lines): + def filter_file_contents(self, lines, abstol=None): filtered = [] deprecated = None for line in lines: @@ -799,14 +799,31 @@ def filter_file_contents(self, lines): item_list.append(float(i)) except: item_list.append(i) - filtered.append(item_list) + + # We can get printed results objects where the baseline is + # exactly 0 (and omitted) and the test is slightly non-zero. + # We will look for the pattern of values printed from + # results objects and remote them if they are within + # tolerance of 0 + if ( + len(item_list) == 2 + and item_list[0] == 'Value:' + and abs(item_list[1]) < (abstol or 0) + and len(filtered[-1]) == 1 + and filtered[-1][-1] == ':' + ): + filtered.pop() + else: + filtered.append(item_list) return filtered def compare_baselines(self, test_output, baseline, abstol=1e-6, reltol=None): # Filter files independently and then compare filtered contents - out_filtered = self.filter_file_contents(test_output.strip().split('\n')) - base_filtered = self.filter_file_contents(baseline.strip().split('\n')) + out_filtered = self.filter_file_contents( + test_output.strip().split('\n'), abstol + ) + base_filtered = self.filter_file_contents(baseline.strip().split('\n'), abstol) try: self.assertStructuredAlmostEqual( From 902caa287e4f59b94dc1bdd2b1253587969260f0 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 01:40:26 -0700 Subject: [PATCH 20/26] Rename BaseLineTestDriver and compare_baselines --- doc/OnlineDocs/tests/test_examples.py | 8 ++++---- examples/pyomobook/test_book_examples.py | 8 ++++---- pyomo/common/unittest.py | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/tests/test_examples.py index 46c258e91f4..e2563745b07 100644 --- a/doc/OnlineDocs/tests/test_examples.py +++ b/doc/OnlineDocs/tests/test_examples.py @@ -29,11 +29,11 @@ currdir = this_file_dir() -class TestOnlineDocExamples(unittest.BaseLineTestDriver, unittest.TestCase): +class TestOnlineDocExamples(unittest.BaselineTestDriver, unittest.TestCase): # Only test files in directories ending in -ch. These directories # contain the updated python and scripting files corresponding to # each chapter in the book. - py_tests, sh_tests = unittest.BaseLineTestDriver.gather_tests( + py_tests, sh_tests = unittest.BaselineTestDriver.gather_tests( list(filter(os.path.isdir, glob.glob(os.path.join(currdir, '*')))) ) @@ -57,13 +57,13 @@ class TestOnlineDocExamples(unittest.BaseLineTestDriver, unittest.TestCase): } @parameterized.parameterized.expand( - sh_tests, name_func=unittest.BaseLineTestDriver.custom_name_func + sh_tests, name_func=unittest.BaselineTestDriver.custom_name_func ) def test_sh(self, tname, test_file, base_file): self.shell_test_driver(tname, test_file, base_file) @parameterized.parameterized.expand( - py_tests, name_func=unittest.BaseLineTestDriver.custom_name_func + py_tests, name_func=unittest.BaselineTestDriver.custom_name_func ) def test_py(self, tname, test_file, base_file): self.python_test_driver(tname, test_file, base_file) diff --git a/examples/pyomobook/test_book_examples.py b/examples/pyomobook/test_book_examples.py index af7e9e33d20..fea9a63d572 100644 --- a/examples/pyomobook/test_book_examples.py +++ b/examples/pyomobook/test_book_examples.py @@ -29,11 +29,11 @@ currdir = this_file_dir() -class TestBookExamples(unittest.BaseLineTestDriver, unittest.TestCase): +class TestBookExamples(unittest.BaselineTestDriver, unittest.TestCase): # Only test files in directories ending in -ch. These directories # contain the updated python and scripting files corresponding to # each chapter in the book. - py_tests, sh_tests = unittest.BaseLineTestDriver.gather_tests( + py_tests, sh_tests = unittest.BaselineTestDriver.gather_tests( list(filter(os.path.isdir, glob.glob(os.path.join(currdir, '*-ch')))) ) @@ -142,13 +142,13 @@ def _check_gurobi_fully_licensed(self): self.__class__.solver_available['gurobi_license'] = False @parameterized.parameterized.expand( - sh_tests, name_func=unittest.BaseLineTestDriver.custom_name_func + sh_tests, name_func=unittest.BaselineTestDriver.custom_name_func ) def test_book_sh(self, tname, test_file, base_file): self.shell_test_driver(tname, test_file, base_file) @parameterized.parameterized.expand( - py_tests, name_func=unittest.BaseLineTestDriver.custom_name_func + py_tests, name_func=unittest.BaselineTestDriver.custom_name_func ) def test_book_py(self, tname, test_file, base_file): self.python_test_driver(tname, test_file, base_file) diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index 7af4ad99bda..77597d7b419 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -556,7 +556,7 @@ def assertRaisesRegex(self, expected_exception, expected_regex, *args, **kwargs) return context.handle('assertRaisesRegex', args, kwargs) -class BaseLineTestDriver(object): +class BaselineTestDriver(object): """Generic driver for performing baseline tests in bulk This test driver was originally crafted for testing the examples in @@ -818,7 +818,7 @@ def filter_file_contents(self, lines, abstol=None): return filtered - def compare_baselines(self, test_output, baseline, abstol=1e-6, reltol=None): + def compare_baseline(self, test_output, baseline, abstol=1e-6, reltol=None): # Filter files independently and then compare filtered contents out_filtered = self.filter_file_contents( test_output.strip().split('\n'), abstol @@ -875,7 +875,7 @@ def python_test_driver(self, tname, test_file, base_file): os.chdir(cwd) try: - self.compare_baselines(OUT.getvalue(), baseline) + self.compare_baseline(OUT.getvalue(), baseline) except: if os.environ.get('PYOMO_TEST_UPDATE_BASELINES', None): with open(base_file, 'w') as FILE: @@ -915,7 +915,7 @@ def shell_test_driver(self, tname, test_file, base_file): os.chdir(cwd) try: - self.compare_baselines(rc.stdout.decode(), baseline) + self.compare_baseline(rc.stdout.decode(), baseline) except: if os.environ.get('PYOMO_TEST_UPDATE_BASELINES', None): with open(base_file, 'w') as FILE: From b94c19d7a1a0d330b9685619962eccacb9da431a Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 01:40:41 -0700 Subject: [PATCH 21/26] Fix filter logic error --- pyomo/common/unittest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyomo/common/unittest.py b/pyomo/common/unittest.py index 77597d7b419..6b416b82c2b 100644 --- a/pyomo/common/unittest.py +++ b/pyomo/common/unittest.py @@ -808,9 +808,10 @@ def filter_file_contents(self, lines, abstol=None): if ( len(item_list) == 2 and item_list[0] == 'Value:' + and type(item_list[1]) is float and abs(item_list[1]) < (abstol or 0) and len(filtered[-1]) == 1 - and filtered[-1][-1] == ':' + and filtered[-1][0][-1] == ':' ): filtered.pop() else: From 44a58b76bf91f7a1c1c7d011ea08e2c1a6c81070 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 01:40:45 -0700 Subject: [PATCH 22/26] Add basic testing for BaselineTestDriver --- pyomo/common/tests/test_unittest.py | 193 ++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/pyomo/common/tests/test_unittest.py b/pyomo/common/tests/test_unittest.py index a87fc57da9e..ef97e73d062 100644 --- a/pyomo/common/tests/test_unittest.py +++ b/pyomo/common/tests/test_unittest.py @@ -236,5 +236,198 @@ def test_bound_function_require_fork(self): self.bound_function_require_fork() +baseline = """ +[ 0.00] Setting up Pyomo environment +[ 0.00] Applying Pyomo preprocessing actions +[ 0.00] Creating model +[ 0.00] Applying solver +[ 0.05] Processing results + Number of solutions: 1 + Solution Information + Gap: None + Status: optimal + Function Value: -9.99943939749e-05 + Solver results file: results.yml +[ 0.05] Applying Pyomo postprocessing actions +[ 0.05] Pyomo Finished +# ========================================================== +# = Solver Results = +# ========================================================== +# ---------------------------------------------------------- +# Problem Information +# ---------------------------------------------------------- +Problem: +- Lower bound: -inf + Upper bound: inf + Number of objectives: 1 + Number of constraints: 3 + Number of variables: 3 + Sense: unknown +# ---------------------------------------------------------- +# Solver Information +# ---------------------------------------------------------- +Solver: +- Status: ok + Message: Ipopt 3.12.3\x3a Optimal Solution Found + Termination condition: optimal + Id: 0 + Error rc: 0 + Time: 0.0408430099487 +# ---------------------------------------------------------- +# Solution Information +# ---------------------------------------------------------- +Solution: +- number of solutions: 1 + number of solutions displayed: 1 +- Gap: None + Status: optimal + Message: Ipopt 3.12.3\x3a Optimal Solution Found + Objective: + f1: + Value: -9.99943939749e-05 + Variable: + compl.v: + Value: 9.99943939749e-05 + y: + Value: 9.99943939749e-05 + Constraint: No values +""" + +pass_ref = """ +[ 0.00] Setting up Pyomo environment +[ 0.00] Applying Pyomo preprocessing actions +[ 0.00] Creating model +[ 0.00] Applying solver +[ 0.05] Processing results + Number of solutions: 1 + Solution Information + Gap: None + Status: optimal + Function Value: -0.00010001318188373491 + Solver results file: results.yml +[ 0.05] Applying Pyomo postprocessing actions +[ 0.05] Pyomo Finished +# ========================================================== +# = Solver Results = +# ========================================================== +# ---------------------------------------------------------- +# Problem Information +# ---------------------------------------------------------- +Problem: +- Lower bound: -inf + Upper bound: inf + Number of objectives: 1 + Number of constraints: 3 + Number of variables: 3 + Sense: unknown +# ---------------------------------------------------------- +# Solver Information +# ---------------------------------------------------------- +Solver: +- Status: ok + Message: Ipopt 3.14.13\x3a Optimal Solution Found + Termination condition: optimal + Id: 0 + Error rc: 0 + Time: 0.04224729537963867 +# ---------------------------------------------------------- +# Solution Information +# ---------------------------------------------------------- +Solution: +- number of solutions: 1 + number of solutions displayed: 1 +- Gap: None + Status: optimal + Message: Ipopt 3.14.13\x3a Optimal Solution Found + Objective: + f1: + Value: -0.00010001318188373491 + Variable: + compl.v: + Value: 9.99943939749205e-05 + x: + Value: -9.39395440720558e-09 + y: + Value: 9.99943939749205e-05 + Constraint: No values + +""" + +fail_ref = """ +[ 0.00] Setting up Pyomo environment +[ 0.00] Applying Pyomo preprocessing actions +[ 0.00] Creating model +[ 0.00] Applying solver +[ 0.05] Processing results + Number of solutions: 1 + Solution Information + Gap: None + Status: optimal + Function Value: -0.00010001318188373491 + Solver results file: results.yml +[ 0.05] Applying Pyomo postprocessing actions +[ 0.05] Pyomo Finished +# ========================================================== +# = Solver Results = +# ========================================================== +# ---------------------------------------------------------- +# Problem Information +# ---------------------------------------------------------- +Problem: +- Lower bound: -inf + Upper bound: inf + Number of objectives: 1 + Number of constraints: 3 + Number of variables: 3 + Sense: unknown +# ---------------------------------------------------------- +# Solver Information +# ---------------------------------------------------------- +Solver: +- Status: ok + Message: Ipopt 3.14.13\x3a Optimal Solution Found + Termination condition: optimal + Id: 0 + Error rc: 0 + Time: 0.04224729537963867 +# ---------------------------------------------------------- +# Solution Information +# ---------------------------------------------------------- +Solution: +- number of solutions: 1 + number of solutions displayed: 1 +- Gap: None + Status: optimal + Message: Ipopt 3.14.13\x3a Optimal Solution Found + Objective: + f1: + Value: -0.00010001318188373491 + Variable: + compl.v: + Value: 9.79943939749205e-05 + x: + Value: -9.39395440720558e-09 + y: + Value: 9.99943939749205e-05 + Constraint: No values + +""" + + +class TestBaselineTestDriver(unittest.BaselineTestDriver, unittest.TestCase): + solver_dependencies = {} + package_dependencies = {} + + def test_baseline_pass(self): + self.compare_baseline(pass_ref, baseline, abstol=1e-6) + + with self.assertRaises(self.failureException): + self.compare_baseline(pass_ref, baseline, None) + + def test_baseline_fail(self): + with self.assertRaises(self.failureException): + self.compare_baseline(fail_ref, baseline) + + if __name__ == '__main__': unittest.main() From 35050837a7e731e62519f4a7864f1aba49badb1d Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 01:50:57 -0700 Subject: [PATCH 23/26] Update test headers to clarify matplotlib_available import --- doc/OnlineDocs/tests/test_examples.py | 10 ++++------ examples/pyomobook/test_book_examples.py | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/tests/test_examples.py index e2563745b07..33cbab2e8b4 100644 --- a/doc/OnlineDocs/tests/test_examples.py +++ b/doc/OnlineDocs/tests/test_examples.py @@ -12,22 +12,20 @@ import pyomo.common.unittest as unittest import glob import os -from pyomo.common.dependencies import attempt_import +from pyomo.common.dependencies import attempt_import, matplotlib_available from pyomo.common.fileutils import this_file_dir import pyomo.environ as pyo +currdir = this_file_dir() + parameterized, param_available = attempt_import('parameterized') if not param_available: raise unittest.SkipTest('Parameterized is not available.') -# Needed for testing (switches the matplotlib backend): -from pyomo.common.dependencies import matplotlib_available - +# Needed for testing (triggers matplotlib import and switches its backend): bool(matplotlib_available) -currdir = this_file_dir() - class TestOnlineDocExamples(unittest.BaselineTestDriver, unittest.TestCase): # Only test files in directories ending in -ch. These directories diff --git a/examples/pyomobook/test_book_examples.py b/examples/pyomobook/test_book_examples.py index fea9a63d572..e946864c1aa 100644 --- a/examples/pyomobook/test_book_examples.py +++ b/examples/pyomobook/test_book_examples.py @@ -12,22 +12,20 @@ import pyomo.common.unittest as unittest import glob import os -from pyomo.common.dependencies import attempt_import +from pyomo.common.dependencies import attempt_import, matplotlib_available from pyomo.common.fileutils import this_file_dir import pyomo.environ as pyo +currdir = this_file_dir() + parameterized, param_available = attempt_import('parameterized') if not param_available: raise unittest.SkipTest('Parameterized is not available.') -# Needed for testing (switches the matplotlib backend): -from pyomo.common.dependencies import matplotlib_available - +# Needed for testing (triggers matplotlib import and switches its backend): bool(matplotlib_available) -currdir = this_file_dir() - class TestBookExamples(unittest.BaselineTestDriver, unittest.TestCase): # Only test files in directories ending in -ch. These directories From 427bcd0242ae2ab1fa5523d7a0dfe7733c8a1260 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 08:44:37 -0700 Subject: [PATCH 24/26] Move doc/OnlineDocs/tests -> doc/OnlineDocs/src --- doc/OnlineDocs/Makefile | 2 +- doc/OnlineDocs/conf.py | 4 +- .../expressions/design.rst | 8 +- .../developer_reference/expressions/index.rst | 2 +- .../expressions/managing.rst | 28 ++-- .../expressions/overview.rst | 14 +- .../expressions/performance.rst | 20 +-- .../pyomo_modeling_components/Constraints.rst | 6 +- .../pyomo_modeling_components/Expressions.rst | 18 +-- .../pyomo_modeling_components/Sets.rst | 4 +- .../pyomo_modeling_components/Variables.rst | 6 +- .../pyomo_overview/simple_examples.rst | 12 +- doc/OnlineDocs/{tests => src}/data/A.tab | 0 doc/OnlineDocs/{tests => src}/data/ABCD.tab | 0 doc/OnlineDocs/{tests => src}/data/ABCD.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD.xls | Bin doc/OnlineDocs/{tests => src}/data/ABCD1.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD1.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD1.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD2.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD2.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD2.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD3.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD3.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD3.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD4.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD4.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD4.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD5.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD5.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD5.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD6.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD6.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD6.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD7.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD7.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD7.txt | 0 doc/OnlineDocs/{tests => src}/data/ABCD8.bad | 0 doc/OnlineDocs/{tests => src}/data/ABCD8.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD8.py | 0 doc/OnlineDocs/{tests => src}/data/ABCD9.bad | 0 doc/OnlineDocs/{tests => src}/data/ABCD9.dat | 0 doc/OnlineDocs/{tests => src}/data/ABCD9.py | 0 doc/OnlineDocs/{tests => src}/data/C.tab | 0 doc/OnlineDocs/{tests => src}/data/D.tab | 0 doc/OnlineDocs/{tests => src}/data/U.tab | 0 doc/OnlineDocs/{tests => src}/data/Y.tab | 0 doc/OnlineDocs/{tests => src}/data/Z.tab | 0 .../{tests => src}/data/data_managers.txt | 0 doc/OnlineDocs/{tests => src}/data/diet.dat | 0 doc/OnlineDocs/{tests => src}/data/diet.sql | 0 .../{tests => src}/data/diet.sqlite | Bin .../{tests => src}/data/diet.sqlite.dat | 0 doc/OnlineDocs/{tests => src}/data/diet1.py | 0 doc/OnlineDocs/{tests => src}/data/ex.dat | 0 doc/OnlineDocs/{tests => src}/data/ex.py | 0 doc/OnlineDocs/{tests => src}/data/ex.txt | 0 doc/OnlineDocs/{tests => src}/data/ex1.dat | 0 doc/OnlineDocs/{tests => src}/data/ex2.dat | 0 .../{tests => src}/data/import1.tab.dat | 0 .../{tests => src}/data/import1.tab.py | 0 .../{tests => src}/data/import1.tab.txt | 0 .../{tests => src}/data/import2.tab.dat | 0 .../{tests => src}/data/import2.tab.py | 0 .../{tests => src}/data/import2.tab.txt | 0 .../{tests => src}/data/import3.tab.dat | 0 .../{tests => src}/data/import3.tab.py | 0 .../{tests => src}/data/import3.tab.txt | 0 .../{tests => src}/data/import4.tab.dat | 0 .../{tests => src}/data/import4.tab.py | 0 .../{tests => src}/data/import4.tab.txt | 0 .../{tests => src}/data/import5.tab.dat | 0 .../{tests => src}/data/import5.tab.py | 0 .../{tests => src}/data/import5.tab.txt | 0 .../{tests => src}/data/import6.tab.dat | 0 .../{tests => src}/data/import6.tab.py | 0 .../{tests => src}/data/import6.tab.txt | 0 .../{tests => src}/data/import7.tab.dat | 0 .../{tests => src}/data/import7.tab.py | 0 .../{tests => src}/data/import7.tab.txt | 0 .../{tests => src}/data/import8.tab.dat | 0 .../{tests => src}/data/import8.tab.py | 0 .../{tests => src}/data/import8.tab.txt | 0 .../{tests => src}/data/namespace1.dat | 0 doc/OnlineDocs/{tests => src}/data/param1.dat | 0 doc/OnlineDocs/{tests => src}/data/param1.py | 0 doc/OnlineDocs/{tests => src}/data/param1.txt | 0 doc/OnlineDocs/{tests => src}/data/param2.dat | 0 doc/OnlineDocs/{tests => src}/data/param2.py | 0 doc/OnlineDocs/{tests => src}/data/param2.txt | 0 .../{tests => src}/data/param2a.dat | 0 doc/OnlineDocs/{tests => src}/data/param2a.py | 0 .../{tests => src}/data/param2a.txt | 0 doc/OnlineDocs/{tests => src}/data/param3.dat | 0 doc/OnlineDocs/{tests => src}/data/param3.py | 0 doc/OnlineDocs/{tests => src}/data/param3.txt | 0 .../{tests => src}/data/param3a.dat | 0 doc/OnlineDocs/{tests => src}/data/param3a.py | 0 .../{tests => src}/data/param3a.txt | 0 .../{tests => src}/data/param3b.dat | 0 doc/OnlineDocs/{tests => src}/data/param3b.py | 0 .../{tests => src}/data/param3b.txt | 0 .../{tests => src}/data/param3c.dat | 0 doc/OnlineDocs/{tests => src}/data/param3c.py | 0 .../{tests => src}/data/param3c.txt | 0 doc/OnlineDocs/{tests => src}/data/param4.dat | 0 doc/OnlineDocs/{tests => src}/data/param4.py | 0 doc/OnlineDocs/{tests => src}/data/param4.txt | 0 doc/OnlineDocs/{tests => src}/data/param5.dat | 0 doc/OnlineDocs/{tests => src}/data/param5.py | 0 doc/OnlineDocs/{tests => src}/data/param5.txt | 0 .../{tests => src}/data/param5a.dat | 0 doc/OnlineDocs/{tests => src}/data/param5a.py | 0 .../{tests => src}/data/param5a.txt | 0 doc/OnlineDocs/{tests => src}/data/param6.dat | 0 doc/OnlineDocs/{tests => src}/data/param6.py | 0 doc/OnlineDocs/{tests => src}/data/param6.txt | 0 .../{tests => src}/data/param6a.dat | 0 doc/OnlineDocs/{tests => src}/data/param6a.py | 0 .../{tests => src}/data/param6a.txt | 0 .../{tests => src}/data/param7a.dat | 0 doc/OnlineDocs/{tests => src}/data/param7a.py | 0 .../{tests => src}/data/param7a.txt | 0 .../{tests => src}/data/param7b.dat | 0 doc/OnlineDocs/{tests => src}/data/param7b.py | 0 .../{tests => src}/data/param7b.txt | 0 .../{tests => src}/data/param8a.dat | 0 doc/OnlineDocs/{tests => src}/data/param8a.py | 0 .../{tests => src}/data/param8a.txt | 0 .../{tests => src}/data/pyomo.diet1.sh | 0 .../{tests => src}/data/pyomo.diet1.txt | 0 .../{tests => src}/data/pyomo.diet2.sh | 0 .../{tests => src}/data/pyomo.diet2.txt | 0 doc/OnlineDocs/{tests => src}/data/set1.dat | 0 doc/OnlineDocs/{tests => src}/data/set1.py | 0 doc/OnlineDocs/{tests => src}/data/set1.txt | 0 doc/OnlineDocs/{tests => src}/data/set2.dat | 0 doc/OnlineDocs/{tests => src}/data/set2.py | 0 doc/OnlineDocs/{tests => src}/data/set2.txt | 0 doc/OnlineDocs/{tests => src}/data/set2a.dat | 0 doc/OnlineDocs/{tests => src}/data/set2a.py | 0 doc/OnlineDocs/{tests => src}/data/set2a.txt | 0 doc/OnlineDocs/{tests => src}/data/set3.dat | 0 doc/OnlineDocs/{tests => src}/data/set3.py | 0 doc/OnlineDocs/{tests => src}/data/set3.txt | 0 doc/OnlineDocs/{tests => src}/data/set4.dat | 0 doc/OnlineDocs/{tests => src}/data/set4.py | 0 doc/OnlineDocs/{tests => src}/data/set4.txt | 0 doc/OnlineDocs/{tests => src}/data/set5.dat | 0 doc/OnlineDocs/{tests => src}/data/set5.py | 0 doc/OnlineDocs/{tests => src}/data/set5.txt | 0 doc/OnlineDocs/{tests => src}/data/table0.dat | 0 doc/OnlineDocs/{tests => src}/data/table0.py | 0 doc/OnlineDocs/{tests => src}/data/table0.txt | 0 .../{tests => src}/data/table0.ul.dat | 0 .../{tests => src}/data/table0.ul.py | 0 .../{tests => src}/data/table0.ul.txt | 0 doc/OnlineDocs/{tests => src}/data/table1.dat | 0 doc/OnlineDocs/{tests => src}/data/table1.py | 0 doc/OnlineDocs/{tests => src}/data/table1.txt | 0 doc/OnlineDocs/{tests => src}/data/table2.dat | 0 doc/OnlineDocs/{tests => src}/data/table2.py | 0 doc/OnlineDocs/{tests => src}/data/table2.txt | 0 doc/OnlineDocs/{tests => src}/data/table3.dat | 0 doc/OnlineDocs/{tests => src}/data/table3.py | 0 doc/OnlineDocs/{tests => src}/data/table3.txt | 0 .../{tests => src}/data/table3.ul.dat | 0 .../{tests => src}/data/table3.ul.py | 0 .../{tests => src}/data/table3.ul.txt | 0 doc/OnlineDocs/{tests => src}/data/table4.dat | 0 doc/OnlineDocs/{tests => src}/data/table4.py | 0 doc/OnlineDocs/{tests => src}/data/table4.txt | 0 .../{tests => src}/data/table4.ul.dat | 0 .../{tests => src}/data/table4.ul.py | 0 .../{tests => src}/data/table4.ul.txt | 0 doc/OnlineDocs/{tests => src}/data/table5.dat | 0 doc/OnlineDocs/{tests => src}/data/table5.py | 0 doc/OnlineDocs/{tests => src}/data/table5.txt | 0 doc/OnlineDocs/{tests => src}/data/table6.dat | 0 doc/OnlineDocs/{tests => src}/data/table6.py | 0 doc/OnlineDocs/{tests => src}/data/table6.txt | 0 doc/OnlineDocs/{tests => src}/data/table7.dat | 0 doc/OnlineDocs/{tests => src}/data/table7.py | 0 doc/OnlineDocs/{tests => src}/data/table7.txt | 0 .../{tests => src}/dataportal/A.tab | 0 .../{tests => src}/dataportal/C.tab | 0 .../{tests => src}/dataportal/D.tab | 0 .../{tests => src}/dataportal/PP.csv | 0 .../{tests => src}/dataportal/PP.json | 0 .../{tests => src}/dataportal/PP.sqlite | Bin .../{tests => src}/dataportal/PP.tab | 0 .../{tests => src}/dataportal/PP.xml | 0 .../{tests => src}/dataportal/PP.yaml | 0 .../{tests => src}/dataportal/PP_sqlite.py | 0 .../{tests => src}/dataportal/Pyomo_mysql | 0 .../{tests => src}/dataportal/S.tab | 0 .../{tests => src}/dataportal/T.json | 0 .../{tests => src}/dataportal/T.yaml | 0 .../{tests => src}/dataportal/U.tab | 0 .../{tests => src}/dataportal/XW.tab | 0 .../{tests => src}/dataportal/Y.tab | 0 .../{tests => src}/dataportal/Z.tab | 0 .../dataportal/dataportal_tab.py | 0 .../dataportal/dataportal_tab.txt | 0 .../{tests => src}/dataportal/excel.xls | Bin .../dataportal/param_initialization.py | 0 .../dataportal/param_initialization.txt | 0 .../dataportal/set_initialization.py | 0 .../dataportal/set_initialization.txt | 0 doc/OnlineDocs/{tests => src}/expr/design.py | 0 doc/OnlineDocs/{tests => src}/expr/design.txt | 0 doc/OnlineDocs/{tests => src}/expr/index.py | 0 doc/OnlineDocs/{tests => src}/expr/index.txt | 0 .../{tests => src}/expr/managing.py | 0 .../{tests => src}/expr/managing.txt | 0 .../{tests => src}/expr/overview.py | 0 .../{tests => src}/expr/overview.txt | 0 .../{tests => src}/expr/performance.py | 0 .../{tests => src}/expr/performance.txt | 0 .../{tests => src}/expr/quicksum.log | 0 .../{tests => src}/expr/quicksum.py | 0 .../{tests => src}/kernel/examples.sh | 0 .../{tests => src}/kernel/examples.txt | 0 .../scripting/AbstractSuffixes.py | 0 .../{tests => src}/scripting/Isinglebuild.py | 0 .../{tests => src}/scripting/Isinglecomm.dat | 0 .../{tests => src}/scripting/NodesIn_init.py | 0 .../{tests => src}/scripting/Z_init.py | 0 .../{tests => src}/scripting/abstract1.dat | 0 .../{tests => src}/scripting/abstract2.dat | 0 .../{tests => src}/scripting/abstract2.py | 0 .../{tests => src}/scripting/abstract2a.dat | 0 .../scripting/abstract2piece.py | 0 .../scripting/abstract2piecebuild.py | 0 .../scripting/block_iter_example.py | 0 .../{tests => src}/scripting/concrete1.py | 0 .../{tests => src}/scripting/doubleA.py | 0 .../{tests => src}/scripting/driveabs2.py | 0 .../{tests => src}/scripting/driveconc1.py | 0 .../{tests => src}/scripting/iterative1.py | 0 .../{tests => src}/scripting/iterative2.py | 0 .../{tests => src}/scripting/noiteration1.py | 0 .../{tests => src}/scripting/parallel.py | 0 .../scripting/spy4Constraints.py | 0 .../scripting/spy4Expressions.py | 0 .../scripting/spy4PyomoCommand.py | 0 .../{tests => src}/scripting/spy4Variables.py | 0 .../{tests => src}/scripting/spy4scripts.py | 0 .../{tests => src}/strip_examples.py | 0 .../{tests => src}/test_examples.py | 0 .../working_abstractmodels/BuildAction.rst | 10 +- .../data/dataportals.rst | 74 ++++----- .../working_abstractmodels/data/datfiles.rst | 146 +++++++++--------- .../working_abstractmodels/data/native.rst | 16 +- .../working_abstractmodels/pyomo_command.rst | 2 +- doc/OnlineDocs/working_models.rst | 62 ++++---- 256 files changed, 217 insertions(+), 217 deletions(-) rename doc/OnlineDocs/{tests => src}/data/A.tab (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD.tab (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD.xls (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD1.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD1.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD1.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD2.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD2.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD2.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD3.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD3.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD3.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD4.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD4.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD4.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD5.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD5.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD5.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD6.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD6.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD6.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD7.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD7.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD7.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD8.bad (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD8.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD8.py (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD9.bad (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD9.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ABCD9.py (100%) rename doc/OnlineDocs/{tests => src}/data/C.tab (100%) rename doc/OnlineDocs/{tests => src}/data/D.tab (100%) rename doc/OnlineDocs/{tests => src}/data/U.tab (100%) rename doc/OnlineDocs/{tests => src}/data/Y.tab (100%) rename doc/OnlineDocs/{tests => src}/data/Z.tab (100%) rename doc/OnlineDocs/{tests => src}/data/data_managers.txt (100%) rename doc/OnlineDocs/{tests => src}/data/diet.dat (100%) rename doc/OnlineDocs/{tests => src}/data/diet.sql (100%) rename doc/OnlineDocs/{tests => src}/data/diet.sqlite (100%) rename doc/OnlineDocs/{tests => src}/data/diet.sqlite.dat (100%) rename doc/OnlineDocs/{tests => src}/data/diet1.py (100%) rename doc/OnlineDocs/{tests => src}/data/ex.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ex.py (100%) rename doc/OnlineDocs/{tests => src}/data/ex.txt (100%) rename doc/OnlineDocs/{tests => src}/data/ex1.dat (100%) rename doc/OnlineDocs/{tests => src}/data/ex2.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import1.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import1.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import1.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/import2.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import2.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import2.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/import3.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import3.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import3.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/import4.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import4.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import4.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/import5.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import5.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import5.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/import6.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import6.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import6.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/import7.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import7.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import7.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/import8.tab.dat (100%) rename doc/OnlineDocs/{tests => src}/data/import8.tab.py (100%) rename doc/OnlineDocs/{tests => src}/data/import8.tab.txt (100%) rename doc/OnlineDocs/{tests => src}/data/namespace1.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param1.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param1.py (100%) rename doc/OnlineDocs/{tests => src}/data/param1.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param2.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param2.py (100%) rename doc/OnlineDocs/{tests => src}/data/param2.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param2a.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param2a.py (100%) rename doc/OnlineDocs/{tests => src}/data/param2a.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param3.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param3.py (100%) rename doc/OnlineDocs/{tests => src}/data/param3.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param3a.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param3a.py (100%) rename doc/OnlineDocs/{tests => src}/data/param3a.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param3b.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param3b.py (100%) rename doc/OnlineDocs/{tests => src}/data/param3b.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param3c.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param3c.py (100%) rename doc/OnlineDocs/{tests => src}/data/param3c.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param4.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param4.py (100%) rename doc/OnlineDocs/{tests => src}/data/param4.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param5.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param5.py (100%) rename doc/OnlineDocs/{tests => src}/data/param5.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param5a.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param5a.py (100%) rename doc/OnlineDocs/{tests => src}/data/param5a.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param6.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param6.py (100%) rename doc/OnlineDocs/{tests => src}/data/param6.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param6a.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param6a.py (100%) rename doc/OnlineDocs/{tests => src}/data/param6a.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param7a.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param7a.py (100%) rename doc/OnlineDocs/{tests => src}/data/param7a.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param7b.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param7b.py (100%) rename doc/OnlineDocs/{tests => src}/data/param7b.txt (100%) rename doc/OnlineDocs/{tests => src}/data/param8a.dat (100%) rename doc/OnlineDocs/{tests => src}/data/param8a.py (100%) rename doc/OnlineDocs/{tests => src}/data/param8a.txt (100%) rename doc/OnlineDocs/{tests => src}/data/pyomo.diet1.sh (100%) rename doc/OnlineDocs/{tests => src}/data/pyomo.diet1.txt (100%) rename doc/OnlineDocs/{tests => src}/data/pyomo.diet2.sh (100%) rename doc/OnlineDocs/{tests => src}/data/pyomo.diet2.txt (100%) rename doc/OnlineDocs/{tests => src}/data/set1.dat (100%) rename doc/OnlineDocs/{tests => src}/data/set1.py (100%) rename doc/OnlineDocs/{tests => src}/data/set1.txt (100%) rename doc/OnlineDocs/{tests => src}/data/set2.dat (100%) rename doc/OnlineDocs/{tests => src}/data/set2.py (100%) rename doc/OnlineDocs/{tests => src}/data/set2.txt (100%) rename doc/OnlineDocs/{tests => src}/data/set2a.dat (100%) rename doc/OnlineDocs/{tests => src}/data/set2a.py (100%) rename doc/OnlineDocs/{tests => src}/data/set2a.txt (100%) rename doc/OnlineDocs/{tests => src}/data/set3.dat (100%) rename doc/OnlineDocs/{tests => src}/data/set3.py (100%) rename doc/OnlineDocs/{tests => src}/data/set3.txt (100%) rename doc/OnlineDocs/{tests => src}/data/set4.dat (100%) rename doc/OnlineDocs/{tests => src}/data/set4.py (100%) rename doc/OnlineDocs/{tests => src}/data/set4.txt (100%) rename doc/OnlineDocs/{tests => src}/data/set5.dat (100%) rename doc/OnlineDocs/{tests => src}/data/set5.py (100%) rename doc/OnlineDocs/{tests => src}/data/set5.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table0.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table0.py (100%) rename doc/OnlineDocs/{tests => src}/data/table0.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table0.ul.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table0.ul.py (100%) rename doc/OnlineDocs/{tests => src}/data/table0.ul.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table1.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table1.py (100%) rename doc/OnlineDocs/{tests => src}/data/table1.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table2.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table2.py (100%) rename doc/OnlineDocs/{tests => src}/data/table2.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table3.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table3.py (100%) rename doc/OnlineDocs/{tests => src}/data/table3.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table3.ul.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table3.ul.py (100%) rename doc/OnlineDocs/{tests => src}/data/table3.ul.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table4.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table4.py (100%) rename doc/OnlineDocs/{tests => src}/data/table4.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table4.ul.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table4.ul.py (100%) rename doc/OnlineDocs/{tests => src}/data/table4.ul.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table5.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table5.py (100%) rename doc/OnlineDocs/{tests => src}/data/table5.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table6.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table6.py (100%) rename doc/OnlineDocs/{tests => src}/data/table6.txt (100%) rename doc/OnlineDocs/{tests => src}/data/table7.dat (100%) rename doc/OnlineDocs/{tests => src}/data/table7.py (100%) rename doc/OnlineDocs/{tests => src}/data/table7.txt (100%) rename doc/OnlineDocs/{tests => src}/dataportal/A.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/C.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/D.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/PP.csv (100%) rename doc/OnlineDocs/{tests => src}/dataportal/PP.json (100%) rename doc/OnlineDocs/{tests => src}/dataportal/PP.sqlite (100%) rename doc/OnlineDocs/{tests => src}/dataportal/PP.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/PP.xml (100%) rename doc/OnlineDocs/{tests => src}/dataportal/PP.yaml (100%) rename doc/OnlineDocs/{tests => src}/dataportal/PP_sqlite.py (100%) rename doc/OnlineDocs/{tests => src}/dataportal/Pyomo_mysql (100%) rename doc/OnlineDocs/{tests => src}/dataportal/S.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/T.json (100%) rename doc/OnlineDocs/{tests => src}/dataportal/T.yaml (100%) rename doc/OnlineDocs/{tests => src}/dataportal/U.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/XW.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/Y.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/Z.tab (100%) rename doc/OnlineDocs/{tests => src}/dataportal/dataportal_tab.py (100%) rename doc/OnlineDocs/{tests => src}/dataportal/dataportal_tab.txt (100%) rename doc/OnlineDocs/{tests => src}/dataportal/excel.xls (100%) rename doc/OnlineDocs/{tests => src}/dataportal/param_initialization.py (100%) rename doc/OnlineDocs/{tests => src}/dataportal/param_initialization.txt (100%) rename doc/OnlineDocs/{tests => src}/dataportal/set_initialization.py (100%) rename doc/OnlineDocs/{tests => src}/dataportal/set_initialization.txt (100%) rename doc/OnlineDocs/{tests => src}/expr/design.py (100%) rename doc/OnlineDocs/{tests => src}/expr/design.txt (100%) rename doc/OnlineDocs/{tests => src}/expr/index.py (100%) rename doc/OnlineDocs/{tests => src}/expr/index.txt (100%) rename doc/OnlineDocs/{tests => src}/expr/managing.py (100%) rename doc/OnlineDocs/{tests => src}/expr/managing.txt (100%) rename doc/OnlineDocs/{tests => src}/expr/overview.py (100%) rename doc/OnlineDocs/{tests => src}/expr/overview.txt (100%) rename doc/OnlineDocs/{tests => src}/expr/performance.py (100%) rename doc/OnlineDocs/{tests => src}/expr/performance.txt (100%) rename doc/OnlineDocs/{tests => src}/expr/quicksum.log (100%) rename doc/OnlineDocs/{tests => src}/expr/quicksum.py (100%) rename doc/OnlineDocs/{tests => src}/kernel/examples.sh (100%) rename doc/OnlineDocs/{tests => src}/kernel/examples.txt (100%) rename doc/OnlineDocs/{tests => src}/scripting/AbstractSuffixes.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/Isinglebuild.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/Isinglecomm.dat (100%) rename doc/OnlineDocs/{tests => src}/scripting/NodesIn_init.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/Z_init.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/abstract1.dat (100%) rename doc/OnlineDocs/{tests => src}/scripting/abstract2.dat (100%) rename doc/OnlineDocs/{tests => src}/scripting/abstract2.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/abstract2a.dat (100%) rename doc/OnlineDocs/{tests => src}/scripting/abstract2piece.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/abstract2piecebuild.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/block_iter_example.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/concrete1.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/doubleA.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/driveabs2.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/driveconc1.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/iterative1.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/iterative2.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/noiteration1.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/parallel.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/spy4Constraints.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/spy4Expressions.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/spy4PyomoCommand.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/spy4Variables.py (100%) rename doc/OnlineDocs/{tests => src}/scripting/spy4scripts.py (100%) rename doc/OnlineDocs/{tests => src}/strip_examples.py (100%) rename doc/OnlineDocs/{tests => src}/test_examples.py (100%) diff --git a/doc/OnlineDocs/Makefile b/doc/OnlineDocs/Makefile index 604903631b2..3625325ef73 100644 --- a/doc/OnlineDocs/Makefile +++ b/doc/OnlineDocs/Makefile @@ -23,4 +23,4 @@ clean clean_tests: @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @echo "Removing *.spy, *.out" @find . -name \*.spy -delete - @find tests -name \*.out -delete + @find src -name \*.out -delete diff --git a/doc/OnlineDocs/conf.py b/doc/OnlineDocs/conf.py index d8939cf61dd..ef6510daedf 100644 --- a/doc/OnlineDocs/conf.py +++ b/doc/OnlineDocs/conf.py @@ -26,12 +26,12 @@ sys.path.insert(0, os.path.abspath('../..')) # -- Rebuild SPY files ---------------------------------------------------- -sys.path.insert(0, os.path.abspath('tests')) +sys.path.insert(0, os.path.abspath('src')) try: print("Regenerating SPY files...") from strip_examples import generate_spy_files - generate_spy_files(os.path.abspath('tests')) + generate_spy_files(os.path.abspath('src')) generate_spy_files( os.path.abspath(os.path.join('library_reference', 'kernel', 'examples')) ) diff --git a/doc/OnlineDocs/developer_reference/expressions/design.rst b/doc/OnlineDocs/developer_reference/expressions/design.rst index 9a6d5b9412f..ddecb39ad0c 100644 --- a/doc/OnlineDocs/developer_reference/expressions/design.rst +++ b/doc/OnlineDocs/developer_reference/expressions/design.rst @@ -73,7 +73,7 @@ Expression trees can be categorized in four different ways: These three categories are illustrated with the following example: -.. literalinclude:: ../../tests/expr/design_categories.spy +.. literalinclude:: ../../src/expr/design_categories.spy The following table describes four different simple expressions that consist of a single model component, and it shows how they @@ -107,7 +107,7 @@ Named expressions allow for changes to an expression after it has been constructed. For example, consider the expression ``f`` defined with the :class:`Expression ` component: -.. literalinclude:: ../../tests/expr/design_named_expression.spy +.. literalinclude:: ../../src/expr/design_named_expression.spy Although ``f`` is an immutable expression, whose definition is fixed, a sub-expressions is the named expression ``M.e``. Named @@ -227,7 +227,7 @@ The :data:`linear_expression ` object is a context manager that can be used to declare a linear sum. For example, consider the following two loops: -.. literalinclude:: ../../tests/expr/design_cm1.spy +.. literalinclude:: ../../src/expr/design_cm1.spy The first apparent difference in these loops is that the value of ``s`` is explicitly initialized while ``e`` is initialized when the @@ -250,7 +250,7 @@ construct different expressions with different context declarations. Finally, note that these context managers can be passed into the :attr:`start` method for the :func:`quicksum ` function. For example: -.. literalinclude:: ../../tests/expr/design_cm2.spy +.. literalinclude:: ../../src/expr/design_cm2.spy This sum contains terms for ``M.x[i]`` and ``M.y[i]``. The syntax in this example is not intuitive because the sum is being stored diff --git a/doc/OnlineDocs/developer_reference/expressions/index.rst b/doc/OnlineDocs/developer_reference/expressions/index.rst index 769639d50eb..685fde25173 100644 --- a/doc/OnlineDocs/developer_reference/expressions/index.rst +++ b/doc/OnlineDocs/developer_reference/expressions/index.rst @@ -21,7 +21,7 @@ nodes contain operators. Pyomo relies on so-called magic methods to automate the construction of symbolic expressions. For example, consider an expression ``e`` declared as follows: -.. literalinclude:: ../../tests/expr/index_simple.spy +.. literalinclude:: ../../src/expr/index_simple.spy Python determines that the magic method ``__mul__`` is called on the ``M.v`` object, with the argument ``2``. This method returns diff --git a/doc/OnlineDocs/developer_reference/expressions/managing.rst b/doc/OnlineDocs/developer_reference/expressions/managing.rst index 43c5ec34816..a4dd2a51436 100644 --- a/doc/OnlineDocs/developer_reference/expressions/managing.rst +++ b/doc/OnlineDocs/developer_reference/expressions/managing.rst @@ -23,7 +23,7 @@ mimics the Python operations used to construct an expression. The :data:`verbose` flag can be set to :const:`True` to generate a string representation that is a nested functional form. For example: -.. literalinclude:: ../../tests/expr/managing_ex1.spy +.. literalinclude:: ../../src/expr/managing_ex1.spy Labeler and Symbol Map ~~~~~~~~~~~~~~~~~~~~~~ @@ -37,7 +37,7 @@ the :class:`NumericLabeler` defines a functor that can be used to sequentially generate simple labels with a prefix followed by the variable count: -.. literalinclude:: ../../tests/expr/managing_ex2.spy +.. literalinclude:: ../../src/expr/managing_ex2.spy The :data:`smap` option is used to specify a symbol map object (:class:`SymbolMap `), which @@ -72,19 +72,19 @@ the expression have a value. The :func:`value ` function can be used to walk the expression tree and compute the value of an expression. For example: -.. literalinclude:: ../../tests/expr/managing_ex5.spy +.. literalinclude:: ../../src/expr/managing_ex5.spy Additionally, expressions define the :func:`__call__` method, so the following is another way to compute the value of an expression: -.. literalinclude:: ../../tests/expr/managing_ex6.spy +.. literalinclude:: ../../src/expr/managing_ex6.spy If a parameter or variable is undefined, then the :func:`value ` function and :func:`__call__` method will raise an exception. This exception can be suppressed using the :attr:`exception` option. For example: -.. literalinclude:: ../../tests/expr/managing_ex7.spy +.. literalinclude:: ../../src/expr/managing_ex7.spy This option is useful in contexts where adding a try block is inconvenient in your modeling script. @@ -108,7 +108,7 @@ functions that support this functionality. First, the function is a generator function that walks the expression tree and yields all nodes whose type is in a specified set of node types. For example: -.. literalinclude:: ../../tests/expr/managing_ex8.spy +.. literalinclude:: ../../src/expr/managing_ex8.spy The :func:`identify_variables ` function is a generator function that yields all nodes that are @@ -117,7 +117,7 @@ but this set of variable types does not need to be specified by the user. However, the :attr:`include_fixed` flag can be specified to omit fixed variables. For example: -.. literalinclude:: ../../tests/expr/managing_ex9.spy +.. literalinclude:: ../../src/expr/managing_ex9.spy Walking an Expression Tree with a Visitor Class ----------------------------------------------- @@ -223,14 +223,14 @@ In this example, we describe an visitor class that counts the number of nodes in an expression (including leaf nodes). Consider the following class: -.. literalinclude:: ../../tests/expr/managing_visitor1.spy +.. literalinclude:: ../../src/expr/managing_visitor1.spy The class constructor creates a counter, and the :func:`visit` method increments this counter for every node that is visited. The :func:`finalize` method returns the value of this counter after the tree has been walked. The following function illustrates this use of this visitor class: -.. literalinclude:: ../../tests/expr/managing_visitor2.spy +.. literalinclude:: ../../src/expr/managing_visitor2.spy ExpressionValueVisitor Example @@ -240,14 +240,14 @@ In this example, we describe an visitor class that clones the expression tree (including leaf nodes). Consider the following class: -.. literalinclude:: ../../tests/expr/managing_visitor3.spy +.. literalinclude:: ../../src/expr/managing_visitor3.spy The :func:`visit` method creates a new expression node with children specified by :attr:`values`. The :func:`visiting_potential_leaf` method performs a :func:`deepcopy` on leaf nodes, which are native Python types or non-expression objects. -.. literalinclude:: ../../tests/expr/managing_visitor4.spy +.. literalinclude:: ../../src/expr/managing_visitor4.spy ExpressionReplacementVisitor Example @@ -258,15 +258,15 @@ variables with scaled variables, using a mutable parameter that can be modified later. the following class: -.. literalinclude:: ../../tests/expr/managing_visitor5.spy +.. literalinclude:: ../../src/expr/managing_visitor5.spy No other method need to be defined. The :func:`beforeChild` method identifies variable nodes and returns a product expression that contains a mutable parameter. -.. literalinclude:: ../../tests/expr/managing_visitor6.spy +.. literalinclude:: ../../src/expr/managing_visitor6.spy The :func:`scale_expression` function is called with an expression and a dictionary, :attr:`scale`, that maps variable ID to model parameter. For example: -.. literalinclude:: ../../tests/expr/managing_visitor7.spy +.. literalinclude:: ../../src/expr/managing_visitor7.spy diff --git a/doc/OnlineDocs/developer_reference/expressions/overview.rst b/doc/OnlineDocs/developer_reference/expressions/overview.rst index 58808a813f1..c1962edec22 100644 --- a/doc/OnlineDocs/developer_reference/expressions/overview.rst +++ b/doc/OnlineDocs/developer_reference/expressions/overview.rst @@ -50,13 +50,13 @@ are: example, the following two loops had dramatically different runtime: - .. literalinclude:: ../../tests/expr/overview_example1.spy + .. literalinclude:: ../../src/expr/overview_example1.spy * Coopr3 eliminates side effects by automatically cloning sub-expressions. Unfortunately, this can easily lead to unexpected cloning in models, which can dramatically slow down Pyomo model generation. For example: - .. literalinclude:: ../../tests/expr/overview_example2.spy + .. literalinclude:: ../../src/expr/overview_example2.spy * Coopr3 leverages recursion in many operations, including expression cloning. Even simple non-linear expressions can result in deep @@ -82,7 +82,7 @@ control for how expressions are managed in Python. For example: * Python variables can point to the same expression tree - .. literalinclude:: ../../tests/expr/overview_tree1.spy + .. literalinclude:: ../../src/expr/overview_tree1.spy This is illustrated as follows: @@ -102,7 +102,7 @@ control for how expressions are managed in Python. For example: * A variable can point to a sub-tree that another variable points to - .. literalinclude:: ../../tests/expr/overview_tree2.spy + .. literalinclude:: ../../src/expr/overview_tree2.spy This is illustrated as follows: @@ -124,7 +124,7 @@ control for how expressions are managed in Python. For example: * Two expression trees can point to the same sub-tree - .. literalinclude:: ../../tests/expr/overview_tree3.spy + .. literalinclude:: ../../src/expr/overview_tree3.spy This is illustrated as follows: @@ -169,7 +169,7 @@ between expressions, we do not consider those expressions entangled. Expression entanglement is problematic because shared expressions complicate the expected behavior when sub-expressions are changed. Consider the following example: -.. literalinclude:: ../../tests/expr/overview_tree4.spy +.. literalinclude:: ../../src/expr/overview_tree4.spy What is the value of ``e`` after ``M.w`` is added to it? What is the value of ``f``? The answers to these questions are not immediately @@ -244,7 +244,7 @@ There is one important exception to the entanglement property described above. The ``Expression`` component is treated as a mutable expression when shared between expressions. For example: -.. literalinclude:: ../../tests/expr/overview_tree5.spy +.. literalinclude:: ../../src/expr/overview_tree5.spy Here, the expression ``M.e`` is a so-called *named expression* that the user has declared. Named expressions are explicitly intended diff --git a/doc/OnlineDocs/developer_reference/expressions/performance.rst b/doc/OnlineDocs/developer_reference/expressions/performance.rst index 4b2c691b729..8e344e50982 100644 --- a/doc/OnlineDocs/developer_reference/expressions/performance.rst +++ b/doc/OnlineDocs/developer_reference/expressions/performance.rst @@ -11,14 +11,14 @@ Expression Generation Pyomo expressions can be constructed using native binary operators in Python. For example, a sum can be created in a simple loop: -.. literalinclude:: ../../tests/expr/performance_loop1.spy +.. literalinclude:: ../../src/expr/performance_loop1.spy Additionally, Pyomo expressions can be constructed using functions that iteratively apply Python binary operators. For example, the Python :func:`sum` function can be used to replace the previous loop: -.. literalinclude:: ../../tests/expr/performance_loop2.spy +.. literalinclude:: ../../src/expr/performance_loop2.spy The :func:`sum` function is both more compact and more efficient. Using :func:`sum` avoids the creation of temporary variables, and @@ -47,7 +47,7 @@ expressions. For example, consider the following quadratic polynomial: -.. literalinclude:: ../../tests/expr/performance_loop3.spy +.. literalinclude:: ../../src/expr/performance_loop3.spy This quadratic polynomial is treated as a nonlinear expression unless the expression is explicitly processed to identify quadratic @@ -78,7 +78,7 @@ The :func:`prod ` function is analogous to the builtin argument list, :attr:`args`, which represents expressions that are multiplied together. For example: -.. literalinclude:: ../../tests/expr/performance_prod.spy +.. literalinclude:: ../../src/expr/performance_prod.spy quicksum ~~~~~~~~ @@ -89,7 +89,7 @@ generates a more compact Pyomo expression. Its main argument is a variable length argument list, :attr:`args`, which represents expressions that are summed together. For example: -.. literalinclude:: ../../tests/expr/performance_quicksum.spy +.. literalinclude:: ../../src/expr/performance_quicksum.spy The summation is customized based on the :attr:`start` and :attr:`linear` arguments. The :attr:`start` defines the initial @@ -111,13 +111,13 @@ more quickly. Consider the following example: -.. literalinclude:: ../../tests/expr/quicksum_runtime.spy +.. literalinclude:: ../../src/expr/quicksum_runtime.spy The sum consists of linear terms because the exponents are one. The following output illustrates that quicksum can identify this linear structure to generate expressions more quickly: -.. literalinclude:: ../../tests/expr/quicksum.log +.. literalinclude:: ../../src/expr/quicksum.log :language: none If :attr:`start` is not a numeric value, then the :func:`quicksum @@ -134,7 +134,7 @@ to be stored in an object that is passed into the function (e.g. the linear cont term in :attr:`args` is misleading. Consider the following example: - .. literalinclude:: ../../tests/expr/performance_warning.spy + .. literalinclude:: ../../src/expr/performance_warning.spy The first term created by the generator is linear, but the subsequent terms are nonlinear. Pyomo gracefully transitions @@ -153,12 +153,12 @@ calling :func:`quicksum `. If two or more components provided, then the result is the summation of their terms multiplied together. For example: -.. literalinclude:: ../../tests/expr/performance_sum_product1.spy +.. literalinclude:: ../../src/expr/performance_sum_product1.spy The :attr:`denom` argument specifies components whose terms are in the denominator. For example: -.. literalinclude:: ../../tests/expr/performance_sum_product2.spy +.. literalinclude:: ../../src/expr/performance_sum_product2.spy The terms summed by this function are explicitly specified, so :func:`sum_product ` can identify diff --git a/doc/OnlineDocs/pyomo_modeling_components/Constraints.rst b/doc/OnlineDocs/pyomo_modeling_components/Constraints.rst index a79d380dcab..0cc42cb2abe 100644 --- a/doc/OnlineDocs/pyomo_modeling_components/Constraints.rst +++ b/doc/OnlineDocs/pyomo_modeling_components/Constraints.rst @@ -6,7 +6,7 @@ that are created using a rule, which is a Python function. For example, if the variable ``model.x`` has the indexes 'butter' and 'scones', then this constraint limits the sum over these indexes to be exactly three: -.. literalinclude:: ../tests/scripting/spy4Constraints_Constraint_example.spy +.. literalinclude:: ../src/scripting/spy4Constraints_Constraint_example.spy :language: python Instead of expressions involving equality (==) or inequalities (`<=` or @@ -16,7 +16,7 @@ lb `<=` expr `<=` ub. Variables can appear only in the middle expr. For example, the following two constraint declarations have the same meaning: -.. literalinclude:: ../tests/scripting/spy4Constraints_Inequality_constraints_2expressions.spy +.. literalinclude:: ../src/scripting/spy4Constraints_Inequality_constraints_2expressions.spy :language: python For this simple example, it would also be possible to declare @@ -30,7 +30,7 @@ interpreted as placing a budget of :math:`i` on the :math:`i^{\mbox{th}}` item to buy where the cost per item is given by the parameter ``model.a``: -.. literalinclude:: ../tests/scripting/spy4Constraints_Passing_elements_crossproduct.spy +.. literalinclude:: ../src/scripting/spy4Constraints_Passing_elements_crossproduct.spy :language: python .. note:: diff --git a/doc/OnlineDocs/pyomo_modeling_components/Expressions.rst b/doc/OnlineDocs/pyomo_modeling_components/Expressions.rst index f0558621316..16c206e2fe8 100644 --- a/doc/OnlineDocs/pyomo_modeling_components/Expressions.rst +++ b/doc/OnlineDocs/pyomo_modeling_components/Expressions.rst @@ -20,7 +20,7 @@ possible to build up expressions. The following example illustrates this, along with a reference to global Python data in the form of a Python variable called ``switch``: -.. literalinclude:: ../tests/scripting/spy4Expressions_Buildup_expression_switch.spy +.. literalinclude:: ../src/scripting/spy4Expressions_Buildup_expression_switch.spy :language: python In this example, the constraint that is generated depends on the value @@ -33,7 +33,7 @@ otherwise, the ``model.d`` term is not present. Because model elements result in expressions, not values, the following does not work as expected in an abstract model! - .. literalinclude:: ../tests/scripting/spy4Expressions_Abstract_wrong_usage.spy + .. literalinclude:: ../src/scripting/spy4Expressions_Abstract_wrong_usage.spy :language: python The trouble is that ``model.d >= 2`` results in an expression, not @@ -58,7 +58,7 @@ as described in the paper [Vielma_et_al]_. There are two basic forms for the declaration of the constraint: -.. literalinclude:: ../tests/scripting/spy4Expressions_Declare_piecewise_constraints.spy +.. literalinclude:: ../src/scripting/spy4Expressions_Declare_piecewise_constraints.spy :language: python where ``pwconst`` can be replaced by a name appropriate for the @@ -124,7 +124,7 @@ Keywords: indexing set is used or when all indices use an identical piecewise function). Examples: - .. literalinclude:: ../tests/scripting/spy4Expressions_f_rule_Function_examples.spy + .. literalinclude:: ../src/scripting/spy4Expressions_f_rule_Function_examples.spy :language: python * **force_pw=True/False** @@ -163,7 +163,7 @@ Keywords: Here is an example of an assignment to a Python dictionary variable that has keywords for a picewise constraint: -.. literalinclude:: ../tests/scripting/spy4Expressions_Keyword_assignment_example.spy +.. literalinclude:: ../src/scripting/spy4Expressions_Keyword_assignment_example.spy :language: python Here is a simple example based on the example given earlier in @@ -175,7 +175,7 @@ whimsically just to make the example. The important thing to note is that variables that are going to appear as the independent variable in a piecewise constraint must have bounds. -.. literalinclude:: ../tests/scripting/abstract2piece.py +.. literalinclude:: ../src/scripting/abstract2piece.py :language: python A more advanced example is provided in abstract2piecebuild.py in @@ -193,13 +193,13 @@ variable x times the index. Later in the model file, just to illustrate how to do it, the expression is changed but just for the first index to be x squared. -.. literalinclude:: ../tests/scripting/spy4Expressions_Expression_objects_illustration.spy +.. literalinclude:: ../src/scripting/spy4Expressions_Expression_objects_illustration.spy :language: python An alternative is to create Python functions that, potentially, manipulate model objects. E.g., if you define a function -.. literalinclude:: ../tests/scripting/spy4Expressions_Define_python_function.spy +.. literalinclude:: ../src/scripting/spy4Expressions_Define_python_function.spy :language: python You can call this function with or without Pyomo modeling components as @@ -211,7 +211,7 @@ expression is used to generate another expression (e.g., f(model.x, 3) + 5), the initial expression is always cloned so that the new generated expression is independent of the old. For example: -.. literalinclude:: ../tests/scripting/spy4Expressions_Generate_new_expression.spy +.. literalinclude:: ../src/scripting/spy4Expressions_Generate_new_expression.spy :language: python If you want to create an expression that is shared between other diff --git a/doc/OnlineDocs/pyomo_modeling_components/Sets.rst b/doc/OnlineDocs/pyomo_modeling_components/Sets.rst index f9a692fcb10..73c3539d79d 100644 --- a/doc/OnlineDocs/pyomo_modeling_components/Sets.rst +++ b/doc/OnlineDocs/pyomo_modeling_components/Sets.rst @@ -443,13 +443,13 @@ model is: for this model, a toy data file (in AMPL "``.dat``" format) would be: -.. literalinclude:: ../tests/scripting/Isinglecomm.dat +.. literalinclude:: ../src/scripting/Isinglecomm.dat :language: text .. doctest:: :hide: - >>> inst = model.create_instance('tests/scripting/Isinglecomm.dat') + >>> inst = model.create_instance('src/scripting/Isinglecomm.dat') This can also be done somewhat more efficiently, and perhaps more clearly, using a :class:`BuildAction` (for more information, see :ref:`BuildAction`): diff --git a/doc/OnlineDocs/pyomo_modeling_components/Variables.rst b/doc/OnlineDocs/pyomo_modeling_components/Variables.rst index 038f5769705..7f7ee74af5f 100644 --- a/doc/OnlineDocs/pyomo_modeling_components/Variables.rst +++ b/doc/OnlineDocs/pyomo_modeling_components/Variables.rst @@ -20,13 +20,13 @@ declaring a *singleton* (i.e. unindexed) variable named ``model.LumberJack`` that will take on real values between zero and 6 and it initialized to be 1.5: -.. literalinclude:: ../tests/scripting/spy4Variables_Declare_singleton_variable.spy +.. literalinclude:: ../src/scripting/spy4Variables_Declare_singleton_variable.spy :language: python Instead of the ``initialize`` option, initialization is sometimes done with a Python assignment statement as in -.. literalinclude:: ../tests/scripting/spy4Variables_Assign_value.spy +.. literalinclude:: ../src/scripting/spy4Variables_Assign_value.spy :language: python For indexed variables, bounds and initial values are often specified by @@ -36,7 +36,7 @@ followed by the indexes. This is illustrated in the following code snippet that makes use of Python dictionaries declared as lb and ub that are used by a function to provide bounds: -.. literalinclude:: ../tests/scripting/spy4Variables_Declare_bounds.spy +.. literalinclude:: ../src/scripting/spy4Variables_Declare_bounds.spy :language: python .. note:: diff --git a/doc/OnlineDocs/pyomo_overview/simple_examples.rst b/doc/OnlineDocs/pyomo_overview/simple_examples.rst index 4358c87b678..11305884c54 100644 --- a/doc/OnlineDocs/pyomo_overview/simple_examples.rst +++ b/doc/OnlineDocs/pyomo_overview/simple_examples.rst @@ -91,7 +91,7 @@ One way to implement this in Pyomo is as shown as follows: :hide: >>> # Create an instance to verify that the rules fire correctly - >>> inst = model.create_instance('tests/scripting/abstract1.dat') + >>> inst = model.create_instance('src/scripting/abstract1.dat') .. note:: @@ -261,9 +261,9 @@ parameters. Here is one file that provides data (in AMPL "``.dat``" format). :hide: >>> # Create an instance to verify that the rules fire correctly - >>> inst = model.create_instance('tests/scripting/abstract1.dat') + >>> inst = model.create_instance('src/scripting/abstract1.dat') -.. literalinclude:: ../tests/scripting/abstract1.dat +.. literalinclude:: ../src/scripting/abstract1.dat :language: text There are multiple formats that can be used to provide data to a Pyomo @@ -327,18 +327,18 @@ the same model. To start with an illustration of general indexes, consider a slightly different Pyomo implementation of the model we just presented. -.. literalinclude:: ../tests/scripting/abstract2.py +.. literalinclude:: ../src/scripting/abstract2.py :language: python To get the same instantiated model, the following data file can be used. -.. literalinclude:: ../tests/scripting/abstract2a.dat +.. literalinclude:: ../src/scripting/abstract2a.dat :language: none However, this model can also be fed different data for problems of the same general form using meaningful indexes. -.. literalinclude:: ../tests/scripting/abstract2.dat +.. literalinclude:: ../src/scripting/abstract2.dat :language: none diff --git a/doc/OnlineDocs/tests/data/A.tab b/doc/OnlineDocs/src/data/A.tab similarity index 100% rename from doc/OnlineDocs/tests/data/A.tab rename to doc/OnlineDocs/src/data/A.tab diff --git a/doc/OnlineDocs/tests/data/ABCD.tab b/doc/OnlineDocs/src/data/ABCD.tab similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD.tab rename to doc/OnlineDocs/src/data/ABCD.tab diff --git a/doc/OnlineDocs/tests/data/ABCD.txt b/doc/OnlineDocs/src/data/ABCD.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD.txt rename to doc/OnlineDocs/src/data/ABCD.txt diff --git a/doc/OnlineDocs/tests/data/ABCD.xls b/doc/OnlineDocs/src/data/ABCD.xls similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD.xls rename to doc/OnlineDocs/src/data/ABCD.xls diff --git a/doc/OnlineDocs/tests/data/ABCD1.dat b/doc/OnlineDocs/src/data/ABCD1.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD1.dat rename to doc/OnlineDocs/src/data/ABCD1.dat diff --git a/doc/OnlineDocs/tests/data/ABCD1.py b/doc/OnlineDocs/src/data/ABCD1.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD1.py rename to doc/OnlineDocs/src/data/ABCD1.py diff --git a/doc/OnlineDocs/tests/data/ABCD1.txt b/doc/OnlineDocs/src/data/ABCD1.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD1.txt rename to doc/OnlineDocs/src/data/ABCD1.txt diff --git a/doc/OnlineDocs/tests/data/ABCD2.dat b/doc/OnlineDocs/src/data/ABCD2.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD2.dat rename to doc/OnlineDocs/src/data/ABCD2.dat diff --git a/doc/OnlineDocs/tests/data/ABCD2.py b/doc/OnlineDocs/src/data/ABCD2.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD2.py rename to doc/OnlineDocs/src/data/ABCD2.py diff --git a/doc/OnlineDocs/tests/data/ABCD2.txt b/doc/OnlineDocs/src/data/ABCD2.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD2.txt rename to doc/OnlineDocs/src/data/ABCD2.txt diff --git a/doc/OnlineDocs/tests/data/ABCD3.dat b/doc/OnlineDocs/src/data/ABCD3.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD3.dat rename to doc/OnlineDocs/src/data/ABCD3.dat diff --git a/doc/OnlineDocs/tests/data/ABCD3.py b/doc/OnlineDocs/src/data/ABCD3.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD3.py rename to doc/OnlineDocs/src/data/ABCD3.py diff --git a/doc/OnlineDocs/tests/data/ABCD3.txt b/doc/OnlineDocs/src/data/ABCD3.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD3.txt rename to doc/OnlineDocs/src/data/ABCD3.txt diff --git a/doc/OnlineDocs/tests/data/ABCD4.dat b/doc/OnlineDocs/src/data/ABCD4.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD4.dat rename to doc/OnlineDocs/src/data/ABCD4.dat diff --git a/doc/OnlineDocs/tests/data/ABCD4.py b/doc/OnlineDocs/src/data/ABCD4.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD4.py rename to doc/OnlineDocs/src/data/ABCD4.py diff --git a/doc/OnlineDocs/tests/data/ABCD4.txt b/doc/OnlineDocs/src/data/ABCD4.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD4.txt rename to doc/OnlineDocs/src/data/ABCD4.txt diff --git a/doc/OnlineDocs/tests/data/ABCD5.dat b/doc/OnlineDocs/src/data/ABCD5.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD5.dat rename to doc/OnlineDocs/src/data/ABCD5.dat diff --git a/doc/OnlineDocs/tests/data/ABCD5.py b/doc/OnlineDocs/src/data/ABCD5.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD5.py rename to doc/OnlineDocs/src/data/ABCD5.py diff --git a/doc/OnlineDocs/tests/data/ABCD5.txt b/doc/OnlineDocs/src/data/ABCD5.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD5.txt rename to doc/OnlineDocs/src/data/ABCD5.txt diff --git a/doc/OnlineDocs/tests/data/ABCD6.dat b/doc/OnlineDocs/src/data/ABCD6.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD6.dat rename to doc/OnlineDocs/src/data/ABCD6.dat diff --git a/doc/OnlineDocs/tests/data/ABCD6.py b/doc/OnlineDocs/src/data/ABCD6.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD6.py rename to doc/OnlineDocs/src/data/ABCD6.py diff --git a/doc/OnlineDocs/tests/data/ABCD6.txt b/doc/OnlineDocs/src/data/ABCD6.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD6.txt rename to doc/OnlineDocs/src/data/ABCD6.txt diff --git a/doc/OnlineDocs/tests/data/ABCD7.dat b/doc/OnlineDocs/src/data/ABCD7.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD7.dat rename to doc/OnlineDocs/src/data/ABCD7.dat diff --git a/doc/OnlineDocs/tests/data/ABCD7.py b/doc/OnlineDocs/src/data/ABCD7.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD7.py rename to doc/OnlineDocs/src/data/ABCD7.py diff --git a/doc/OnlineDocs/tests/data/ABCD7.txt b/doc/OnlineDocs/src/data/ABCD7.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD7.txt rename to doc/OnlineDocs/src/data/ABCD7.txt diff --git a/doc/OnlineDocs/tests/data/ABCD8.bad b/doc/OnlineDocs/src/data/ABCD8.bad similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD8.bad rename to doc/OnlineDocs/src/data/ABCD8.bad diff --git a/doc/OnlineDocs/tests/data/ABCD8.dat b/doc/OnlineDocs/src/data/ABCD8.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD8.dat rename to doc/OnlineDocs/src/data/ABCD8.dat diff --git a/doc/OnlineDocs/tests/data/ABCD8.py b/doc/OnlineDocs/src/data/ABCD8.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD8.py rename to doc/OnlineDocs/src/data/ABCD8.py diff --git a/doc/OnlineDocs/tests/data/ABCD9.bad b/doc/OnlineDocs/src/data/ABCD9.bad similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD9.bad rename to doc/OnlineDocs/src/data/ABCD9.bad diff --git a/doc/OnlineDocs/tests/data/ABCD9.dat b/doc/OnlineDocs/src/data/ABCD9.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD9.dat rename to doc/OnlineDocs/src/data/ABCD9.dat diff --git a/doc/OnlineDocs/tests/data/ABCD9.py b/doc/OnlineDocs/src/data/ABCD9.py similarity index 100% rename from doc/OnlineDocs/tests/data/ABCD9.py rename to doc/OnlineDocs/src/data/ABCD9.py diff --git a/doc/OnlineDocs/tests/data/C.tab b/doc/OnlineDocs/src/data/C.tab similarity index 100% rename from doc/OnlineDocs/tests/data/C.tab rename to doc/OnlineDocs/src/data/C.tab diff --git a/doc/OnlineDocs/tests/data/D.tab b/doc/OnlineDocs/src/data/D.tab similarity index 100% rename from doc/OnlineDocs/tests/data/D.tab rename to doc/OnlineDocs/src/data/D.tab diff --git a/doc/OnlineDocs/tests/data/U.tab b/doc/OnlineDocs/src/data/U.tab similarity index 100% rename from doc/OnlineDocs/tests/data/U.tab rename to doc/OnlineDocs/src/data/U.tab diff --git a/doc/OnlineDocs/tests/data/Y.tab b/doc/OnlineDocs/src/data/Y.tab similarity index 100% rename from doc/OnlineDocs/tests/data/Y.tab rename to doc/OnlineDocs/src/data/Y.tab diff --git a/doc/OnlineDocs/tests/data/Z.tab b/doc/OnlineDocs/src/data/Z.tab similarity index 100% rename from doc/OnlineDocs/tests/data/Z.tab rename to doc/OnlineDocs/src/data/Z.tab diff --git a/doc/OnlineDocs/tests/data/data_managers.txt b/doc/OnlineDocs/src/data/data_managers.txt similarity index 100% rename from doc/OnlineDocs/tests/data/data_managers.txt rename to doc/OnlineDocs/src/data/data_managers.txt diff --git a/doc/OnlineDocs/tests/data/diet.dat b/doc/OnlineDocs/src/data/diet.dat similarity index 100% rename from doc/OnlineDocs/tests/data/diet.dat rename to doc/OnlineDocs/src/data/diet.dat diff --git a/doc/OnlineDocs/tests/data/diet.sql b/doc/OnlineDocs/src/data/diet.sql similarity index 100% rename from doc/OnlineDocs/tests/data/diet.sql rename to doc/OnlineDocs/src/data/diet.sql diff --git a/doc/OnlineDocs/tests/data/diet.sqlite b/doc/OnlineDocs/src/data/diet.sqlite similarity index 100% rename from doc/OnlineDocs/tests/data/diet.sqlite rename to doc/OnlineDocs/src/data/diet.sqlite diff --git a/doc/OnlineDocs/tests/data/diet.sqlite.dat b/doc/OnlineDocs/src/data/diet.sqlite.dat similarity index 100% rename from doc/OnlineDocs/tests/data/diet.sqlite.dat rename to doc/OnlineDocs/src/data/diet.sqlite.dat diff --git a/doc/OnlineDocs/tests/data/diet1.py b/doc/OnlineDocs/src/data/diet1.py similarity index 100% rename from doc/OnlineDocs/tests/data/diet1.py rename to doc/OnlineDocs/src/data/diet1.py diff --git a/doc/OnlineDocs/tests/data/ex.dat b/doc/OnlineDocs/src/data/ex.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ex.dat rename to doc/OnlineDocs/src/data/ex.dat diff --git a/doc/OnlineDocs/tests/data/ex.py b/doc/OnlineDocs/src/data/ex.py similarity index 100% rename from doc/OnlineDocs/tests/data/ex.py rename to doc/OnlineDocs/src/data/ex.py diff --git a/doc/OnlineDocs/tests/data/ex.txt b/doc/OnlineDocs/src/data/ex.txt similarity index 100% rename from doc/OnlineDocs/tests/data/ex.txt rename to doc/OnlineDocs/src/data/ex.txt diff --git a/doc/OnlineDocs/tests/data/ex1.dat b/doc/OnlineDocs/src/data/ex1.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ex1.dat rename to doc/OnlineDocs/src/data/ex1.dat diff --git a/doc/OnlineDocs/tests/data/ex2.dat b/doc/OnlineDocs/src/data/ex2.dat similarity index 100% rename from doc/OnlineDocs/tests/data/ex2.dat rename to doc/OnlineDocs/src/data/ex2.dat diff --git a/doc/OnlineDocs/tests/data/import1.tab.dat b/doc/OnlineDocs/src/data/import1.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import1.tab.dat rename to doc/OnlineDocs/src/data/import1.tab.dat diff --git a/doc/OnlineDocs/tests/data/import1.tab.py b/doc/OnlineDocs/src/data/import1.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import1.tab.py rename to doc/OnlineDocs/src/data/import1.tab.py diff --git a/doc/OnlineDocs/tests/data/import1.tab.txt b/doc/OnlineDocs/src/data/import1.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import1.tab.txt rename to doc/OnlineDocs/src/data/import1.tab.txt diff --git a/doc/OnlineDocs/tests/data/import2.tab.dat b/doc/OnlineDocs/src/data/import2.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import2.tab.dat rename to doc/OnlineDocs/src/data/import2.tab.dat diff --git a/doc/OnlineDocs/tests/data/import2.tab.py b/doc/OnlineDocs/src/data/import2.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import2.tab.py rename to doc/OnlineDocs/src/data/import2.tab.py diff --git a/doc/OnlineDocs/tests/data/import2.tab.txt b/doc/OnlineDocs/src/data/import2.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import2.tab.txt rename to doc/OnlineDocs/src/data/import2.tab.txt diff --git a/doc/OnlineDocs/tests/data/import3.tab.dat b/doc/OnlineDocs/src/data/import3.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import3.tab.dat rename to doc/OnlineDocs/src/data/import3.tab.dat diff --git a/doc/OnlineDocs/tests/data/import3.tab.py b/doc/OnlineDocs/src/data/import3.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import3.tab.py rename to doc/OnlineDocs/src/data/import3.tab.py diff --git a/doc/OnlineDocs/tests/data/import3.tab.txt b/doc/OnlineDocs/src/data/import3.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import3.tab.txt rename to doc/OnlineDocs/src/data/import3.tab.txt diff --git a/doc/OnlineDocs/tests/data/import4.tab.dat b/doc/OnlineDocs/src/data/import4.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import4.tab.dat rename to doc/OnlineDocs/src/data/import4.tab.dat diff --git a/doc/OnlineDocs/tests/data/import4.tab.py b/doc/OnlineDocs/src/data/import4.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import4.tab.py rename to doc/OnlineDocs/src/data/import4.tab.py diff --git a/doc/OnlineDocs/tests/data/import4.tab.txt b/doc/OnlineDocs/src/data/import4.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import4.tab.txt rename to doc/OnlineDocs/src/data/import4.tab.txt diff --git a/doc/OnlineDocs/tests/data/import5.tab.dat b/doc/OnlineDocs/src/data/import5.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import5.tab.dat rename to doc/OnlineDocs/src/data/import5.tab.dat diff --git a/doc/OnlineDocs/tests/data/import5.tab.py b/doc/OnlineDocs/src/data/import5.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import5.tab.py rename to doc/OnlineDocs/src/data/import5.tab.py diff --git a/doc/OnlineDocs/tests/data/import5.tab.txt b/doc/OnlineDocs/src/data/import5.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import5.tab.txt rename to doc/OnlineDocs/src/data/import5.tab.txt diff --git a/doc/OnlineDocs/tests/data/import6.tab.dat b/doc/OnlineDocs/src/data/import6.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import6.tab.dat rename to doc/OnlineDocs/src/data/import6.tab.dat diff --git a/doc/OnlineDocs/tests/data/import6.tab.py b/doc/OnlineDocs/src/data/import6.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import6.tab.py rename to doc/OnlineDocs/src/data/import6.tab.py diff --git a/doc/OnlineDocs/tests/data/import6.tab.txt b/doc/OnlineDocs/src/data/import6.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import6.tab.txt rename to doc/OnlineDocs/src/data/import6.tab.txt diff --git a/doc/OnlineDocs/tests/data/import7.tab.dat b/doc/OnlineDocs/src/data/import7.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import7.tab.dat rename to doc/OnlineDocs/src/data/import7.tab.dat diff --git a/doc/OnlineDocs/tests/data/import7.tab.py b/doc/OnlineDocs/src/data/import7.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import7.tab.py rename to doc/OnlineDocs/src/data/import7.tab.py diff --git a/doc/OnlineDocs/tests/data/import7.tab.txt b/doc/OnlineDocs/src/data/import7.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import7.tab.txt rename to doc/OnlineDocs/src/data/import7.tab.txt diff --git a/doc/OnlineDocs/tests/data/import8.tab.dat b/doc/OnlineDocs/src/data/import8.tab.dat similarity index 100% rename from doc/OnlineDocs/tests/data/import8.tab.dat rename to doc/OnlineDocs/src/data/import8.tab.dat diff --git a/doc/OnlineDocs/tests/data/import8.tab.py b/doc/OnlineDocs/src/data/import8.tab.py similarity index 100% rename from doc/OnlineDocs/tests/data/import8.tab.py rename to doc/OnlineDocs/src/data/import8.tab.py diff --git a/doc/OnlineDocs/tests/data/import8.tab.txt b/doc/OnlineDocs/src/data/import8.tab.txt similarity index 100% rename from doc/OnlineDocs/tests/data/import8.tab.txt rename to doc/OnlineDocs/src/data/import8.tab.txt diff --git a/doc/OnlineDocs/tests/data/namespace1.dat b/doc/OnlineDocs/src/data/namespace1.dat similarity index 100% rename from doc/OnlineDocs/tests/data/namespace1.dat rename to doc/OnlineDocs/src/data/namespace1.dat diff --git a/doc/OnlineDocs/tests/data/param1.dat b/doc/OnlineDocs/src/data/param1.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param1.dat rename to doc/OnlineDocs/src/data/param1.dat diff --git a/doc/OnlineDocs/tests/data/param1.py b/doc/OnlineDocs/src/data/param1.py similarity index 100% rename from doc/OnlineDocs/tests/data/param1.py rename to doc/OnlineDocs/src/data/param1.py diff --git a/doc/OnlineDocs/tests/data/param1.txt b/doc/OnlineDocs/src/data/param1.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param1.txt rename to doc/OnlineDocs/src/data/param1.txt diff --git a/doc/OnlineDocs/tests/data/param2.dat b/doc/OnlineDocs/src/data/param2.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param2.dat rename to doc/OnlineDocs/src/data/param2.dat diff --git a/doc/OnlineDocs/tests/data/param2.py b/doc/OnlineDocs/src/data/param2.py similarity index 100% rename from doc/OnlineDocs/tests/data/param2.py rename to doc/OnlineDocs/src/data/param2.py diff --git a/doc/OnlineDocs/tests/data/param2.txt b/doc/OnlineDocs/src/data/param2.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param2.txt rename to doc/OnlineDocs/src/data/param2.txt diff --git a/doc/OnlineDocs/tests/data/param2a.dat b/doc/OnlineDocs/src/data/param2a.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param2a.dat rename to doc/OnlineDocs/src/data/param2a.dat diff --git a/doc/OnlineDocs/tests/data/param2a.py b/doc/OnlineDocs/src/data/param2a.py similarity index 100% rename from doc/OnlineDocs/tests/data/param2a.py rename to doc/OnlineDocs/src/data/param2a.py diff --git a/doc/OnlineDocs/tests/data/param2a.txt b/doc/OnlineDocs/src/data/param2a.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param2a.txt rename to doc/OnlineDocs/src/data/param2a.txt diff --git a/doc/OnlineDocs/tests/data/param3.dat b/doc/OnlineDocs/src/data/param3.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param3.dat rename to doc/OnlineDocs/src/data/param3.dat diff --git a/doc/OnlineDocs/tests/data/param3.py b/doc/OnlineDocs/src/data/param3.py similarity index 100% rename from doc/OnlineDocs/tests/data/param3.py rename to doc/OnlineDocs/src/data/param3.py diff --git a/doc/OnlineDocs/tests/data/param3.txt b/doc/OnlineDocs/src/data/param3.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param3.txt rename to doc/OnlineDocs/src/data/param3.txt diff --git a/doc/OnlineDocs/tests/data/param3a.dat b/doc/OnlineDocs/src/data/param3a.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param3a.dat rename to doc/OnlineDocs/src/data/param3a.dat diff --git a/doc/OnlineDocs/tests/data/param3a.py b/doc/OnlineDocs/src/data/param3a.py similarity index 100% rename from doc/OnlineDocs/tests/data/param3a.py rename to doc/OnlineDocs/src/data/param3a.py diff --git a/doc/OnlineDocs/tests/data/param3a.txt b/doc/OnlineDocs/src/data/param3a.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param3a.txt rename to doc/OnlineDocs/src/data/param3a.txt diff --git a/doc/OnlineDocs/tests/data/param3b.dat b/doc/OnlineDocs/src/data/param3b.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param3b.dat rename to doc/OnlineDocs/src/data/param3b.dat diff --git a/doc/OnlineDocs/tests/data/param3b.py b/doc/OnlineDocs/src/data/param3b.py similarity index 100% rename from doc/OnlineDocs/tests/data/param3b.py rename to doc/OnlineDocs/src/data/param3b.py diff --git a/doc/OnlineDocs/tests/data/param3b.txt b/doc/OnlineDocs/src/data/param3b.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param3b.txt rename to doc/OnlineDocs/src/data/param3b.txt diff --git a/doc/OnlineDocs/tests/data/param3c.dat b/doc/OnlineDocs/src/data/param3c.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param3c.dat rename to doc/OnlineDocs/src/data/param3c.dat diff --git a/doc/OnlineDocs/tests/data/param3c.py b/doc/OnlineDocs/src/data/param3c.py similarity index 100% rename from doc/OnlineDocs/tests/data/param3c.py rename to doc/OnlineDocs/src/data/param3c.py diff --git a/doc/OnlineDocs/tests/data/param3c.txt b/doc/OnlineDocs/src/data/param3c.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param3c.txt rename to doc/OnlineDocs/src/data/param3c.txt diff --git a/doc/OnlineDocs/tests/data/param4.dat b/doc/OnlineDocs/src/data/param4.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param4.dat rename to doc/OnlineDocs/src/data/param4.dat diff --git a/doc/OnlineDocs/tests/data/param4.py b/doc/OnlineDocs/src/data/param4.py similarity index 100% rename from doc/OnlineDocs/tests/data/param4.py rename to doc/OnlineDocs/src/data/param4.py diff --git a/doc/OnlineDocs/tests/data/param4.txt b/doc/OnlineDocs/src/data/param4.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param4.txt rename to doc/OnlineDocs/src/data/param4.txt diff --git a/doc/OnlineDocs/tests/data/param5.dat b/doc/OnlineDocs/src/data/param5.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param5.dat rename to doc/OnlineDocs/src/data/param5.dat diff --git a/doc/OnlineDocs/tests/data/param5.py b/doc/OnlineDocs/src/data/param5.py similarity index 100% rename from doc/OnlineDocs/tests/data/param5.py rename to doc/OnlineDocs/src/data/param5.py diff --git a/doc/OnlineDocs/tests/data/param5.txt b/doc/OnlineDocs/src/data/param5.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param5.txt rename to doc/OnlineDocs/src/data/param5.txt diff --git a/doc/OnlineDocs/tests/data/param5a.dat b/doc/OnlineDocs/src/data/param5a.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param5a.dat rename to doc/OnlineDocs/src/data/param5a.dat diff --git a/doc/OnlineDocs/tests/data/param5a.py b/doc/OnlineDocs/src/data/param5a.py similarity index 100% rename from doc/OnlineDocs/tests/data/param5a.py rename to doc/OnlineDocs/src/data/param5a.py diff --git a/doc/OnlineDocs/tests/data/param5a.txt b/doc/OnlineDocs/src/data/param5a.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param5a.txt rename to doc/OnlineDocs/src/data/param5a.txt diff --git a/doc/OnlineDocs/tests/data/param6.dat b/doc/OnlineDocs/src/data/param6.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param6.dat rename to doc/OnlineDocs/src/data/param6.dat diff --git a/doc/OnlineDocs/tests/data/param6.py b/doc/OnlineDocs/src/data/param6.py similarity index 100% rename from doc/OnlineDocs/tests/data/param6.py rename to doc/OnlineDocs/src/data/param6.py diff --git a/doc/OnlineDocs/tests/data/param6.txt b/doc/OnlineDocs/src/data/param6.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param6.txt rename to doc/OnlineDocs/src/data/param6.txt diff --git a/doc/OnlineDocs/tests/data/param6a.dat b/doc/OnlineDocs/src/data/param6a.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param6a.dat rename to doc/OnlineDocs/src/data/param6a.dat diff --git a/doc/OnlineDocs/tests/data/param6a.py b/doc/OnlineDocs/src/data/param6a.py similarity index 100% rename from doc/OnlineDocs/tests/data/param6a.py rename to doc/OnlineDocs/src/data/param6a.py diff --git a/doc/OnlineDocs/tests/data/param6a.txt b/doc/OnlineDocs/src/data/param6a.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param6a.txt rename to doc/OnlineDocs/src/data/param6a.txt diff --git a/doc/OnlineDocs/tests/data/param7a.dat b/doc/OnlineDocs/src/data/param7a.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param7a.dat rename to doc/OnlineDocs/src/data/param7a.dat diff --git a/doc/OnlineDocs/tests/data/param7a.py b/doc/OnlineDocs/src/data/param7a.py similarity index 100% rename from doc/OnlineDocs/tests/data/param7a.py rename to doc/OnlineDocs/src/data/param7a.py diff --git a/doc/OnlineDocs/tests/data/param7a.txt b/doc/OnlineDocs/src/data/param7a.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param7a.txt rename to doc/OnlineDocs/src/data/param7a.txt diff --git a/doc/OnlineDocs/tests/data/param7b.dat b/doc/OnlineDocs/src/data/param7b.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param7b.dat rename to doc/OnlineDocs/src/data/param7b.dat diff --git a/doc/OnlineDocs/tests/data/param7b.py b/doc/OnlineDocs/src/data/param7b.py similarity index 100% rename from doc/OnlineDocs/tests/data/param7b.py rename to doc/OnlineDocs/src/data/param7b.py diff --git a/doc/OnlineDocs/tests/data/param7b.txt b/doc/OnlineDocs/src/data/param7b.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param7b.txt rename to doc/OnlineDocs/src/data/param7b.txt diff --git a/doc/OnlineDocs/tests/data/param8a.dat b/doc/OnlineDocs/src/data/param8a.dat similarity index 100% rename from doc/OnlineDocs/tests/data/param8a.dat rename to doc/OnlineDocs/src/data/param8a.dat diff --git a/doc/OnlineDocs/tests/data/param8a.py b/doc/OnlineDocs/src/data/param8a.py similarity index 100% rename from doc/OnlineDocs/tests/data/param8a.py rename to doc/OnlineDocs/src/data/param8a.py diff --git a/doc/OnlineDocs/tests/data/param8a.txt b/doc/OnlineDocs/src/data/param8a.txt similarity index 100% rename from doc/OnlineDocs/tests/data/param8a.txt rename to doc/OnlineDocs/src/data/param8a.txt diff --git a/doc/OnlineDocs/tests/data/pyomo.diet1.sh b/doc/OnlineDocs/src/data/pyomo.diet1.sh similarity index 100% rename from doc/OnlineDocs/tests/data/pyomo.diet1.sh rename to doc/OnlineDocs/src/data/pyomo.diet1.sh diff --git a/doc/OnlineDocs/tests/data/pyomo.diet1.txt b/doc/OnlineDocs/src/data/pyomo.diet1.txt similarity index 100% rename from doc/OnlineDocs/tests/data/pyomo.diet1.txt rename to doc/OnlineDocs/src/data/pyomo.diet1.txt diff --git a/doc/OnlineDocs/tests/data/pyomo.diet2.sh b/doc/OnlineDocs/src/data/pyomo.diet2.sh similarity index 100% rename from doc/OnlineDocs/tests/data/pyomo.diet2.sh rename to doc/OnlineDocs/src/data/pyomo.diet2.sh diff --git a/doc/OnlineDocs/tests/data/pyomo.diet2.txt b/doc/OnlineDocs/src/data/pyomo.diet2.txt similarity index 100% rename from doc/OnlineDocs/tests/data/pyomo.diet2.txt rename to doc/OnlineDocs/src/data/pyomo.diet2.txt diff --git a/doc/OnlineDocs/tests/data/set1.dat b/doc/OnlineDocs/src/data/set1.dat similarity index 100% rename from doc/OnlineDocs/tests/data/set1.dat rename to doc/OnlineDocs/src/data/set1.dat diff --git a/doc/OnlineDocs/tests/data/set1.py b/doc/OnlineDocs/src/data/set1.py similarity index 100% rename from doc/OnlineDocs/tests/data/set1.py rename to doc/OnlineDocs/src/data/set1.py diff --git a/doc/OnlineDocs/tests/data/set1.txt b/doc/OnlineDocs/src/data/set1.txt similarity index 100% rename from doc/OnlineDocs/tests/data/set1.txt rename to doc/OnlineDocs/src/data/set1.txt diff --git a/doc/OnlineDocs/tests/data/set2.dat b/doc/OnlineDocs/src/data/set2.dat similarity index 100% rename from doc/OnlineDocs/tests/data/set2.dat rename to doc/OnlineDocs/src/data/set2.dat diff --git a/doc/OnlineDocs/tests/data/set2.py b/doc/OnlineDocs/src/data/set2.py similarity index 100% rename from doc/OnlineDocs/tests/data/set2.py rename to doc/OnlineDocs/src/data/set2.py diff --git a/doc/OnlineDocs/tests/data/set2.txt b/doc/OnlineDocs/src/data/set2.txt similarity index 100% rename from doc/OnlineDocs/tests/data/set2.txt rename to doc/OnlineDocs/src/data/set2.txt diff --git a/doc/OnlineDocs/tests/data/set2a.dat b/doc/OnlineDocs/src/data/set2a.dat similarity index 100% rename from doc/OnlineDocs/tests/data/set2a.dat rename to doc/OnlineDocs/src/data/set2a.dat diff --git a/doc/OnlineDocs/tests/data/set2a.py b/doc/OnlineDocs/src/data/set2a.py similarity index 100% rename from doc/OnlineDocs/tests/data/set2a.py rename to doc/OnlineDocs/src/data/set2a.py diff --git a/doc/OnlineDocs/tests/data/set2a.txt b/doc/OnlineDocs/src/data/set2a.txt similarity index 100% rename from doc/OnlineDocs/tests/data/set2a.txt rename to doc/OnlineDocs/src/data/set2a.txt diff --git a/doc/OnlineDocs/tests/data/set3.dat b/doc/OnlineDocs/src/data/set3.dat similarity index 100% rename from doc/OnlineDocs/tests/data/set3.dat rename to doc/OnlineDocs/src/data/set3.dat diff --git a/doc/OnlineDocs/tests/data/set3.py b/doc/OnlineDocs/src/data/set3.py similarity index 100% rename from doc/OnlineDocs/tests/data/set3.py rename to doc/OnlineDocs/src/data/set3.py diff --git a/doc/OnlineDocs/tests/data/set3.txt b/doc/OnlineDocs/src/data/set3.txt similarity index 100% rename from doc/OnlineDocs/tests/data/set3.txt rename to doc/OnlineDocs/src/data/set3.txt diff --git a/doc/OnlineDocs/tests/data/set4.dat b/doc/OnlineDocs/src/data/set4.dat similarity index 100% rename from doc/OnlineDocs/tests/data/set4.dat rename to doc/OnlineDocs/src/data/set4.dat diff --git a/doc/OnlineDocs/tests/data/set4.py b/doc/OnlineDocs/src/data/set4.py similarity index 100% rename from doc/OnlineDocs/tests/data/set4.py rename to doc/OnlineDocs/src/data/set4.py diff --git a/doc/OnlineDocs/tests/data/set4.txt b/doc/OnlineDocs/src/data/set4.txt similarity index 100% rename from doc/OnlineDocs/tests/data/set4.txt rename to doc/OnlineDocs/src/data/set4.txt diff --git a/doc/OnlineDocs/tests/data/set5.dat b/doc/OnlineDocs/src/data/set5.dat similarity index 100% rename from doc/OnlineDocs/tests/data/set5.dat rename to doc/OnlineDocs/src/data/set5.dat diff --git a/doc/OnlineDocs/tests/data/set5.py b/doc/OnlineDocs/src/data/set5.py similarity index 100% rename from doc/OnlineDocs/tests/data/set5.py rename to doc/OnlineDocs/src/data/set5.py diff --git a/doc/OnlineDocs/tests/data/set5.txt b/doc/OnlineDocs/src/data/set5.txt similarity index 100% rename from doc/OnlineDocs/tests/data/set5.txt rename to doc/OnlineDocs/src/data/set5.txt diff --git a/doc/OnlineDocs/tests/data/table0.dat b/doc/OnlineDocs/src/data/table0.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table0.dat rename to doc/OnlineDocs/src/data/table0.dat diff --git a/doc/OnlineDocs/tests/data/table0.py b/doc/OnlineDocs/src/data/table0.py similarity index 100% rename from doc/OnlineDocs/tests/data/table0.py rename to doc/OnlineDocs/src/data/table0.py diff --git a/doc/OnlineDocs/tests/data/table0.txt b/doc/OnlineDocs/src/data/table0.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table0.txt rename to doc/OnlineDocs/src/data/table0.txt diff --git a/doc/OnlineDocs/tests/data/table0.ul.dat b/doc/OnlineDocs/src/data/table0.ul.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table0.ul.dat rename to doc/OnlineDocs/src/data/table0.ul.dat diff --git a/doc/OnlineDocs/tests/data/table0.ul.py b/doc/OnlineDocs/src/data/table0.ul.py similarity index 100% rename from doc/OnlineDocs/tests/data/table0.ul.py rename to doc/OnlineDocs/src/data/table0.ul.py diff --git a/doc/OnlineDocs/tests/data/table0.ul.txt b/doc/OnlineDocs/src/data/table0.ul.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table0.ul.txt rename to doc/OnlineDocs/src/data/table0.ul.txt diff --git a/doc/OnlineDocs/tests/data/table1.dat b/doc/OnlineDocs/src/data/table1.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table1.dat rename to doc/OnlineDocs/src/data/table1.dat diff --git a/doc/OnlineDocs/tests/data/table1.py b/doc/OnlineDocs/src/data/table1.py similarity index 100% rename from doc/OnlineDocs/tests/data/table1.py rename to doc/OnlineDocs/src/data/table1.py diff --git a/doc/OnlineDocs/tests/data/table1.txt b/doc/OnlineDocs/src/data/table1.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table1.txt rename to doc/OnlineDocs/src/data/table1.txt diff --git a/doc/OnlineDocs/tests/data/table2.dat b/doc/OnlineDocs/src/data/table2.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table2.dat rename to doc/OnlineDocs/src/data/table2.dat diff --git a/doc/OnlineDocs/tests/data/table2.py b/doc/OnlineDocs/src/data/table2.py similarity index 100% rename from doc/OnlineDocs/tests/data/table2.py rename to doc/OnlineDocs/src/data/table2.py diff --git a/doc/OnlineDocs/tests/data/table2.txt b/doc/OnlineDocs/src/data/table2.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table2.txt rename to doc/OnlineDocs/src/data/table2.txt diff --git a/doc/OnlineDocs/tests/data/table3.dat b/doc/OnlineDocs/src/data/table3.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table3.dat rename to doc/OnlineDocs/src/data/table3.dat diff --git a/doc/OnlineDocs/tests/data/table3.py b/doc/OnlineDocs/src/data/table3.py similarity index 100% rename from doc/OnlineDocs/tests/data/table3.py rename to doc/OnlineDocs/src/data/table3.py diff --git a/doc/OnlineDocs/tests/data/table3.txt b/doc/OnlineDocs/src/data/table3.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table3.txt rename to doc/OnlineDocs/src/data/table3.txt diff --git a/doc/OnlineDocs/tests/data/table3.ul.dat b/doc/OnlineDocs/src/data/table3.ul.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table3.ul.dat rename to doc/OnlineDocs/src/data/table3.ul.dat diff --git a/doc/OnlineDocs/tests/data/table3.ul.py b/doc/OnlineDocs/src/data/table3.ul.py similarity index 100% rename from doc/OnlineDocs/tests/data/table3.ul.py rename to doc/OnlineDocs/src/data/table3.ul.py diff --git a/doc/OnlineDocs/tests/data/table3.ul.txt b/doc/OnlineDocs/src/data/table3.ul.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table3.ul.txt rename to doc/OnlineDocs/src/data/table3.ul.txt diff --git a/doc/OnlineDocs/tests/data/table4.dat b/doc/OnlineDocs/src/data/table4.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table4.dat rename to doc/OnlineDocs/src/data/table4.dat diff --git a/doc/OnlineDocs/tests/data/table4.py b/doc/OnlineDocs/src/data/table4.py similarity index 100% rename from doc/OnlineDocs/tests/data/table4.py rename to doc/OnlineDocs/src/data/table4.py diff --git a/doc/OnlineDocs/tests/data/table4.txt b/doc/OnlineDocs/src/data/table4.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table4.txt rename to doc/OnlineDocs/src/data/table4.txt diff --git a/doc/OnlineDocs/tests/data/table4.ul.dat b/doc/OnlineDocs/src/data/table4.ul.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table4.ul.dat rename to doc/OnlineDocs/src/data/table4.ul.dat diff --git a/doc/OnlineDocs/tests/data/table4.ul.py b/doc/OnlineDocs/src/data/table4.ul.py similarity index 100% rename from doc/OnlineDocs/tests/data/table4.ul.py rename to doc/OnlineDocs/src/data/table4.ul.py diff --git a/doc/OnlineDocs/tests/data/table4.ul.txt b/doc/OnlineDocs/src/data/table4.ul.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table4.ul.txt rename to doc/OnlineDocs/src/data/table4.ul.txt diff --git a/doc/OnlineDocs/tests/data/table5.dat b/doc/OnlineDocs/src/data/table5.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table5.dat rename to doc/OnlineDocs/src/data/table5.dat diff --git a/doc/OnlineDocs/tests/data/table5.py b/doc/OnlineDocs/src/data/table5.py similarity index 100% rename from doc/OnlineDocs/tests/data/table5.py rename to doc/OnlineDocs/src/data/table5.py diff --git a/doc/OnlineDocs/tests/data/table5.txt b/doc/OnlineDocs/src/data/table5.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table5.txt rename to doc/OnlineDocs/src/data/table5.txt diff --git a/doc/OnlineDocs/tests/data/table6.dat b/doc/OnlineDocs/src/data/table6.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table6.dat rename to doc/OnlineDocs/src/data/table6.dat diff --git a/doc/OnlineDocs/tests/data/table6.py b/doc/OnlineDocs/src/data/table6.py similarity index 100% rename from doc/OnlineDocs/tests/data/table6.py rename to doc/OnlineDocs/src/data/table6.py diff --git a/doc/OnlineDocs/tests/data/table6.txt b/doc/OnlineDocs/src/data/table6.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table6.txt rename to doc/OnlineDocs/src/data/table6.txt diff --git a/doc/OnlineDocs/tests/data/table7.dat b/doc/OnlineDocs/src/data/table7.dat similarity index 100% rename from doc/OnlineDocs/tests/data/table7.dat rename to doc/OnlineDocs/src/data/table7.dat diff --git a/doc/OnlineDocs/tests/data/table7.py b/doc/OnlineDocs/src/data/table7.py similarity index 100% rename from doc/OnlineDocs/tests/data/table7.py rename to doc/OnlineDocs/src/data/table7.py diff --git a/doc/OnlineDocs/tests/data/table7.txt b/doc/OnlineDocs/src/data/table7.txt similarity index 100% rename from doc/OnlineDocs/tests/data/table7.txt rename to doc/OnlineDocs/src/data/table7.txt diff --git a/doc/OnlineDocs/tests/dataportal/A.tab b/doc/OnlineDocs/src/dataportal/A.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/A.tab rename to doc/OnlineDocs/src/dataportal/A.tab diff --git a/doc/OnlineDocs/tests/dataportal/C.tab b/doc/OnlineDocs/src/dataportal/C.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/C.tab rename to doc/OnlineDocs/src/dataportal/C.tab diff --git a/doc/OnlineDocs/tests/dataportal/D.tab b/doc/OnlineDocs/src/dataportal/D.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/D.tab rename to doc/OnlineDocs/src/dataportal/D.tab diff --git a/doc/OnlineDocs/tests/dataportal/PP.csv b/doc/OnlineDocs/src/dataportal/PP.csv similarity index 100% rename from doc/OnlineDocs/tests/dataportal/PP.csv rename to doc/OnlineDocs/src/dataportal/PP.csv diff --git a/doc/OnlineDocs/tests/dataportal/PP.json b/doc/OnlineDocs/src/dataportal/PP.json similarity index 100% rename from doc/OnlineDocs/tests/dataportal/PP.json rename to doc/OnlineDocs/src/dataportal/PP.json diff --git a/doc/OnlineDocs/tests/dataportal/PP.sqlite b/doc/OnlineDocs/src/dataportal/PP.sqlite similarity index 100% rename from doc/OnlineDocs/tests/dataportal/PP.sqlite rename to doc/OnlineDocs/src/dataportal/PP.sqlite diff --git a/doc/OnlineDocs/tests/dataportal/PP.tab b/doc/OnlineDocs/src/dataportal/PP.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/PP.tab rename to doc/OnlineDocs/src/dataportal/PP.tab diff --git a/doc/OnlineDocs/tests/dataportal/PP.xml b/doc/OnlineDocs/src/dataportal/PP.xml similarity index 100% rename from doc/OnlineDocs/tests/dataportal/PP.xml rename to doc/OnlineDocs/src/dataportal/PP.xml diff --git a/doc/OnlineDocs/tests/dataportal/PP.yaml b/doc/OnlineDocs/src/dataportal/PP.yaml similarity index 100% rename from doc/OnlineDocs/tests/dataportal/PP.yaml rename to doc/OnlineDocs/src/dataportal/PP.yaml diff --git a/doc/OnlineDocs/tests/dataportal/PP_sqlite.py b/doc/OnlineDocs/src/dataportal/PP_sqlite.py similarity index 100% rename from doc/OnlineDocs/tests/dataportal/PP_sqlite.py rename to doc/OnlineDocs/src/dataportal/PP_sqlite.py diff --git a/doc/OnlineDocs/tests/dataportal/Pyomo_mysql b/doc/OnlineDocs/src/dataportal/Pyomo_mysql similarity index 100% rename from doc/OnlineDocs/tests/dataportal/Pyomo_mysql rename to doc/OnlineDocs/src/dataportal/Pyomo_mysql diff --git a/doc/OnlineDocs/tests/dataportal/S.tab b/doc/OnlineDocs/src/dataportal/S.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/S.tab rename to doc/OnlineDocs/src/dataportal/S.tab diff --git a/doc/OnlineDocs/tests/dataportal/T.json b/doc/OnlineDocs/src/dataportal/T.json similarity index 100% rename from doc/OnlineDocs/tests/dataportal/T.json rename to doc/OnlineDocs/src/dataportal/T.json diff --git a/doc/OnlineDocs/tests/dataportal/T.yaml b/doc/OnlineDocs/src/dataportal/T.yaml similarity index 100% rename from doc/OnlineDocs/tests/dataportal/T.yaml rename to doc/OnlineDocs/src/dataportal/T.yaml diff --git a/doc/OnlineDocs/tests/dataportal/U.tab b/doc/OnlineDocs/src/dataportal/U.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/U.tab rename to doc/OnlineDocs/src/dataportal/U.tab diff --git a/doc/OnlineDocs/tests/dataportal/XW.tab b/doc/OnlineDocs/src/dataportal/XW.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/XW.tab rename to doc/OnlineDocs/src/dataportal/XW.tab diff --git a/doc/OnlineDocs/tests/dataportal/Y.tab b/doc/OnlineDocs/src/dataportal/Y.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/Y.tab rename to doc/OnlineDocs/src/dataportal/Y.tab diff --git a/doc/OnlineDocs/tests/dataportal/Z.tab b/doc/OnlineDocs/src/dataportal/Z.tab similarity index 100% rename from doc/OnlineDocs/tests/dataportal/Z.tab rename to doc/OnlineDocs/src/dataportal/Z.tab diff --git a/doc/OnlineDocs/tests/dataportal/dataportal_tab.py b/doc/OnlineDocs/src/dataportal/dataportal_tab.py similarity index 100% rename from doc/OnlineDocs/tests/dataportal/dataportal_tab.py rename to doc/OnlineDocs/src/dataportal/dataportal_tab.py diff --git a/doc/OnlineDocs/tests/dataportal/dataportal_tab.txt b/doc/OnlineDocs/src/dataportal/dataportal_tab.txt similarity index 100% rename from doc/OnlineDocs/tests/dataportal/dataportal_tab.txt rename to doc/OnlineDocs/src/dataportal/dataportal_tab.txt diff --git a/doc/OnlineDocs/tests/dataportal/excel.xls b/doc/OnlineDocs/src/dataportal/excel.xls similarity index 100% rename from doc/OnlineDocs/tests/dataportal/excel.xls rename to doc/OnlineDocs/src/dataportal/excel.xls diff --git a/doc/OnlineDocs/tests/dataportal/param_initialization.py b/doc/OnlineDocs/src/dataportal/param_initialization.py similarity index 100% rename from doc/OnlineDocs/tests/dataportal/param_initialization.py rename to doc/OnlineDocs/src/dataportal/param_initialization.py diff --git a/doc/OnlineDocs/tests/dataportal/param_initialization.txt b/doc/OnlineDocs/src/dataportal/param_initialization.txt similarity index 100% rename from doc/OnlineDocs/tests/dataportal/param_initialization.txt rename to doc/OnlineDocs/src/dataportal/param_initialization.txt diff --git a/doc/OnlineDocs/tests/dataportal/set_initialization.py b/doc/OnlineDocs/src/dataportal/set_initialization.py similarity index 100% rename from doc/OnlineDocs/tests/dataportal/set_initialization.py rename to doc/OnlineDocs/src/dataportal/set_initialization.py diff --git a/doc/OnlineDocs/tests/dataportal/set_initialization.txt b/doc/OnlineDocs/src/dataportal/set_initialization.txt similarity index 100% rename from doc/OnlineDocs/tests/dataportal/set_initialization.txt rename to doc/OnlineDocs/src/dataportal/set_initialization.txt diff --git a/doc/OnlineDocs/tests/expr/design.py b/doc/OnlineDocs/src/expr/design.py similarity index 100% rename from doc/OnlineDocs/tests/expr/design.py rename to doc/OnlineDocs/src/expr/design.py diff --git a/doc/OnlineDocs/tests/expr/design.txt b/doc/OnlineDocs/src/expr/design.txt similarity index 100% rename from doc/OnlineDocs/tests/expr/design.txt rename to doc/OnlineDocs/src/expr/design.txt diff --git a/doc/OnlineDocs/tests/expr/index.py b/doc/OnlineDocs/src/expr/index.py similarity index 100% rename from doc/OnlineDocs/tests/expr/index.py rename to doc/OnlineDocs/src/expr/index.py diff --git a/doc/OnlineDocs/tests/expr/index.txt b/doc/OnlineDocs/src/expr/index.txt similarity index 100% rename from doc/OnlineDocs/tests/expr/index.txt rename to doc/OnlineDocs/src/expr/index.txt diff --git a/doc/OnlineDocs/tests/expr/managing.py b/doc/OnlineDocs/src/expr/managing.py similarity index 100% rename from doc/OnlineDocs/tests/expr/managing.py rename to doc/OnlineDocs/src/expr/managing.py diff --git a/doc/OnlineDocs/tests/expr/managing.txt b/doc/OnlineDocs/src/expr/managing.txt similarity index 100% rename from doc/OnlineDocs/tests/expr/managing.txt rename to doc/OnlineDocs/src/expr/managing.txt diff --git a/doc/OnlineDocs/tests/expr/overview.py b/doc/OnlineDocs/src/expr/overview.py similarity index 100% rename from doc/OnlineDocs/tests/expr/overview.py rename to doc/OnlineDocs/src/expr/overview.py diff --git a/doc/OnlineDocs/tests/expr/overview.txt b/doc/OnlineDocs/src/expr/overview.txt similarity index 100% rename from doc/OnlineDocs/tests/expr/overview.txt rename to doc/OnlineDocs/src/expr/overview.txt diff --git a/doc/OnlineDocs/tests/expr/performance.py b/doc/OnlineDocs/src/expr/performance.py similarity index 100% rename from doc/OnlineDocs/tests/expr/performance.py rename to doc/OnlineDocs/src/expr/performance.py diff --git a/doc/OnlineDocs/tests/expr/performance.txt b/doc/OnlineDocs/src/expr/performance.txt similarity index 100% rename from doc/OnlineDocs/tests/expr/performance.txt rename to doc/OnlineDocs/src/expr/performance.txt diff --git a/doc/OnlineDocs/tests/expr/quicksum.log b/doc/OnlineDocs/src/expr/quicksum.log similarity index 100% rename from doc/OnlineDocs/tests/expr/quicksum.log rename to doc/OnlineDocs/src/expr/quicksum.log diff --git a/doc/OnlineDocs/tests/expr/quicksum.py b/doc/OnlineDocs/src/expr/quicksum.py similarity index 100% rename from doc/OnlineDocs/tests/expr/quicksum.py rename to doc/OnlineDocs/src/expr/quicksum.py diff --git a/doc/OnlineDocs/tests/kernel/examples.sh b/doc/OnlineDocs/src/kernel/examples.sh similarity index 100% rename from doc/OnlineDocs/tests/kernel/examples.sh rename to doc/OnlineDocs/src/kernel/examples.sh diff --git a/doc/OnlineDocs/tests/kernel/examples.txt b/doc/OnlineDocs/src/kernel/examples.txt similarity index 100% rename from doc/OnlineDocs/tests/kernel/examples.txt rename to doc/OnlineDocs/src/kernel/examples.txt diff --git a/doc/OnlineDocs/tests/scripting/AbstractSuffixes.py b/doc/OnlineDocs/src/scripting/AbstractSuffixes.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/AbstractSuffixes.py rename to doc/OnlineDocs/src/scripting/AbstractSuffixes.py diff --git a/doc/OnlineDocs/tests/scripting/Isinglebuild.py b/doc/OnlineDocs/src/scripting/Isinglebuild.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/Isinglebuild.py rename to doc/OnlineDocs/src/scripting/Isinglebuild.py diff --git a/doc/OnlineDocs/tests/scripting/Isinglecomm.dat b/doc/OnlineDocs/src/scripting/Isinglecomm.dat similarity index 100% rename from doc/OnlineDocs/tests/scripting/Isinglecomm.dat rename to doc/OnlineDocs/src/scripting/Isinglecomm.dat diff --git a/doc/OnlineDocs/tests/scripting/NodesIn_init.py b/doc/OnlineDocs/src/scripting/NodesIn_init.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/NodesIn_init.py rename to doc/OnlineDocs/src/scripting/NodesIn_init.py diff --git a/doc/OnlineDocs/tests/scripting/Z_init.py b/doc/OnlineDocs/src/scripting/Z_init.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/Z_init.py rename to doc/OnlineDocs/src/scripting/Z_init.py diff --git a/doc/OnlineDocs/tests/scripting/abstract1.dat b/doc/OnlineDocs/src/scripting/abstract1.dat similarity index 100% rename from doc/OnlineDocs/tests/scripting/abstract1.dat rename to doc/OnlineDocs/src/scripting/abstract1.dat diff --git a/doc/OnlineDocs/tests/scripting/abstract2.dat b/doc/OnlineDocs/src/scripting/abstract2.dat similarity index 100% rename from doc/OnlineDocs/tests/scripting/abstract2.dat rename to doc/OnlineDocs/src/scripting/abstract2.dat diff --git a/doc/OnlineDocs/tests/scripting/abstract2.py b/doc/OnlineDocs/src/scripting/abstract2.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/abstract2.py rename to doc/OnlineDocs/src/scripting/abstract2.py diff --git a/doc/OnlineDocs/tests/scripting/abstract2a.dat b/doc/OnlineDocs/src/scripting/abstract2a.dat similarity index 100% rename from doc/OnlineDocs/tests/scripting/abstract2a.dat rename to doc/OnlineDocs/src/scripting/abstract2a.dat diff --git a/doc/OnlineDocs/tests/scripting/abstract2piece.py b/doc/OnlineDocs/src/scripting/abstract2piece.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/abstract2piece.py rename to doc/OnlineDocs/src/scripting/abstract2piece.py diff --git a/doc/OnlineDocs/tests/scripting/abstract2piecebuild.py b/doc/OnlineDocs/src/scripting/abstract2piecebuild.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/abstract2piecebuild.py rename to doc/OnlineDocs/src/scripting/abstract2piecebuild.py diff --git a/doc/OnlineDocs/tests/scripting/block_iter_example.py b/doc/OnlineDocs/src/scripting/block_iter_example.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/block_iter_example.py rename to doc/OnlineDocs/src/scripting/block_iter_example.py diff --git a/doc/OnlineDocs/tests/scripting/concrete1.py b/doc/OnlineDocs/src/scripting/concrete1.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/concrete1.py rename to doc/OnlineDocs/src/scripting/concrete1.py diff --git a/doc/OnlineDocs/tests/scripting/doubleA.py b/doc/OnlineDocs/src/scripting/doubleA.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/doubleA.py rename to doc/OnlineDocs/src/scripting/doubleA.py diff --git a/doc/OnlineDocs/tests/scripting/driveabs2.py b/doc/OnlineDocs/src/scripting/driveabs2.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/driveabs2.py rename to doc/OnlineDocs/src/scripting/driveabs2.py diff --git a/doc/OnlineDocs/tests/scripting/driveconc1.py b/doc/OnlineDocs/src/scripting/driveconc1.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/driveconc1.py rename to doc/OnlineDocs/src/scripting/driveconc1.py diff --git a/doc/OnlineDocs/tests/scripting/iterative1.py b/doc/OnlineDocs/src/scripting/iterative1.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/iterative1.py rename to doc/OnlineDocs/src/scripting/iterative1.py diff --git a/doc/OnlineDocs/tests/scripting/iterative2.py b/doc/OnlineDocs/src/scripting/iterative2.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/iterative2.py rename to doc/OnlineDocs/src/scripting/iterative2.py diff --git a/doc/OnlineDocs/tests/scripting/noiteration1.py b/doc/OnlineDocs/src/scripting/noiteration1.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/noiteration1.py rename to doc/OnlineDocs/src/scripting/noiteration1.py diff --git a/doc/OnlineDocs/tests/scripting/parallel.py b/doc/OnlineDocs/src/scripting/parallel.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/parallel.py rename to doc/OnlineDocs/src/scripting/parallel.py diff --git a/doc/OnlineDocs/tests/scripting/spy4Constraints.py b/doc/OnlineDocs/src/scripting/spy4Constraints.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/spy4Constraints.py rename to doc/OnlineDocs/src/scripting/spy4Constraints.py diff --git a/doc/OnlineDocs/tests/scripting/spy4Expressions.py b/doc/OnlineDocs/src/scripting/spy4Expressions.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/spy4Expressions.py rename to doc/OnlineDocs/src/scripting/spy4Expressions.py diff --git a/doc/OnlineDocs/tests/scripting/spy4PyomoCommand.py b/doc/OnlineDocs/src/scripting/spy4PyomoCommand.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/spy4PyomoCommand.py rename to doc/OnlineDocs/src/scripting/spy4PyomoCommand.py diff --git a/doc/OnlineDocs/tests/scripting/spy4Variables.py b/doc/OnlineDocs/src/scripting/spy4Variables.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/spy4Variables.py rename to doc/OnlineDocs/src/scripting/spy4Variables.py diff --git a/doc/OnlineDocs/tests/scripting/spy4scripts.py b/doc/OnlineDocs/src/scripting/spy4scripts.py similarity index 100% rename from doc/OnlineDocs/tests/scripting/spy4scripts.py rename to doc/OnlineDocs/src/scripting/spy4scripts.py diff --git a/doc/OnlineDocs/tests/strip_examples.py b/doc/OnlineDocs/src/strip_examples.py similarity index 100% rename from doc/OnlineDocs/tests/strip_examples.py rename to doc/OnlineDocs/src/strip_examples.py diff --git a/doc/OnlineDocs/tests/test_examples.py b/doc/OnlineDocs/src/test_examples.py similarity index 100% rename from doc/OnlineDocs/tests/test_examples.py rename to doc/OnlineDocs/src/test_examples.py diff --git a/doc/OnlineDocs/working_abstractmodels/BuildAction.rst b/doc/OnlineDocs/working_abstractmodels/BuildAction.rst index 5706ce97e6f..6840e15a1d5 100644 --- a/doc/OnlineDocs/working_abstractmodels/BuildAction.rst +++ b/doc/OnlineDocs/working_abstractmodels/BuildAction.rst @@ -13,7 +13,7 @@ trigger actions to be done as part of the model building process. The takes as arguments optional index sets and a function to perform the action. For example, -.. literalinclude:: ../tests/scripting/abstract2piecebuild_BuildAction_example.spy +.. literalinclude:: ../src/scripting/abstract2piecebuild_BuildAction_example.spy :language: python calls the function ``bpts_build`` for each member of ``model.J``. The @@ -21,14 +21,14 @@ function ``bpts_build`` should have the model and a variable for the members of ``model.J`` as formal arguments. In this example, the following would be a valid declaration for the function: -.. literalinclude:: ../tests/scripting/abstract2piecebuild_Function_valid_declaration.spy +.. literalinclude:: ../src/scripting/abstract2piecebuild_Function_valid_declaration.spy :language: python A full example, which extends the :ref:`abstract2.py` and :ref:`abstract2piece.py` examples, is -.. literalinclude:: ../tests/scripting/abstract2piecebuild.spy +.. literalinclude:: ../src/scripting/abstract2piecebuild.spy :language: python This example uses the build action to create a model component with @@ -51,13 +51,13 @@ clearer, to use a build action. The full model is: -.. literalinclude:: ../tests/scripting/Isinglebuild.py +.. literalinclude:: ../src/scripting/Isinglebuild.py :language: python for this model, the same data file can be used as for Isinglecomm.py in :ref:`Isinglecomm.py` such as the toy data file: -.. literalinclude:: ../tests/scripting/Isinglecomm.dat +.. literalinclude:: ../src/scripting/Isinglecomm.dat Build actions can also be a way to implement data validation, particularly when multiple Sets or Parameters must be analyzed. However, diff --git a/doc/OnlineDocs/working_abstractmodels/data/dataportals.rst b/doc/OnlineDocs/working_abstractmodels/data/dataportals.rst index 88b89653a37..5ce907fda2a 100644 --- a/doc/OnlineDocs/working_abstractmodels/data/dataportals.rst +++ b/doc/OnlineDocs/working_abstractmodels/data/dataportals.rst @@ -62,14 +62,14 @@ can be used to initialize both concrete and abstract Pyomo models. Consider the file ``A.tab``, which defines a simple set with a tabular format: -.. literalinclude:: ../../tests/dataportal/A.tab +.. literalinclude:: ../../src/dataportal/A.tab :language: none The ``load`` method is used to load data into a :class:`~pyomo.environ.DataPortal` object. Components in a concrete model can be explicitly initialized with data loaded by a :class:`~pyomo.environ.DataPortal` object: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_concrete1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_concrete1.spy :language: python All data needed to initialize an abstract model *must* be provided by a @@ -77,7 +77,7 @@ All data needed to initialize an abstract model *must* be provided by a and the use of the :class:`~pyomo.environ.DataPortal` object to initialize components is automated for the user: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_load.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_load.spy :language: python Note the difference in the execution of the ``load`` method in these two @@ -126,7 +126,7 @@ that are loaded from different data sources. The ``[]`` operator is used to access set and parameter values. Consider the following example, which loads data and prints the value of the ``[]`` operator: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_getitem.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_getitem.spy :language: python The :class:`~pyomo.environ.DataPortal` @@ -162,12 +162,12 @@ with lists and dictionaries: For example, consider the following JSON file: -.. literalinclude:: ../../tests/dataportal/T.json +.. literalinclude:: ../../src/dataportal/T.json :language: none The data in this file can be used to load the following model: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_json1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_json1.spy :language: python Note that no ``set`` or ``param`` option needs to be specified when @@ -178,13 +178,13 @@ needed for model construction is used. The following YAML file has a similar structure: -.. literalinclude:: ../../tests/dataportal/T.yaml +.. literalinclude:: ../../src/dataportal/T.yaml :language: none The data in this file can be used to load a Pyomo model with the same syntax as a JSON file: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_yaml1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_yaml1.spy :language: python @@ -212,7 +212,7 @@ TAB files represent tabular data in an ascii file using whitespace as a delimiter. A TAB file consists of rows of values, where each row has the same length. For example, the file ``PP.tab`` has the format: -.. literalinclude:: ../../tests/dataportal/PP.tab +.. literalinclude:: ../../src/dataportal/PP.tab :language: none CSV files represent tabular data in a format that is very similar to TAB @@ -220,7 +220,7 @@ files. Pyomo assumes that a CSV file consists of rows of values, where each row has the same length. For example, the file ``PP.csv`` has the format: -.. literalinclude:: ../../tests/dataportal/PP.csv +.. literalinclude:: ../../src/dataportal/PP.csv :language: none Excel spreadsheets can express complex data relationships. A *range* is @@ -242,7 +242,7 @@ sub-element of a ``row`` element represents a different column, where each row has the same length. For example, the file ``PP.xml`` has the format: -.. literalinclude:: ../../tests/dataportal/PP.xml +.. literalinclude:: ../../src/dataportal/PP.xml :language: none Loading Set Data @@ -256,13 +256,13 @@ Loading a Simple Set Consider the file ``A.tab``, which defines a simple set: -.. literalinclude:: ../../tests/dataportal/A.tab +.. literalinclude:: ../../src/dataportal/A.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for a simple set ``A``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_set1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_set1.spy :language: python Loading a Set of Tuples @@ -270,13 +270,13 @@ Loading a Set of Tuples Consider the file ``C.tab``: -.. literalinclude:: ../../tests/dataportal/C.tab +.. literalinclude:: ../../src/dataportal/C.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for a two-dimensional set ``C``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_set2.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_set2.spy :language: python In this example, the column titles do not directly impact the process of @@ -289,13 +289,13 @@ Loading a Set Array Consider the file ``D.tab``, which defines an array representation of a two-dimensional set: -.. literalinclude:: ../../tests/dataportal/D.tab +.. literalinclude:: ../../src/dataportal/D.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for a two-dimensional set ``D``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_set3.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_set3.spy :language: python The ``format`` option indicates that the set data is declared in a array @@ -313,13 +313,13 @@ Loading a Simple Parameter The simplest parameter is simply a singleton value. Consider the file ``Z.tab``: -.. literalinclude:: ../../tests/dataportal/Z.tab +.. literalinclude:: ../../src/dataportal/Z.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for a simple parameter ``z``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param1.spy :language: python Loading an Indexed Parameter @@ -328,13 +328,13 @@ Loading an Indexed Parameter An indexed parameter can be defined by a single column in a table. For example, consider the file ``Y.tab``: -.. literalinclude:: ../../tests/dataportal/Y.tab +.. literalinclude:: ../../src/dataportal/Y.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for an indexed parameter ``y``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param2.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param2.spy :language: python When column names are not used to specify the index and parameter data, @@ -351,19 +351,19 @@ The index set can be loaded with the parameter data using the ``index`` option. In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for set ``A`` and the indexed parameter ``y`` -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param3.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param3.spy :language: python An index set with multiple dimensions can also be loaded with an indexed parameter. Consider the file ``PP.tab``: -.. literalinclude:: ../../tests/dataportal/PP.tab +.. literalinclude:: ../../src/dataportal/PP.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for a tuple set and an indexed parameter: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param10.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param10.spy :language: python Loading a Parameter with Missing Values @@ -373,7 +373,7 @@ Missing parameter data can be expressed in two ways. First, parameter data can be defined with indices that are a subset of valid indices in the model. The following example loads the indexed parameter ``y``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param9.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param9.spy :language: python The model defines an index set with four values, but only three @@ -382,13 +382,13 @@ parameter values are declared in the data file ``Y.tab``. Parameter data can also be declared with missing values using the period (``.``) symbol. For example, consider the file ``S.tab``: -.. literalinclude:: ../../tests/dataportal/PP.tab +.. literalinclude:: ../../src/dataportal/PP.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for the index set ``A`` and indexed parameter ``y``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param8.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param8.spy :language: python The period (``.``) symbol indicates a missing parameter value, but the @@ -400,13 +400,13 @@ Loading Multiple Parameters Multiple parameters can be initialized at once by specifying a list (or tuple) of component parameters. Consider the file ``XW.tab``: -.. literalinclude:: ../../tests/dataportal/XW.tab +.. literalinclude:: ../../src/dataportal/XW.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for parameters ``x`` and ``w``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param4.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param4.spy :language: python Selecting Parameter Columns @@ -421,7 +421,7 @@ component data. For example, consider the following load declaration: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param5.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param5.spy :language: python The columns ``A`` and ``W`` are selected from the file ``XW.tab``, and a @@ -433,20 +433,20 @@ Loading a Parameter Array Consider the file ``U.tab``, which defines an array representation of a multiply-indexed parameter: -.. literalinclude:: ../../tests/dataportal/U.tab +.. literalinclude:: ../../src/dataportal/U.tab :language: none In the following example, a :class:`~pyomo.environ.DataPortal` object loads data for a two-dimensional parameter ``u``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param6.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param6.spy :language: python The ``format`` option indicates that the parameter data is declared in a array format. The ``format`` option can also indicate that the parameter data should be transposed. -.. literalinclude:: ../../tests/dataportal/dataportal_tab_param7.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_param7.spy :language: python Note that the transposed parameter data changes the index set for the @@ -467,7 +467,7 @@ the following range of cells, which is named ``PPtable``: In the following example, a :class:`~pyomo.environ.DataPortal` object loads the named range ``PPtable`` from the file ``excel.xls``: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_excel1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_excel1.spy :language: python Note that the ``range`` option is required to specify the table of cell @@ -477,14 +477,14 @@ There are a variety of ways that data can be loaded from a relational database. In the simplest case, a table can be specified within a database: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_db1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_db1.spy :language: python In this example, the interface ``sqlite3`` is used to load data from an SQLite database in the file ``PP.sqlite``. More generally, an SQL query can be specified to dynamically generate a table. For example: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_db2.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_db2.spy :language: python Data Namespaces @@ -524,7 +524,7 @@ components. For example, the following script generates two model instances from an abstract model using data loaded into different namespaces: -.. literalinclude:: ../../tests/dataportal/dataportal_tab_namespaces1.spy +.. literalinclude:: ../../src/dataportal/dataportal_tab_namespaces1.spy :language: python diff --git a/doc/OnlineDocs/working_abstractmodels/data/datfiles.rst b/doc/OnlineDocs/working_abstractmodels/data/datfiles.rst index 06d28093cf4..4982ed2fff0 100644 --- a/doc/OnlineDocs/working_abstractmodels/data/datfiles.rst +++ b/doc/OnlineDocs/working_abstractmodels/data/datfiles.rst @@ -104,7 +104,7 @@ A set may be empty, and it may contain any combination of numeric and non-numeric string values. For example, the following are valid ``set`` commands: -.. literalinclude:: ../../tests/data/set1.dat +.. literalinclude:: ../../src/data/set1.dat :language: python @@ -115,19 +115,19 @@ The ``set`` data command can also specify tuple data with the standard notation for tuples. For example, suppose that set ``A`` contains 3-tuples: -.. literalinclude:: ../../tests/data/set2_decl.spy +.. literalinclude:: ../../src/data/set2_decl.spy :language: python The following ``set`` data command then specifies that ``A`` is the set containing the tuples ``(1,2,3)`` and ``(4,5,6)``: -.. literalinclude:: ../../tests/data/set2a.dat +.. literalinclude:: ../../src/data/set2a.dat :language: none Alternatively, set data can simply be listed in the order that the tuple is represented: -.. literalinclude:: ../../tests/data/set2.dat +.. literalinclude:: ../../src/data/set2.dat :language: none Obviously, the number of data elements specified using this syntax @@ -138,7 +138,7 @@ membership. For example, the following ``set`` data command declares 2-tuples in ``A`` using plus (``+``) to denote valid tuples and minus (``-``) to denote invalid tuples: -.. literalinclude:: ../../tests/data/set4.dat +.. literalinclude:: ../../src/data/set4.dat :language: none This data command declares the following five 2-tuples: ``('A1',1)``, @@ -148,13 +148,13 @@ Finally, a set of tuple data can be concisely represented with tuple *templates* that represent a *slice* of tuple data. For example, suppose that the set ``A`` contains 4-tuples: -.. literalinclude:: ../../tests/data/set5_decl.spy +.. literalinclude:: ../../src/data/set5_decl.spy :language: python The following ``set`` data command declares groups of tuples that are defined by a template and data to complete this template: -.. literalinclude:: ../../tests/data/set5.dat +.. literalinclude:: ../../src/data/set5.dat :language: none A tuple template consists of a tuple that contains one or more asterisk @@ -163,7 +163,7 @@ tuple value is replaced by the values from the list of values that follows the tuple template. In this example, the following tuples are in set ``A``: -.. literalinclude:: ../../tests/data/set5.txt +.. literalinclude:: ../../src/data/set5.txt :language: none Set Arrays @@ -183,12 +183,12 @@ list of string values. Suppose that a set ``A`` is used to index a set ``B`` as follows: -.. literalinclude:: ../../tests/data/set3_decl.spy +.. literalinclude:: ../../src/data/set3_decl.spy :language: python Then set ``B`` is indexed using the values declared for set ``A``: -.. literalinclude:: ../../tests/data/set3.dat +.. literalinclude:: ../../src/data/set3.dat :language: none The ``param`` Command @@ -197,7 +197,7 @@ The ``param`` Command Simple or non-indexed parameters are declared in an obvious way, as shown by these examples: -.. literalinclude:: ../../tests/data/param1.dat +.. literalinclude:: ../../src/data/param1.dat :language: none Parameters can be defined with numeric data, simple strings and quoted @@ -213,33 +213,33 @@ parameter data. One-dimensional parameter data is indexed over a single set. Suppose that the parameter ``B`` is a parameter indexed by the set ``A``: -.. literalinclude:: ../../tests/data/param2_decl.spy +.. literalinclude:: ../../src/data/param2_decl.spy :language: python A ``param`` data command can specify values for ``B`` with a list of index-value pairs: -.. literalinclude:: ../../tests/data/param2.dat +.. literalinclude:: ../../src/data/param2.dat :language: none Because whitespace is ignored, this example data command file can be reorganized to specify the same data in a tabular format: -.. literalinclude:: ../../tests/data/param2a.dat +.. literalinclude:: ../../src/data/param2a.dat :language: none Multiple parameters can be defined using a single ``param`` data command. For example, suppose that parameters ``B``, ``C``, and ``D`` are one-dimensional parameters all indexed by the set ``A``: -.. literalinclude:: ../../tests/data/param3_decl.spy +.. literalinclude:: ../../src/data/param3_decl.spy :language: python Values for these parameters can be specified using a single ``param`` data command that declares these parameter names followed by a list of index and parameter values: -.. literalinclude:: ../../tests/data/param3.dat +.. literalinclude:: ../../src/data/param3.dat :language: none The values in the ``param`` data command are interpreted as a list of @@ -249,7 +249,7 @@ corresponding numeric value. Note that parameter values do not need to be defined for all indices. For example, the following data command file is valid: -.. literalinclude:: ../../tests/data/param3a.dat +.. literalinclude:: ../../src/data/param3a.dat :language: none The index ``g`` is omitted from the ``param`` command, and consequently @@ -259,7 +259,7 @@ More complex patterns of missing data can be specified using the period specifying multiple parameters that do not necessarily have the same index values: -.. literalinclude:: ../../tests/data/param3b.dat +.. literalinclude:: ../../src/data/param3b.dat :language: none This example provides a concise representation of parameters that share @@ -270,13 +270,13 @@ Note that this data file specifies the data for set ``A`` twice: defined. An alternate syntax for ``param`` allows the user to concisely specify the definition of an index set along with associated parameters: -.. literalinclude:: ../../tests/data/param3c.dat +.. literalinclude:: ../../src/data/param3c.dat :language: none Finally, we note that default values for missing data can also be specified using the ``default`` keyword: -.. literalinclude:: ../../tests/data/param4.dat +.. literalinclude:: ../../src/data/param4.dat :language: none Note that default values can only be specified in ``param`` commands @@ -290,58 +290,58 @@ Multi-dimensional parameter data is indexed over either multiple sets or a single multi-dimensional set. Suppose that parameter ``B`` is a parameter indexed by set ``A`` that has dimension 2: -.. literalinclude:: ../../tests/data/param5_decl.spy +.. literalinclude:: ../../src/data/param5_decl.spy :language: python The syntax of the ``param`` data command remains essentially the same when specifying values for ``B`` with a list of index and parameter values: -.. literalinclude:: ../../tests/data/param5.dat +.. literalinclude:: ../../src/data/param5.dat :language: none Missing and default values are also handled in the same way with multi-dimensional index sets: -.. literalinclude:: ../../tests/data/param5a.dat +.. literalinclude:: ../../src/data/param5a.dat :language: none Similarly, multiple parameters can defined with a single ``param`` data command. Suppose that parameters ``B``, ``C``, and ``D`` are parameters indexed over set ``A`` that has dimension 2: -.. literalinclude:: ../../tests/data/param6_decl.spy +.. literalinclude:: ../../src/data/param6_decl.spy :language: python These parameters can be defined with a single ``param`` command that declares the parameter names followed by a list of index and parameter values: -.. literalinclude:: ../../tests/data/param6.dat +.. literalinclude:: ../../src/data/param6.dat :language: none Similarly, the following ``param`` data command defines the index set along with the parameters: -.. literalinclude:: ../../tests/data/param6a.dat +.. literalinclude:: ../../src/data/param6a.dat :language: none The ``param`` command also supports a matrix syntax for specifying the values in a parameter that has a 2-dimensional index. Suppose parameter ``B`` is indexed over set ``A`` that has dimension 2: -.. literalinclude:: ../../tests/data/param7a_decl.spy +.. literalinclude:: ../../src/data/param7a_decl.spy :language: python The following ``param`` command defines a matrix of parameter values: -.. literalinclude:: ../../tests/data/param7a.dat +.. literalinclude:: ../../src/data/param7a.dat :language: none Additionally, the following syntax can be used to specify a transposed matrix of parameter values: -.. literalinclude:: ../../tests/data/param7b.dat +.. literalinclude:: ../../src/data/param7b.dat :language: none This functionality facilitates the presentation of parameter data in a @@ -355,13 +355,13 @@ be specified as a series of slices. Each slice is defined by a template followed by a list of index and parameter values. Suppose that parameter ``B`` is indexed over set ``A`` that has dimension 4: -.. literalinclude:: ../../tests/data/param8a_decl.spy +.. literalinclude:: ../../src/data/param8a_decl.spy :language: python The following ``param`` command defines a matrix of parameter values with multiple templates: -.. literalinclude:: ../../tests/data/param8a.dat +.. literalinclude:: ../../src/data/param8a.dat :language: none The ``B`` parameter consists of four values: ``B[a,1,a,1]=10``, @@ -376,7 +376,7 @@ data declaration than is possible with a ``param`` declaration. The following example illustrates a simple ``table`` command that declares data for a single parameter: -.. literalinclude:: ../../tests/data/table0.dat +.. literalinclude:: ../../src/data/table0.dat :language: none The parameter ``M`` is indexed by column ``A``, which must be @@ -385,20 +385,20 @@ are provided after the colon and before the colon-equal (``:=``). Subsequently, the table data is provided. The syntax is not sensitive to whitespace, so the following is an equivalent ``table`` command: -.. literalinclude:: ../../tests/data/table1.dat +.. literalinclude:: ../../src/data/table1.dat :language: none Multiple parameters can be declared by simply including additional parameter names. For example: -.. literalinclude:: ../../tests/data/table2.dat +.. literalinclude:: ../../src/data/table2.dat :language: none This example declares data for the ``M`` and ``N`` parameters, which have different indexing columns. The indexing columns represent set data, which is specified separately. For example: -.. literalinclude:: ../../tests/data/table3.dat +.. literalinclude:: ../../src/data/table3.dat :language: none This example declares data for the ``M`` and ``N`` parameters, along @@ -406,12 +406,12 @@ with the ``A`` and ``Z`` indexing sets. The correspondence between the index set ``Z`` and the indices of parameter ``N`` can be made more explicit by indexing ``N`` by ``Z``: -.. literalinclude:: ../../tests/data/table4.dat +.. literalinclude:: ../../src/data/table4.dat :language: none Set data can also be specified independent of parameter data: -.. literalinclude:: ../../tests/data/table5.dat +.. literalinclude:: ../../src/data/table5.dat :language: none .. warning:: @@ -423,13 +423,13 @@ Set data can also be specified independent of parameter data: that is initialized. For example, the ``table`` command initializes a set ``Z`` and a parameter ``M`` that are not related: - .. literalinclude:: ../../tests/data/table7.dat + .. literalinclude:: ../../src/data/table7.dat :language: none Finally, simple parameter values can also be specified with a ``table`` command: -.. literalinclude:: ../../tests/data/table6.dat +.. literalinclude:: ../../src/data/table6.dat :language: none The previous examples considered examples of the ``table`` command where @@ -437,7 +437,7 @@ column labels are provided. The ``table`` command can also be used without column labels. For example, the first example can be revised to omit column labels as follows: -.. literalinclude:: ../../tests/data/table0.ul.dat +.. literalinclude:: ../../src/data/table0.ul.dat :language: none The ``columns=4`` is a keyword-value pair that defines the number of @@ -450,12 +450,12 @@ braces syntax declares the column where the ``M`` data is provided. Similarly, set data can be declared referencing the integer column labels: -.. literalinclude:: ../../tests/data/table3.ul.dat +.. literalinclude:: ../../src/data/table3.ul.dat :language: none Declared set names can also be used to index parameters: -.. literalinclude:: ../../tests/data/table4.ul.dat +.. literalinclude:: ../../src/data/table4.ul.dat :language: none Finally, we compare and contrast the ``table`` and ``param`` commands. @@ -521,13 +521,13 @@ Simple Load Examples The simplest illustration of the ``load`` command is specifying data for an indexed parameter. Consider the file ``Y.tab``: -.. literalinclude:: ../../tests/data/Y.tab +.. literalinclude:: ../../src/data/Y.tab :language: none This file specifies the values of parameter ``Y`` which is indexed by set ``A``. The following ``load`` command loads the parameter data: -.. literalinclude:: ../../tests/data/import1.tab.dat +.. literalinclude:: ../../src/data/import1.tab.dat :language: none The first argument is the filename. The options after the colon @@ -538,7 +538,7 @@ indicates the parameter that is initialized. Similarly, the following load command loads both the parameter data as well as the index set ``A``: -.. literalinclude:: ../../tests/data/import2.tab.dat +.. literalinclude:: ../../src/data/import2.tab.dat :language: none The difference is the specification of the index set, ``A=[A]``, which @@ -548,24 +548,24 @@ ASCII table file. Set data can also be loaded from a ASCII table file that contains a single column of data: -.. literalinclude:: ../../tests/data/A.tab +.. literalinclude:: ../../src/data/A.tab :language: none The ``format`` option must be specified to denote the fact that the relational data is being interpreted as a set: -.. literalinclude:: ../../tests/data/import3.tab.dat +.. literalinclude:: ../../src/data/import3.tab.dat :language: none Note that this allows for specifying set data that contains tuples. Consider file ``C.tab``: -.. literalinclude:: ../../tests/data/C.tab +.. literalinclude:: ../../src/data/C.tab :language: none A similar ``load`` syntax will load this data into set ``C``: -.. literalinclude:: ../../tests/data/import4.tab.dat +.. literalinclude:: ../../src/data/import4.tab.dat :language: none Note that this example requires that ``C`` be declared with dimension @@ -609,7 +609,7 @@ describes different specifications and how they define how data is loaded into a model. Suppose file ``ABCD.tab`` defines the following relational table: -.. literalinclude:: ../../tests/data/ABCD.tab +.. literalinclude:: ../../src/data/ABCD.tab :language: none There are many ways to interpret this relational table. It could @@ -621,7 +621,7 @@ for specifying how a table is interpreted. A simple specification is to interpret the relational table as a set: -.. literalinclude:: ../../tests/data/ABCD1.dat +.. literalinclude:: ../../src/data/ABCD1.dat :language: none Note that ``Z`` is a set in the model that the data is being loaded @@ -631,7 +631,7 @@ data from this table. Another simple specification is to interpret the relational table as a parameter with indexed by 3-tuples: -.. literalinclude:: ../../tests/data/ABCD2.dat +.. literalinclude:: ../../src/data/ABCD2.dat :language: none Again, this requires that ``D`` be a parameter in the model that the @@ -639,14 +639,14 @@ data is being loaded into. Additionally, the index set for ``D`` must contain the indices that are specified in the table. The ``load`` command also allows for the specification of the index set: -.. literalinclude:: ../../tests/data/ABCD3.dat +.. literalinclude:: ../../src/data/ABCD3.dat :language: none This specifies that the index set is loaded into the ``Z`` set in the model. Similarly, data can be loaded into another parameter than what is specified in the relational table: -.. literalinclude:: ../../tests/data/ABCD4.dat +.. literalinclude:: ../../src/data/ABCD4.dat :language: none This specifies that the index set is loaded into the ``Z`` set and that @@ -658,13 +658,13 @@ specification of data mappings from columns in a relational table into index sets and parameters. For example, suppose that a model is defined with set ``Z`` and parameters ``Y`` and ``W``: -.. literalinclude:: ../../tests/data/ABCD5_decl.spy +.. literalinclude:: ../../src/data/ABCD5_decl.spy :language: python Then the following command defines how these data items are loaded using columns ``B``, ``C`` and ``D``: -.. literalinclude:: ../../tests/data/ABCD5.dat +.. literalinclude:: ../../src/data/ABCD5.dat :language: none When the ``using`` option is omitted the data manager is inferred from @@ -672,13 +672,13 @@ the filename suffix. However, the filename suffix does not always reflect the format of the data it contains. For example, consider the relational table in the file ``ABCD.txt``: -.. literalinclude:: ../../tests/data/ABCD.txt +.. literalinclude:: ../../src/data/ABCD.txt :language: none We can specify the ``using`` option to load from this file into parameter ``D`` and set ``Z``: -.. literalinclude:: ../../tests/data/ABCD6.dat +.. literalinclude:: ../../src/data/ABCD6.dat :language: none .. note:: @@ -692,7 +692,7 @@ parameter ``D`` and set ``Z``: The following data managers are supported in Pyomo 5.1: - .. literalinclude:: ../../tests/data/data_managers.txt + .. literalinclude:: ../../src/data/data_managers.txt :language: none Interpreting Tabular Data @@ -725,12 +725,12 @@ A table with a single value can be interpreted as a simple parameter using the ``param`` format value. Suppose that ``Z.tab`` contains the following table: -.. literalinclude:: ../../tests/data/Z.tab +.. literalinclude:: ../../src/data/Z.tab :language: none The following load command then loads this value into parameter ``p``: -.. literalinclude:: ../../tests/data/import6.tab.dat +.. literalinclude:: ../../src/data/import6.tab.dat :language: none Sets with 2-tuple data can be represented with a matrix format that @@ -739,12 +739,12 @@ relational table as a matrix that defines a set of 2-tuples where ``+`` denotes a valid tuple and ``-`` denotes an invalid tuple. Suppose that ``D.tab`` contains the following relational table: -.. literalinclude:: ../../tests/data/D.tab +.. literalinclude:: ../../src/data/D.tab :language: none Then the following load command loads data into set ``B``: -.. literalinclude:: ../../tests/data/import5.tab.dat +.. literalinclude:: ../../src/data/import5.tab.dat :language: none This command declares the following 2-tuples: ``('A1',1)``, @@ -754,19 +754,19 @@ Parameters with 2-tuple indices can be interpreted with a matrix format that where rows and columns are different indices. Suppose that ``U.tab`` contains the following table: -.. literalinclude:: ../../tests/data/U.tab +.. literalinclude:: ../../src/data/U.tab :language: none Then the following load command loads this value into parameter ``U`` with a 2-dimensional index using the ``array`` format value.: -.. literalinclude:: ../../tests/data/import7.tab.dat +.. literalinclude:: ../../src/data/import7.tab.dat :language: none The ``transpose_array`` format value also interprets the table as a matrix, but it loads the data in a transposed format: -.. literalinclude:: ../../tests/data/import8.tab.dat +.. literalinclude:: ../../src/data/import8.tab.dat :language: none Note that these format values do not support the initialization of the @@ -789,7 +789,7 @@ in the following figure: The following command loads this data to initialize parameter ``D`` and index ``Z``: -.. literalinclude:: ../../tests/data/ABCD7.dat +.. literalinclude:: ../../src/data/ABCD7.dat :language: none Thus, the syntax for loading data from spreadsheets only differs from @@ -809,7 +809,7 @@ command loads data from the Excel spreadsheet ``ABCD.xls`` using the ``pyodbc`` interface. The command loads this data to initialize parameter ``D`` and index ``Z``: -.. literalinclude:: ../../tests/data/ABCD8.dat +.. literalinclude:: ../../src/data/ABCD8.dat :language: none The ``using`` option specifies that the ``pyodbc`` package will be @@ -818,7 +818,7 @@ specifies that the table ``ABCD`` is loaded from this spreadsheet. Similarly, the following command specifies a data connection string to specify the ODBC driver explicitly: -.. literalinclude:: ../../tests/data/ABCD9.dat +.. literalinclude:: ../../src/data/ABCD9.dat :language: none ODBC drivers are generally tailored to the type of data source that @@ -836,7 +836,7 @@ task of minimizing the cost for a meal at a fast food restaurant -- they must purchase a sandwich, side, and a drink for the lowest cost. The following is a Pyomo model for this problem: -.. literalinclude:: ../../tests/data/diet1.py +.. literalinclude:: ../../src/data/diet1.py :language: python Suppose that the file ``diet1.sqlite`` be a SQLite database file that @@ -884,7 +884,7 @@ We can solve the ``diet1`` model using the Python definition in ``diet.sqlite.dat`` specifies a ``load`` command that uses that ``sqlite3`` data manager and embeds a SQL query to retrieve the data: -.. literalinclude:: ../../tests/data/diet.sqlite.dat +.. literalinclude:: ../../src/data/diet.sqlite.dat :language: none The PyODBC driver module will pass the SQL query through an Access ODBC @@ -904,7 +904,7 @@ The ``include`` command allows a data command file to execute data commands from another file. For example, the following command file executes data commands from ``ex1.dat`` and then ``ex2.dat``: -.. literalinclude:: ../../tests/data/ex.dat +.. literalinclude:: ../../src/data/ex.dat :language: none Pyomo is sensitive to the order of execution of data commands, since @@ -921,7 +921,7 @@ to structure the specification of Pyomo's data commands. Specifically, a namespace declaration is used to group data commands and to provide a group label. Consider the following data command file: -.. literalinclude:: ../../tests/data/namespace1.dat +.. literalinclude:: ../../src/data/namespace1.dat :language: none This data file defines two namespaces: ``ns1`` and ``ns2`` that diff --git a/doc/OnlineDocs/working_abstractmodels/data/native.rst b/doc/OnlineDocs/working_abstractmodels/data/native.rst index 2a52c8356aa..ed92d78d78e 100644 --- a/doc/OnlineDocs/working_abstractmodels/data/native.rst +++ b/doc/OnlineDocs/working_abstractmodels/data/native.rst @@ -34,29 +34,29 @@ can be initialized with: * list, set and tuple data: - .. literalinclude:: ../../tests/dataportal/set_initialization_decl2.spy + .. literalinclude:: ../../src/dataportal/set_initialization_decl2.spy :language: python * generators: - .. literalinclude:: ../../tests/dataportal/set_initialization_decl3.spy + .. literalinclude:: ../../src/dataportal/set_initialization_decl3.spy :language: python * numpy arrays: - .. literalinclude:: ../../tests/dataportal/set_initialization_decl4.spy + .. literalinclude:: ../../src/dataportal/set_initialization_decl4.spy :language: python Sets can also be indirectly initialized with functions that return native Python data: -.. literalinclude:: ../../tests/dataportal/set_initialization_decl5.spy +.. literalinclude:: ../../src/dataportal/set_initialization_decl5.spy :language: python Indexed sets can be initialized with dictionary data where the dictionary values are iterable data: -.. literalinclude:: ../../tests/dataportal/set_initialization_decl6.spy +.. literalinclude:: ../../src/dataportal/set_initialization_decl6.spy :language: python @@ -66,19 +66,19 @@ Parameter Components When a parameter is a single value, then a :class:`~pyomo.environ.Param` component can be simply initialized with a value: -.. literalinclude:: ../../tests/dataportal/param_initialization_decl1.spy +.. literalinclude:: ../../src/dataportal/param_initialization_decl1.spy :language: python More generally, :class:`~pyomo.environ.Param` components can be initialized with dictionary data where the dictionary values are single values: -.. literalinclude:: ../../tests/dataportal/param_initialization_decl2.spy +.. literalinclude:: ../../src/dataportal/param_initialization_decl2.spy :language: python Parameters can also be indirectly initialized with functions that return native Python data: -.. literalinclude:: ../../tests/dataportal/param_initialization_decl3.spy +.. literalinclude:: ../../src/dataportal/param_initialization_decl3.spy :language: python diff --git a/doc/OnlineDocs/working_abstractmodels/pyomo_command.rst b/doc/OnlineDocs/working_abstractmodels/pyomo_command.rst index 1d22798d8ce..aabfc8667f7 100644 --- a/doc/OnlineDocs/working_abstractmodels/pyomo_command.rst +++ b/doc/OnlineDocs/working_abstractmodels/pyomo_command.rst @@ -90,7 +90,7 @@ When there seem to be troubles expressing the model, it is often useful to embed print commands in the model in places that will yield helpful information. Consider the following snippet: -.. literalinclude:: ../tests/scripting/spy4PyomoCommand_Troubleshooting_printed_command.spy +.. literalinclude:: ../src/scripting/spy4PyomoCommand_Troubleshooting_printed_command.spy :language: python The effect will be to output every member of the set ``model.I`` at the diff --git a/doc/OnlineDocs/working_models.rst b/doc/OnlineDocs/working_models.rst index 2b9b664c548..dbd7aa383e3 100644 --- a/doc/OnlineDocs/working_models.rst +++ b/doc/OnlineDocs/working_models.rst @@ -58,7 +58,7 @@ computer to solve the problem or even to iterate over solutions. This example is provided just to illustrate some elementary aspects of scripting. -.. literalinclude:: tests/scripting/iterative1.spy +.. literalinclude:: src/scripting/iterative1.spy :language: python Let us now analyze this script. The first line is a comment that happens @@ -66,7 +66,7 @@ to give the name of the file. This is followed by two lines that import symbols for Pyomo. The pyomo namespace is imported as ``pyo``. Therefore, ``pyo.`` must precede each use of a Pyomo name. -.. literalinclude:: tests/scripting/iterative1_Import_symbols_for_pyomo.spy +.. literalinclude:: src/scripting/iterative1_Import_symbols_for_pyomo.spy :language: python An object to perform optimization is created by calling @@ -74,7 +74,7 @@ An object to perform optimization is created by calling argument would be ``'gurobi'`` if, e.g., Gurobi was desired instead of glpk: -.. literalinclude:: tests/scripting/iterative1_Call_SolverFactory_with_argument.spy +.. literalinclude:: src/scripting/iterative1_Call_SolverFactory_with_argument.spy :language: python The next lines after a comment create a model. For our discussion here, @@ -86,13 +86,13 @@ to keep it simple. Constraints could be present in the base model. Even though it is an abstract model, the base model is fully specified by these commands because it requires no external data: -.. literalinclude:: tests/scripting/iterative1_Create_base_model.spy +.. literalinclude:: src/scripting/iterative1_Create_base_model.spy :language: python The next line is not part of the base model specification. It creates an empty constraint list that the script will use to add constraints. -.. literalinclude:: tests/scripting/iterative1_Create_empty_constraint_list.spy +.. literalinclude:: src/scripting/iterative1_Create_empty_constraint_list.spy :language: python The next non-comment line creates the instantiated model and refers to @@ -103,19 +103,19 @@ the ``create`` function is called without arguments because none are needed; however, the name of a file with data commands is given as an argument in many scripts. -.. literalinclude:: tests/scripting/iterative1_Create_instantiated_model.spy +.. literalinclude:: src/scripting/iterative1_Create_instantiated_model.spy :language: python The next line invokes the solver and refers to the object contain results with the Python variable ``results``. -.. literalinclude:: tests/scripting/iterative1_Solve_and_refer_to_results.spy +.. literalinclude:: src/scripting/iterative1_Solve_and_refer_to_results.spy :language: python The solve function loads the results into the instance, so the next line writes out the updated values. -.. literalinclude:: tests/scripting/iterative1_Display_updated_value.spy +.. literalinclude:: src/scripting/iterative1_Display_updated_value.spy :language: python The next non-comment line is a Python iteration command that will @@ -123,7 +123,7 @@ successively assign the integers from 0 to 4 to the Python variable ``i``, although that variable is not used in script. This loop is what causes the script to generate five more solutions: -.. literalinclude:: tests/scripting/iterative1_Assign_integers.spy +.. literalinclude:: src/scripting/iterative1_Assign_integers.spy :language: python An expression is built up in the Python variable named ``expr``. The @@ -135,7 +135,7 @@ zero and the expression in ``expr`` is augmented accordingly. Although Pyomo expression when it is assigned expressions involving Pyomo variable objects: -.. literalinclude:: tests/scripting/iterative1_Iteratively_assign_and_test.spy +.. literalinclude:: src/scripting/iterative1_Iteratively_assign_and_test.spy :language: python During the first iteration (when ``i`` is 0), we know that all values of @@ -159,7 +159,7 @@ function to get it. The next line adds to the constraint list called ``c`` the requirement that the expression be greater than or equal to one: -.. literalinclude:: tests/scripting/iterative1_Add_expression_constraint.spy +.. literalinclude:: src/scripting/iterative1_Add_expression_constraint.spy :language: python The proof that this precludes the last solution is left as an exerise @@ -167,7 +167,7 @@ for the reader. The final lines in the outer for loop find a solution and display it: -.. literalinclude:: tests/scripting/iterative1_Find_and_display_solution.spy +.. literalinclude:: src/scripting/iterative1_Find_and_display_solution.spy :language: python .. note:: @@ -268,14 +268,14 @@ Fixing Variables and Re-solving Instead of changing model data, scripts are often used to fix variable values. The following example illustrates this. -.. literalinclude:: tests/scripting/iterative2.spy +.. literalinclude:: src/scripting/iterative2.spy :language: python In this example, the variables are binary. The model is solved and then the value of ``model.x[2]`` is flipped to the opposite value before solving the model again. The main lines of interest are: -.. literalinclude:: tests/scripting/iterative2_Flip_value_before_solve_again.spy +.. literalinclude:: src/scripting/iterative2_Flip_value_before_solve_again.spy :language: python This could also have been accomplished by setting the upper and lower @@ -430,7 +430,7 @@ Consider the following very simple example, which is similar to the iterative example. This is a concrete model. In this example, the value of ``x[2]`` is accessed. -.. literalinclude:: tests/scripting/noiteration1.py +.. literalinclude:: src/scripting/noiteration1.py :language: python .. note:: @@ -476,7 +476,7 @@ Another way to access all of the variables (particularly if there are blocks) is as follows (this particular snippet assumes that instead of `import pyomo.environ as pyo` `from pyo.environ import *` was used): -.. literalinclude:: tests/scripting/block_iter_example_compprintloop.spy +.. literalinclude:: src/scripting/block_iter_example_compprintloop.spy :language: python .. _ParamAccess: @@ -521,21 +521,21 @@ To signal that duals are desired, declare a Suffix component with the name "dual" on the model or instance with an IMPORT or IMPORT_EXPORT direction. -.. literalinclude:: tests/scripting/driveabs2_Create_dual_suffix_component.spy +.. literalinclude:: src/scripting/driveabs2_Create_dual_suffix_component.spy :language: python See the section on Suffixes :ref:`Suffixes` for more information on Pyomo's Suffix component. After the results are obtained and loaded into an instance, duals can be accessed in the following fashion. -.. literalinclude:: tests/scripting/driveabs2_Access_all_dual.spy +.. literalinclude:: src/scripting/driveabs2_Access_all_dual.spy :language: python The following snippet will only work, of course, if there is a constraint with the name ``AxbConstraint`` that has and index, which is the string ``Film``. -.. literalinclude:: tests/scripting/driveabs2_Access_one_dual.spy +.. literalinclude:: src/scripting/driveabs2_Access_one_dual.spy :language: python Here is a complete example that relies on the file ``abstract2.py`` to @@ -544,14 +544,14 @@ data. Note that the model in ``abstract2.py`` does contain a constraint named ``AxbConstraint`` and ``abstract2.dat`` does specify an index for it named ``Film``. -.. literalinclude:: tests/scripting/driveabs2.spy +.. literalinclude:: src/scripting/driveabs2.spy :language: python Concrete models are slightly different because the model is the instance. Here is a complete example that relies on the file ``concrete1.py`` to provide the model and instantiate it. -.. literalinclude:: tests/scripting/driveconc1.py +.. literalinclude:: src/scripting/driveconc1.py :language: python Accessing Slacks @@ -568,7 +568,7 @@ After a solve, the results object has a member ``Solution.Status`` that contains the solver status. The following snippet shows an example of access via a ``print`` statement: -.. literalinclude:: tests/scripting/spy4scripts_Print_solver_status.spy +.. literalinclude:: src/scripting/spy4scripts_Print_solver_status.spy :language: python The use of the Python ``str`` function to cast the value to a be string @@ -576,12 +576,12 @@ makes it easy to test it. In particular, the value 'optimal' indicates that the solver succeeded. It is also possible to access Pyomo data that can be compared with the solver status as in the following code snippet: -.. literalinclude:: tests/scripting/spy4scripts_Pyomo_data_comparedwith_solver_status_1.spy +.. literalinclude:: src/scripting/spy4scripts_Pyomo_data_comparedwith_solver_status_1.spy :language: python Alternatively, -.. literalinclude:: tests/scripting/spy4scripts_Pyomo_data_comparedwith_solver_status_2.spy +.. literalinclude:: src/scripting/spy4scripts_Pyomo_data_comparedwith_solver_status_2.spy :language: python .. _TeeTrue: @@ -592,7 +592,7 @@ Display of Solver Output To see the output of the solver, use the option ``tee=True`` as in -.. literalinclude:: tests/scripting/spy4scripts_See_solver_output.spy +.. literalinclude:: src/scripting/spy4scripts_See_solver_output.spy :language: python This can be useful for troubleshooting solver difficulties. @@ -607,7 +607,7 @@ solver. In scripts or callbacks, the options can be attached to the solver object by adding to its options dictionary as illustrated by this snippet: -.. literalinclude:: tests/scripting/spy4scripts_Add_option_to_solver.spy +.. literalinclude:: src/scripting/spy4scripts_Add_option_to_solver.spy :language: python If multiple options are needed, then multiple dictionary entries should @@ -616,7 +616,7 @@ be added. Sometimes it is desirable to pass options as part of the call to the solve function as in this snippet: -.. literalinclude:: tests/scripting/spy4scripts_Add_multiple_options_to_solver.spy +.. literalinclude:: src/scripting/spy4scripts_Add_multiple_options_to_solver.spy :language: python The quoted string is passed directly to the solver. If multiple options @@ -644,7 +644,7 @@ situations where they are not, the SolverFactory function accepts the keyword ``executable``, which you can use to set an absolute or relative path to a solver executable. E.g., -.. literalinclude:: tests/scripting/spy4scripts_Set_path_to_solver_executable.spy +.. literalinclude:: src/scripting/spy4scripts_Set_path_to_solver_executable.spy :language: python Warm Starts @@ -654,7 +654,7 @@ Some solvers support a warm start based on current values of variables. To use this feature, set the values of variables in the instance and pass ``warmstart=True`` to the ``solve()`` method. E.g., -.. literalinclude:: tests/scripting/spy4scripts_Pass_warmstart_to_solver.spy +.. literalinclude:: src/scripting/spy4scripts_Pass_warmstart_to_solver.spy :language: python .. note:: @@ -686,7 +686,7 @@ parallel. The example can be run with the following command: mpirun -np 2 python -m mpi4py parallel.py -.. literalinclude:: tests/scripting/parallel.py +.. literalinclude:: src/scripting/parallel.py :language: python @@ -700,5 +700,5 @@ The pyomo command-line ``--tempdir`` option propagates through to the TempFileManager service. One can accomplish the same through the following few lines of code in a script: -.. literalinclude:: tests/scripting/spy4scripts_Specify_temporary_directory_name.spy +.. literalinclude:: src/scripting/spy4scripts_Specify_temporary_directory_name.spy :language: python From 63a09a986341b3914a15887663b494b5fc32b8fa Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 14:17:30 -0700 Subject: [PATCH 25/26] Add testing of gather files, test drivers, and baseline updater --- pyomo/common/tests/test_unittest.py | 146 +++++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 11 deletions(-) diff --git a/pyomo/common/tests/test_unittest.py b/pyomo/common/tests/test_unittest.py index ef97e73d062..882b5601552 100644 --- a/pyomo/common/tests/test_unittest.py +++ b/pyomo/common/tests/test_unittest.py @@ -11,11 +11,14 @@ import datetime import multiprocessing -from io import StringIO +import os import time +from io import StringIO import pyomo.common.unittest as unittest from pyomo.common.log import LoggingIntercept +from pyomo.common.tee import capture_output +from pyomo.common.tempfiles import TempfileManager from pyomo.environ import ConcreteModel, Var, Param @@ -296,17 +299,19 @@ def test_bound_function_require_fork(self): pass_ref = """ [ 0.00] Setting up Pyomo environment [ 0.00] Applying Pyomo preprocessing actions +WARNING: DEPRECATED: The Model.preprocess() method is deprecated and no longer + performs any actions (deprecated in 6.0) (called from :1) [ 0.00] Creating model -[ 0.00] Applying solver -[ 0.05] Processing results +[ 0.01] Applying solver +[ 0.06] Processing results Number of solutions: 1 Solution Information Gap: None Status: optimal Function Value: -0.00010001318188373491 Solver results file: results.yml -[ 0.05] Applying Pyomo postprocessing actions -[ 0.05] Pyomo Finished +[ 0.06] Applying Pyomo postprocessing actions +[ 0.06] Pyomo Finished # ========================================================== # = Solver Results = # ========================================================== @@ -357,16 +362,16 @@ def test_bound_function_require_fork(self): [ 0.00] Setting up Pyomo environment [ 0.00] Applying Pyomo preprocessing actions [ 0.00] Creating model -[ 0.00] Applying solver -[ 0.05] Processing results +[ 0.01] Applying solver +[ 0.06] Processing results Number of solutions: 1 Solution Information Gap: None Status: optimal Function Value: -0.00010001318188373491 Solver results file: results.yml -[ 0.05] Applying Pyomo postprocessing actions -[ 0.05] Pyomo Finished +[ 0.06] Applying Pyomo postprocessing actions +[ 0.06] Pyomo Finished # ========================================================== # = Solver Results = # ========================================================== @@ -422,11 +427,130 @@ def test_baseline_pass(self): self.compare_baseline(pass_ref, baseline, abstol=1e-6) with self.assertRaises(self.failureException): - self.compare_baseline(pass_ref, baseline, None) + with capture_output() as OUT: + self.compare_baseline(pass_ref, baseline, None) + self.assertEqual( + OUT.getvalue(), + f"""--------------------------------- +BASELINE FILE +--------------------------------- +{baseline} +================================= +--------------------------------- +TEST OUTPUT FILE +--------------------------------- +{pass_ref} +""", + ) def test_baseline_fail(self): with self.assertRaises(self.failureException): - self.compare_baseline(fail_ref, baseline) + with capture_output() as OUT: + self.compare_baseline(fail_ref, baseline) + self.assertEqual( + OUT.getvalue(), + f"""--------------------------------- +BASELINE FILE +--------------------------------- +{baseline} +================================= +--------------------------------- +TEST OUTPUT FILE +--------------------------------- +{fail_ref} +""", + ) + + def test_testcase_collection(self): + with TempfileManager.new_context() as TMP: + tmpdir = TMP.create_tempdir() + for fname in ( + 'a.py', + 'b.py', + 'b.txt', + 'c.py', + 'c.sh', + 'c.yml', + 'd.sh', + 'd.yml', + 'e.sh', + ): + with open(os.path.join(tmpdir, fname), 'w'): + pass + + py_tests, sh_tests = unittest.BaselineTestDriver.gather_tests([tmpdir]) + self.assertEqual( + py_tests, + [ + ( + os.path.basename(tmpdir) + '_b', + os.path.join(tmpdir, 'b.py'), + os.path.join(tmpdir, 'b.txt'), + ) + ], + ) + self.assertEqual( + sh_tests, + [ + ( + os.path.basename(tmpdir) + '_c', + os.path.join(tmpdir, 'c.sh'), + os.path.join(tmpdir, 'c.yml'), + ), + ( + os.path.basename(tmpdir) + '_d', + os.path.join(tmpdir, 'd.sh'), + os.path.join(tmpdir, 'd.txt'), + ), + ], + ) + + self.python_test_driver(*py_tests[0]) + + _update_baselines = os.environ.pop('PYOMO_TEST_UPDATE_BASELINES', None) + try: + with open(os.path.join(tmpdir, 'b.py'), 'w') as FILE: + FILE.write('print("Hello, World")\n') + + with self.assertRaises(self.failureException): + self.python_test_driver(*py_tests[0]) + with open(os.path.join(tmpdir, 'b.txt'), 'r') as FILE: + self.assertEqual(FILE.read(), "") + + os.environ['PYOMO_TEST_UPDATE_BASELINES'] = '1' + + with self.assertRaises(self.failureException): + self.python_test_driver(*py_tests[0]) + with open(os.path.join(tmpdir, 'b.txt'), 'r') as FILE: + self.assertEqual(FILE.read(), "Hello, World\n") + + finally: + os.environ.pop('PYOMO_TEST_UPDATE_BASELINES', None) + if _update_baselines is not None: + os.environ['PYOMO_TEST_UPDATE_BASELINES'] = _update_baselines + + self.shell_test_driver(*sh_tests[1]) + _update_baselines = os.environ.pop('PYOMO_TEST_UPDATE_BASELINES', None) + try: + with open(os.path.join(tmpdir, 'd.sh'), 'w') as FILE: + FILE.write('echo "Hello, World"\n') + + with self.assertRaises(self.failureException): + self.shell_test_driver(*sh_tests[1]) + with open(os.path.join(tmpdir, 'd.txt'), 'r') as FILE: + self.assertEqual(FILE.read(), "") + + os.environ['PYOMO_TEST_UPDATE_BASELINES'] = '1' + + with self.assertRaises(self.failureException): + self.shell_test_driver(*sh_tests[1]) + with open(os.path.join(tmpdir, 'd.txt'), 'r') as FILE: + self.assertEqual(FILE.read(), "Hello, World\n") + + finally: + os.environ.pop('PYOMO_TEST_UPDATE_BASELINES', None) + if _update_baselines is not None: + os.environ['PYOMO_TEST_UPDATE_BASELINES'] = _update_baselines if __name__ == '__main__': From ba5f5f20a702ec4ff904b9e3d45caf2261a52141 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 12 Jan 2024 16:14:57 -0700 Subject: [PATCH 26/26] Fix typo in test --- pyomo/common/tests/test_unittest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/common/tests/test_unittest.py b/pyomo/common/tests/test_unittest.py index 882b5601552..e3779e6f86e 100644 --- a/pyomo/common/tests/test_unittest.py +++ b/pyomo/common/tests/test_unittest.py @@ -472,7 +472,7 @@ def test_testcase_collection(self): 'c.sh', 'c.yml', 'd.sh', - 'd.yml', + 'd.txt', 'e.sh', ): with open(os.path.join(tmpdir, fname), 'w'):