nodemodel


Namenodemodel JSON
Version 0.1.4 PyPI version JSON
download
home_pageNone
SummaryGenerates and processes a graph based on a dictionary of functions, using the function names and their argument names to define the relationships.
upload_time2024-09-26 21:20:53
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords graph model node function relationship
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            nodemodel
=========

.. image:: https://github.com/krzysztof-pankow/nodemodel/actions/workflows/quality.yml/badge.svg
   :target: https://github.com/krzysztof-pankow/nodemodel/actions?query=workflow%3Atest

.. image:: https://codecov.io/github/krzysztof-pankow/nodemodel/graph/badge.svg?token=00PQHNZH4W
   :target: https://codecov.io/github/krzysztof-pankow/nodemodel

.. image:: https://readthedocs.org/projects/nodemodel/badge/?version=latest
   :target: https://nodemodel.readthedocs.io/en/latest/?badge=latest
   :alt: Documentation Status

.. image:: https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue
   :target: https://pypi.python.org/pypi/nodemodel


Nodemodel is a small Python package for generating and computing a graph based on a dictionary of functions. It uses the function names and their argument names to define relationships within the graph.

- **Source:** https://github.com/krzysztof-pankow/nodemodel
- **Tutorial:** https://nodemodel.readthedocs.io/en/latest

Main Features
-------------
- **Simple Interface** – Use a single class, ``Model``, to generate a graph of functions, and its method ``compute`` to compute the graph on a dictionary.
- **Organizes Your Code** – Add a ``@node`` decorator to your functions and load them with the ``load_nodes`` function for easy management.
- **Supports Conditional Functions** – Easily specify that the computation of a function depends on modified inputs or the modified results of other functions.
- **Lightweight** – ``nodemodel`` only depends on the ``networkx`` package; everything else is pure Python.
- **Efficient** – Avoids copying data and executes all functions iteratively to maximize performance.

Example: Basic
--------------

.. code-block:: python

   from nodemodel import Model

   # Define functions:
   def d(a):
       return a * 10

   def c(a, b):
       return a + b

   def b(y):
       return y + 1

   def a(x):
       return x + 1

   # Initialize the model with the defined functions
   m = Model({"a": a, "b": b, "c": c, "d": d})

   # Compute values for the given inputs
   result = m.compute({"x": 1, "y": 2})
   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'b': 3, 'd': 20, 'c': 5}

   # Compute only a part of the model
   result = m.submodel("d").compute({"x": 1, "y": 2})
   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'd': 20}

Example: Conditional functions
------------------------------

.. code-block:: python

   #"c" will be calculated with "x" forced to 100
   c.forced_nodes = {"x":100}

   #"d" will be calculated with "a" forced to "b"
   d.forced_nodes = {"a":("node","b")}

   # Reinitialize the model:
   m = Model({"a": a, "b": b, "c": c,"d": d})

   #Compute the model on a dictionary:
   result = m.compute({"x": 1, "y": 2})
   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'b': 3, 'c': 104, 'd': 30}

Please notice that only "c" and "d" values changed after computing the model.

Example: Node decorators
------------------------

Suppose we have the following file structure:

.. code-block:: text

   my_model/
   ├── __init__.py
   ├── c_and_d_code.py
   ├── a_and_b/
   │   ├── __init__.py
   │   └── a_and_b_code.py

We will place the example functions in these files:

**c_and_d_code.py**

.. code-block:: python

   from nodemodel import node

   @node(x=100)
   def c(a, b):
       return a + b

   @node(a=("node","b"))
   def d(a):
       return a * 10

**a_and_b_code.py**

.. code-block:: python

   from nodemodel import node

   @node
   def a(x):
       return x + 1

   @node
   def b(y):
       return y + 1

Now we can load and execute these functions using the `nodemodel` package:

.. code-block:: python

   from nodemodel import Model, load_nodes

   # Import all functions with a @node decorator from the "my_model" directory
   nodes = load_nodes("my_model")

   # Initialize the model with the loaded functions
   m = Model(nodes)

   #Compute the model on a dictionary:
   result = m.compute({"x": 1, "y": 2})
   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'b': 3, 'c': 104, 'd': 30}

Example: Using nodemodel with Pandas
------------------------------------

Nodemodel can be useful for working with different data structures.
For example, with `pandas` DataFrames:

