Skip to content

Commit 86efbb7

Browse files
authored
Polish documentation (#18)
1 parent a8e858a commit 86efbb7

File tree

8 files changed

+318
-10
lines changed

8 files changed

+318
-10
lines changed

README.rst

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,86 @@ dags
3939

4040
.. end-badges
4141
42+
About
43+
-----
44+
45+
dags provides tools to combine several interrelated functions into one function.
46+
The order in which the functions are called is determined by a topological sort on
47+
a dag that is constructed from the function signatures. You can specify which of the
48+
function results will be returned in the combined function.
49+
50+
dags is a tiny library, all the hard work is done by the great
51+
`NetworkX <https://networkx.org/documentation/stable/tutorial.html>`_
52+
53+
Example
54+
-------
55+
56+
To understand what dags does, let's look at a very simple example of a few functions
57+
that do simple calculations.
58+
59+
.. code-block:: python
60+
61+
def f(x, y):
62+
return x**2 + y**2
63+
64+
65+
def g(y, z):
66+
return 0.5 * y * z
67+
68+
69+
def h(f, g):
70+
return g / f
71+
72+
73+
Assume that we are interested in a function that calculates h, given x, y and z.
74+
75+
We could hardcode this function as:
76+
77+
.. code-block:: python
78+
79+
def hardcoded_combined(x, y, z):
80+
_f = f(x, y)
81+
_g = g(y, z)
82+
return h(_f, _g)
83+
84+
85+
hardcoded_combined(x=1, y=2, z=3)
86+
87+
.. code-block:: python
88+
89+
0.6
90+
91+
Instead, we can use dags to construct the same function:
92+
93+
.. code-block:: python
94+
95+
from dags import concatenate_functions
96+
97+
combined = concatenate_functions([h, f, g], targets="h")
98+
99+
combined(x=1, y=2, z=3)
100+
101+
.. code-block:: python
102+
103+
0.6
104+
105+
More examples can be found in the `documentation <https://dags.readthedocs.io/en/latest/#>`_
106+
107+
108+
Notable features
109+
----------------
110+
111+
- The dag is constructed while the combined function is created and does not cause too
112+
much overhead when the function is called.
113+
- If all individual functions are jax compatible, the combined function is jax compatible.
114+
- When jitted or vmapped with jax, we havenot seen any performance loss compared to
115+
hard coding the combined function.
116+
- Whene there is more than one target, you can determine whether the result is returned
117+
as tuple, list or dict or pass in an aggregator to combine the multiple outputs.
118+
- Since the relationships are discoverd from function signatures, dags provides
119+
decorators to rename arguments.
120+
121+
42122
Installation
43123
------------
44124

@@ -53,8 +133,7 @@ dags is available on `PyPI <https://pypi.org/project/dags>`_ and `Anaconda.org
53133
54134
$ conda install -c conda-forge dags
55135
136+
Documentation
137+
-------------
56138

57-
About
58-
-----
59-
60-
dags provides Tools to create executable dags from interdependent functions.
139+
The `documentation <https://dags.readthedocs.io/en/latest/#>`_ is hosted on Read the Docs.

docs/source/_static/images/logo.svg

Lines changed: 1 addition & 0 deletions
Loading

docs/source/api.rst

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
API Reference
22
=============
33

4-
The following documents are auto-generated and not carefully edited. They provide direct
5-
access to the source code and the docstrings.
4+
5+
Core functions
6+
--------------
7+
8+
.. automodule:: dags
9+
:members:
10+
:undoc-members:
11+
:noindex:
12+
13+
14+
Signature tools
15+
---------------
16+
17+
18+
.. automodule:: dags.signature
19+
:members:
20+
:undoc-members:
21+
:noindex:
22+
23+
24+
Internals
25+
---------
26+
27+
The following documents are auto-generated and not carefully edited.
28+
They provide direct access to the source code and the docstrings.
629

730
.. toctree::
831
:titlesonly:

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
# a list of builtin themes.
114114
html_theme = "pydata_sphinx_theme"
115115

116-
# html_logo = "_static/images/logo.svg"
116+
html_logo = "_static/images/logo.svg"
117117

118118
html_theme_options = {
119119
"github_url": "https://github.com/OpenSourceEconomics/dags",

docs/source/examples.rst

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
Examples
2+
========
3+
4+
5+
A simple example
6+
----------------
7+
8+
To understand what dags does, let's look at a few functions
9+
that do simple calculations.
10+
11+
.. code-block:: python
12+
13+
def f(x, y):
14+
return x**2 + y**2
15+
16+
17+
def g(y, z):
18+
return 0.5 * y * z
19+
20+
21+
def h(f, g):
22+
return g / f
23+
24+
25+
Combine with a single target
26+
----------------------------
27+
28+
29+
Assume that we are interested in a function that calculates h, given x, y and z.
30+
31+
We could hardcode this function as:
32+
33+
.. code-block:: python
34+
35+
def hardcoded_combined(x, y, z):
36+
_f = f(x, y)
37+
_g = g(y, z)
38+
return h(_f, _g)
39+
40+
41+
hardcoded_combined(x=1, y=2, z=3)
42+
43+
.. code-block:: python
44+
45+
0.6
46+
47+
Instead, we can use dags to construct the same function:
48+
49+
.. code-block:: python
50+
51+
from dags import concatenate_functions
52+
53+
combined = concatenate_functions([h, f, g], targets="h")
54+
55+
combined(x=1, y=2, z=3)
56+
57+
.. code-block:: python
58+
59+
0.6
60+
61+
Importantly, the order in which the functions are passed into ``concatenate_functions``
62+
does not matter!
63+
64+
65+
Combine with multiple targets
66+
-----------------------------
67+
68+
Assume that we want the same combined h function as before but we also need intermediate
69+
outputs. And we would like to have them as a dictionary. We can do this as follows:
70+
71+
.. code-block:: python
72+
73+
combined = concatenate_functions(
74+
[h, f, g],
75+
targets=["h", "f", "g"],
76+
return_type="dict",
77+
)
78+
79+
combined(x=1, y=2, z=3)
80+
81+
.. code-block:: python
82+
83+
{"h": 0.6, "f": 5, "g": 3.0}
84+
85+
86+
Renaming the output of a function
87+
---------------------------------
88+
89+
So far, the name of the output of the function was determined from the ``__name__``
90+
attribute of each function. This is not enough if you want to use dags to create
91+
functions with exchangeable parts. Let's assume we have two implementations of f
92+
and want to create combined functions for both versions.
93+
94+
95+
.. code-block:: python
96+
97+
import numpy as np
98+
99+
100+
def f_standard(x, y):
101+
return x**2 + y**2
102+
103+
104+
def f_numpy(x, y):
105+
return np.square(x) + np.square(y)
106+
107+
We can do that as follows:
108+
109+
.. code-block:: python
110+
111+
combined_standard = concatenate_functions(
112+
{"f": f_standard, "g": g, "h": h},
113+
targets="h",
114+
)
115+
116+
combined_numpy = concatenate_functions(
117+
{"f": f_numpy, "g": g, "h": h},
118+
targets="h",
119+
)
120+
121+
In fact, this ability to switch out components was the primary reason we wrote dags.
122+
This functionality has, for example, been used in
123+
`GETTSIM <https://github.com/iza-institute-of-labor-economics/gettsim>`_, a
124+
framework to simulate reforms to the German tax and transfer system.
125+
126+
127+
Renaming the input of functions
128+
-------------------------------
129+
130+
Sometimes, we want to re-use a general function inside dags, but the arguments of that
131+
function don't have the correct names. For example, we might have a general
132+
implementation that we could re-use for `f`:
133+
134+
135+
.. code-block:: python
136+
137+
def sum_of_squares(a, b):
138+
return a**2 + b**2
139+
140+
Instead of writing a wrapper like:
141+
142+
143+
.. code-block:: python
144+
145+
def f(x, y):
146+
return sum_of_squares(a=x, b=y)
147+
148+
We can simply rename the arguments programmatically:
149+
150+
.. code-block:: python
151+
152+
from dags.signature import rename_arguments
153+
154+
functions = {
155+
"f": rename_arguments(sum_of_squares, mapper={"a": "x", "b": "y"}),
156+
"g": g,
157+
"h": h,
158+
}
159+
160+
combined = concatenate_functions(functions, targets="h")
161+
combined(x=1, y=2, z=3)
162+
163+
.. code-block:: python
164+
165+
0.6

docs/source/index.rst

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1-
dags
2-
====
31

4-
``dags`` contains tools to create executable dags from interdependent functions.
2+
.. image:: _static/images/logo.svg
3+
:width: 700
4+
5+
|
6+
7+
About dags
8+
==========
9+
10+
dags provides tools to combine several interrelated functions into one function.
11+
The order in which the functions are called is determined by a topological sort on
12+
a Directed Acyclic Graph (DAG) that is constructed from the function signatures.
13+
14+
515

616
.. toctree::
717
:maxdepth: 1
818

19+
installation
20+
examples
921
api
22+
23+
Who uses dags
24+
=============
25+
26+
dags is used by the following open source projects:
27+
28+
- `GETTSIM <https://github.com/iza-institute-of-labor-economics/gettsim>`_
29+
- `LCM <https://github.com/OpenSourceEconomics/lcm>`_
30+
- `Skillmodels <https://github.com/janosg/skillmodels/tree/main/skillmodels>`_
31+
32+
dags is a tiny library, all the hard work is done by the great
33+
`NetworkX <https://networkx.org/documentation/stable/tutorial.html>`_.

docs/source/installation.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Installation
2+
------------
3+
4+
dags is available on `PyPI <https://pypi.org/project/dags>`_ and `Anaconda.org
5+
<https://anaconda.org/conda-forge/dags>`_. Install it with
6+
7+
.. code-block:: console
8+
9+
$ pip install dags
10+
11+
# or
12+
13+
$ conda install -c conda-forge dags

environment.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ dependencies:
3030
# Development
3131
- jupyterlab
3232
- nbsphinx
33+
34+
- pip:
35+
- -e .

0 commit comments

Comments
 (0)