-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
318 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
Examples | ||
======== | ||
|
||
|
||
A simple example | ||
---------------- | ||
|
||
To understand what dags does, let's look at a few functions | ||
that do simple calculations. | ||
|
||
.. code-block:: python | ||
def f(x, y): | ||
return x**2 + y**2 | ||
def g(y, z): | ||
return 0.5 * y * z | ||
def h(f, g): | ||
return g / f | ||
Combine with a single target | ||
---------------------------- | ||
|
||
|
||
Assume that we are interested in a function that calculates h, given x, y and z. | ||
|
||
We could hardcode this function as: | ||
|
||
.. code-block:: python | ||
def hardcoded_combined(x, y, z): | ||
_f = f(x, y) | ||
_g = g(y, z) | ||
return h(_f, _g) | ||
hardcoded_combined(x=1, y=2, z=3) | ||
.. code-block:: python | ||
0.6 | ||
Instead, we can use dags to construct the same function: | ||
|
||
.. code-block:: python | ||
from dags import concatenate_functions | ||
combined = concatenate_functions([h, f, g], targets="h") | ||
combined(x=1, y=2, z=3) | ||
.. code-block:: python | ||
0.6 | ||
Importantly, the order in which the functions are passed into ``concatenate_functions`` | ||
does not matter! | ||
|
||
|
||
Combine with multiple targets | ||
----------------------------- | ||
|
||
Assume that we want the same combined h function as before but we also need intermediate | ||
outputs. And we would like to have them as a dictionary. We can do this as follows: | ||
|
||
.. code-block:: python | ||
combined = concatenate_functions( | ||
[h, f, g], | ||
targets=["h", "f", "g"], | ||
return_type="dict", | ||
) | ||
combined(x=1, y=2, z=3) | ||
.. code-block:: python | ||
{"h": 0.6, "f": 5, "g": 3.0} | ||
Renaming the output of a function | ||
--------------------------------- | ||
|
||
So far, the name of the output of the function was determined from the ``__name__`` | ||
attribute of each function. This is not enough if you want to use dags to create | ||
functions with exchangeable parts. Let's assume we have two implementations of f | ||
and want to create combined functions for both versions. | ||
|
||
|
||
.. code-block:: python | ||
import numpy as np | ||
def f_standard(x, y): | ||
return x**2 + y**2 | ||
def f_numpy(x, y): | ||
return np.square(x) + np.square(y) | ||
We can do that as follows: | ||
|
||
.. code-block:: python | ||
combined_standard = concatenate_functions( | ||
{"f": f_standard, "g": g, "h": h}, | ||
targets="h", | ||
) | ||
combined_numpy = concatenate_functions( | ||
{"f": f_numpy, "g": g, "h": h}, | ||
targets="h", | ||
) | ||
In fact, this ability to switch out components was the primary reason we wrote dags. | ||
This functionality has, for example, been used in | ||
`GETTSIM <https://github.com/iza-institute-of-labor-economics/gettsim>`_, a | ||
framework to simulate reforms to the German tax and transfer system. | ||
|
||
|
||
Renaming the input of functions | ||
------------------------------- | ||
|
||
Sometimes, we want to re-use a general function inside dags, but the arguments of that | ||
function don't have the correct names. For example, we might have a general | ||
implementation that we could re-use for `f`: | ||
|
||
|
||
.. code-block:: python | ||
def sum_of_squares(a, b): | ||
return a**2 + b**2 | ||
Instead of writing a wrapper like: | ||
|
||
|
||
.. code-block:: python | ||
def f(x, y): | ||
return sum_of_squares(a=x, b=y) | ||
We can simply rename the arguments programmatically: | ||
|
||
.. code-block:: python | ||
from dags.signature import rename_arguments | ||
functions = { | ||
"f": rename_arguments(sum_of_squares, mapper={"a": "x", "b": "y"}), | ||
"g": g, | ||
"h": h, | ||
} | ||
combined = concatenate_functions(functions, targets="h") | ||
combined(x=1, y=2, z=3) | ||
.. code-block:: python | ||
0.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,33 @@ | ||
dags | ||
==== | ||
|
||
``dags`` contains tools to create executable dags from interdependent functions. | ||
.. image:: _static/images/logo.svg | ||
:width: 700 | ||
|
||
| | ||
About dags | ||
========== | ||
|
||
dags provides tools to combine several interrelated functions into one function. | ||
The order in which the functions are called is determined by a topological sort on | ||
a Directed Acyclic Graph (DAG) that is constructed from the function signatures. | ||
|
||
|
||
|
||
.. toctree:: | ||
:maxdepth: 1 | ||
|
||
installation | ||
examples | ||
api | ||
|
||
Who uses dags | ||
============= | ||
|
||
dags is used by the following open source projects: | ||
|
||
- `GETTSIM <https://github.com/iza-institute-of-labor-economics/gettsim>`_ | ||
- `LCM <https://github.com/OpenSourceEconomics/lcm>`_ | ||
- `Skillmodels <https://github.com/janosg/skillmodels/tree/main/skillmodels>`_ | ||
|
||
dags is a tiny library, all the hard work is done by the great | ||
`NetworkX <https://networkx.org/documentation/stable/tutorial.html>`_. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Installation | ||
------------ | ||
|
||
dags is available on `PyPI <https://pypi.org/project/dags>`_ and `Anaconda.org | ||
<https://anaconda.org/conda-forge/dags>`_. Install it with | ||
|
||
.. code-block:: console | ||
$ pip install dags | ||
# or | ||
$ conda install -c conda-forge dags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,6 @@ dependencies: | |
# Development | ||
- jupyterlab | ||
- nbsphinx | ||
|
||
- pip: | ||
- -e . |