{"id":16518551,"url":"https://github.com/willu47/amply","last_synced_at":"2025-04-30T05:20:47.304Z","repository":{"id":41874909,"uuid":"251601139","full_name":"willu47/amply","owner":"willu47","description":"A Python package for AMPL/GMPL datafile parsing","archived":false,"fork":false,"pushed_at":"2024-06-13T04:35:15.000Z","size":68,"stargazers_count":16,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T13:01:48.377Z","etag":null,"topics":["ampl","coin-or","gmpl","linear-programming"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willu47.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-31T12:49:20.000Z","updated_at":"2025-03-30T00:14:36.000Z","dependencies_parsed_at":"2024-06-19T01:52:48.084Z","dependency_job_id":"ade72934-5801-4f17-b1d6-02475f463929","html_url":"https://github.com/willu47/amply","commit_stats":{"total_commits":63,"total_committers":6,"mean_commits":10.5,"dds":"0.15873015873015872","last_synced_commit":"47db97130c2d9a37b1b97daa9d9699d94e1ed165"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willu47%2Famply","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willu47%2Famply/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willu47%2Famply/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willu47%2Famply/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willu47","download_url":"https://codeload.github.com/willu47/amply/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251645772,"owners_count":21620810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ampl","coin-or","gmpl","linear-programming"],"created_at":"2024-10-11T16:36:36.656Z","updated_at":"2025-04-30T05:20:47.284Z","avatar_url":"https://github.com/willu47.png","language":"Python","readme":"Amply\n======\n\n.. image:: https://travis-ci.com/willu47/amply.svg?branch=master\n    :target: https://travis-ci.com/willu47/amply\n.. image:: https://img.shields.io/pypi/v/amply?style=plastic\n     :alt: PyPI\n     :target: https://pypi.org/project/amply/\n.. image:: https://coveralls.io/repos/github/willu47/amply/badge.svg?branch=master\n    :target: https://coveralls.io/github/willu47/amply?branch=master\n\n\nIntroduction\n------------\n\nAmply allows you to load and manipulate AMPL data as Python data structures.\n\nAmply only supports a specific subset of the AMPL syntax:\n\n* set declarations\n* set data statements\n* parameter declarations\n* parameter data statements\n\nDeclarations and data statements\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypically, problems expressed in AMPL consist of two parts, a *model* section and a *data* section.\nAmply is only designed to parse the parameter and set statements contained within AMPL data sections.\nHowever, in order to parse these statements correctly, information that would usually be contained\nwithin the model section may be required. For instance, it may not be possible to infer the dimension\nof a set purely from its data statement. Therefore, Amply also supports set and parameter declarations.\nThese do not have to be put in a separate section, they only need to occur before the corresponding\ndata statement.\n\n\nThe declaration syntax supported is extremely limited, and does not include most\nelements of the AMPL programming language. The intention is that this library\nis used as a way of loading data specified in an AMPL-like syntax.\n\nFurthermore, Amply does not perform any validation on data statements.\n\nAbout this document\n^^^^^^^^^^^^^^^^^^^^\n\nThis document is intended as a guide to the syntax supported by Amply, and not as a general\nAMPL reference manual. For more in depth coverage see the `GNU MathProg manual, Chapter 5: Model data\n\u003chttp://gusek.sourceforge.net/gmpl.pdf\u003e`_ or the following links:\n\n* `Sets in AMPL \u003chttp://twiki.esc.auckland.ac.nz/twiki/bin/view/OpsRes/SetsInAMPL\u003e`_\n* `Parameters in AMPL \u003chttp://twiki.esc.auckland.ac.nz/twiki/bin/view/OpsRes/ParametersInAMPL\u003e`_\n\nQuickstart Guide\n----------------\n\n  \u003e\u003e\u003e from amply import Amply\n\nImport the class: ::\n\n  \u003e\u003e\u003e from amply import Amply\n\nA simple set. Sets behave a lot like lists.\n\n  \u003e\u003e\u003e data = Amply(\"set CITIES := Auckland Wellington Christchurch;\")\n  \u003e\u003e\u003e print data.CITIES\n  \u003cSetObject: ['Auckland', 'Wellington', 'Christchurch']\u003e\n  \u003e\u003e\u003e print data['CITIES']\n  \u003cSetObject: ['Auckland', 'Wellington', 'Christchurch']\u003e\n  \u003e\u003e\u003e for c in data.CITIES: print c\n  ...\n  Auckland\n  Wellington\n  Christchurch\n  \u003e\u003e\u003e print data.CITIES[0]\n  Auckland\n  \u003e\u003e\u003e print len(data.CITIES)\n  3\n\n\nData can be integers, reals, symbolic, or quoted strings:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ...   set BitsNPieces := 0 3.2 -6e4 Hello \"Hello, World!\";\n  ... \"\"\")\n  \u003e\u003e\u003e print data.BitsNPieces\n  \u003cSetObject: [0.0, 3.2000000000000002, -60000.0, 'Hello', 'Hello, World!']\u003e\n\nSets can contain multidimensional data, but we have to declare them to be so first.\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... set pairs dimen 2;\n  ... set pairs := (1, 2) (2, 3) (3, 4);\n  ... \"\"\")\n  \u003e\u003e\u003e print data.pairs\n  \u003cSetObject: [(1, 2), (2, 3), (3, 4)]\u003e\n\nSets themselves can be multidimensional (i.e. be subscriptable):\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... set CITIES{COUNTRIES};\n  ... set CITIES[Australia] := Adelaide Melbourne Sydney;\n  ... set CITIES[Italy] := Florence Milan Rome;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.CITIES['Australia']\n  ['Adelaide', 'Melbourne', 'Sydney']\n  \u003e\u003e\u003e print data.CITIES['Italy']\n  ['Florence', 'Milan', 'Rome']\n\nNote that in the above example, the set COUNTRIES didn't actually have to exist itself.\nAmply does not perform any validation on subscripts, it only uses them to figure out\nhow many subscripts a set has. To specify more than one, separate them by commas:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... set SUBURBS{COUNTRIES, CITIES};\n  ... set SUBURBS[Australia, Melbourne] := Docklands 'South Wharf' Kensington;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.SUBURBS['Australia', 'Melbourne']\n  ['Docklands', 'South Wharf', 'Kensington']\n\n*Slices* can be used to simplify the entry of multi-dimensional data.\n\n  \u003e\u003e\u003e data=Amply(\"\"\"\n  ... set TRIPLES dimen 3;\n  ... set TRIPLES := (1, 1, *) 2 3 4 (*, 2, *) 6 7 8 9 (*, *, *) (1, 1, 1);\n  ... \"\"\")\n  \u003e\u003e\u003e print data.TRIPLES\n  \u003cSetObject: [(1, 1, 2), (1, 1, 3), (1, 1, 4), (6, 2, 7), (8, 2, 9), (1, 1, 1)]\u003e\n  \u003e\n\nSet data can also be specified using a matrix notation.\nA '+' indicates that the pair is included in the set whereas a '-' indicates a\npair not in the set.\n\n  \u003e\u003e\u003e data=Amply(\"\"\"\n  ... set ROUTES dimen 2;\n  ... set ROUTES : A B C D :=\n  ...            E + - - +\n  ...            F + + - -\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.ROUTES\n  \u003cSetObject: [('E', 'A'), ('E', 'D'), ('F', 'A'), ('F', 'B')]\u003e\n\nMatrices can also be transposed:\n\n  \u003e\u003e\u003e data=Amply(\"\"\"\n  ... set ROUTES dimen 2;\n  ... set ROUTES (tr) : E F :=\n  ...                 A + +\n  ...                 B - +\n  ...                 C - -\n  ...                 D + -\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.ROUTES\n  \u003cSetObject: [('E', 'A'), ('F', 'A'), ('F', 'B'), ('E', 'D')]\u003e\n\nMatrices only specify 2d data, however they can be combined with slices\nto define higher-dimensional data:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... set QUADS dimen 2;\n  ... set QUADS :=\n  ... (1, 1, *, *) : 2 3 4 :=\n  ...              2 + - +\n  ...              3 - + +\n  ... (1, 2, *, *) : 2 3 4 :=\n  ...              2 - + -\n  ...              3 + - -\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.QUADS\n  \u003cSetObject: [(1, 1, 2, 2), (1, 1, 2, 4), (1, 1, 3, 3), (1, 1, 3, 4), (1, 2, 2, 3), (1, 2, 3, 2)]\u003e\n\nParameters are also supported:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param T := 30;\n  ... param n := 5;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.T\n  30\n  \u003e\u003e\u003e print data.n\n  5\n\nParameters are commonly indexed over sets. No validation is done by Amply,\nand the sets do not have to exist. Parameter objects are represented\nas a mapping.\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{PRODUCTS};\n  ... param COSTS :=\n  ...   FISH 8.5\n  ...   CARROTS 2.4\n  ...   POTATOES 1.6\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS\n  \u003cParamObject: {'POTATOES': 1.6000000000000001, 'FISH': 8.5, 'CARROTS': 2.3999999999999999}\u003e\n  \u003e\u003e\u003e print data.COSTS['FISH']\n  8.5\n\nParameter data statements can include a *default* clause. If a '.' is included\nin the data, it is replaced with the default value:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{P};\n  ... param COSTS default 2 :=\n  ... F 2\n  ... E 1\n  ... D .\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS['D']\n  2.0\n\nParameter declarations can also have a default clause. For these parameters,\nany attempt to access the parameter for a key that has not been defined\nwill return the default value:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{P} default 42;\n  ... param COSTS :=\n  ... F 2\n  ... E 1\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS['DOES NOT EXIST']\n  42.0\n\nParameters can be indexed over multiple sets. The resulting values can be\naccessed by treating the parameter object as a nested dictionary, or by\nusing a tuple as an index:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{CITIES, PRODUCTS};\n  ... param COSTS :=\n  ...  Auckland FISH 5\n  ...  Auckland CHIPS 3\n  ...  Wellington FISH 4\n  ...  Wellington CHIPS 1\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS\n  \u003cParamObject: {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}\u003e\n  \u003e\u003e\u003e print data.COSTS['Wellington']['CHIPS'] # nested dict\n  1.0\n  \u003e\u003e\u003e print data.COSTS['Wellington', 'CHIPS'] # tuple as key\n  1.0\n\nParameters support a slice syntax similar to that of sets:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{CITIES, PRODUCTS};\n  ... param COSTS :=\n  ...  [Auckland, * ]\n  ...   FISH 5\n  ...   CHIPS 3\n  ...  [Wellington, * ]\n  ...   FISH 4\n  ...   CHIPS 1\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS\n  \u003cParamObject: {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}\u003e\n\n\n\nParameters indexed over two sets can also be specified in tabular format:\n\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{CITIES, PRODUCTS};\n  ... param COSTS: FISH CHIPS :=\n  ...  Auckland    5    3\n  ...  Wellington  4    1\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS\n  \u003cParamObject: {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}\u003e\n\nTabular data can also be transposed:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{CITIES, PRODUCTS};\n  ... param COSTS (tr): Auckland Wellington :=\n  ...            FISH   5        4\n  ...            CHIPS  3        1\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS\n  \u003cParamObject: {'Wellington': {'FISH': 4.0, 'CHIPS': 1.0}, 'Auckland': {'FISH': 5.0, 'CHIPS': 3.0}}\u003e\n\n\nSlices can be combined with tabular data for parameters indexed over more than\n2 sets:\n\n  \u003e\u003e\u003e data = Amply(\"\"\"\n  ... param COSTS{CITIES, PRODUCTS, SIZE};\n  ... param COSTS :=\n  ...  [Auckland, *, *] :   SMALL LARGE :=\n  ...                 FISH  5     9\n  ...                 CHIPS 3     5\n  ...  [Wellington, *, *] : SMALL LARGE :=\n  ...                 FISH  4     7\n  ...                 CHIPS 1     2\n  ... ;\n  ... \"\"\")\n  \u003e\u003e\u003e print data.COSTS\n  \u003cParamObject: {'Wellington': {'FISH': {'SMALL': 4.0, 'LARGE': 7.0}, 'CHIPS': {'SMALL': 1.0, 'LARGE': 2.0}}, 'Auckland': {'FISH': {'SMALL': 5.0, 'LARGE': 9.0}, '\n\n\nAPI\n---\n\nAll functionality is contained within the ``Amply`` class.\n\n.. class:: Amply(string=\"\")\n\n  load_string(string)\n\n    Parse string data.\n\n  load_file(file)\n\n    Parse contents of file or file-like object (has a read() method).\n\n  from_file(file)\n\n    Alternate constructor. Create Amply object from contents of file or file-like object.\n\n\nThe parsed data structures can then be accessed from an ``Amply`` object via\nattribute lookup (if the name of the symbol is a valid Python name) or item\nlookup. ::\n\n    from pulp import Amply\n\n    data = Amply(\"set CITIES := Auckland Hamilton Wellington\")\n\n    # attribute lookup\n    assert data.CITIES == ['Auckland', 'Hamilton', 'Wellington']\n\n    # item lookup\n    assert data['CITIES'] == data.CITIES\n\nNote that additional data may be loaded into an Amply object simply by calling\none of its methods. A common idiom might be to specify the set and parameter\ndeclarations within your Python script, then load the actual data from\nexternal files. ::\n\n    from pulp import Amply\n\n    data = Amply(\"\"\"\n      set CITIES;\n      set ROUTES dimen 2;\n      param COSTS{ROUTES};\n      param DISTANCES{ROUTES};\n    \"\"\")\n\n    for data_file in ('cities.dat', 'routes.dat', 'costs.dat', 'distances.dat'):\n        data.load_file(open(data_file))\n\n.. Commented out the below, not sure if we need it (incomplete)\n\n    Reference\n    ---------\n\n    Sets\n    ^^^^\n\n    Set declarations\n    ~~~~~~~~~~~~~~~~\n\n    A set declaration is an extremely limited version of set statements which are valid in AMPL models.\n    They determine the *subscript domain* and *data dimension* of the set. If not specified, the default\n    subscript domain is an empty set and the default dimension is 1.\n\n    .. productionlist::\n        set_def_stmt: \"set\" `name` [`subscript_domain`] [\"dimen\" `integer`] \";\"\n        subscript_domain: \"{\" `name` (\",\" `name`)* \"}\"\n\n    The following statment declares a set named \"countries\". ::\n\n        set countries;\n\n    The following statement declares a set named \"cities\" which is indexed over \"countries\". ::\n\n        set cities {countries};\n\n    The following declares a set named \"routes\" with 2d data. ::\n\n        set routes dimen 2;\n\n    Set data statements\n    ~~~~~~~~~~~~~~~~~~~~~\n\n    A set data statement is used to specify the members of a set. It consists of one or more\n    *data records*. There are four types of data records: simple data, slice records, matrix\n    data and transposed matrix data.\n\n    .. productionlist::\n        set_stmt: \"set\" `name` [`set_member`] `data_record`+ \";\"\n        data_record: `simple_data` | `set_slice_record` | `matrix_data` | `tr_matrix_data`\n\n    Simple Data\n    ############\n\n    A simple data record is an optionally comma-separated list of data values.\n\n    .. productionlist::\n        simple_data: `data` ([\",\"] `data`)*\n\n    For instance: ::\n\n        set CITIES := Auckland Hamilton 'Palmerston North' Wellington;\n\n    ::\n\n        set ROUTES dimen 2;\n        set ROUTES := (Auckland, Hamilton) (Auckland, Wellington);\n\n    Slice Records\n    ###############\n\n    Slice records are used to simplify the entry of multi-dimensional sets. They allow you to partially\n    specify the values of elements. A slice affects all data records that follow it (until a new slice\n    is specified).\n\n    .. productionlist::\n        set_slice_record: \"(\" `set_slice_component` (\",\" `set_slice_component`)* \")\"\n        set_slice_component: `number` | `symbol` | \"*\"\n\n    This is best demonstrated by some examples. The sets A and B are identical: ::\n\n        set A dimen 3;\n        set B dimen 3;\n\n        set A := (1, 2, 3) (1, 3, 2) (1, 4, 6) (1, 8, 8) (2, 1, 3) (2, 1, 1) (2, 1, 2);\n        set B := (1, *, *) (2, 3) (3, 2) (4, 6) (8, 8) (2, 1, *) 3 1 2;\n\n    The number of asterisks in a slice is called the *slice dimension*. Any data records that follow\n    are interpreted as being of the same dimension; the value is taken as the value of the slice with\n    the asterisks replaced with the value of the record.\n\n    Matrix records\n    ################\n\n    Matrix records are a convenient way of specifying 2-dimensional data. The data record looks like\n    a matrix with row and column headings, where the values are either '+' if the combination is in\n    the set, and '-' if the combination is not in the set. A common use-case is for defining the\n    set of arcs that exist between a set of nodes.\n\n    .. productionlist::\n        matrix_data: \":\" `matrix_columns` \":=\" `matrix_row`+\n        matrix_columns: `data`+\n        matrix_row: `data` (\"+\"|\"-\")+\n        tr_matrix_data: \"(tr)\" `matrix_data`\n\n    Matrices can also be transposed by including ``(tr)`` immediately preceding the record.\n\n    In the example below the sets A, B and C are identical: ::\n\n        set A dimen 2;\n        set B dimen 2;\n        set C dimen 2;\n\n        set A := (1, 1) (1, 3) (2, 2) (3, 1) (3, 2) (3, 3);\n        set B : 1 2 3 :=\n              1 + - +\n              2 - + -\n              3 + + +\n        ;\n        set C (tr) : 1 2 3 :=\n                   1 + - +\n                   2 - + +\n                   3 + - +\n        ;\n\n\n    Matrices can be used for sets with higher dimensions by placing them after 2 dimensional\n    slice records.\n\n\n    Set examples\n    ~~~~~~~~~~~~\n\n    Parameters\n    ^^^^^^^^^^^^\n\n    Plain Data\n    ~~~~~~~~~~~~~\n\n    Tabular data\n    ~~~~~~~~~~~~~~\n\n    Tabbing Data\n    ~~~~~~~~~~~~~~\n\nDevelopment Notes\n-----------------\n\nMany thanks to Johannes Ragam (@thet), former custodian of the \"amply\" project on PyPi.\nJohannes graciously transferred the project to this. Thanks!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillu47%2Famply","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillu47%2Famply","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillu47%2Famply/lists"}