.. code-block:: python

   import pandas as pd
   df = pd.DataFrame({"x": [1, 2, 3],"y": [2, 3, 4]})

   df = df.to_dict(orient="series")
   result = pd.DataFrame(m.compute(df))
   print(result)

      x  y  a  b    c   d
   0  1  2  2  3  104  30
   1  2  3  3  4  105  40
   2  3  4  4  5  106  50

Installation
------------
You can install `nodemodel` using `pip`:

.. code-block:: bash

   pip install nodemodel

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "nodemodel",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "graph, model, node, function, relationship",
    "author": null,
    "author_email": "Krzysztof Pankow <kpankow@dinga.ai>",
    "download_url": "https://files.pythonhosted.org/packages/e3/c6/81f60987cd0fe87958c1e4bd758daae27aea855ed7e99ef74dc448fb191a/nodemodel-0.1.4.tar.gz",
    "platform": null,
    "description": "nodemodel\n=========\n\n.. image:: https://github.com/krzysztof-pankow/nodemodel/actions/workflows/quality.yml/badge.svg\n   :target: https://github.com/krzysztof-pankow/nodemodel/actions?query=workflow%3Atest\n\n.. image:: https://codecov.io/github/krzysztof-pankow/nodemodel/graph/badge.svg?token=00PQHNZH4W\n   :target: https://codecov.io/github/krzysztof-pankow/nodemodel\n\n.. image:: https://readthedocs.org/projects/nodemodel/badge/?version=latest\n   :target: https://nodemodel.readthedocs.io/en/latest/?badge=latest\n   :alt: Documentation Status\n\n.. image:: https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue\n   :target: https://pypi.python.org/pypi/nodemodel\n\n\nNodemodel is a small Python package for generating and computing a graph based on a dictionary of functions. It uses the function names and their argument names to define relationships within the graph.\n\n- **Source:** https://github.com/krzysztof-pankow/nodemodel\n- **Tutorial:** https://nodemodel.readthedocs.io/en/latest\n\nMain Features\n-------------\n- **Simple Interface** \u2013 Use a single class, ``Model``, to generate a graph of functions, and its method ``compute`` to compute the graph on a dictionary.\n- **Organizes Your Code** \u2013 Add a ``@node`` decorator to your functions and load them with the ``load_nodes`` function for easy management.\n- **Supports Conditional Functions** \u2013 Easily specify that the computation of a function depends on modified inputs or the modified results of other functions.\n- **Lightweight** \u2013 ``nodemodel`` only depends on the ``networkx`` package; everything else is pure Python.\n- **Efficient** \u2013 Avoids copying data and executes all functions iteratively to maximize performance.\n\nExample: Basic\n--------------\n\n.. code-block:: python\n\n   from nodemodel import Model\n\n   # Define functions:\n   def d(a):\n       return a * 10\n\n   def c(a, b):\n       return a + b\n\n   def b(y):\n       return y + 1\n\n   def a(x):\n       return x + 1\n\n   # Initialize the model with the defined functions\n   m = Model({\"a\": a, \"b\": b, \"c\": c, \"d\": d})\n\n   # Compute values for the given inputs\n   result = m.compute({\"x\": 1, \"y\": 2})\n   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'b': 3, 'd': 20, 'c': 5}\n\n   # Compute only a part of the model\n   result = m.submodel(\"d\").compute({\"x\": 1, \"y\": 2})\n   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'd': 20}\n\nExample: Conditional functions\n------------------------------\n\n.. code-block:: python\n\n   #\"c\" will be calculated with \"x\" forced to 100\n   c.forced_nodes = {\"x\":100}\n\n   #\"d\" will be calculated with \"a\" forced to \"b\"\n   d.forced_nodes = {\"a\":(\"node\",\"b\")}\n\n   # Reinitialize the model:\n   m = Model({\"a\": a, \"b\": b, \"c\": c,\"d\": d})\n\n   #Compute the model on a dictionary:\n   result = m.compute({\"x\": 1, \"y\": 2})\n   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'b': 3, 'c': 104, 'd': 30}\n\nPlease notice that only \"c\" and \"d\" values changed after computing the model.\n\nExample: Node decorators\n------------------------\n\nSuppose we have the following file structure:\n\n.. code-block:: text\n\n   my_model/\n   \u251c\u2500\u2500 __init__.py\n   \u251c\u2500\u2500 c_and_d_code.py\n   \u251c\u2500\u2500 a_and_b/\n   \u2502   \u251c\u2500\u2500 __init__.py\n   \u2502   \u2514\u2500\u2500 a_and_b_code.py\n\nWe will place the example functions in these files:\n\n**c_and_d_code.py**\n\n.. code-block:: python\n\n   from nodemodel import node\n\n   @node(x=100)\n   def c(a, b):\n       return a + b\n\n   @node(a=(\"node\",\"b\"))\n   def d(a):\n       return a * 10\n\n**a_and_b_code.py**\n\n.. code-block:: python\n\n   from nodemodel import node\n\n   @node\n   def a(x):\n       return x + 1\n\n   @node\n   def b(y):\n       return y + 1\n\nNow we can load and execute these functions using the `nodemodel` package:\n\n.. code-block:: python\n\n   from nodemodel import Model, load_nodes\n\n   # Import all functions with a @node decorator from the \"my_model\" directory\n   nodes = load_nodes(\"my_model\")\n\n   # Initialize the model with the loaded functions\n   m = Model(nodes)\n\n   #Compute the model on a dictionary:\n   result = m.compute({\"x\": 1, \"y\": 2})\n   print(result)  # Output: {'x': 1, 'y': 2, 'a': 2, 'b': 3, 'c': 104, 'd': 30}\n\nExample: Using nodemodel with Pandas\n------------------------------------\n\nNodemodel can be useful for working with different data structures.\nFor example, with `pandas` DataFrames:\n\n.. code-block:: python\n\n   import pandas as pd\n   df = pd.DataFrame({\"x\": [1, 2, 3],\"y\": [2, 3, 4]})\n\n   df = df.to_dict(orient=\"series\")\n   result = pd.DataFrame(m.compute(df))\n   print(result)\n\n      x  y  a  b    c   d\n   0  1  2  2  3  104  30\n   1  2  3  3  4  105  40\n   2  3  4  4  5  106  50\n\nInstallation\n------------\nYou can install `nodemodel` using `pip`:\n\n.. code-block:: bash\n\n   pip install nodemodel\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Generates and processes a graph based on a dictionary of functions, using the function names and their argument names to define the relationships.",
    "version": "0.1.4",
    "project_urls": {
        "Homepage": "https://github.com/krzysztof-pankow/nodemodel",
        "Source": "https://github.com/krzysztof-pankow/nodemodel"
    },
    "split_keywords": [
        "graph",
        " model",
        " node",
        " function",
        " relationship"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "04f7eb2aa81ac26dbcd2ee89163a1ac106b3bd9a6d896a8fd14085a88bee67bb",
                "md5": "0af849d52b8e25ca237ca79fa3a792cb",
                "sha256": "e476695c7fe81f6065d7682096c766c13cae3178b06197eb7ae75a21ed7281a7"
            },
            "downloads": -1,
            "filename": "nodemodel-0.1.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0af849d52b8e25ca237ca79fa3a792cb",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 11630,
            "upload_time": "2024-09-26T21:20:52",
            "upload_time_iso_8601": "2024-09-26T21:20:52.197574Z",
            "url": "https://files.pythonhosted.org/packages/04/f7/eb2aa81ac26dbcd2ee89163a1ac106b3bd9a6d896a8fd14085a88bee67bb/nodemodel-0.1.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e3c681f60987cd0fe87958c1e4bd758daae27aea855ed7e99ef74dc448fb191a",
                "md5": "3ade2a7832bc4d88fdcc5021ce1227ca",
                "sha256": "fac1151d8841703ecda76874e17c582af5fae56ee6e2cebc78e7abd653f6d23e"
            },
            "downloads": -1,
            "filename": "nodemodel-0.1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "3ade2a7832bc4d88fdcc5021ce1227ca",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 14394,
            "upload_time": "2024-09-26T21:20:53",
            "upload_time_iso_8601": "2024-09-26T21:20:53.481242Z",
            "url": "https://files.pythonhosted.org/packages/e3/c6/81f60987cd0fe87958c1e4bd758daae27aea855ed7e99ef74dc448fb191a/nodemodel-0.1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-26 21:20:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "krzysztof-pankow",
    "github_project": "nodemodel",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "nodemodel"
}
        
Elapsed time: 3.74742s