Bug 1337145 - Remove python components used for EME generation; r=glandium

MozReview-Commit-ID: G8OhcbStQkG

--HG--
extra : rebase_source : ad7434cf729c3257bcc3911a4d25ba0145384939
This commit is contained in:
Mike Shal 2017-04-10 13:40:03 -04:00
parent 2a2f301a96
commit 5b62b8c036
231 changed files with 0 additions and 37686 deletions

View File

@ -1,4 +1,3 @@
altgraph.pth:python/altgraph
marionette_driver.pth:testing/marionette/client
marionette_harness.pth:testing/marionette/harness
browsermobproxy.pth:testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py
@ -16,7 +15,6 @@ optional:setup.py:python/psutil:build_ext:--inplace
optional:psutil.pth:python/psutil
which.pth:python/which
ply.pth:other-licenses/ply/
macholib.pth:python/macholib
mock.pth:python/mock-1.0.0
py.pth:python/py
pytest.pth:python/pytest
@ -32,7 +30,6 @@ objdir:build
gyp.pth:media/webrtc/trunk/tools/gyp/pylib
pyasn1.pth:python/pyasn1
pyasn1_modules.pth:python/pyasn1-modules
bitstring.pth:python/bitstring
redo.pth:python/redo
requests.pth:python/requests
rsa.pth:python/rsa

View File

@ -1,9 +0,0 @@
include ReadMe.txt
include *.txt MANIFEST.in *.py
graft doc
graft doc/_static
graft doc/_templates
graft altgraph_tests
global-exclude .DS_Store
global-exclude *.pyc
global-exclude *.so

View File

@ -1,216 +0,0 @@
Metadata-Version: 1.1
Name: altgraph
Version: 0.12
Summary: Python graph (network) package
Home-page: http://packages.python.org/altgraph
Author: Ronald Oussoren
Author-email: ronaldoussoren@mac.com
License: MIT
Download-URL: http://pypi.python.org/pypi/altgraph
Description: altgraph is a fork of graphlib: a graph (network) package for constructing
graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
graphviz output.
altgraph includes some additional usage of Python 2.6+ features and
enhancements related to modulegraph and macholib.
Release history
===============
0.12
----
- Added ``ObjectGraph.edgeData`` to retrieve the edge data
from a specific edge.
- Added ``AltGraph.update_edge_data`` and ``ObjectGraph.updateEdgeData``
to update the data associated with a graph edge.
0.11
----
- Stabilize the order of elements in dot file exports,
patch from bitbucket user 'pombredanne'.
- Tweak setup.py file to remove dependency on distribute (but
keep the dependency on setuptools)
0.10.2
------
- There where no classifiers in the package metadata due to a bug
in setup.py
0.10.1
------
This is a bugfix release
Bug fixes:
- Issue #3: The source archive contains a README.txt
while the setup file refers to ReadMe.txt.
This is caused by a misfeature in distutils, as a
workaround I've renamed ReadMe.txt to README.txt
in the source tree and setup file.
0.10
-----
This is a minor feature release
Features:
- Do not use "2to3" to support Python 3.
As a side effect of this altgraph now supports
Python 2.6 and later, and no longer supports
earlier releases of Python.
- The order of attributes in the Dot output
is now always alphabetical.
With this change the output will be consistent
between runs and Python versions.
0.9
---
This is a minor bugfix release
Features:
- Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
yielding all nodes in an object graph.
Bugfixes:
- The 0.8 release didn't work with py2app when using
python 3.x.
0.8
-----
This is a minor feature release. The major new feature
is a extensive set of unittests, which explains almost
all other changes in this release.
Bugfixes:
- Installing failed with Python 2.5 due to using a distutils
class that isn't available in that version of Python
(issue #1 on the issue tracker)
- ``altgraph.GraphStat.degree_dist`` now actually works
- ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
no longer create the edge when one of the nodes doesn't
exist.
- ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
- ``altgraph.Graph.back_topo_sort`` was completely broken in
previous releases.
- ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
- ``altgraph.Graph.back_bfs_subgraph`` now actually works.
- ``altgraph.Graph.iterdfs`` now returns the correct result
when the ``forward`` argument is ``False``.
- ``altgraph.Graph.iterdata`` now returns the correct result
when the ``forward`` argument is ``False``.
Features:
- The ``altgraph.Graph`` constructor now accepts an argument
that contains 2- and 3-tuples instead of requireing that
all items have the same size. The (optional) argument can now
also be any iterator.
- ``altgraph.Graph.Graph.add_node`` has no effect when you
add a hidden node.
- The private method ``altgraph.Graph._bfs`` is no longer
present.
- The private method ``altgraph.Graph._dfs`` is no longer
present.
- ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
which means you can use the ``in`` operator to check if a
node is part of a graph.
- ``altgraph.GraphUtil.generate_random_graph`` will raise
``GraphError`` instead of looping forever when it is
impossible to create the requested graph.
- ``altgraph.Dot.edge_style`` raises ``GraphError`` when
one of the nodes is not present in the graph. The method
silently added the tail in the past, but without ensuring
a consistent graph state.
- ``altgraph.Dot.save_img`` now works when the mode is
``"neato"``.
0.7.2
-----
This is a minor bugfix release
Bugfixes:
- distutils didn't include the documentation subtree
0.7.1
-----
This is a minor feature release
Features:
- Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
and can be viewed at <http://packages.python.org/altgraph>.
- The repository has moved to bitbucket
- ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
implementation and no specified behaviour.
- the module ``altgraph.compat`` is gone, which means altgraph will no
longer work with Python 2.3.
0.7.0
-----
This is a minor feature release.
Features:
- Support for Python 3
- It is now possible to run tests using 'python setup.py test'
(The actual testsuite is still very minimal though)
Keywords: graph
Platform: any
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Visualization

View File

@ -1,6 +0,0 @@
altgraph is a fork of graphlib: a graph (network) package for constructing
graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
graphviz output.
altgraph includes some additional usage of Python 2.6+ features and
enhancements related to modulegraph and macholib.

View File

@ -1,216 +0,0 @@
Metadata-Version: 1.1
Name: altgraph
Version: 0.12
Summary: Python graph (network) package
Home-page: http://packages.python.org/altgraph
Author: Ronald Oussoren
Author-email: ronaldoussoren@mac.com
License: MIT
Download-URL: http://pypi.python.org/pypi/altgraph
Description: altgraph is a fork of graphlib: a graph (network) package for constructing
graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
graphviz output.
altgraph includes some additional usage of Python 2.6+ features and
enhancements related to modulegraph and macholib.
Release history
===============
0.12
----
- Added ``ObjectGraph.edgeData`` to retrieve the edge data
from a specific edge.
- Added ``AltGraph.update_edge_data`` and ``ObjectGraph.updateEdgeData``
to update the data associated with a graph edge.
0.11
----
- Stabilize the order of elements in dot file exports,
patch from bitbucket user 'pombredanne'.
- Tweak setup.py file to remove dependency on distribute (but
keep the dependency on setuptools)
0.10.2
------
- There where no classifiers in the package metadata due to a bug
in setup.py
0.10.1
------
This is a bugfix release
Bug fixes:
- Issue #3: The source archive contains a README.txt
while the setup file refers to ReadMe.txt.
This is caused by a misfeature in distutils, as a
workaround I've renamed ReadMe.txt to README.txt
in the source tree and setup file.
0.10
-----
This is a minor feature release
Features:
- Do not use "2to3" to support Python 3.
As a side effect of this altgraph now supports
Python 2.6 and later, and no longer supports
earlier releases of Python.
- The order of attributes in the Dot output
is now always alphabetical.
With this change the output will be consistent
between runs and Python versions.
0.9
---
This is a minor bugfix release
Features:
- Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
yielding all nodes in an object graph.
Bugfixes:
- The 0.8 release didn't work with py2app when using
python 3.x.
0.8
-----
This is a minor feature release. The major new feature
is a extensive set of unittests, which explains almost
all other changes in this release.
Bugfixes:
- Installing failed with Python 2.5 due to using a distutils
class that isn't available in that version of Python
(issue #1 on the issue tracker)
- ``altgraph.GraphStat.degree_dist`` now actually works
- ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
no longer create the edge when one of the nodes doesn't
exist.
- ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
- ``altgraph.Graph.back_topo_sort`` was completely broken in
previous releases.
- ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
- ``altgraph.Graph.back_bfs_subgraph`` now actually works.
- ``altgraph.Graph.iterdfs`` now returns the correct result
when the ``forward`` argument is ``False``.
- ``altgraph.Graph.iterdata`` now returns the correct result
when the ``forward`` argument is ``False``.
Features:
- The ``altgraph.Graph`` constructor now accepts an argument
that contains 2- and 3-tuples instead of requireing that
all items have the same size. The (optional) argument can now
also be any iterator.
- ``altgraph.Graph.Graph.add_node`` has no effect when you
add a hidden node.
- The private method ``altgraph.Graph._bfs`` is no longer
present.
- The private method ``altgraph.Graph._dfs`` is no longer
present.
- ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
which means you can use the ``in`` operator to check if a
node is part of a graph.
- ``altgraph.GraphUtil.generate_random_graph`` will raise
``GraphError`` instead of looping forever when it is
impossible to create the requested graph.
- ``altgraph.Dot.edge_style`` raises ``GraphError`` when
one of the nodes is not present in the graph. The method
silently added the tail in the past, but without ensuring
a consistent graph state.
- ``altgraph.Dot.save_img`` now works when the mode is
``"neato"``.
0.7.2
-----
This is a minor bugfix release
Bugfixes:
- distutils didn't include the documentation subtree
0.7.1
-----
This is a minor feature release
Features:
- Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
and can be viewed at <http://packages.python.org/altgraph>.
- The repository has moved to bitbucket
- ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
implementation and no specified behaviour.
- the module ``altgraph.compat`` is gone, which means altgraph will no
longer work with Python 2.3.
0.7.0
-----
This is a minor feature release.
Features:
- Support for Python 3
- It is now possible to run tests using 'python setup.py test'
(The actual testsuite is still very minimal though)
Keywords: graph
Platform: any
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Visualization

View File

@ -1,92 +0,0 @@
MANIFEST.in
README.txt
ReadMe.txt
setup.cfg
setup.py
altgraph/Dot.py
altgraph/Graph.py
altgraph/GraphAlgo.py
altgraph/GraphStat.py
altgraph/GraphUtil.py
altgraph/ObjectGraph.py
altgraph/__init__.py
altgraph.egg-info/PKG-INFO
altgraph.egg-info/SOURCES.txt
altgraph.egg-info/dependency_links.txt
altgraph.egg-info/top_level.txt
altgraph.egg-info/zip-safe
altgraph_tests/__init__.py
altgraph_tests/test_altgraph.py
altgraph_tests/test_dot.py
altgraph_tests/test_graph.py
altgraph_tests/test_graphstat.py
altgraph_tests/test_graphutil.py
altgraph_tests/test_object_graph.py
doc/Makefile
doc/changelog.rst
doc/conf.py
doc/core.rst
doc/dot.rst
doc/graph.rst
doc/graphalgo.rst
doc/graphstat.rst
doc/graphutil.rst
doc/index.rst
doc/license.rst
doc/objectgraph.rst
doc/_build/doctrees/changelog.doctree
doc/_build/doctrees/core.doctree
doc/_build/doctrees/dot.doctree
doc/_build/doctrees/environment.pickle
doc/_build/doctrees/graph.doctree
doc/_build/doctrees/graphalgo.doctree
doc/_build/doctrees/graphstat.doctree
doc/_build/doctrees/graphutil.doctree
doc/_build/doctrees/index.doctree
doc/_build/doctrees/license.doctree
doc/_build/doctrees/objectgraph.doctree
doc/_build/html/.buildinfo
doc/_build/html/changelog.html
doc/_build/html/core.html
doc/_build/html/dot.html
doc/_build/html/genindex.html
doc/_build/html/graph.html
doc/_build/html/graphalgo.html
doc/_build/html/graphstat.html
doc/_build/html/graphutil.html
doc/_build/html/index.html
doc/_build/html/license.html
doc/_build/html/objectgraph.html
doc/_build/html/objects.inv
doc/_build/html/py-modindex.html
doc/_build/html/search.html
doc/_build/html/searchindex.js
doc/_build/html/_sources/changelog.txt
doc/_build/html/_sources/core.txt
doc/_build/html/_sources/dot.txt
doc/_build/html/_sources/graph.txt
doc/_build/html/_sources/graphalgo.txt
doc/_build/html/_sources/graphstat.txt
doc/_build/html/_sources/graphutil.txt
doc/_build/html/_sources/index.txt
doc/_build/html/_sources/license.txt
doc/_build/html/_sources/objectgraph.txt
doc/_build/html/_static/ajax-loader.gif
doc/_build/html/_static/basic.css
doc/_build/html/_static/comment-bright.png
doc/_build/html/_static/comment-close.png
doc/_build/html/_static/comment.png
doc/_build/html/_static/doctools.js
doc/_build/html/_static/down-pressed.png
doc/_build/html/_static/down.png
doc/_build/html/_static/file.png
doc/_build/html/_static/jquery.js
doc/_build/html/_static/minus.png
doc/_build/html/_static/nature.css
doc/_build/html/_static/plus.png
doc/_build/html/_static/pygments.css
doc/_build/html/_static/searchtools.js
doc/_build/html/_static/underscore.js
doc/_build/html/_static/up-pressed.png
doc/_build/html/_static/up.png
doc/_build/html/_static/websupport.js

View File

@ -1 +0,0 @@
altgraph

View File

@ -1 +0,0 @@

View File

@ -1,299 +0,0 @@
'''
altgraph.Dot - Interface to the dot language
============================================
The :py:mod:`~altgraph.Dot` module provides a simple interface to the
file format used in the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
program. The module is intended to offload the most tedious part of the process
(the **dot** file generation) while transparently exposing most of its features.
To display the graphs or to generate image files the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
package needs to be installed on the system, moreover the :command:`dot` and :command:`dotty` programs must
be accesible in the program path so that they can be ran from processes spawned
within the module.
Example usage
-------------
Here is a typical usage::
from altgraph import Graph, Dot
# create a graph
edges = [ (1,2), (1,3), (3,4), (3,5), (4,5), (5,4) ]
graph = Graph.Graph(edges)
# create a dot representation of the graph
dot = Dot.Dot(graph)
# display the graph
dot.display()
# save the dot representation into the mydot.dot file
dot.save_dot(file_name='mydot.dot')
# save dot file as gif image into the graph.gif file
dot.save_img(file_name='graph', file_type='gif')
Directed graph and non-directed graph
-------------------------------------
Dot class can use for both directed graph and non-directed graph
by passing ``graphtype`` parameter.
Example::
# create directed graph(default)
dot = Dot.Dot(graph, graphtype="digraph")
# create non-directed graph
dot = Dot.Dot(graph, graphtype="graph")
Customizing the output
----------------------
The graph drawing process may be customized by passing
valid :command:`dot` parameters for the nodes and edges. For a list of all
parameters see the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
documentation.
Example::
# customizing the way the overall graph is drawn
dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
# customizing node drawing
dot.node_style(1, label='BASE_NODE',shape='box', color='blue' )
dot.node_style(2, style='filled', fillcolor='red')
# customizing edge drawing
dot.edge_style(1, 2, style='dotted')
dot.edge_style(3, 5, arrowhead='dot', label='binds', labelangle='90')
dot.edge_style(4, 5, arrowsize=2, style='bold')
.. note::
dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
display all graphics styles. To verify the output save it to an image file
and look at it that way.
Valid attributes
----------------
- dot styles, passed via the :py:meth:`Dot.style` method::
rankdir = 'LR' (draws the graph horizontally, left to right)
ranksep = number (rank separation in inches)
- node attributes, passed via the :py:meth:`Dot.node_style` method::
style = 'filled' | 'invisible' | 'diagonals' | 'rounded'
shape = 'box' | 'ellipse' | 'circle' | 'point' | 'triangle'
- edge attributes, passed via the :py:meth:`Dot.edge_style` method::
style = 'dashed' | 'dotted' | 'solid' | 'invis' | 'bold'
arrowhead = 'box' | 'crow' | 'diamond' | 'dot' | 'inv' | 'none' | 'tee' | 'vee'
weight = number (the larger the number the closer the nodes will be)
- valid `graphviz colors <http://www.research.att.com/~erg/graphviz/info/colors.html>`_
- for more details on how to control the graph drawing process see the
`graphviz reference <http://www.research.att.com/sw/tools/graphviz/refs.html>`_.
'''
import os
import warnings
from altgraph import GraphError
class Dot(object):
'''
A class providing a **graphviz** (dot language) representation
allowing a fine grained control over how the graph is being
displayed.
If the :command:`dot` and :command:`dotty` programs are not in the current system path
their location needs to be specified in the contructor.
'''
def __init__(self, graph=None, nodes=None, edgefn=None, nodevisitor=None, edgevisitor=None, name="G", dot='dot', dotty='dotty', neato='neato', graphtype="digraph"):
'''
Initialization.
'''
self.name, self.attr = name, {}
assert graphtype in ['graph', 'digraph']
self.type = graphtype
self.temp_dot = "tmp_dot.dot"
self.temp_neo = "tmp_neo.dot"
self.dot, self.dotty, self.neato = dot, dotty, neato
# self.nodes: node styles
# self.edges: edge styles
self.nodes, self.edges = {}, {}
if graph is not None and nodes is None:
nodes = graph
if graph is not None and edgefn is None:
def edgefn(node, graph=graph):
return graph.out_nbrs(node)
if nodes is None:
nodes = ()
seen = set()
for node in nodes:
if nodevisitor is None:
style = {}
else:
style = nodevisitor(node)
if style is not None:
self.nodes[node] = {}
self.node_style(node, **style)
seen.add(node)
if edgefn is not None:
for head in seen:
for tail in (n for n in edgefn(head) if n in seen):
if edgevisitor is None:
edgestyle = {}
else:
edgestyle = edgevisitor(head, tail)
if edgestyle is not None:
if head not in self.edges:
self.edges[head] = {}
self.edges[head][tail] = {}
self.edge_style(head, tail, **edgestyle)
def style(self, **attr):
'''
Changes the overall style
'''
self.attr = attr
def display(self, mode='dot'):
'''
Displays the current graph via dotty
'''
if mode == 'neato':
self.save_dot(self.temp_neo)
neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo)
os.system(neato_cmd)
else:
self.save_dot(self.temp_dot)
plot_cmd = "%s %s" % (self.dotty, self.temp_dot)
os.system(plot_cmd)
def node_style(self, node, **kwargs):
'''
Modifies a node style to the dot representation.
'''
if node not in self.edges:
self.edges[node] = {}
self.nodes[node] = kwargs
def all_node_style(self, **kwargs):
'''
Modifies all node styles
'''
for node in self.nodes:
self.node_style(node, **kwargs)
def edge_style(self, head, tail, **kwargs):
'''
Modifies an edge style to the dot representation.
'''
if tail not in self.nodes:
raise GraphError("invalid node %s" % (tail,))
try:
if tail not in self.edges[head]:
self.edges[head][tail]= {}
self.edges[head][tail] = kwargs
except KeyError:
raise GraphError("invalid edge %s -> %s " % (head, tail) )
def iterdot(self):
# write graph title
if self.type == 'digraph':
yield 'digraph %s {\n' % (self.name,)
elif self.type == 'graph':
yield 'graph %s {\n' % (self.name,)
else:
raise GraphError("unsupported graphtype %s" % (self.type,))
# write overall graph attributes
for attr_name, attr_value in sorted(self.attr.items()):
yield '%s="%s";' % (attr_name, attr_value)
yield '\n'
# some reusable patterns
cpatt = '%s="%s",' # to separate attributes
epatt = '];\n' # to end attributes
# write node attributes
for node_name, node_attr in sorted(self.nodes.items()):
yield '\t"%s" [' % (node_name,)
for attr_name, attr_value in sorted(node_attr.items()):
yield cpatt % (attr_name, attr_value)
yield epatt
# write edge attributes
for head in sorted(self.edges):
for tail in sorted(self.edges[head]):
if self.type == 'digraph':
yield '\t"%s" -> "%s" [' % (head, tail)
else:
yield '\t"%s" -- "%s" [' % (head, tail)
for attr_name, attr_value in sorted(self.edges[head][tail].items()):
yield cpatt % (attr_name, attr_value)
yield epatt
# finish file
yield '}\n'
def __iter__(self):
return self.iterdot()
def save_dot(self, file_name=None):
'''
Saves the current graph representation into a file
'''
if not file_name:
warnings.warn(DeprecationWarning, "always pass a file_name")
file_name = self.temp_dot
fp = open(file_name, "w")
try:
for chunk in self.iterdot():
fp.write(chunk)
finally:
fp.close()
def save_img(self, file_name=None, file_type="gif", mode='dot'):
'''
Saves the dot file as an image file
'''
if not file_name:
warnings.warn(DeprecationWarning, "always pass a file_name")
file_name = "out"
if mode == 'neato':
self.save_dot(self.temp_neo)
neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo)
os.system(neato_cmd)
plot_cmd = self.dot
else:
self.save_dot(self.temp_dot)
plot_cmd = self.dot
file_name = "%s.%s" % (file_name, file_type)
create_cmd = "%s -T%s %s -o %s" % (plot_cmd, file_type, self.temp_dot, file_name)
os.system(create_cmd)

View File

@ -1,677 +0,0 @@
"""
altgraph.Graph - Base Graph class
=================================
..
#--Version 2.1
#--Bob Ippolito October, 2004
#--Version 2.0
#--Istvan Albert June, 2004
#--Version 1.0
#--Nathan Denny, May 27, 1999
"""
from altgraph import GraphError
from collections import deque
class Graph(object):
"""
The Graph class represents a directed graph with *N* nodes and *E* edges.
Naming conventions:
- the prefixes such as *out*, *inc* and *all* will refer to methods
that operate on the outgoing, incoming or all edges of that node.
For example: :py:meth:`inc_degree` will refer to the degree of the node
computed over the incoming edges (the number of neighbours linking to
the node).
- the prefixes such as *forw* and *back* will refer to the
orientation of the edges used in the method with respect to the node.
For example: :py:meth:`forw_bfs` will start at the node then use the outgoing
edges to traverse the graph (goes forward).
"""
def __init__(self, edges=None):
"""
Initialization
"""
self.next_edge = 0
self.nodes, self.edges = {}, {}
self.hidden_edges, self.hidden_nodes = {}, {}
if edges is not None:
for item in edges:
if len(item) == 2:
head, tail = item
self.add_edge(head, tail)
elif len(item) == 3:
head, tail, data = item
self.add_edge(head, tail, data)
else:
raise GraphError("Cannot create edge from %s"%(item,))
def __repr__(self):
return '<Graph: %d nodes, %d edges>' % (
self.number_of_nodes(), self.number_of_edges())
def add_node(self, node, node_data=None):
"""
Adds a new node to the graph. Arbitrary data can be attached to the
node via the node_data parameter. Adding the same node twice will be
silently ignored.
The node must be a hashable value.
"""
#
# the nodes will contain tuples that will store incoming edges,
# outgoing edges and data
#
# index 0 -> incoming edges
# index 1 -> outgoing edges
if node in self.hidden_nodes:
# Node is present, but hidden
return
if node not in self.nodes:
self.nodes[node] = ([], [], node_data)
def add_edge(self, head_id, tail_id, edge_data=1, create_nodes=True):
"""
Adds a directed edge going from head_id to tail_id.
Arbitrary data can be attached to the edge via edge_data.
It may create the nodes if adding edges between nonexisting ones.
:param head_id: head node
:param tail_id: tail node
:param edge_data: (optional) data attached to the edge
:param create_nodes: (optional) creates the head_id or tail_id node in case they did not exist
"""
# shorcut
edge = self.next_edge
# add nodes if on automatic node creation
if create_nodes:
self.add_node(head_id)
self.add_node(tail_id)
# update the corresponding incoming and outgoing lists in the nodes
# index 0 -> incoming edges
# index 1 -> outgoing edges
try:
self.nodes[tail_id][0].append(edge)
self.nodes[head_id][1].append(edge)
except KeyError:
raise GraphError('Invalid nodes %s -> %s' % (head_id, tail_id))
# store edge information
self.edges[edge] = (head_id, tail_id, edge_data)
self.next_edge += 1
def hide_edge(self, edge):
"""
Hides an edge from the graph. The edge may be unhidden at some later
time.
"""
try:
head_id, tail_id, edge_data = self.hidden_edges[edge] = self.edges[edge]
self.nodes[tail_id][0].remove(edge)
self.nodes[head_id][1].remove(edge)
del self.edges[edge]
except KeyError:
raise GraphError('Invalid edge %s' % edge)
def hide_node(self, node):
"""
Hides a node from the graph. The incoming and outgoing edges of the
node will also be hidden. The node may be unhidden at some later time.
"""
try:
all_edges = self.all_edges(node)
self.hidden_nodes[node] = (self.nodes[node], all_edges)
for edge in all_edges:
self.hide_edge(edge)
del self.nodes[node]
except KeyError:
raise GraphError('Invalid node %s' % node)
def restore_node(self, node):
"""
Restores a previously hidden node back into the graph and restores
all of its incoming and outgoing edges.
"""
try:
self.nodes[node], all_edges = self.hidden_nodes[node]
for edge in all_edges:
self.restore_edge(edge)
del self.hidden_nodes[node]
except KeyError:
raise GraphError('Invalid node %s' % node)
def restore_edge(self, edge):
"""
Restores a previously hidden edge back into the graph.
"""
try:
head_id, tail_id, data = self.hidden_edges[edge]
self.nodes[tail_id][0].append(edge)
self.nodes[head_id][1].append(edge)
self.edges[edge] = head_id, tail_id, data
del self.hidden_edges[edge]
except KeyError:
raise GraphError('Invalid edge %s' % edge)
def restore_all_edges(self):
"""
Restores all hidden edges.
"""
for edge in list(self.hidden_edges.keys()):
try:
self.restore_edge(edge)
except GraphError:
pass
def restore_all_nodes(self):
"""
Restores all hidden nodes.
"""
for node in list(self.hidden_nodes.keys()):
self.restore_node(node)
def __contains__(self, node):
"""
Test whether a node is in the graph
"""
return node in self.nodes
def edge_by_id(self, edge):
"""
Returns the edge that connects the head_id and tail_id nodes
"""
try:
head, tail, data = self.edges[edge]
except KeyError:
head, tail = None, None
raise GraphError('Invalid edge %s' % edge)
return (head, tail)
def edge_by_node(self, head, tail):
"""
Returns the edge that connects the head_id and tail_id nodes
"""
for edge in self.out_edges(head):
if self.tail(edge) == tail:
return edge
return None
def number_of_nodes(self):
"""
Returns the number of nodes
"""
return len(self.nodes)
def number_of_edges(self):
"""
Returns the number of edges
"""
return len(self.edges)
def __iter__(self):
"""
Iterates over all nodes in the graph
"""
return iter(self.nodes)
def node_list(self):
"""
Return a list of the node ids for all visible nodes in the graph.
"""
return list(self.nodes.keys())
def edge_list(self):
"""
Returns an iterator for all visible nodes in the graph.
"""
return list(self.edges.keys())
def number_of_hidden_edges(self):
"""
Returns the number of hidden edges
"""
return len(self.hidden_edges)
def number_of_hidden_nodes(self):
"""
Returns the number of hidden nodes
"""
return len(self.hidden_nodes)
def hidden_node_list(self):
"""
Returns the list with the hidden nodes
"""
return list(self.hidden_nodes.keys())
def hidden_edge_list(self):
"""
Returns a list with the hidden edges
"""
return list(self.hidden_edges.keys())
def describe_node(self, node):
"""
return node, node data, outgoing edges, incoming edges for node
"""
incoming, outgoing, data = self.nodes[node]
return node, data, outgoing, incoming
def describe_edge(self, edge):
"""
return edge, edge data, head, tail for edge
"""
head, tail, data = self.edges[edge]
return edge, data, head, tail
def node_data(self, node):
"""
Returns the data associated with a node
"""
return self.nodes[node][2]
def edge_data(self, edge):
"""
Returns the data associated with an edge
"""
return self.edges[edge][2]
def update_edge_data(self, edge, edge_data):
"""
Replace the edge data for a specific edge
"""
self.edges[edge] = self.edges[edge][0:2] + (edge_data,)
def head(self, edge):
"""
Returns the node of the head of the edge.
"""
return self.edges[edge][0]
def tail(self, edge):
"""
Returns node of the tail of the edge.
"""
return self.edges[edge][1]
def out_nbrs(self, node):
"""
List of nodes connected by outgoing edges
"""
l = [self.tail(n) for n in self.out_edges(node)]
return l
def inc_nbrs(self, node):
"""
List of nodes connected by incoming edges
"""
l = [self.head(n) for n in self.inc_edges(node)]
return l
def all_nbrs(self, node):
"""
List of nodes connected by incoming and outgoing edges
"""
l = dict.fromkeys( self.inc_nbrs(node) + self.out_nbrs(node) )
return list(l)
def out_edges(self, node):
"""
Returns a list of the outgoing edges
"""
try:
return list(self.nodes[node][1])
except KeyError:
raise GraphError('Invalid node %s' % node)
return None
def inc_edges(self, node):
"""
Returns a list of the incoming edges
"""
try:
return list(self.nodes[node][0])
except KeyError:
raise GraphError('Invalid node %s' % node)
return None
def all_edges(self, node):
"""
Returns a list of incoming and outging edges.
"""
return set(self.inc_edges(node) + self.out_edges(node))
def out_degree(self, node):
"""
Returns the number of outgoing edges
"""
return len(self.out_edges(node))
def inc_degree(self, node):
"""
Returns the number of incoming edges
"""
return len(self.inc_edges(node))
def all_degree(self, node):
"""
The total degree of a node
"""
return self.inc_degree(node) + self.out_degree(node)
def _topo_sort(self, forward=True):
"""
Topological sort.
Returns a list of nodes where the successors (based on outgoing and
incoming edges selected by the forward parameter) of any given node
appear in the sequence after that node.
"""
topo_list = []
queue = deque()
indeg = {}
# select the operation that will be performed
if forward:
get_edges = self.out_edges
get_degree = self.inc_degree
get_next = self.tail
else:
get_edges = self.inc_edges
get_degree = self.out_degree
get_next = self.head
for node in self.node_list():
degree = get_degree(node)
if degree:
indeg[node] = degree
else:
queue.append(node)
while queue:
curr_node = queue.popleft()
topo_list.append(curr_node)
for edge in get_edges(curr_node):
tail_id = get_next(edge)
if tail_id in indeg:
indeg[tail_id] -= 1
if indeg[tail_id] == 0:
queue.append(tail_id)
if len(topo_list) == len(self.node_list()):
valid = True
else:
# the graph has cycles, invalid topological sort
valid = False
return (valid, topo_list)
def forw_topo_sort(self):
"""
Topological sort.
Returns a list of nodes where the successors (based on outgoing edges)
of any given node appear in the sequence after that node.
"""
return self._topo_sort(forward=True)
def back_topo_sort(self):
"""
Reverse topological sort.
Returns a list of nodes where the successors (based on incoming edges)
of any given node appear in the sequence after that node.
"""
return self._topo_sort(forward=False)
def _bfs_subgraph(self, start_id, forward=True):
"""
Private method creates a subgraph in a bfs order.
The forward parameter specifies whether it is a forward or backward
traversal.
"""
if forward:
get_bfs = self.forw_bfs
get_nbrs = self.out_nbrs
else:
get_bfs = self.back_bfs
get_nbrs = self.inc_nbrs
g = Graph()
bfs_list = get_bfs(start_id)
for node in bfs_list:
g.add_node(node)
for node in bfs_list:
for nbr_id in get_nbrs(node):
g.add_edge(node, nbr_id)
return g
def forw_bfs_subgraph(self, start_id):
"""
Creates and returns a subgraph consisting of the breadth first
reachable nodes based on their outgoing edges.
"""
return self._bfs_subgraph(start_id, forward=True)
def back_bfs_subgraph(self, start_id):
"""
Creates and returns a subgraph consisting of the breadth first
reachable nodes based on the incoming edges.
"""
return self._bfs_subgraph(start_id, forward=False)
def iterdfs(self, start, end=None, forward=True):
"""
Collecting nodes in some depth first traversal.
The forward parameter specifies whether it is a forward or backward
traversal.
"""
visited, stack = set([start]), deque([start])
if forward:
get_edges = self.out_edges
get_next = self.tail
else:
get_edges = self.inc_edges
get_next = self.head
while stack:
curr_node = stack.pop()
yield curr_node
if curr_node == end:
break
for edge in sorted(get_edges(curr_node)):
tail = get_next(edge)
if tail not in visited:
visited.add(tail)
stack.append(tail)
def iterdata(self, start, end=None, forward=True, condition=None):
"""
Perform a depth-first walk of the graph (as ``iterdfs``)
and yield the item data of every node where condition matches. The
condition callback is only called when node_data is not None.
"""
visited, stack = set([start]), deque([start])
if forward:
get_edges = self.out_edges
get_next = self.tail
else:
get_edges = self.inc_edges
get_next = self.head
get_data = self.node_data
while stack:
curr_node = stack.pop()
curr_data = get_data(curr_node)
if curr_data is not None:
if condition is not None and not condition(curr_data):
continue
yield curr_data
if curr_node == end:
break
for edge in get_edges(curr_node):
tail = get_next(edge)
if tail not in visited:
visited.add(tail)
stack.append(tail)
def _iterbfs(self, start, end=None, forward=True):
"""
The forward parameter specifies whether it is a forward or backward
traversal. Returns a list of tuples where the first value is the hop
value the second value is the node id.
"""
queue, visited = deque([(start, 0)]), set([start])
# the direction of the bfs depends on the edges that are sampled
if forward:
get_edges = self.out_edges
get_next = self.tail
else:
get_edges = self.inc_edges
get_next = self.head
while queue:
curr_node, curr_step = queue.popleft()
yield (curr_node, curr_step)
if curr_node == end:
break
for edge in get_edges(curr_node):
tail = get_next(edge)
if tail not in visited:
visited.add(tail)
queue.append((tail, curr_step + 1))
def forw_bfs(self, start, end=None):
"""
Returns a list of nodes in some forward BFS order.
Starting from the start node the breadth first search proceeds along
outgoing edges.
"""
return [node for node, step in self._iterbfs(start, end, forward=True)]
def back_bfs(self, start, end=None):
"""
Returns a list of nodes in some backward BFS order.
Starting from the start node the breadth first search proceeds along
incoming edges.
"""
return [node for node, step in self._iterbfs(start, end, forward=False)]
def forw_dfs(self, start, end=None):
"""
Returns a list of nodes in some forward DFS order.
Starting with the start node the depth first search proceeds along
outgoing edges.
"""
return list(self.iterdfs(start, end, forward=True))
def back_dfs(self, start, end=None):
"""
Returns a list of nodes in some backward DFS order.
Starting from the start node the depth first search proceeds along
incoming edges.
"""
return list(self.iterdfs(start, end, forward=False))
def connected(self):
"""
Returns :py:data:`True` if the graph's every node can be reached from every
other node.
"""
node_list = self.node_list()
for node in node_list:
bfs_list = self.forw_bfs(node)
if len(bfs_list) != len(node_list):
return False
return True
def clust_coef(self, node):
"""
Computes and returns the local clustering coefficient of node. The
local cluster coefficient is proportion of the actual number of edges between
neighbours of node and the maximum number of edges between those neighbours.
See <http://en.wikipedia.org/wiki/Clustering_coefficient#Local_clustering_coefficient>
for a formal definition.
"""
num = 0
nbr_set = set(self.out_nbrs(node))
if node in nbr_set:
nbr_set.remove(node) # loop defense
for nbr in nbr_set:
sec_set = set(self.out_nbrs(nbr))
if nbr in sec_set:
sec_set.remove(nbr) # loop defense
num += len(nbr_set & sec_set)
nbr_num = len(nbr_set)
if nbr_num:
clust_coef = float(num) / (nbr_num * (nbr_num - 1))
else:
clust_coef = 0.0
return clust_coef
def get_hops(self, start, end=None, forward=True):
"""
Computes the hop distance to all nodes centered around a specified node.
First order neighbours are at hop 1, their neigbours are at hop 2 etc.
Uses :py:meth:`forw_bfs` or :py:meth:`back_bfs` depending on the value of the forward
parameter. If the distance between all neighbouring nodes is 1 the hop
number corresponds to the shortest distance between the nodes.
:param start: the starting node
:param end: ending node (optional). When not specified will search the whole graph.
:param forward: directionality parameter (optional). If C{True} (default) it uses L{forw_bfs} otherwise L{back_bfs}.
:return: returns a list of tuples where each tuple contains the node and the hop.
Typical usage::
>>> print (graph.get_hops(1, 8))
>>> [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
# node 1 is at 0 hops
# node 2 is at 1 hop
# ...
# node 8 is at 5 hops
"""
if forward:
return list(self._iterbfs(start=start, end=end, forward=True))
else:
return list(self._iterbfs(start=start, end=end, forward=False))

View File

@ -1,147 +0,0 @@
'''
altgraph.GraphAlgo - Graph algorithms
=====================================
'''
from altgraph import GraphError
def dijkstra(graph, start, end=None):
"""
Dijkstra's algorithm for shortest paths
`David Eppstein, UC Irvine, 4 April 2002 <http://www.ics.uci.edu/~eppstein/161/python/>`_
`Python Cookbook Recipe <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/119466>`_
Find shortest paths from the start node to all nodes nearer than or equal to the end node.
Dijkstra's algorithm is only guaranteed to work correctly when all edge lengths are positive.
This code does not verify this property for all edges (only the edges examined until the end
vertex is reached), but will correctly compute shortest paths even for some graphs with negative
edges, and will raise an exception if it discovers that a negative edge has caused it to make a mistake.
*Adapted to altgraph by Istvan Albert, Pennsylvania State University - June, 9 2004*
"""
D = {} # dictionary of final distances
P = {} # dictionary of predecessors
Q = _priorityDictionary() # estimated distances of non-final vertices
Q[start] = 0
for v in Q:
D[v] = Q[v]
if v == end: break
for w in graph.out_nbrs(v):
edge_id = graph.edge_by_node(v,w)
vwLength = D[v] + graph.edge_data(edge_id)
if w in D:
if vwLength < D[w]:
raise GraphError("Dijkstra: found better path to already-final vertex")
elif w not in Q or vwLength < Q[w]:
Q[w] = vwLength
P[w] = v
return (D,P)
def shortest_path(graph, start, end):
"""
Find a single shortest path from the given start node to the given end node.
The input has the same conventions as dijkstra(). The output is a list of the nodes
in order along the shortest path.
**Note that the distances must be stored in the edge data as numeric data**
"""
D,P = dijkstra(graph, start, end)
Path = []
while 1:
Path.append(end)
if end == start: break
end = P[end]
Path.reverse()
return Path
#
# Utility classes and functions
#
class _priorityDictionary(dict):
'''
Priority dictionary using binary heaps (internal use only)
David Eppstein, UC Irvine, 8 Mar 2002
Implements a data structure that acts almost like a dictionary, with two modifications:
1. D.smallest() returns the value x minimizing D[x]. For this to work correctly,
all values D[x] stored in the dictionary must be comparable.
2. iterating "for x in D" finds and removes the items from D in sorted order.
Each item is not removed until the next item is requested, so D[x] will still
return a useful value until the next iteration of the for-loop.
Each operation takes logarithmic amortized time.
'''
def __init__(self):
'''
Initialize priorityDictionary by creating binary heap of pairs (value,key).
Note that changing or removing a dict entry will not remove the old pair from the heap
until it is found by smallest() or until the heap is rebuilt.
'''
self.__heap = []
dict.__init__(self)
def smallest(self):
'''
Find smallest item after removing deleted items from front of heap.
'''
if len(self) == 0:
raise IndexError("smallest of empty priorityDictionary")
heap = self.__heap
while heap[0][1] not in self or self[heap[0][1]] != heap[0][0]:
lastItem = heap.pop()
insertionPoint = 0
while 1:
smallChild = 2*insertionPoint+1
if smallChild+1 < len(heap) and heap[smallChild] > heap[smallChild+1] :
smallChild += 1
if smallChild >= len(heap) or lastItem <= heap[smallChild]:
heap[insertionPoint] = lastItem
break
heap[insertionPoint] = heap[smallChild]
insertionPoint = smallChild
return heap[0][1]
def __iter__(self):
'''
Create destructive sorted iterator of priorityDictionary.
'''
def iterfn():
while len(self) > 0:
x = self.smallest()
yield x
del self[x]
return iterfn()
def __setitem__(self,key,val):
'''
Change value stored in dictionary and add corresponding pair to heap.
Rebuilds the heap if the number of deleted items gets large, to avoid memory leakage.
'''
dict.__setitem__(self,key,val)
heap = self.__heap
if len(heap) > 2 * len(self):
self.__heap = [(v,k) for k,v in self.iteritems()]
self.__heap.sort() # builtin sort probably faster than O(n)-time heapify
else:
newPair = (val,key)
insertionPoint = len(heap)
heap.append(None)
while insertionPoint > 0 and newPair < heap[(insertionPoint-1)//2]:
heap[insertionPoint] = heap[(insertionPoint-1)//2]
insertionPoint = (insertionPoint-1)//2
heap[insertionPoint] = newPair
def setdefault(self,key,val):
'''
Reimplement setdefault to pass through our customized __setitem__.
'''
if key not in self:
self[key] = val
return self[key]

View File

@ -1,73 +0,0 @@
'''
altgraph.GraphStat - Functions providing various graph statistics
=================================================================
'''
import sys
def degree_dist(graph, limits=(0,0), bin_num=10, mode='out'):
'''
Computes the degree distribution for a graph.
Returns a list of tuples where the first element of the tuple is the center of the bin
representing a range of degrees and the second element of the tuple are the number of nodes
with the degree falling in the range.
Example::
....
'''
deg = []
if mode == 'inc':
get_deg = graph.inc_degree
else:
get_deg = graph.out_degree
for node in graph:
deg.append( get_deg(node) )
if not deg:
return []
results = _binning(values=deg, limits=limits, bin_num=bin_num)
return results
_EPS = 1.0/(2.0**32)
def _binning(values, limits=(0,0), bin_num=10):
'''
Bins data that falls between certain limits, if the limits are (0, 0) the
minimum and maximum values are used.
Returns a list of tuples where the first element of the tuple is the center of the bin
and the second element of the tuple are the counts.
'''
if limits == (0, 0):
min_val, max_val = min(values) - _EPS, max(values) + _EPS
else:
min_val, max_val = limits
# get bin size
bin_size = (max_val - min_val)/float(bin_num)
bins = [0] * (bin_num)
# will ignore these outliers for now
out_points = 0
for value in values:
try:
if (value - min_val) < 0:
out_points += 1
else:
index = int((value - min_val)/float(bin_size))
bins[index] += 1
except IndexError:
out_points += 1
# make it ready for an x,y plot
result = []
center = (bin_size/2) + min_val
for i, y in enumerate(bins):
x = center + bin_size * i
result.append( (x,y) )
return result

View File

@ -1,137 +0,0 @@
'''
altgraph.GraphUtil - Utility classes and functions
==================================================
'''
import random
from collections import deque
from altgraph import Graph
from altgraph import GraphError
def generate_random_graph(node_num, edge_num, self_loops=False, multi_edges=False):
'''
Generates and returns a :py:class:`~altgraph.Graph.Graph` instance with *node_num* nodes
randomly connected by *edge_num* edges.
'''
g = Graph.Graph()
if not multi_edges:
if self_loops:
max_edges = node_num * node_num
else:
max_edges = node_num * (node_num-1)
if edge_num > max_edges:
raise GraphError("inconsistent arguments to 'generate_random_graph'")
nodes = range(node_num)
for node in nodes:
g.add_node(node)
while 1:
head = random.choice(nodes)
tail = random.choice(nodes)
# loop defense
if head == tail and not self_loops:
continue
# multiple edge defense
if g.edge_by_node(head,tail) is not None and not multi_edges:
continue
# add the edge
g.add_edge(head, tail)
if g.number_of_edges() >= edge_num:
break
return g
def generate_scale_free_graph(steps, growth_num, self_loops=False, multi_edges=False):
'''
Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that will have *steps* \* *growth_num* nodes
and a scale free (powerlaw) connectivity. Starting with a fully connected graph with *growth_num* nodes
at every step *growth_num* nodes are added to the graph and are connected to existing nodes with
a probability proportional to the degree of these existing nodes.
'''
# FIXME: The code doesn't seem to do what the documentation claims.
graph = Graph.Graph()
# initialize the graph
store = []
for i in range(growth_num):
#store += [ i ] * (growth_num - 1)
for j in range(i + 1, growth_num):
store.append(i)
store.append(j)
graph.add_edge(i,j)
# generate
for node in range(growth_num, steps * growth_num):
graph.add_node(node)
while ( graph.out_degree(node) < growth_num ):
nbr = random.choice(store)
# loop defense
if node == nbr and not self_loops:
continue
# multi edge defense
if graph.edge_by_node(node, nbr) and not multi_edges:
continue
graph.add_edge(node, nbr)
for nbr in graph.out_nbrs(node):
store.append(node)
store.append(nbr)
return graph
def filter_stack(graph, head, filters):
"""
Perform a walk in a depth-first order starting
at *head*.
Returns (visited, removes, orphans).
* visited: the set of visited nodes
* removes: the list of nodes where the node
data does not all *filters*
* orphans: tuples of (last_good, node),
where node is not in removes, is directly
reachable from a node in *removes* and
*last_good* is the closest upstream node that is not
in *removes*.
"""
visited, removes, orphans = set([head]), set(), set()
stack = deque([(head, head)])
get_data = graph.node_data
get_edges = graph.out_edges
get_tail = graph.tail
while stack:
last_good, node = stack.pop()
data = get_data(node)
if data is not None:
for filtfunc in filters:
if not filtfunc(data):
removes.add(node)
break
else:
last_good = node
for edge in get_edges(node):
tail = get_tail(edge)
if last_good is not node:
orphans.add((last_good, tail))
if tail not in visited:
visited.add(tail)
stack.append((last_good, tail))
orphans = [(last_good, tail) for (last_good, tail) in orphans if tail not in removes]
#orphans.sort()
return visited, removes, orphans

View File

@ -1,202 +0,0 @@
"""
altgraph.ObjectGraph - Graph of objects with an identifier
==========================================================
A graph of objects that have a "graphident" attribute.
graphident is the key for the object in the graph
"""
from altgraph import GraphError
from altgraph.Graph import Graph
from altgraph.GraphUtil import filter_stack
class ObjectGraph(object):
"""
A graph of objects that have a "graphident" attribute.
graphident is the key for the object in the graph
"""
def __init__(self, graph=None, debug=0):
if graph is None:
graph = Graph()
self.graphident = self
self.graph = graph
self.debug = debug
self.indent = 0
graph.add_node(self, None)
def __repr__(self):
return '<%s>' % (type(self).__name__,)
def flatten(self, condition=None, start=None):
"""
Iterate over the subgraph that is entirely reachable by condition
starting from the given start node or the ObjectGraph root
"""
if start is None:
start = self
start = self.getRawIdent(start)
return self.graph.iterdata(start=start, condition=condition)
def nodes(self):
for ident in self.graph:
node = self.graph.node_data(ident)
if node is not None:
yield self.graph.node_data(ident)
def get_edges(self, node):
start = self.getRawIdent(node)
_, _, outraw, incraw = self.graph.describe_node(start)
def iter_edges(lst, n):
seen = set()
for tpl in (self.graph.describe_edge(e) for e in lst):
ident = tpl[n]
if ident not in seen:
yield self.findNode(ident)
seen.add(ident)
return iter_edges(outraw, 3), iter_edges(incraw, 2)
def edgeData(self, fromNode, toNode):
start = self.getRawIdent(fromNode)
stop = self.getRawIdent(toNode)
edge = self.graph.edge_by_node(start, stop)
return self.graph.edge_data(edge)
def updateEdgeData(self, fromNode, toNode, edgeData):
start = self.getRawIdent(fromNode)
stop = self.getRawIdent(toNode)
edge = self.graph.edge_by_node(start, stop)
self.graph.update_edge_data(edge, edgeData)
def filterStack(self, filters):
"""
Filter the ObjectGraph in-place by removing all edges to nodes that
do not match every filter in the given filter list
Returns a tuple containing the number of: (nodes_visited, nodes_removed, nodes_orphaned)
"""
visited, removes, orphans = filter_stack(self.graph, self, filters)
for last_good, tail in orphans:
self.graph.add_edge(last_good, tail, edge_data='orphan')
for node in removes:
self.graph.hide_node(node)
return len(visited)-1, len(removes), len(orphans)
def removeNode(self, node):
"""
Remove the given node from the graph if it exists
"""
ident = self.getIdent(node)
if ident is not None:
self.graph.hide_node(ident)
def removeReference(self, fromnode, tonode):
"""
Remove all edges from fromnode to tonode
"""
if fromnode is None:
fromnode = self
fromident = self.getIdent(fromnode)
toident = self.getIdent(tonode)
if fromident is not None and toident is not None:
while True:
edge = self.graph.edge_by_node(fromident, toident)
if edge is None:
break
self.graph.hide_edge(edge)
def getIdent(self, node):
"""
Get the graph identifier for a node
"""
ident = self.getRawIdent(node)
if ident is not None:
return ident
node = self.findNode(node)
if node is None:
return None
return node.graphident
def getRawIdent(self, node):
"""
Get the identifier for a node object
"""
if node is self:
return node
ident = getattr(node, 'graphident', None)
return ident
def __contains__(self, node):
return self.findNode(node) is not None
def findNode(self, node):
"""
Find the node on the graph
"""
ident = self.getRawIdent(node)
if ident is None:
ident = node
try:
return self.graph.node_data(ident)
except KeyError:
return None
def addNode(self, node):
"""
Add a node to the graph referenced by the root
"""
self.msg(4, "addNode", node)
try:
self.graph.restore_node(node.graphident)
except GraphError:
self.graph.add_node(node.graphident, node)
def createReference(self, fromnode, tonode, edge_data=None):
"""
Create a reference from fromnode to tonode
"""
if fromnode is None:
fromnode = self
fromident, toident = self.getIdent(fromnode), self.getIdent(tonode)
if fromident is None or toident is None:
return
self.msg(4, "createReference", fromnode, tonode, edge_data)
self.graph.add_edge(fromident, toident, edge_data=edge_data)
def createNode(self, cls, name, *args, **kw):
"""
Add a node of type cls to the graph if it does not already exist
by the given name
"""
m = self.findNode(name)
if m is None:
m = cls(name, *args, **kw)
self.addNode(m)
return m
def msg(self, level, s, *args):
"""
Print a debug message with the given level
"""
if s and level <= self.debug:
print ("%s%s %s" % (" " * self.indent, s, ' '.join(map(repr, args))))
def msgin(self, level, s, *args):
"""
Print a debug message and indent
"""
if level <= self.debug:
self.msg(level, s, *args)
self.indent = self.indent + 1
def msgout(self, level, s, *args):
"""
Dedent and print a debug message
"""
if level <= self.debug:
self.indent = self.indent - 1
self.msg(level, s, *args)

View File

@ -1,135 +0,0 @@
'''
altgraph - a python graph library
=================================
altgraph is a fork of `graphlib <http://pygraphlib.sourceforge.net>`_ tailored
to use newer Python 2.3+ features, including additional support used by the
py2app suite (modulegraph and macholib, specifically).
altgraph is a python based graph (network) representation and manipulation package.
It has started out as an extension to the `graph_lib module <http://www.ece.arizona.edu/~denny/python_nest/graph_lib_1.0.1.html>`_
written by Nathan Denny it has been significantly optimized and expanded.
The :class:`altgraph.Graph.Graph` class is loosely modeled after the `LEDA <http://www.algorithmic-solutions.com/enleda.htm>`_
(Library of Efficient Datatypes) representation. The library
includes methods for constructing graphs, BFS and DFS traversals,
topological sort, finding connected components, shortest paths as well as a number
graph statistics functions. The library can also visualize graphs
via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_.
The package contains the following modules:
- the :py:mod:`altgraph.Graph` module contains the :class:`~altgraph.Graph.Graph` class that stores the graph data
- the :py:mod:`altgraph.GraphAlgo` module implements graph algorithms operating on graphs (:py:class:`~altgraph.Graph.Graph`} instances)
- the :py:mod:`altgraph.GraphStat` module contains functions for computing statistical measures on graphs
- the :py:mod:`altgraph.GraphUtil` module contains functions for generating, reading and saving graphs
- the :py:mod:`altgraph.Dot` module contains functions for displaying graphs via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
- the :py:mod:`altgraph.ObjectGraph` module implements a graph of objects with a unique identifier
Installation
------------
Download and unpack the archive then type::
python setup.py install
This will install the library in the default location. For instructions on
how to customize the install procedure read the output of::
python setup.py --help install
To verify that the code works run the test suite::
python setup.py test
Example usage
-------------
Lets assume that we want to analyze the graph below (links to the full picture) GRAPH_IMG.
Our script then might look the following way::
from altgraph import Graph, GraphAlgo, Dot
# these are the edges
edges = [ (1,2), (2,4), (1,3), (2,4), (3,4), (4,5), (6,5),
(6,14), (14,15), (6, 15), (5,7), (7, 8), (7,13), (12,8),
(8,13), (11,12), (11,9), (13,11), (9,13), (13,10) ]
# creates the graph
graph = Graph.Graph()
for head, tail in edges:
graph.add_edge(head, tail)
# do a forward bfs from 1 at most to 20
print(graph.forw_bfs(1))
This will print the nodes in some breadth first order::
[1, 2, 3, 4, 5, 7, 8, 13, 11, 10, 12, 9]
If we wanted to get the hop-distance from node 1 to node 8
we coud write::
print(graph.get_hops(1, 8))
This will print the following::
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
Node 1 is at 0 hops since it is the starting node, nodes 2,3 are 1 hop away ...
node 8 is 5 hops away. To find the shortest distance between two nodes you
can use::
print(GraphAlgo.shortest_path(graph, 1, 12))
It will print the nodes on one (if there are more) the shortest paths::
[1, 2, 4, 5, 7, 13, 11, 12]
To display the graph we can use the GraphViz backend::
dot = Dot.Dot(graph)
# display the graph on the monitor
dot.display()
# save it in an image file
dot.save_img(file_name='graph', file_type='gif')
..
@author: U{Istvan Albert<http://www.personal.psu.edu/staff/i/u/iua1/>}
@license: MIT License
Copyright (c) 2004 Istvan Albert unless otherwise noted.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@requires: Python 2.3 or higher
@newfield contributor: Contributors:
@contributor: U{Reka Albert <http://www.phys.psu.edu/~ralbert/>}
'''
import pkg_resources
__version__ = pkg_resources.require('altgraph')[0].version
class GraphError(ValueError):
pass

View File

@ -1 +0,0 @@
""" altgraph tests """

View File

@ -1,45 +0,0 @@
#!/usr/bin/env py.test
import os
import sys
from altgraph import Graph, GraphAlgo
import unittest
class BasicTests (unittest.TestCase):
def setUp(self):
self.edges = [
(1,2), (2,4), (1,3), (2,4), (3,4), (4,5), (6,5), (6,14), (14,15),
(6, 15), (5,7), (7, 8), (7,13), (12,8), (8,13), (11,12), (11,9),
(13,11), (9,13), (13,10)
]
# these are the edges
self.store = {}
self.g = Graph.Graph()
for head, tail in self.edges:
self.store[head] = self.store[tail] = None
self.g.add_edge(head, tail)
def test_num_edges(self):
# check the parameters
self.assertEqual(self.g.number_of_nodes(), len(self.store))
self.assertEqual(self.g.number_of_edges(), len(self.edges))
def test_forw_bfs(self):
# do a forward bfs
self.assertEqual( self.g.forw_bfs(1),
[1, 2, 3, 4, 5, 7, 8, 13, 11, 10, 12, 9])
def test_get_hops(self):
# diplay the hops and hop numbers between nodes
self.assertEqual(self.g.get_hops(1, 8),
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
def test_shortest_path(self):
self.assertEqual(GraphAlgo.shortest_path(self.g, 1, 12),
[1, 2, 4, 5, 7, 13, 11, 12])
if __name__ == "__main__": # pragma: no cover
unittest.main()

View File

@ -1,370 +0,0 @@
import unittest
import os
from altgraph import Dot
from altgraph import Graph
from altgraph import GraphError
class TestDot (unittest.TestCase):
def test_constructor(self):
g = Graph.Graph([
(1,2),
(1,3),
(1,4),
(2,4),
(2,6),
(2,7),
(7,4),
(6,1),
]
)
dot = Dot.Dot(g)
self.assertEqual(dot.name, 'G')
self.assertEqual(dot.attr, {})
self.assertEqual(dot.temp_dot, 'tmp_dot.dot')
self.assertEqual(dot.temp_neo, 'tmp_neo.dot')
self.assertEqual(dot.dot, 'dot')
self.assertEqual(dot.dotty, 'dotty')
self.assertEqual(dot.neato, 'neato')
self.assertEqual(dot.type, 'digraph')
self.assertEqual(dot.nodes, dict([(x, {}) for x in g]))
edges = {}
for head in g:
edges[head] = {}
for tail in g.out_nbrs(head):
edges[head][tail] = {}
self.assertEqual(dot.edges[1], edges[1])
self.assertEqual(dot.edges, edges)
dot = Dot.Dot(g, nodes=[1,2],
edgefn=lambda node: list(sorted(g.out_nbrs(node)))[:-1],
nodevisitor=lambda node: {'label': node},
edgevisitor=lambda head, tail: {'label': (head, tail) },
name="testgraph",
dot='/usr/local/bin/dot',
dotty='/usr/local/bin/dotty',
neato='/usr/local/bin/neato',
graphtype="graph")
self.assertEqual(dot.name, 'testgraph')
self.assertEqual(dot.attr, {})
self.assertEqual(dot.temp_dot, 'tmp_dot.dot')
self.assertEqual(dot.temp_neo, 'tmp_neo.dot')
self.assertEqual(dot.dot, '/usr/local/bin/dot')
self.assertEqual(dot.dotty, '/usr/local/bin/dotty')
self.assertEqual(dot.neato, '/usr/local/bin/neato')
self.assertEqual(dot.type, 'graph')
self.assertEqual(dot.nodes, dict([(x, {'label': x}) for x in [1,2]]))
edges = {}
for head in [1,2]:
edges[head] = {}
for tail in list(sorted(g.out_nbrs(head)))[:-1]:
if tail not in [1,2]: continue
edges[head][tail] = {'label': (head, tail) }
self.assertEqual(dot.edges[1], edges[1])
self.assertEqual(dot.edges, edges)
self.assertRaises(GraphError, Dot.Dot, g, nodes=[1,2, 9])
def test_style(self):
g = Graph.Graph([])
dot = Dot.Dot(g)
self.assertEqual(dot.attr, {})
dot.style(key='value')
self.assertEqual(dot.attr, {'key': 'value'})
dot.style(key2='value2')
self.assertEqual(dot.attr, {'key2': 'value2'})
def test_node_style(self):
g = Graph.Graph([
(1,2),
(1,3),
(1,4),
(2,4),
(2,6),
(2,7),
(7,4),
(6,1),
]
)
dot = Dot.Dot(g)
self.assertEqual(dot.nodes[1], {})
dot.node_style(1, key='value')
self.assertEqual(dot.nodes[1], {'key': 'value'})
dot.node_style(1, key2='value2')
self.assertEqual(dot.nodes[1], {'key2': 'value2'})
self.assertEqual(dot.nodes[2], {})
dot.all_node_style(key3='value3')
for n in g:
self.assertEqual(dot.nodes[n], {'key3': 'value3'})
self.assertTrue(9 not in dot.nodes)
dot.node_style(9, key='value')
self.assertEqual(dot.nodes[9], {'key': 'value'})
def test_edge_style(self):
g = Graph.Graph([
(1,2),
(1,3),
(1,4),
(2,4),
(2,6),
(2,7),
(7,4),
(6,1),
]
)
dot = Dot.Dot(g)
self.assertEqual(dot.edges[1][2], {})
dot.edge_style(1,2, foo='bar')
self.assertEqual(dot.edges[1][2], {'foo': 'bar'})
dot.edge_style(1,2, foo2='2bar')
self.assertEqual(dot.edges[1][2], {'foo2': '2bar'})
self.assertEqual(dot.edges[1][3], {})
self.assertFalse(6 in dot.edges[1])
dot.edge_style(1,6, foo2='2bar')
self.assertEqual(dot.edges[1][6], {'foo2': '2bar'})
self.assertRaises(GraphError, dot.edge_style, 1, 9, a=1)
self.assertRaises(GraphError, dot.edge_style, 9, 1, a=1)
def test_iter(self):
g = Graph.Graph([
(1,2),
(1,3),
(1,4),
(2,4),
(2,6),
(2,7),
(7,4),
(6,1),
]
)
dot = Dot.Dot(g)
dot.style(graph="foobar")
dot.node_style(1, key='value')
dot.node_style(2, key='another', key2='world')
dot.edge_style(1,4, key1='value1', key2='value2')
dot.edge_style(2,4, key1='valueA')
self.assertEqual(list(iter(dot)), list(dot.iterdot()))
for item in dot.iterdot():
self.assertTrue(isinstance(item, str))
first = list(dot.iterdot())[0]
self.assertEqual(first, "digraph %s {\n"%(dot.name,))
dot.type = 'graph'
first = list(dot.iterdot())[0]
self.assertEqual(first, "graph %s {\n"%(dot.name,))
dot.type = 'foo'
self.assertRaises(GraphError, list, dot.iterdot())
dot.type = 'digraph'
self.assertEqual(list(dot), [
'digraph G {\n',
'graph="foobar";',
'\n',
'\t"1" [',
'key="value",',
'];\n',
'\t"2" [',
'key="another",',
'key2="world",',
'];\n',
'\t"3" [',
'];\n',
'\t"4" [',
'];\n',
'\t"6" [',
'];\n',
'\t"7" [',
'];\n',
'\t"1" -> "2" [',
'];\n',
'\t"1" -> "3" [',
'];\n',
'\t"1" -> "4" [',
'key1="value1",',
'key2="value2",',
'];\n',
'\t"2" -> "4" [',
'key1="valueA",',
'];\n',
'\t"2" -> "6" [',
'];\n',
'\t"2" -> "7" [',
'];\n',
'\t"6" -> "1" [',
'];\n',
'\t"7" -> "4" [',
'];\n',
'}\n'])
def test_save(self):
g = Graph.Graph([
(1,2),
(1,3),
(1,4),
(2,4),
(2,6),
(2,7),
(7,4),
(6,1),
]
)
dot = Dot.Dot(g)
dot.style(graph="foobar")
dot.node_style(1, key='value')
dot.node_style(2, key='another', key2='world')
dot.edge_style(1,4, key1='value1', key2='value2')
dot.edge_style(2,4, key1='valueA')
fn = 'test_dot.dot'
self.assertTrue(not os.path.exists(fn))
try:
dot.save_dot(fn)
fp = open(fn, 'r')
data = fp.read()
fp.close()
self.assertEqual(data, ''.join(dot))
finally:
if os.path.exists(fn):
os.unlink(fn)
def test_img(self):
g = Graph.Graph([
(1,2),
(1,3),
(1,4),
(2,4),
(2,6),
(2,7),
(7,4),
(6,1),
]
)
dot = Dot.Dot(g, dot='/usr/local/bin/!!dot', dotty='/usr/local/bin/!!dotty', neato='/usr/local/bin/!!neato')
dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
dot.node_style(1, label='BASE_NODE',shape='box', color='blue')
dot.node_style(2, style='filled', fillcolor='red')
dot.edge_style(1,4, style='dotted')
dot.edge_style(2,4, arrowhead='dot', label='binds', labelangle='90')
system_cmds = []
def fake_system(cmd):
system_cmds.append(cmd)
return None
try:
real_system = os.system
os.system = fake_system
system_cmds = []
dot.save_img('foo')
self.assertEqual(system_cmds, ['/usr/local/bin/!!dot -Tgif tmp_dot.dot -o foo.gif'])
system_cmds = []
dot.save_img('foo', file_type='jpg')
self.assertEqual(system_cmds, ['/usr/local/bin/!!dot -Tjpg tmp_dot.dot -o foo.jpg'])
system_cmds = []
dot.save_img('bar', file_type='jpg', mode='neato')
self.assertEqual(system_cmds, [
'/usr/local/bin/!!neato -o tmp_dot.dot tmp_neo.dot',
'/usr/local/bin/!!dot -Tjpg tmp_dot.dot -o bar.jpg',
])
system_cmds = []
dot.display()
self.assertEqual(system_cmds, [
'/usr/local/bin/!!dotty tmp_dot.dot'
])
system_cmds = []
dot.display(mode='neato')
self.assertEqual(system_cmds, [
'/usr/local/bin/!!neato -o tmp_dot.dot tmp_neo.dot',
'/usr/local/bin/!!dotty tmp_dot.dot'
])
finally:
if os.path.exists(dot.temp_dot):
os.unlink(dot.temp_dot)
if os.path.exists(dot.temp_neo):
os.unlink(dot.temp_neo)
os.system = real_system
if os.path.exists('/usr/local/bin/dot') and os.path.exists('/usr/local/bin/neato'):
try:
dot.dot='/usr/local/bin/dot'
dot.neato='/usr/local/bin/neato'
self.assertFalse(os.path.exists('foo.gif'))
dot.save_img('foo')
self.assertTrue(os.path.exists('foo.gif'))
os.unlink('foo.gif')
self.assertFalse(os.path.exists('foo.gif'))
dot.save_img('foo', mode='neato')
self.assertTrue(os.path.exists('foo.gif'))
os.unlink('foo.gif')
finally:
if os.path.exists(dot.temp_dot):
os.unlink(dot.temp_dot)
if os.path.exists(dot.temp_neo):
os.unlink(dot.temp_neo)
if __name__ == "__main__": # pragma: no cover
unittest.main()

View File

@ -1,644 +0,0 @@
import unittest
from altgraph import GraphError
from altgraph.Graph import Graph
class TestGraph (unittest.TestCase):
def test_nodes(self):
graph = Graph()
self.assertEqual(graph.node_list(), [])
o1 = object()
o1b = object()
o2 = object()
graph.add_node(1, o1)
graph.add_node(1, o1b)
graph.add_node(2, o2)
graph.add_node(3)
self.assertRaises(TypeError, graph.add_node, [])
self.assertTrue(graph.node_data(1) is o1)
self.assertTrue(graph.node_data(2) is o2)
self.assertTrue(graph.node_data(3) is None)
self.assertTrue(1 in graph)
self.assertTrue(2 in graph)
self.assertTrue(3 in graph)
self.assertEqual(graph.number_of_nodes(), 3)
self.assertEqual(graph.number_of_hidden_nodes(), 0)
self.assertEqual(graph.hidden_node_list(), [])
self.assertEqual(list(sorted(graph)), [1, 2, 3])
graph.hide_node(1)
graph.hide_node(2)
graph.hide_node(3)
self.assertEqual(graph.number_of_nodes(), 0)
self.assertEqual(graph.number_of_hidden_nodes(), 3)
self.assertEqual(list(sorted(graph.hidden_node_list())), [1, 2, 3])
self.assertFalse(1 in graph)
self.assertFalse(2 in graph)
self.assertFalse(3 in graph)
graph.add_node(1)
self.assertFalse(1 in graph)
graph.restore_node(1)
self.assertTrue(1 in graph)
self.assertFalse(2 in graph)
self.assertFalse(3 in graph)
graph.restore_all_nodes()
self.assertTrue(1 in graph)
self.assertTrue(2 in graph)
self.assertTrue(3 in graph)
self.assertEqual(list(sorted(graph.node_list())), [1, 2, 3])
v = graph.describe_node(1)
self.assertEqual(v, (1, o1, [], []))
def test_edges(self):
graph = Graph()
graph.add_node(1)
graph.add_node(2)
graph.add_node(3)
graph.add_node(4)
graph.add_node(5)
self.assertTrue(isinstance(graph.edge_list(), list))
graph.add_edge(1, 2)
graph.add_edge(4, 5, 'a')
self.assertRaises(GraphError, graph.add_edge, 'a', 'b', create_nodes=False)
self.assertEqual(graph.number_of_hidden_edges(), 0)
self.assertEqual(graph.number_of_edges(), 2)
e = graph.edge_by_node(1, 2)
self.assertTrue(isinstance(e, int))
graph.hide_edge(e)
self.assertEqual(graph.number_of_hidden_edges(), 1)
self.assertEqual(graph.number_of_edges(), 1)
e2 = graph.edge_by_node(1, 2)
self.assertTrue(e2 is None)
graph.restore_edge(e)
e2 = graph.edge_by_node(1, 2)
self.assertEqual(e, e2)
self.assertEqual(graph.number_of_hidden_edges(), 0)
self.assertEqual(graph.number_of_edges(), 2)
e1 = graph.edge_by_node(1, 2)
e2 = graph.edge_by_node(4, 5)
graph.hide_edge(e1)
graph.hide_edge(e2)
self.assertEqual(graph.number_of_edges(), 0)
graph.restore_all_edges()
self.assertEqual(graph.number_of_edges(), 2)
self.assertEqual(graph.edge_by_id(e1), (1,2))
self.assertRaises(GraphError, graph.edge_by_id, (e1+1)*(e2+1)+1)
self.assertEqual(list(sorted(graph.edge_list())), [e1, e2])
self.assertEqual(graph.describe_edge(e1), (e1, 1, 1, 2))
self.assertEqual(graph.describe_edge(e2), (e2, 'a', 4, 5))
self.assertEqual(graph.edge_data(e1), 1)
self.assertEqual(graph.edge_data(e2), 'a')
self.assertEqual(graph.head(e2), 4)
self.assertEqual(graph.tail(e2), 5)
graph.add_edge(1, 3)
graph.add_edge(1, 5)
graph.add_edge(4, 1)
self.assertEqual(list(sorted(graph.out_nbrs(1))), [2, 3, 5])
self.assertEqual(list(sorted(graph.inc_nbrs(1))), [4])
self.assertEqual(list(sorted(graph.inc_nbrs(5))), [1, 4])
self.assertEqual(list(sorted(graph.all_nbrs(1))), [2, 3, 4, 5])
graph.add_edge(5, 1)
self.assertEqual(list(sorted(graph.all_nbrs(5))), [1, 4])
self.assertEqual(graph.out_degree(1), 3)
self.assertEqual(graph.inc_degree(2), 1)
self.assertEqual(graph.inc_degree(5), 2)
self.assertEqual(graph.all_degree(5), 3)
v = graph.out_edges(4)
self.assertTrue(isinstance(v, list))
self.assertEqual(graph.edge_by_id(v[0]), (4, 5))
v = graph.out_edges(1)
for e in v:
self.assertEqual(graph.edge_by_id(e)[0], 1)
v = graph.inc_edges(1)
self.assertTrue(isinstance(v, list))
self.assertEqual(graph.edge_by_id(v[0]), (4, 1))
v = graph.inc_edges(5)
for e in v:
self.assertEqual(graph.edge_by_id(e)[1], 5)
v = graph.all_edges(5)
for e in v:
self.assertTrue(graph.edge_by_id(e)[1] == 5 or graph.edge_by_id(e)[0] == 5)
e1 = graph.edge_by_node(1, 2)
self.assertTrue(isinstance(e1, int))
graph.hide_node(1)
self.assertRaises(GraphError, graph.edge_by_node, 1, 2)
graph.restore_node(1)
e2 = graph.edge_by_node(1, 2)
self.assertEqual(e1, e2)
def test_toposort(self):
graph = Graph()
graph.add_node(1)
graph.add_node(2)
graph.add_node(3)
graph.add_node(4)
graph.add_node(5)
graph.add_edge(1, 2)
graph.add_edge(1, 3)
graph.add_edge(2, 4)
graph.add_edge(3, 5)
ok, result = graph.forw_topo_sort()
self.assertTrue(ok)
for idx in range(1, 6):
self.assertTrue(idx in result)
self.assertTrue(result.index(1) < result.index(2))
self.assertTrue(result.index(1) < result.index(3))
self.assertTrue(result.index(2) < result.index(4))
self.assertTrue(result.index(3) < result.index(5))
ok, result = graph.back_topo_sort()
self.assertTrue(ok)
for idx in range(1, 6):
self.assertTrue(idx in result)
self.assertTrue(result.index(2) < result.index(1))
self.assertTrue(result.index(3) < result.index(1))
self.assertTrue(result.index(4) < result.index(2))
self.assertTrue(result.index(5) < result.index(3))
# Same graph as before, but with edges
# reversed, which means we should get
# the same results as before if using
# back_topo_sort rather than forw_topo_sort
# (and v.v.)
graph = Graph()
graph.add_node(1)
graph.add_node(2)
graph.add_node(3)
graph.add_node(4)
graph.add_node(5)
graph.add_edge(2, 1)
graph.add_edge(3, 1)
graph.add_edge(4, 2)
graph.add_edge(5, 3)
ok, result = graph.back_topo_sort()
self.assertTrue(ok)
for idx in range(1, 6):
self.assertTrue(idx in result)
self.assertTrue(result.index(1) < result.index(2))
self.assertTrue(result.index(1) < result.index(3))
self.assertTrue(result.index(2) < result.index(4))
self.assertTrue(result.index(3) < result.index(5))
ok, result = graph.forw_topo_sort()
self.assertTrue(ok)
for idx in range(1, 6):
self.assertTrue(idx in result)
self.assertTrue(result.index(2) < result.index(1))
self.assertTrue(result.index(3) < result.index(1))
self.assertTrue(result.index(4) < result.index(2))
self.assertTrue(result.index(5) < result.index(3))
# Create a cycle
graph.add_edge(1, 5)
ok, result = graph.forw_topo_sort()
self.assertFalse(ok)
ok, result = graph.back_topo_sort()
self.assertFalse(ok)
def test_bfs_subgraph(self):
graph = Graph()
graph.add_edge(1, 2)
graph.add_edge(1, 4)
graph.add_edge(2, 4)
graph.add_edge(4, 8)
graph.add_edge(4, 9)
graph.add_edge(4, 10)
graph.add_edge(8, 10)
subgraph = graph.forw_bfs_subgraph(10)
self.assertTrue(isinstance(subgraph, Graph))
self.assertEqual(subgraph.number_of_nodes(), 1)
self.assertTrue(10 in subgraph)
self.assertEqual(subgraph.number_of_edges(), 0)
subgraph = graph.forw_bfs_subgraph(4)
self.assertTrue(isinstance(subgraph, Graph))
self.assertEqual(subgraph.number_of_nodes(), 4)
self.assertTrue(4 in subgraph)
self.assertTrue(8 in subgraph)
self.assertTrue(9 in subgraph)
self.assertTrue(10 in subgraph)
self.assertEqual(subgraph.number_of_edges(), 4)
e = subgraph.edge_by_node(4, 8)
e = subgraph.edge_by_node(4, 9)
e = subgraph.edge_by_node(4, 10)
e = subgraph.edge_by_node(8, 10)
# same graph as before, but switch around
# edges. This results in the same test results
# but now for back_bfs_subgraph rather than
# forw_bfs_subgraph
graph = Graph()
graph.add_edge(2, 1)
graph.add_edge(4, 1)
graph.add_edge(4, 2)
graph.add_edge(8, 4)
graph.add_edge(9, 4)
graph.add_edge(10, 4)
graph.add_edge(10, 8)
subgraph = graph.back_bfs_subgraph(10)
self.assertTrue(isinstance(subgraph, Graph))
self.assertEqual(subgraph.number_of_nodes(), 1)
self.assertTrue(10 in subgraph)
self.assertEqual(subgraph.number_of_edges(), 0)
subgraph = graph.back_bfs_subgraph(4)
self.assertTrue(isinstance(subgraph, Graph))
self.assertEqual(subgraph.number_of_nodes(), 4)
self.assertTrue(4 in subgraph)
self.assertTrue(8 in subgraph)
self.assertTrue(9 in subgraph)
self.assertTrue(10 in subgraph)
self.assertEqual(subgraph.number_of_edges(), 4)
e = subgraph.edge_by_node(4, 8)
e = subgraph.edge_by_node(4, 9)
e = subgraph.edge_by_node(4, 10)
e = subgraph.edge_by_node(8, 10)
def test_iterdfs(self):
graph = Graph()
graph.add_edge("1", "1.1")
graph.add_edge("1", "1.2")
graph.add_edge("1", "1.3")
graph.add_edge("1.1", "1.1.1")
graph.add_edge("1.1", "1.1.2")
graph.add_edge("1.2", "1.2.1")
graph.add_edge("1.2", "1.2.2")
graph.add_edge("1.2.2", "1.2.2.1")
graph.add_edge("1.2.2", "1.2.2.2")
graph.add_edge("1.2.2", "1.2.2.3")
result = list(graph.iterdfs("1"))
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
])
result = list(graph.iterdfs("1", "1.2.1"))
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1'
])
result = graph.forw_dfs("1")
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
])
result = graph.forw_dfs("1", "1.2.1")
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1'
])
graph = Graph()
graph.add_edge("1.1", "1")
graph.add_edge("1.2", "1")
graph.add_edge("1.3", "1")
graph.add_edge("1.1.1", "1.1")
graph.add_edge("1.1.2", "1.1")
graph.add_edge("1.2.1", "1.2")
graph.add_edge("1.2.2", "1.2")
graph.add_edge("1.2.2.1", "1.2.2")
graph.add_edge("1.2.2.2", "1.2.2")
graph.add_edge("1.2.2.3", "1.2.2")
result = list(graph.iterdfs("1", forward=False))
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
])
result = list(graph.iterdfs("1", "1.2.1", forward=False))
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1'
])
result = graph.back_dfs("1")
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
])
result = graph.back_dfs("1", "1.2.1")
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1'
])
# Introduce cyle:
graph.add_edge("1", "1.2")
result = list(graph.iterdfs("1", forward=False))
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
])
result = graph.back_dfs("1")
self.assertEqual(result, [
'1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
'1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
])
def test_iterdata(self):
graph = Graph()
graph.add_node("1", "I")
graph.add_node("1.1", "I.I")
graph.add_node("1.2", "I.II")
graph.add_node("1.3", "I.III")
graph.add_node("1.1.1", "I.I.I")
graph.add_node("1.1.2", "I.I.II")
graph.add_node("1.2.1", "I.II.I")
graph.add_node("1.2.2", "I.II.II")
graph.add_node("1.2.2.1", "I.II.II.I")
graph.add_node("1.2.2.2", "I.II.II.II")
graph.add_node("1.2.2.3", "I.II.II.III")
graph.add_edge("1", "1.1")
graph.add_edge("1", "1.2")
graph.add_edge("1", "1.3")
graph.add_edge("1.1", "1.1.1")
graph.add_edge("1.1", "1.1.2")
graph.add_edge("1.2", "1.2.1")
graph.add_edge("1.2", "1.2.2")
graph.add_edge("1.2.2", "1.2.2.1")
graph.add_edge("1.2.2", "1.2.2.2")
graph.add_edge("1.2.2", "1.2.2.3")
result = list(graph.iterdata("1", forward=True))
self.assertEqual(result, [
'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
'I.II.II.I', 'I.II.I', 'I.I', 'I.I.II', 'I.I.I'
])
result = list(graph.iterdata("1", end="1.2.1", forward=True))
self.assertEqual(result, [
'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
'I.II.II.I', 'I.II.I'
])
result = list(graph.iterdata("1", condition=lambda n: len(n) < 6, forward=True))
self.assertEqual(result, [
'I', 'I.III', 'I.II',
'I.I', 'I.I.I'
])
# And the revese option:
graph = Graph()
graph.add_node("1", "I")
graph.add_node("1.1", "I.I")
graph.add_node("1.2", "I.II")
graph.add_node("1.3", "I.III")
graph.add_node("1.1.1", "I.I.I")
graph.add_node("1.1.2", "I.I.II")
graph.add_node("1.2.1", "I.II.I")
graph.add_node("1.2.2", "I.II.II")
graph.add_node("1.2.2.1", "I.II.II.I")
graph.add_node("1.2.2.2", "I.II.II.II")
graph.add_node("1.2.2.3", "I.II.II.III")
graph.add_edge("1.1", "1")
graph.add_edge("1.2", "1")
graph.add_edge("1.3", "1")
graph.add_edge("1.1.1", "1.1")
graph.add_edge("1.1.2", "1.1")
graph.add_edge("1.2.1", "1.2")
graph.add_edge("1.2.2", "1.2")
graph.add_edge("1.2.2.1", "1.2.2")
graph.add_edge("1.2.2.2", "1.2.2")
graph.add_edge("1.2.2.3", "1.2.2")
result = list(graph.iterdata("1", forward=False))
self.assertEqual(result, [
'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
'I.II.II.I', 'I.II.I', 'I.I', 'I.I.II', 'I.I.I'
])
result = list(graph.iterdata("1", end="1.2.1", forward=False))
self.assertEqual(result, [
'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
'I.II.II.I', 'I.II.I'
])
result = list(graph.iterdata("1", condition=lambda n: len(n) < 6, forward=False))
self.assertEqual(result, [
'I', 'I.III', 'I.II',
'I.I', 'I.I.I'
])
def test_bfs(self):
graph = Graph()
graph.add_edge("1", "1.1")
graph.add_edge("1.1", "1.1.1")
graph.add_edge("1.1", "1.1.2")
graph.add_edge("1.1.2", "1.1.2.1")
graph.add_edge("1.1.2", "1.1.2.2")
graph.add_edge("1", "1.2")
graph.add_edge("1", "1.3")
graph.add_edge("1.2", "1.2.1")
self.assertEqual(graph.forw_bfs("1"),
['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
self.assertEqual(graph.forw_bfs("1", "1.1.1"),
['1', '1.1', '1.2', '1.3', '1.1.1'])
# And the "reverse" graph
graph = Graph()
graph.add_edge("1.1", "1")
graph.add_edge("1.1.1", "1.1")
graph.add_edge("1.1.2", "1.1")
graph.add_edge("1.1.2.1", "1.1.2")
graph.add_edge("1.1.2.2", "1.1.2")
graph.add_edge("1.2", "1")
graph.add_edge("1.3", "1")
graph.add_edge("1.2.1", "1.2")
self.assertEqual(graph.back_bfs("1"),
['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
self.assertEqual(graph.back_bfs("1", "1.1.1"),
['1', '1.1', '1.2', '1.3', '1.1.1'])
# check cycle handling
graph.add_edge("1", "1.2.1")
self.assertEqual(graph.back_bfs("1"),
['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
def test_connected(self):
graph = Graph()
graph.add_node(1)
graph.add_node(2)
graph.add_node(3)
graph.add_node(4)
self.assertFalse(graph.connected())
graph.add_edge(1, 2)
graph.add_edge(3, 4)
self.assertFalse(graph.connected())
graph.add_edge(2, 3)
graph.add_edge(4, 1)
self.assertTrue(graph.connected())
def test_edges_complex(self):
g = Graph()
g.add_edge(1, 2)
e = g.edge_by_node(1,2)
g.hide_edge(e)
g.hide_node(2)
self.assertRaises(GraphError, g.restore_edge, e)
g.restore_all_edges()
self.assertRaises(GraphError, g.edge_by_id, e)
def test_clust_coef(self):
g = Graph()
g.add_edge(1, 2)
g.add_edge(1, 3)
g.add_edge(1, 4)
self.assertEqual(g.clust_coef(1), 0)
g.add_edge(2, 5)
g.add_edge(3, 5)
g.add_edge(4, 5)
self.assertEqual(g.clust_coef(1), 0)
g.add_edge(2, 3)
self.assertEqual(g.clust_coef(1), 1./6)
g.add_edge(2, 4)
self.assertEqual(g.clust_coef(1), 2./6)
g.add_edge(4, 2)
self.assertEqual(g.clust_coef(1), 3./6)
g.add_edge(2, 3)
g.add_edge(2, 4)
g.add_edge(3, 4)
g.add_edge(3, 2)
g.add_edge(4, 2)
g.add_edge(4, 3)
self.assertEqual(g.clust_coef(1), 1)
def test_get_hops(self):
graph = Graph()
graph.add_edge(1, 2)
graph.add_edge(1, 3)
graph.add_edge(2, 4)
graph.add_edge(4, 5)
graph.add_edge(5, 7)
graph.add_edge(7, 8)
self.assertEqual(graph.get_hops(1),
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
self.assertEqual(graph.get_hops(1, 5),
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3)])
graph.add_edge(5, 1)
graph.add_edge(7, 1)
graph.add_edge(7, 4)
self.assertEqual(graph.get_hops(1),
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
# And the reverse graph
graph = Graph()
graph.add_edge(2, 1)
graph.add_edge(3, 1)
graph.add_edge(4, 2)
graph.add_edge(5, 4)
graph.add_edge(7, 5)
graph.add_edge(8, 7)
self.assertEqual(graph.get_hops(1, forward=False),
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
self.assertEqual(graph.get_hops(1, 5, forward=False),
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3)])
graph.add_edge(1, 5)
graph.add_edge(1, 7)
graph.add_edge(4, 7)
self.assertEqual(graph.get_hops(1, forward=False),
[(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
def test_constructor(self):
graph = Graph(iter([
(1, 2),
(2, 3, 'a'),
(1, 3),
(3, 4),
]))
self.assertEqual(graph.number_of_nodes(), 4)
self.assertEqual(graph.number_of_edges(), 4)
try:
graph.edge_by_node(1,2)
graph.edge_by_node(2,3)
graph.edge_by_node(1,3)
graph.edge_by_node(3,4)
except GraphError:
self.fail("Incorrect graph")
self.assertEqual(graph.edge_data(graph.edge_by_node(2, 3)), 'a')
self.assertRaises(GraphError, Graph, [(1,2,3,4)])
if __name__ == "__main__": # pragma: no cover
unittest.main()

View File

@ -1,70 +0,0 @@
import unittest
from altgraph import GraphStat
from altgraph import Graph
import sys
class TestDegreesDist (unittest.TestCase):
def test_simple(self):
a = Graph.Graph()
self.assertEqual(GraphStat.degree_dist(a), [])
a.add_node(1)
a.add_node(2)
a.add_node(3)
self.assertEqual(GraphStat.degree_dist(a), GraphStat._binning([0, 0, 0]))
for x in range(100):
a.add_node(x)
for x in range(1, 100):
for y in range(1, 50):
if x % y == 0:
a.add_edge(x, y)
counts_inc = []
counts_out = []
for n in a:
counts_inc.append(a.inc_degree(n))
counts_out.append(a.out_degree(n))
self.assertEqual(GraphStat.degree_dist(a), GraphStat._binning(counts_out))
self.assertEqual(GraphStat.degree_dist(a, mode='inc'), GraphStat._binning(counts_inc))
class TestBinning (unittest.TestCase):
def test_simple(self):
# Binning [0, 100) into 10 bins
a = list(range(100))
out = GraphStat._binning(a, limits=(0, 100), bin_num=10)
self.assertEqual(out,
[ (x*1.0, 10) for x in range(5, 100, 10) ])
# Check that outliers are ignored.
a = list(range(100))
out = GraphStat._binning(a, limits=(0, 90), bin_num=9)
self.assertEqual(out,
[ (x*1.0, 10) for x in range(5, 90, 10) ])
out = GraphStat._binning(a, limits=(0, 100), bin_num=15)
binSize = 100 / 15.0
result = [0]*15
for i in range(100):
bin = int(i/binSize)
try:
result[bin] += 1
except IndexError:
pass
result = [ (i * binSize + binSize/2, result[i]) for i in range(len(result))]
self.assertEqual(result, out)
if __name__ == "__main__": # pragma: no cover
unittest.main()

View File

@ -1,140 +0,0 @@
import unittest
from altgraph import GraphUtil
from altgraph import Graph, GraphError
class TestGraphUtil (unittest.TestCase):
def test_generate_random(self):
g = GraphUtil.generate_random_graph(10, 50)
self.assertEqual(g.number_of_nodes(), 10)
self.assertEqual(g.number_of_edges(), 50)
seen = set()
for e in g.edge_list():
h, t = g.edge_by_id(e)
self.assertFalse(h == t)
self.assertTrue((h, t) not in seen)
seen.add((h, t))
g = GraphUtil.generate_random_graph(5, 30, multi_edges=True)
self.assertEqual(g.number_of_nodes(), 5)
self.assertEqual(g.number_of_edges(), 30)
seen = set()
for e in g.edge_list():
h, t = g.edge_by_id(e)
self.assertFalse(h == t)
if (h, t) in seen:
break
seen.add((h, t))
else:
self.fail("no duplicates?")
g = GraphUtil.generate_random_graph(5, 21, self_loops=True)
self.assertEqual(g.number_of_nodes(), 5)
self.assertEqual(g.number_of_edges(), 21)
seen = set()
for e in g.edge_list():
h, t = g.edge_by_id(e)
self.assertFalse((h, t) in seen)
if h == t:
break
seen.add((h, t))
else:
self.fail("no self loops?")
self.assertRaises(GraphError, GraphUtil.generate_random_graph, 5, 21)
g = GraphUtil.generate_random_graph(5, 21, True)
self.assertRaises(GraphError, GraphUtil.generate_random_graph, 5, 26, True)
def test_generate_scale_free(self):
graph = GraphUtil.generate_scale_free_graph(50, 10)
self.assertEqual(graph.number_of_nodes(), 500)
counts = {}
for node in graph:
degree = graph.inc_degree(node)
try:
counts[degree] += 1
except KeyError:
counts[degree] = 1
total_counts = sum(counts.values())
P = {}
for degree, count in counts.items():
P[degree] = count * 1.0 / total_counts
# XXX: use algoritm <http://stackoverflow.com/questions/3433486/how-to-do-exponential-and-logarithmic-curve-fitting-in-python-i-found-only-polyn>
# to check if P[degree] ~ degree ** G (for some G)
#print sorted(P.items())
#print sorted([(count, degree) for degree, count in counts.items()])
#self.fail("missing tests for GraphUtil.generate_scale_free_graph")
def test_filter_stack(self):
g = Graph.Graph()
g.add_node("1", "N.1")
g.add_node("1.1", "N.1.1")
g.add_node("1.1.1", "N.1.1.1")
g.add_node("1.1.2", "N.1.1.2")
g.add_node("1.1.3", "N.1.1.3")
g.add_node("1.1.1.1", "N.1.1.1.1")
g.add_node("1.1.1.2", "N.1.1.1.2")
g.add_node("1.1.2.1", "N.1.1.2.1")
g.add_node("1.1.2.2", "N.1.1.2.2")
g.add_node("1.1.2.3", "N.1.1.2.3")
g.add_node("2", "N.2")
g.add_edge("1", "1.1")
g.add_edge("1.1", "1.1.1")
g.add_edge("1.1", "1.1.2")
g.add_edge("1.1", "1.1.3")
g.add_edge("1.1.1", "1.1.1.1")
g.add_edge("1.1.1", "1.1.1.2")
g.add_edge("1.1.2", "1.1.2.1")
g.add_edge("1.1.2", "1.1.2.2")
g.add_edge("1.1.2", "1.1.2.3")
v, r, o = GraphUtil.filter_stack(g, "1", [
lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.2.3" ])
self.assertEqual(v,
set(["1", "1.1", "1.1.1", "1.1.2", "1.1.3",
"1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2",
"1.1.2.3"]))
self.assertEqual(r, set([
"1.1.1", "1.1.2.3"]))
o.sort()
self.assertEqual(o,
[
("1.1", "1.1.1.1"),
("1.1", "1.1.1.2")
])
v, r, o = GraphUtil.filter_stack(g, "1", [
lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.1.2" ])
self.assertEqual(v,
set(["1", "1.1", "1.1.1", "1.1.2", "1.1.3",
"1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2",
"1.1.2.3"]))
self.assertEqual(r, set([
"1.1.1", "1.1.1.2"]))
self.assertEqual(o,
[
("1.1", "1.1.1.1"),
])
if __name__ == "__main__": # pragma: no cover
unittest.main()

View File

@ -1,349 +0,0 @@
import unittest
import sys
from altgraph.ObjectGraph import ObjectGraph
from altgraph.Graph import Graph
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
class Node (object):
def __init__(self, graphident):
self.graphident = graphident
class SubNode (Node):
pass
class ArgNode (object):
def __init__(self, graphident, *args, **kwds):
self.graphident = graphident
self.args = args
self.kwds = kwds
def __repr__(self):
return '<ArgNode %s>'%(self.graphident,)
class TestObjectGraph (unittest.TestCase):
def test_constructor(self):
graph = ObjectGraph()
self.assertTrue(isinstance(graph, ObjectGraph))
g = Graph()
graph = ObjectGraph(g)
self.assertTrue(graph.graph is g)
self.assertEqual(graph.debug, 0)
self.assertEqual(graph.indent, 0)
graph = ObjectGraph(debug=5)
self.assertEqual(graph.debug, 5)
def test_repr(self):
graph = ObjectGraph()
self.assertEqual(repr(graph), '<ObjectGraph>')
def testNodes(self):
graph = ObjectGraph()
n1 = Node("n1")
n2 = Node("n2")
n3 = Node("n3")
n4 = Node("n4")
n1b = Node("n1")
self.assertTrue(graph.getIdent(graph) is graph)
self.assertTrue(graph.getRawIdent(graph) is graph)
graph.addNode(n1)
graph.addNode(n2)
graph.addNode(n3)
self.assertTrue(n1 in graph)
self.assertFalse(n4 in graph)
self.assertTrue("n1" in graph)
self.assertFalse("n4" in graph)
self.assertTrue(graph.findNode(n1) is n1)
self.assertTrue(graph.findNode(n1b) is n1)
self.assertTrue(graph.findNode(n2) is n2)
self.assertTrue(graph.findNode(n4) is None)
self.assertTrue(graph.findNode("n1") is n1)
self.assertTrue(graph.findNode("n2") is n2)
self.assertTrue(graph.findNode("n4") is None)
self.assertEqual(graph.getRawIdent(n1), "n1")
self.assertEqual(graph.getRawIdent(n1b), "n1")
self.assertEqual(graph.getRawIdent(n4), "n4")
self.assertEqual(graph.getRawIdent("n1"), None)
self.assertEqual(graph.getIdent(n1), "n1")
self.assertEqual(graph.getIdent(n1b), "n1")
self.assertEqual(graph.getIdent(n4), "n4")
self.assertEqual(graph.getIdent("n1"), "n1")
self.assertTrue(n3 in graph)
graph.removeNode(n3)
self.assertTrue(n3 not in graph)
graph.addNode(n3)
self.assertTrue(n3 in graph)
n = graph.createNode(SubNode, "n1")
self.assertTrue(n is n1)
n = graph.createNode(SubNode, "n8")
self.assertTrue(isinstance(n, SubNode))
self.assertTrue(n in graph)
self.assertTrue(graph.findNode("n8") is n)
n = graph.createNode(ArgNode, "args", 1, 2, 3, a='a', b='b')
self.assertTrue(isinstance(n, ArgNode))
self.assertTrue(n in graph)
self.assertTrue(graph.findNode("args") is n)
self.assertEqual(n.args, (1, 2, 3))
self.assertEqual(n.kwds, {'a':'a', 'b':'b'})
def testEdges(self):
graph = ObjectGraph()
n1 = graph.createNode(ArgNode, "n1", 1)
n2 = graph.createNode(ArgNode, "n2", 1)
n3 = graph.createNode(ArgNode, "n3", 1)
n4 = graph.createNode(ArgNode, "n4", 1)
graph.createReference(n1, n2, "n1-n2")
graph.createReference("n1", "n3", "n1-n3")
graph.createReference("n2", n3)
g = graph.graph
e = g.edge_by_node("n1", "n2")
self.assertTrue(e is not None)
self.assertEqual(g.edge_data(e), "n1-n2")
e = g.edge_by_node("n1", "n3")
self.assertTrue(e is not None)
self.assertEqual(g.edge_data(e), "n1-n3")
e = g.edge_by_node("n2", "n3")
self.assertTrue(e is not None)
self.assertEqual(g.edge_data(e), None)
e = g.edge_by_node("n1", "n4")
self.assertTrue(e is None)
graph.removeReference(n1, n2)
e = g.edge_by_node("n1", "n2")
self.assertTrue(e is None)
graph.removeReference("n1", "n3")
e = g.edge_by_node("n1", "n3")
self.assertTrue(e is None)
graph.createReference(n1, n2, "foo")
e = g.edge_by_node("n1", "n2")
self.assertTrue(e is not None)
self.assertEqual(g.edge_data(e), "foo")
def test_flatten(self):
graph = ObjectGraph()
n1 = graph.createNode(ArgNode, "n1", 1)
n2 = graph.createNode(ArgNode, "n2", 2)
n3 = graph.createNode(ArgNode, "n3", 3)
n4 = graph.createNode(ArgNode, "n4", 4)
n5 = graph.createNode(ArgNode, "n5", 5)
n6 = graph.createNode(ArgNode, "n6", 6)
n7 = graph.createNode(ArgNode, "n7", 7)
n8 = graph.createNode(ArgNode, "n8", 8)
graph.createReference(graph, n1)
graph.createReference(graph, n7)
graph.createReference(n1, n2)
graph.createReference(n1, n4)
graph.createReference(n2, n3)
graph.createReference(n2, n5)
graph.createReference(n5, n6)
graph.createReference(n4, n6)
graph.createReference(n4, n2)
self.assertFalse(isinstance(graph.flatten(), list))
fl = list(graph.flatten())
self.assertTrue(n1 in fl)
self.assertTrue(n2 in fl)
self.assertTrue(n3 in fl)
self.assertTrue(n4 in fl)
self.assertTrue(n5 in fl)
self.assertTrue(n6 in fl)
self.assertTrue(n7 in fl)
self.assertFalse(n8 in fl)
fl = list(graph.flatten(start=n2))
self.assertFalse(n1 in fl)
self.assertTrue(n2 in fl)
self.assertTrue(n3 in fl)
self.assertFalse(n4 in fl)
self.assertTrue(n5 in fl)
self.assertTrue(n6 in fl)
self.assertFalse(n7 in fl)
self.assertFalse(n8 in fl)
graph.createReference(n1, n5)
fl = list(graph.flatten(lambda n: n.args[0] % 2 != 0))
self.assertTrue(n1 in fl)
self.assertFalse(n2 in fl)
self.assertFalse(n3 in fl)
self.assertFalse(n4 in fl)
self.assertTrue(n5 in fl)
self.assertFalse(n6 in fl)
self.assertTrue(n7 in fl)
self.assertFalse(n8 in fl)
def test_iter_nodes(self):
graph = ObjectGraph()
n1 = graph.createNode(ArgNode, "n1", 1)
n2 = graph.createNode(ArgNode, "n2", 2)
n3 = graph.createNode(ArgNode, "n3", 3)
n4 = graph.createNode(ArgNode, "n4", 4)
n5 = graph.createNode(ArgNode, "n5", 5)
n6 = graph.createNode(ArgNode, "n6", 5)
nodes = graph.nodes()
if sys.version[0] == '2':
self.assertTrue(hasattr(nodes, 'next'))
else:
self.assertTrue(hasattr(nodes, '__next__'))
self.assertTrue(hasattr(nodes, '__iter__'))
nodes = list(nodes)
self.assertEqual(len(nodes), 6)
self.assertTrue(n1 in nodes)
self.assertTrue(n2 in nodes)
self.assertTrue(n3 in nodes)
self.assertTrue(n4 in nodes)
self.assertTrue(n5 in nodes)
self.assertTrue(n6 in nodes)
def test_get_edges(self):
graph = ObjectGraph()
n1 = graph.createNode(ArgNode, "n1", 1)
n2 = graph.createNode(ArgNode, "n2", 2)
n3 = graph.createNode(ArgNode, "n3", 3)
n4 = graph.createNode(ArgNode, "n4", 4)
n5 = graph.createNode(ArgNode, "n5", 5)
n6 = graph.createNode(ArgNode, "n6", 5)
graph.createReference(n1, n2)
graph.createReference(n1, n3)
graph.createReference(n3, n1)
graph.createReference(n5, n1)
graph.createReference(n2, n4)
graph.createReference(n2, n5)
graph.createReference(n6, n2)
outs, ins = graph.get_edges(n1)
self.assertFalse(isinstance(outs, list))
self.assertFalse(isinstance(ins, list))
ins = list(ins)
outs = list(outs)
self.assertTrue(n1 not in outs)
self.assertTrue(n2 in outs)
self.assertTrue(n3 in outs)
self.assertTrue(n4 not in outs)
self.assertTrue(n5 not in outs)
self.assertTrue(n6 not in outs)
self.assertTrue(n1 not in ins)
self.assertTrue(n2 not in ins)
self.assertTrue(n3 in ins)
self.assertTrue(n4 not in ins)
self.assertTrue(n5 in ins)
self.assertTrue(n6 not in ins)
def test_filterStack(self):
graph = ObjectGraph()
n1 = graph.createNode(ArgNode, "n1", 0)
n11 = graph.createNode(ArgNode, "n1.1", 1)
n12 = graph.createNode(ArgNode, "n1.2", 0)
n111 = graph.createNode(ArgNode, "n1.1.1", 0)
n112 = graph.createNode(ArgNode, "n1.1.2",2)
n2 = graph.createNode(ArgNode, "n2", 0)
n3 = graph.createNode(ArgNode, "n2", 0)
graph.createReference(None, n1)
graph.createReference(None, n2)
graph.createReference(n1, n11)
graph.createReference(n1, n12)
graph.createReference(n11, n111)
graph.createReference(n11, n112)
self.assertTrue(n1 in graph)
self.assertTrue(n2 in graph)
self.assertTrue(n11 in graph)
self.assertTrue(n12 in graph)
self.assertTrue(n111 in graph)
self.assertTrue(n112 in graph)
self.assertTrue(n2 in graph)
self.assertTrue(n3 in graph)
visited, removes, orphans = graph.filterStack(
[lambda n: n.args[0] != 1, lambda n: n.args[0] != 2])
self.assertEqual(visited, 6)
self.assertEqual(removes, 2)
self.assertEqual(orphans, 1)
e = graph.graph.edge_by_node(n1.graphident, n111.graphident)
self.assertEqual(graph.graph.edge_data(e), "orphan")
self.assertTrue(n1 in graph)
self.assertTrue(n2 in graph)
self.assertTrue(n11 not in graph)
self.assertTrue(n12 in graph)
self.assertTrue(n111 in graph)
self.assertTrue(n112 not in graph)
self.assertTrue(n2 in graph)
self.assertTrue(n3 in graph)
class TestObjectGraphIO (unittest.TestCase):
def setUp(self):
self._stdout = sys.stdout
def tearDown(self):
sys.stdout = self._stdout
def test_msg(self):
graph = ObjectGraph()
sys.stdout = fp = StringIO()
graph.msg(0, "foo")
self.assertEqual(fp.getvalue(), "foo \n")
sys.stdout = fp = StringIO()
graph.msg(5, "foo")
self.assertEqual(fp.getvalue(), "")
sys.stdout = fp = StringIO()
graph.debug = 10
graph.msg(5, "foo")
self.assertEqual(fp.getvalue(), "foo \n")
sys.stdout = fp = StringIO()
graph.msg(0, "foo", 1, "a")
self.assertEqual(fp.getvalue(), "foo 1 'a'\n")
sys.stdout = fp = StringIO()
graph.msgin(0, "hello", "world")
graph.msg(0, "test me")
graph.msgout(0, "bye bye")
self.assertEqual(fp.getvalue(), "hello 'world'\n test me \nbye bye \n")
if __name__ == "__main__": # pragma: no cover
unittest.main()

View File

@ -1,89 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/altgraph.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/altgraph.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +0,0 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 84aa655833f036f5ba0f6f2dbd1945fa
tags: 645f666f9bcd5a90fca523b33c5a78b7

View File

@ -1,176 +0,0 @@
Release history
===============
0.11
----
- Stabilize the order of elements in dot file exports,
patch from bitbucket user 'pombredanne'.
- Tweak setup.py file to remove dependency on distribute (but
keep the dependency on setuptools)
0.10.2
------
- There where no classifiers in the package metadata due to a bug
in setup.py
0.10.1
------
This is a bugfix release
Bug fixes:
- Issue #3: The source archive contains a README.txt
while the setup file refers to ReadMe.txt.
This is caused by a misfeature in distutils, as a
workaround I've renamed ReadMe.txt to README.txt
in the source tree and setup file.
0.10
-----
This is a minor feature release
Features:
- Do not use "2to3" to support Python 3.
As a side effect of this altgraph now supports
Python 2.6 and later, and no longer supports
earlier releases of Python.
- The order of attributes in the Dot output
is now always alphabetical.
With this change the output will be consistent
between runs and Python versions.
0.9
---
This is a minor bugfix release
Features:
- Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
yielding all nodes in an object graph.
Bugfixes:
- The 0.8 release didn't work with py2app when using
python 3.x.
0.8
-----
This is a minor feature release. The major new feature
is a extensive set of unittests, which explains almost
all other changes in this release.
Bugfixes:
- Installing failed with Python 2.5 due to using a distutils
class that isn't available in that version of Python
(issue #1 on the issue tracker)
- ``altgraph.GraphStat.degree_dist`` now actually works
- ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
no longer create the edge when one of the nodes doesn't
exist.
- ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
- ``altgraph.Graph.back_topo_sort`` was completely broken in
previous releases.
- ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
- ``altgraph.Graph.back_bfs_subgraph`` now actually works.
- ``altgraph.Graph.iterdfs`` now returns the correct result
when the ``forward`` argument is ``False``.
- ``altgraph.Graph.iterdata`` now returns the correct result
when the ``forward`` argument is ``False``.
Features:
- The ``altgraph.Graph`` constructor now accepts an argument
that contains 2- and 3-tuples instead of requireing that
all items have the same size. The (optional) argument can now
also be any iterator.
- ``altgraph.Graph.Graph.add_node`` has no effect when you
add a hidden node.
- The private method ``altgraph.Graph._bfs`` is no longer
present.
- The private method ``altgraph.Graph._dfs`` is no longer
present.
- ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
which means you can use the ``in`` operator to check if a
node is part of a graph.
- ``altgraph.GraphUtil.generate_random_graph`` will raise
``GraphError`` instead of looping forever when it is
impossible to create the requested graph.
- ``altgraph.Dot.edge_style`` raises ``GraphError`` when
one of the nodes is not present in the graph. The method
silently added the tail in the past, but without ensuring
a consistent graph state.
- ``altgraph.Dot.save_img`` now works when the mode is
``"neato"``.
0.7.2
-----
This is a minor bugfix release
Bugfixes:
- distutils didn't include the documentation subtree
0.7.1
-----
This is a minor feature release
Features:
- Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
and can be viewed at <http://packages.python.org/altgraph>.
- The repository has moved to bitbucket
- ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
implementation and no specified behaviour.
- the module ``altgraph.compat`` is gone, which means altgraph will no
longer work with Python 2.3.
0.7.0
-----
This is a minor feature release.
Features:
- Support for Python 3
- It is now possible to run tests using 'python setup.py test'
(The actual testsuite is still very minimal though)

View File

@ -1,26 +0,0 @@
:mod:`altgraph` --- A Python Graph Library
==================================================
.. module:: altgraph
:synopsis: A directional graph for python
altgraph is a fork of `graphlib <http://pygraphlib.sourceforge.net>`_ tailored
to use newer Python 2.3+ features, including additional support used by the
py2app suite (modulegraph and macholib, specifically).
altgraph is a python based graph (network) representation and manipulation package.
It has started out as an extension to the `graph_lib module <http://www.ece.arizona.edu/~denny/python_nest/graph_lib_1.0.1.html>`_
written by Nathan Denny it has been significantly optimized and expanded.
The :class:`altgraph.Graph.Graph` class is loosely modeled after the `LEDA <http://www.algorithmic-solutions.com/enleda.htm>`_
(Library of Efficient Datatypes) representation. The library
includes methods for constructing graphs, BFS and DFS traversals,
topological sort, finding connected components, shortest paths as well as a number
graph statistics functions. The library can also visualize graphs
via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_.
.. exception:: GraphError
Exception raised when methods are called with bad values of
an inconsistent state.

View File

@ -1,224 +0,0 @@
:mod:`altgraph.Dot` --- Interface to the dot language
=====================================================
.. module:: altgraph.Dot
:synopsis: Interface to the dot language as used by Graphviz..
The :py:mod:`~altgraph.Dot` module provides a simple interface to the
file format used in the `graphviz`_ program. The module is intended to
offload the most tedious part of the process (the **dot** file generation)
while transparently exposing most of its features.
.. _`graphviz`: <http://www.research.att.com/sw/tools/graphviz/>`_
To display the graphs or to generate image files the `graphviz`_
package needs to be installed on the system, moreover the :command:`dot` and :command:`dotty` programs must
be accesible in the program path so that they can be ran from processes spawned
within the module.
Example usage
-------------
Here is a typical usage::
from altgraph import Graph, Dot
# create a graph
edges = [ (1,2), (1,3), (3,4), (3,5), (4,5), (5,4) ]
graph = Graph.Graph(edges)
# create a dot representation of the graph
dot = Dot.Dot(graph)
# display the graph
dot.display()
# save the dot representation into the mydot.dot file
dot.save_dot(file_name='mydot.dot')
# save dot file as gif image into the graph.gif file
dot.save_img(file_name='graph', file_type='gif')
Directed graph and non-directed graph
-------------------------------------
Dot class can use for both directed graph and non-directed graph
by passing *graphtype* parameter.
Example::
# create directed graph(default)
dot = Dot.Dot(graph, graphtype="digraph")
# create non-directed graph
dot = Dot.Dot(graph, graphtype="graph")
Customizing the output
----------------------
The graph drawing process may be customized by passing
valid :command:`dot` parameters for the nodes and edges. For a list of all
parameters see the `graphviz`_ documentation.
Example::
# customizing the way the overall graph is drawn
dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
# customizing node drawing
dot.node_style(1, label='BASE_NODE',shape='box', color='blue' )
dot.node_style(2, style='filled', fillcolor='red')
# customizing edge drawing
dot.edge_style(1, 2, style='dotted')
dot.edge_style(3, 5, arrowhead='dot', label='binds', labelangle='90')
dot.edge_style(4, 5, arrowsize=2, style='bold')
.. note::
dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
display all graphics styles. To verify the output save it to an image
file and look at it that way.
Valid attributes
----------------
- dot styles, passed via the :py:meth:`Dot.style` method::
rankdir = 'LR' (draws the graph horizontally, left to right)
ranksep = number (rank separation in inches)
- node attributes, passed via the :py:meth:`Dot.node_style` method::
style = 'filled' | 'invisible' | 'diagonals' | 'rounded'
shape = 'box' | 'ellipse' | 'circle' | 'point' | 'triangle'
- edge attributes, passed via the :py:meth:`Dot.edge_style` method::
style = 'dashed' | 'dotted' | 'solid' | 'invis' | 'bold'
arrowhead = 'box' | 'crow' | 'diamond' | 'dot' | 'inv' | 'none' | 'tee' | 'vee'
weight = number (the larger the number the closer the nodes will be)
- valid `graphviz colors <http://www.research.att.com/~erg/graphviz/info/colors.html>`_
- for more details on how to control the graph drawing process see the
`graphviz reference <http://www.research.att.com/sw/tools/graphviz/refs.html>`_.
Class interface
---------------
.. class:: Dot(graph[, nodes[, edgefn[, nodevisitor[, edgevisitor[, name[, dot[, dotty[, neato[, graphtype]]]]]]]]])
Creates a new Dot generator based on the specified
:class:`Graph <altgraph.Graph.Graph>`. The Dot generator won't reference
the *graph* once it is constructed.
If the *nodes* argument is present it is the list of nodes to include
in the graph, otherwise all nodes in *graph* are included.
If the *edgefn* argument is present it is a function that yields the
nodes connected to another node, this defaults to
:meth:`graph.out_nbr <altgraph.Graph.Graph.out_nbr>`. The constructor won't
add edges to the dot file unless both the head and tail of the edge
are in *nodes*.
If the *name* is present it specifies the name of the graph in the resulting
dot file. The default is ``"G"``.
The functions *nodevisitor* and *edgevisitor* return the default style
for a given edge or node (both default to functions that return an empty
style).
The arguments *dot*, *dotty* and *neato* are used to pass the path to
the corresponding `graphviz`_ command.
Updating graph attributes
.........................
.. method:: Dot.style(\**attr)
Sets the overall style (graph attributes) to the given attributes.
See `Valid Attributes`_ for more information about the attributes.
.. method:: Dot.node_style(node, \**attr)
Sets the style for *node* to the given attributes.
This method will add *node* to the graph when it isn't already
present.
See `Valid Attributes`_ for more information about the attributes.
.. method:: Dot.all_node_style(\**attr)
Replaces the current style for all nodes
.. method:: edge_style(head, tail, \**attr)
Sets the style of an edge to the given attributes. The edge will
be added to the graph when it isn't already present, but *head*
and *tail* must both be valid nodes.
See `Valid Attributes`_ for more information about the attributes.
Emitting output
...............
.. method:: Dot.display([mode])
Displays the current graph via dotty.
If the *mode* is ``"neato"`` the dot file is processed with
the neato command before displaying.
This method won't return until the dotty command exits.
.. method:: save_dot(filename)
Saves the current graph representation into the given file.
.. note::
For backward compatibility reasons this method can also
be called without an argument, it will then write the graph
into a fixed filename (present in the attribute :data:`Graph.temp_dot`).
This feature is deprecated and should not be used.
.. method:: save_image(file_name[, file_type[, mode]])
Saves the current graph representation as an image file. The output
is written into a file whose basename is *file_name* and whose suffix
is *file_type*.
The *file_type* specifies the type of file to write, the default
is ``"gif"``.
If the *mode* is ``"neato"`` the dot file is processed with
the neato command before displaying.
.. note::
For backward compatibility reasons this method can also
be called without an argument, it will then write the graph
with a fixed basename (``"out"``).
This feature is deprecated and should not be used.
.. method:: iterdot()
Yields all lines of a `graphviz`_ input file (including line endings).
.. method:: __iter__()
Alias for the :meth:`iterdot` method.

View File

@ -1,299 +0,0 @@
:mod:`altgraph.Graph` --- Basic directional graphs
==================================================
.. module:: altgraph.Graph
:synopsis: Basic directional graphs.
The module :mod:`altgraph.Graph` provides a class :class:`Graph` that
represents a directed graph with *N* nodes and *E* edges.
.. class:: Graph([edges])
Constructs a new empty :class:`Graph` object. If the optional
*edges* parameter is supplied, updates the graph by adding the
specified edges.
All of the elements in *edges* should be tuples with two or three
elements. The first two elements of the tuple are the source and
destination node of the edge, the optional third element is the
edge data. The source and destination nodes are added to the graph
when the aren't already present.
Node related methods
--------------------
.. method:: Graph.add_node(node[, node_data])
Adds a new node to the graph if it is not already present. The new
node must be a hashable object.
Arbitrary data can be attached to the node via the optional *node_data*
argument.
.. note:: the node also won't be added to the graph when it is
present but currently hidden.
.. method:: Graph.hide_node(node)
Hides a *node* from the graph. The incoming and outgoing edges of
the node will also be hidden.
Raises :class:`altgraph.GraphError` when the node is not (visible)
node of the graph.
.. method:: Graph.restore_node(node)
Restores a previously hidden *node*. The incoming and outgoing
edges of the node are also restored.
Raises :class:`altgraph.GraphError` when the node is not a hidden
node of the graph.
.. method:: Graph.restore_all_nodes()
Restores all hidden nodes.
.. method:: Graph.number_of_nodes()
Return the number of visible nodes in the graph.
.. method:: Graph.number_of_hidden_nodes()
Return the number of hidden nodes in the graph.
.. method:: Graph.node_list()
Return a list with all visible nodes in the graph.
.. method:: Graph.hidden_node_list()
Return a list with all hidden nodes in the graph.
.. method:: node_data(node)
Return the data associated with the *node* when it was
added.
.. method:: Graph.describe_node(node)
Returns *node*, the node's data and the lists of outgoing
and incoming edges for the node.
.. note::
the edge lists should not be modified, doing so
can result in unpredicatable behavior.
.. method:: Graph.__contains__(node)
Returns True iff *node* is a node in the graph. This
method is accessed through the *in* operator.
.. method:: Graph.__iter__()
Yield all nodes in the graph.
.. method:: Graph.out_edges(node)
Return the list of outgoing edges for *node*
.. method:: Graph.inc_edges(node)
Return the list of incoming edges for *node*
.. method:: Graph.all_edges(node)
Return the list of incoming and outgoing edges for *node*
.. method:: Graph.out_degree(node)
Return the number of outgoing edges for *node*.
.. method:: Graph.inc_degree(node)
Return the number of incoming edges for *node*.
.. method:: Graph.all_degree(node)
Return the number of edges (incoming or outgoing) for *node*.
Edge related methods
--------------------
.. method:: Graph.add_edge(head_id, tail_id [, edge data [, create_nodes]])
Adds a directed edge from *head_id* to *tail_id*. Arbitrary data can
be added via *edge_data*. When *create_nodes* is *True* (the default),
*head_id* and *tail_id* will be added to the graph when the aren't
already present.
.. method:: Graph.hide_edge(edge)
Hides an edge from the graph. The edge may be unhidden at some later
time.
.. method:: Graph.restore_edge(edge)
Restores a previously hidden *edge*.
.. method:: Graph.restore_all_edges()
Restore all edges that were hidden before, except for edges
referring to hidden nodes.
.. method:: Graph.edge_by_node(head, tail)
Return the edge ID for an edge from *head* to *tail*,
or :data:`None` when no such edge exists.
.. method:: Graph.edge_by_id(edge)
Return the head and tail of the *edge*
.. method:: Graph.edge_data(edge)
Return the data associated with the *edge*.
.. method:: Graph.head(edge)
Return the head of an *edge*
.. method:: Graph.tail(edge)
Return the tail of an *edge*
.. method:: Graph.describe_edge(edge)
Return the *edge*, the associated data, its head and tail.
.. method:: Graph.number_of_edges()
Return the number of visible edges.
.. method:: Graph.number_of_hidden_edges()
Return the number of hidden edges.
.. method:: Graph.edge_list()
Returns a list with all visible edges in the graph.
.. method:: Graph.hidden_edge_list()
Returns a list with all hidden edges in the graph.
Graph traversal
---------------
.. method:: Graph.out_nbrs(node)
Return a list of all nodes connected by outgoing edges.
.. method:: Graph.inc_nbrs(node)
Return a list of all nodes connected by incoming edges.
.. method:: Graph.all_nbrs(node)
Returns a list of nodes connected by an incoming or outgoing edge.
.. method:: Graph.forw_topo_sort()
Return a list of nodes where the successors (based on outgoing
edges) of any given node apear in the sequence after that node.
.. method:: Graph.back_topo_sort()
Return a list of nodes where the successors (based on incoming
edges) of any given node apear in the sequence after that node.
.. method:: Graph.forw_bfs_subgraph(start_id)
Return a subgraph consisting of the breadth first
reachable nodes from *start_id* based on their outgoing edges.
.. method:: Graph.back_bfs_subgraph(start_id)
Return a subgraph consisting of the breadth first
reachable nodes from *start_id* based on their incoming edges.
.. method:: Graph.iterdfs(start[, end[, forward]])
Yield nodes in a depth first traversal starting at the *start*
node.
If *end* is specified traversal stops when reaching that node.
If forward is True (the default) edges are traversed in forward
direction, otherwise they are traversed in reverse direction.
.. method:: Graph.iterdata(start[, end[, forward[, condition]]])
Yield the associated data for nodes in a depth first traversal
starting at the *start* node. This method will not yield values for nodes
without associated data.
If *end* is specified traversal stops when reaching that node.
If *condition* is specified and the condition callable returns
False for the associated data this method will not yield the
associated data and will not follow the edges for the node.
If forward is True (the default) edges are traversed in forward
direction, otherwise they are traversed in reverse direction.
.. method:: Graph.forw_bfs(start[, end])
Returns a list of nodes starting at *start* in some bread first
search order (following outgoing edges).
When *end* is specified iteration stops at that node.
.. method:: Graph.back_bfs(start[, end])
Returns a list of nodes starting at *start* in some bread first
search order (following incoming edges).
When *end* is specified iteration stops at that node.
.. method:: Graph.get_hops(start[, end[, forward]])
Computes the hop distance to all nodes centered around a specified node.
First order neighbours are at hop 1, their neigbours are at hop 2 etc.
Uses :py:meth:`forw_bfs` or :py:meth:`back_bfs` depending on the value of
the forward parameter.
If the distance between all neighbouring nodes is 1 the hop number
corresponds to the shortest distance between the nodes.
Typical usage::
>>> print graph.get_hops(1, 8)
>>> [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
# node 1 is at 0 hops
# node 2 is at 1 hop
# ...
# node 8 is at 5 hops
Graph statistics
----------------
.. method:: Graph.connected()
Returns True iff every node in the graph can be reached from
every other node.
.. method:: Graph.clust_coef(node)
Returns the local clustering coefficient of node.
The local cluster coefficient is the proportion of the actual number
of edges between neighbours of node and the maximum number of
edges between those nodes.

View File

@ -1,26 +0,0 @@
:mod:`altgraph.GraphAlgo` --- Graph algorithms
==================================================
.. module:: altgraph.GraphAlgo
:synopsis: Basic graphs algoritms
.. function:: dijkstra(graph, start[, end])
Dijkstra's algorithm for shortest paths.
Find shortest paths from the start node to all nodes nearer
than or equal to the *end* node. The edge data is assumed to be the edge length.
.. note::
Dijkstra's algorithm is only guaranteed to work correctly when all edge lengths are positive.
This code does not verify this property for all edges (only the edges examined until the end
vertex is reached), but will correctly compute shortest paths even for some graphs with negative
edges, and will raise an exception if it discovers that a negative edge has caused it to make a mistake.
.. function:: shortest_path(graph, start, end)
Find a single shortest path from the given start node to the given end node.
The input has the same conventions as :func:`dijkstra`. The output is a list
of the nodes in order along the shortest path.

View File

@ -1,25 +0,0 @@
:mod:`altgraph.GraphStat` --- Functions providing various graph statistics
==========================================================================
.. module:: altgraph.GraphStat
:synopsis: Functions providing various graph statistics
The module :mod:`altgraph.GraphStat` provides function that calculate
graph statistics. Currently there is only one such function, more may
be added later.
.. function:: degree_dist(graph[, limits[, bin_num[, mode]]])
Groups the number of edges per node into *bin_num* bins
and returns the list of those bins. Every item in the result
is a tuple with the center of the bin and the number of items
in that bin.
When the *limits* argument is present it must be a tuple with
the mininum and maximum number of edges that get binned (that
is, when *limits* is ``(4, 10)`` only nodes with between 4
and 10 edges get counted.
The *mode* argument is used to count incoming (``'inc'``) or
outgoing (``'out'``) edges. The default is to count the outgoing
edges.

View File

@ -1,55 +0,0 @@
:mod:`altgraph.GraphUtil` --- Utility functions
================================================
.. module:: altgraph.GraphUtil
:synopsis: Utility functions
The module :mod:`altgraph.GraphUtil` performs a number of more
or less useful utility functions.
.. function:: generate_random_graph(node_num, edge_num[, self_loops[, multi_edges])
Generates and returns a :class:`Graph <altgraph.Graph.Graph>` instance
with *node_num* nodes randomly connected by *edge_num* edges.
When *self_loops* is present and True there can be edges that point from
a node to itself.
When *multi_edge* is present and True there can be duplicate edges.
This method raises :class:`GraphError <altgraph.GraphError` when
a graph with the requested configuration cannot be created.
.. function:: generate_scale_free_graph(steps, growth_num[, self_loops[, multi_edges]])
Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that
will have *steps*growth_n um* nodes and a scale free (powerlaw)
connectivity.
Starting with a fully connected graph with *growth_num* nodes
at every step *growth_num* nodes are added to the graph and are connected
to existing nodes with a probability proportional to the degree of these
existing nodes.
.. warning:: The current implementation is basically untested, although
code inspection seems to indicate an implementation that is consistent
with the description at
`Wolfram MathWorld <http://mathworld.wolfram.com/Scale-FreeNetwork.html>`_
.. function:: filter_stack(graph, head, filters)
Perform a depth-first oder walk of the graph starting at *head* and
apply all filter functions in *filters* on the node data of the nodes
found.
Returns (*visited*, *removes*, *orphans*), where
* *visited*: the set of visited nodes
* *removes*: the list of nodes where the node data doesn't match
all *filters*.
* *orphans*: list of tuples (*last_good*, *node*), where
node is not in *removes* and one of the nodes that is connected
by an incoming edge is in *removes*. *Last_good* is the
closest upstream node that is not in *removes*.

View File

@ -1,41 +0,0 @@
.. altgraph documentation master file, created by
sphinx-quickstart on Tue Aug 31 11:04:49 2010.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Altgraph - A basic graph library
================================
altgraph is a fork of graphlib: a graph (network) package for constructing
graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
graphviz output.
The primary users of this package are `macholib <http://pypi.python.org/pypi/macholib>`_ and `modulegraph <http://pypi.python.org/pypi/modulegraph>`_.
.. toctree::
:maxdepth: 1
changelog
license
core
graph
objectgraph
graphalgo
graphstat
graphutil
dot
Online Resources
----------------
* `Sourcecode repository on bitbucket <http://bitbucket.org/ronaldoussoren/altgraph/>`_
* `The issue tracker <http://bitbucket.org/ronaldoussoren/altgraph/issues>`_
Indices and tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,25 +0,0 @@
License
=======
Copyright (c) 2004 Istvan Albert unless otherwise noted.
Parts are copyright (c) Bob Ippolito
Parts are copyright (c) 2010-2014 Ronald Oussoren
MIT License
...........
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,134 +0,0 @@
:mod:`altgraph.ObjectGraph` --- Graphs of objecs with an identifier
===================================================================
.. module:: altgraph.ObjectGraph
:synopsis: A graph of objects that have a "graphident" attribute.
.. class:: ObjectGraph([graph[, debug]])
A graph of objects that have a "graphident" attribute. The
value of this attribute is the key for the object in the
graph.
The optional *graph* is a previously constructed
:class:`Graph <altgraph.Graph.Graph>`.
The optional *debug* level controls the amount of debug output
(see :meth:`msg`, :meth:`msgin` and :meth:`msgout`).
.. note:: the altgraph library does not generate output, the
debug attribute and message methods are present for use
by subclasses.
.. data:: ObjectGraph.graph
An :class:`Graph <altgraph.Graph.Graph>` object that contains
the graph data.
.. method:: ObjectGraph.addNode(node)
Adds a *node* to the graph.
.. note:: re-adding a node that was previously removed
using :meth:`removeNode` will reinstate the previously
removed node.
.. method:: ObjectGraph.createNode(self, cls, name, \*args, \**kwds)
Creates a new node using ``cls(*args, **kwds)`` and adds that
node using :meth:`addNode`.
Returns the newly created node.
.. method:: ObjectGraph.removeNode(node)
Removes a *node* from the graph when it exists. The *node* argument
is either a node object, or the graphident of a node.
.. method:: ObjectGraph.createReferences(fromnode, tonode[, edge_data])
Creates a reference from *fromnode* to *tonode*. The optional
*edge_data* is associated with the edge.
*Fromnode* and *tonode* can either be node objects or the graphident
values for nodes.
.. method:: removeReference(fromnode, tonode)
Removes the reference from *fromnode* to *tonode* if it exists.
.. method:: ObjectGraph.getRawIdent(node)
Returns the *graphident* attribute of *node*, or the graph itself
when *node* is :data:`None`.
.. method:: getIdent(node)
Same as :meth:`getRawIdent`, but only if the node is part
of the graph.
*Node* can either be an actual node object or the graphident of
a node.
.. method:: ObjectGraph.findNode(node)
Returns a given node in the graph, or :data:`Node` when it cannot
be found.
*Node* is either an object with a *graphident* attribute or
the *graphident* attribute itself.
.. method:: ObjectGraph.__contains__(node)
Returns True if *node* is a member of the graph. *Node* is either an
object with a *graphident* attribute or the *graphident* attribute itself.
.. method:: ObjectGraph.flatten([condition[, start]])
Yield all nodes that are entirely reachable by *condition*
starting fromt he given *start* node or the graph root.
.. note:: objects are only reachable from the graph root
when there is a reference from the root to the node
(either directly or through another node)
.. method:: ObjectGraph.nodes()
Yield all nodes in the graph.
.. method:: ObjectGraph.get_edges(node)
Returns two iterators that yield the nodes reaching by
outgoing and incoming edges.
.. method:: ObjectGraph.filterStack(filters)
Filter the ObjectGraph in-place by removing all edges to nodes that
do not match every filter in the given filter list
Returns a tuple containing the number of:
(*nodes_visited*, *nodes_removed*, *nodes_orphaned*)
Debug output
------------
.. data:: ObjectGraph.debug
The current debug level.
.. method:: ObjectGraph.msg(level, text, \*args)
Print a debug message at the current indentation level when the current
debug level is *level* or less.
.. method:: ObjectGraph.msgin(level, text, \*args)
Print a debug message when the current debug level is *level* or less,
and increase the indentation level.
.. method:: ObjectGraph.msgout(level, text, \*args)
Decrease the indentation level and print a debug message when the
current debug level is *level* or less.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

View File

@ -1,537 +0,0 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox input[type="text"] {
width: 170px;
}
div.sphinxsidebar #searchbox input[type="submit"] {
width: 30px;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlighted {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1,238 +0,0 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
var span = document.createElement("span");
span.className = className;
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this);
});
}
}
return this.each(function() {
highlight(this);
});
};
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) == 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

View File

@ -1,245 +0,0 @@
/*
* nature.css_t
* ~~~~~~~~~~~~
*
* Sphinx stylesheet -- nature theme.
*
* :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Arial, sans-serif;
font-size: 100%;
background-color: #111;
color: #555;
margin: 0;
padding: 0;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
hr {
border: 1px solid #B1B4B6;
}
div.document {
background-color: #eee;
}
div.body {
background-color: #ffffff;
color: #3E4349;
padding: 0 30px 30px 30px;
font-size: 0.9em;
}
div.footer {
color: #555;
width: 100%;
padding: 13px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #444;
text-decoration: underline;
}
div.related {
background-color: #6BA81E;
line-height: 32px;
color: #fff;
text-shadow: 0px 1px 0 #444;
font-size: 0.9em;
}
div.related a {
color: #E2F3CC;
}
div.sphinxsidebar {
font-size: 0.75em;
line-height: 1.5em;
}
div.sphinxsidebarwrapper{
padding: 20px 0;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Arial, sans-serif;
color: #222;
font-size: 1.2em;
font-weight: normal;
margin: 0;
padding: 5px 10px;
background-color: #ddd;
text-shadow: 1px 1px 0 white
}
div.sphinxsidebar h4{
font-size: 1.1em;
}
div.sphinxsidebar h3 a {
color: #444;
}
div.sphinxsidebar p {
color: #888;
padding: 5px 20px;
}
div.sphinxsidebar p.topless {
}
div.sphinxsidebar ul {
margin: 10px 20px;
padding: 0;
color: #000;
}
div.sphinxsidebar a {
color: #444;
}
div.sphinxsidebar input {
border: 1px solid #ccc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar input[type=text]{
margin-left: 20px;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #005B81;
text-decoration: none;
}
a:hover {
color: #E32E00;
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: Arial, sans-serif;
background-color: #BED4EB;
font-weight: normal;
color: #212224;
margin: 30px 0px 10px 0px;
padding: 5px 0 5px 10px;
text-shadow: 0px 1px 0 white
}
div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 150%; background-color: #C8D5E3; }
div.body h3 { font-size: 120%; background-color: #D8DEE3; }
div.body h4 { font-size: 110%; background-color: #D8DEE3; }
div.body h5 { font-size: 100%; background-color: #D8DEE3; }
div.body h6 { font-size: 100%; background-color: #D8DEE3; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
line-height: 1.5em;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.highlight{
background-color: white;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 10px;
background-color: White;
color: #222;
line-height: 1.2em;
border: 1px solid #C6C9CB;
font-size: 1.1em;
margin: 1.5em 0 1.5em 0;
-webkit-box-shadow: 1px 1px 1px #d8d8d8;
-moz-box-shadow: 1px 1px 1px #d8d8d8;
}
tt {
background-color: #ecf0f3;
color: #222;
/* padding: 1px 2px; */
font-size: 1.1em;
font-family: monospace;
}
.viewcode-back {
font-family: Arial, sans-serif;
}
div.viewcode-block:target {
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

View File

@ -1,62 +0,0 @@
.highlight .hll { background-color: #ffffcc }
.highlight { background: #eeffcc; }
.highlight .c { color: #408090; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #333333 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #208050 } /* Literal.Number */
.highlight .s { color: #4070a0 } /* Literal.String */
.highlight .na { color: #4070a0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .no { color: #60add5 } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
.highlight .nf { color: #06287e } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #208050 } /* Literal.Number.Float */
.highlight .mh { color: #208050 } /* Literal.Number.Hex */
.highlight .mi { color: #208050 } /* Literal.Number.Integer */
.highlight .mo { color: #208050 } /* Literal.Number.Oct */
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */

View File

@ -1,622 +0,0 @@
/*
* searchtools.js_t
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilties for the full-text search.
*
* :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
// query found in terms
term: 5
};
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null,
dataType: "script", cache: true,
complete: function(jqxhr, textstatus) {
if (textstatus != "success") {
document.getElementById("searchindexloader").src = url;
}
}});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
var i;
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
}
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
/**
* execute search (requires search index to be loaded)
*/
query : function(query) {
var i;
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = query.split(/\s+/);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
var toAppend;
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
}
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var terms = this._index.terms;
var titleterms = this._index.titleterms;
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(this.performObjectSearch(objectterms[i], others));
}
// lookup as search terms in fulltext
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, Scorer.term))
.concat(this.performTermsSearch(searchterms, excluded, titleterms, Scorer.title));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
}
});
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
listItem.append($('<a/>').attr('href',
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
highlightstring + item[2]).html(item[1]));
} else {
// normal html builders
listItem.append($('<a/>').attr('href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
}
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '') {
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
}
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}});
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
/**
* search for object names
*/
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var i;
var results = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
var score = 0;
var parts = fullname.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullname == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
var anchor = match[3];
if (anchor === '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2])) {
score += Scorer.objPrio[match[2]];
} else {
score += Scorer.objPrioDefault;
}
results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]);
}
}
}
return results;
},
/**
* search for full-text terms in the index
*/
performTermsSearch : function(searchterms, excluded, terms, score) {
var filenames = this._index.filenames;
var titles = this._index.titles;
var i, j, file, files;
var fileMap = {};
var results = [];
// perform the search on the required terms
for (i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
// no match but word was a required one
if ((files = terms[word]) === undefined)
break;
if (files.length === undefined) {
files = [files];
}
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
$u.contains(terms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it to the result list
if (valid) {
results.push([filenames[file], titles[file], '', null, score]);
}
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurance, the
* latter for highlighting it.
*/
makeSearchSummary : function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
};
$(document).ready(function() {
Search.init();
});

View File

@ -1,31 +0,0 @@
// Underscore.js 1.3.1
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),
function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

View File

@ -1,808 +0,0 @@
/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilties for all documentation.
*
* :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$('a.comment-close').live("click", function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$('a.vote').live("click", function(event) {
event.preventDefault();
handleVote($(this));
});
$('a.reply').live("click", function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$('a.close-reply').live("click", function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$('a.sort-option').live("click", function(event) {
event.preventDefault();
handleReSort($(this));
});
$('a.show-proposal').live("click", function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$('a.hide-proposal').live("click", function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$('a.show-propose-change').live("click", function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$('a.hide-propose-change').live("click", function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$('a.accept-comment').live("click", function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$('a.delete-comment').live("click", function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$('a.comment-markup').live("click", function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('<li>No comments yet.</li>');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; i<classes.length; i++) {
if (classes[i] != 'sort-option') {
by = classes[i].substring(2);
}
}
setComparator();
// Save/update the sortBy cookie.
var expiration = new Date();
expiration.setDate(expiration.getDate() + 365);
document.cookie= 'sortBy=' + escape(by) +
';expires=' + expiration.toUTCString();
$('ul.comment-ul').each(function(index, ul) {
var comments = getChildren($(ul), true);
comments = sortComments(comments);
appendComments(comments, $(ul).empty());
});
}
/**
* Function to process a vote when a user clicks an arrow.
*/
function handleVote(link) {
if (!opts.voting) {
showError("You'll need to login to vote.");
return;
}
var id = link.attr('id');
if (!id) {
// Didn't click on one of the voting arrows.
return;
}
// If it is an unvote, the new vote value is 0,
// Otherwise it's 1 for an upvote, or -1 for a downvote.
var value = 0;
if (id.charAt(1) != 'u') {
value = id.charAt(0) == 'u' ? 1 : -1;
}
// The data to be sent to the server.
var d = {
comment_id: id.substring(2),
value: value
};
// Swap the vote and unvote links.
link.hide();
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
.show();
// The div the comment is displayed in.
var div = $('div#cd' + d.comment_id);
var data = div.data('comment');
// If this is not an unvote, and the other vote arrow has
// already been pressed, unpress it.
if ((d.value !== 0) && (data.vote === d.value * -1)) {
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
}
// Update the comments rating in the local data.
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
data.vote = d.value;
div.data('comment', data);
// Change the rating text.
div.find('.rating:first')
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
// Send the vote information to the server.
$.ajax({
type: "POST",
url: opts.processVoteURL,
data: d,
error: function(request, textStatus, error) {
showError('Oops, there was a problem casting that vote.');
}
});
}
/**
* Open a reply form used to reply to an existing comment.
*/
function openReply(id) {
// Swap out the reply link for the hide link
$('#rl' + id).hide();
$('#cr' + id).show();
// Add the reply li to the children ul.
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
$('#cl' + id)
.prepend(div)
// Setup the submit handler for the reply form.
.find('#rf' + id)
.submit(function(event) {
event.preventDefault();
addComment($('#rf' + id));
closeReply(id);
})
.find('input[type=button]')
.click(function() {
closeReply(id);
});
div.slideDown('fast', function() {
$('#rf' + id).find('textarea').focus();
});
}
/**
* Close the reply form opened with openReply.
*/
function closeReply(id) {
// Remove the reply div from the DOM.
$('#rd' + id).slideUp('fast', function() {
$(this).remove();
});
// Swap out the hide link for the reply link
$('#cr' + id).hide();
$('#rl' + id).show();
}
/**
* Recursively sort a tree of comments using the comp comparator.
*/
function sortComments(comments) {
comments.sort(comp);
$.each(comments, function() {
this.children = sortComments(this.children);
});
return comments;
}
/**
* Get the children comments from a ul. If recursive is true,
* recursively include childrens' children.
*/
function getChildren(ul, recursive) {
var children = [];
ul.children().children("[id^='cd']")
.each(function() {
var comment = $(this).data('comment');
if (recursive)
comment.children = getChildren($(this).find('#cl' + comment.id), true);
children.push(comment);
});
return children;
}
/** Create a div to display a comment in. */
function createCommentDiv(comment) {
if (!comment.displayed && !opts.moderator) {
return $('<div class="moderate">Thank you! Your comment will show up '
+ 'once it is has been approved by a moderator.</div>');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
<div class="sphinx-comments" id="sc<%id%>">\
<p class="sort-options">\
Sort by:\
<a href="#" class="sort-option byrating">best rated</a>\
<a href="#" class="sort-option byascage">newest</a>\
<a href="#" class="sort-option byage">oldest</a>\
</p>\
<div class="comment-header">Comments</div>\
<div class="comment-loading" id="cn<%id%>">\
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
<ul id="cl<%id%>" class="comment-ul"></ul>\
<div id="ca<%id%>">\
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
<tt>``code``</tt>, \
code blocks: <tt>::</tt> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
<a href="#" id="pc<%id%>" class="show-propose-change">\
Propose a change &#9657;\
</a>\
<a href="#" id="hc<%id%>" class="hide-propose-change">\
Propose a change &#9663;\
</a>\
</p>\
<textarea name="proposal" id="pt<%id%>" cols="80"\
spellcheck="false"></textarea>\
<input type="submit" value="Add comment" />\
<input type="hidden" name="node" value="<%id%>" />\
<input type="hidden" name="parent" value="" />\
</form>\
</div>\
</div>';
var commentTemplate = '\
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
<div class="vote">\
<div class="arrow">\
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
<img src="<%upArrow%>" />\
</a>\
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
<img src="<%upArrowPressed%>" />\
</a>\
</div>\
<div class="arrow">\
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
<img src="<%downArrow%>" id="da<%id%>" />\
</a>\
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
<img src="<%downArrowPressed%>" />\
</a>\
</div>\
</div>\
<div class="comment-content">\
<p class="tagline comment">\
<span class="user-id"><%username%></span>\
<span class="rating"><%pretty_rating%></span>\
<span class="delta"><%time.delta%></span>\
</p>\
<div class="comment-text comment"><#text#></div>\
<p class="comment-opts comment">\
<a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
<a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
<a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
<a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
<span id="cm<%id%>" class="moderation hidden">\
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
</span>\
</p>\
<pre class="proposal" id="pr<%id%>">\
<#proposal_diff#>\
</pre>\
<ul class="comment-children" id="cl<%id%>"></ul>\
</div>\
<div class="clearleft"></div>\
</div>\
</div>';
var replyTemplate = '\
<li>\
<div class="reply-div" id="rd<%id%>">\
<form id="rf<%id%>">\
<textarea name="comment" cols="80"></textarea>\
<input type="submit" value="Add reply" />\
<input type="button" value="Cancel" />\
<input type="hidden" name="parent" value="<%id%>" />\
<input type="hidden" name="node" value="" />\
</form>\
</div>\
</li>';
$(document).ready(function() {
init();
});
})(jQuery);
$(document).ready(function() {
// add comment anchors for all paragraphs that are commentable
$('.sphinx-has-comment').comment();
// highlight search words in search results
$("div.context").each(function() {
var params = $.getQueryParameters();
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
var result = $(this);
$.each(terms, function() {
result.highlightText(this.toLowerCase(), 'highlighted');
});
});
// directly open comment window if requested
var anchor = document.location.hash;
if (anchor.substring(0, 9) == '#comment-') {
$('#ao' + anchor.substring(9)).click();
document.location.hash = '#s' + anchor.substring(9);
}
});

View File

@ -1,271 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Release history &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="License" href="license.html" />
<link rel="prev" title="Altgraph - A basic graph library" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="license.html" title="License"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Altgraph - A basic graph library"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="release-history">
<h1>Release history<a class="headerlink" href="#release-history" title="Permalink to this headline"></a></h1>
<div class="section" id="id1">
<h2>0.11<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>Stabilize the order of elements in dot file exports,
patch from bitbucket user &#8216;pombredanne&#8217;.</li>
<li>Tweak setup.py file to remove dependency on distribute (but
keep the dependency on setuptools)</li>
</ul>
</div>
<div class="section" id="id2">
<h2>0.10.2<a class="headerlink" href="#id2" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>There where no classifiers in the package metadata due to a bug
in setup.py</li>
</ul>
</div>
<div class="section" id="id3">
<h2>0.10.1<a class="headerlink" href="#id3" title="Permalink to this headline"></a></h2>
<p>This is a bugfix release</p>
<p>Bug fixes:</p>
<ul>
<li><p class="first">Issue #3: The source archive contains a README.txt
while the setup file refers to ReadMe.txt.</p>
<p>This is caused by a misfeature in distutils, as a
workaround I&#8217;ve renamed ReadMe.txt to README.txt
in the source tree and setup file.</p>
</li>
</ul>
</div>
<div class="section" id="id4">
<h2>0.10<a class="headerlink" href="#id4" title="Permalink to this headline"></a></h2>
<p>This is a minor feature release</p>
<p>Features:</p>
<ul>
<li><p class="first">Do not use &#8220;2to3&#8221; to support Python 3.</p>
<p>As a side effect of this altgraph now supports
Python 2.6 and later, and no longer supports
earlier releases of Python.</p>
</li>
<li><p class="first">The order of attributes in the Dot output
is now always alphabetical.</p>
<p>With this change the output will be consistent
between runs and Python versions.</p>
</li>
</ul>
</div>
<div class="section" id="id5">
<h2>0.9<a class="headerlink" href="#id5" title="Permalink to this headline"></a></h2>
<p>This is a minor bugfix release</p>
<p>Features:</p>
<ul class="simple">
<li>Added <tt class="docutils literal"><span class="pre">altgraph.ObjectGraph.ObjectGraph.nodes</span></tt>, a method
yielding all nodes in an object graph.</li>
</ul>
<p>Bugfixes:</p>
<ul class="simple">
<li>The 0.8 release didn&#8217;t work with py2app when using
python 3.x.</li>
</ul>
</div>
<div class="section" id="id6">
<h2>0.8<a class="headerlink" href="#id6" title="Permalink to this headline"></a></h2>
<p>This is a minor feature release. The major new feature
is a extensive set of unittests, which explains almost
all other changes in this release.</p>
<p>Bugfixes:</p>
<ul class="simple">
<li>Installing failed with Python 2.5 due to using a distutils
class that isn&#8217;t available in that version of Python
(issue #1 on the issue tracker)</li>
<li><tt class="docutils literal"><span class="pre">altgraph.GraphStat.degree_dist</span></tt> now actually works</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.add_edge(a,</span> <span class="pre">b,</span> <span class="pre">create_nodes=False)</span></tt> will
no longer create the edge when one of the nodes doesn&#8217;t
exist.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.forw_topo_sort</span></tt> failed for some sparse graphs.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.back_topo_sort</span></tt> was completely broken in
previous releases.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.forw_bfs_subgraph</span></tt> now actually works.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.back_bfs_subgraph</span></tt> now actually works.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.iterdfs</span></tt> now returns the correct result
when the <tt class="docutils literal"><span class="pre">forward</span></tt> argument is <tt class="docutils literal"><span class="pre">False</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.iterdata</span></tt> now returns the correct result
when the <tt class="docutils literal"><span class="pre">forward</span></tt> argument is <tt class="docutils literal"><span class="pre">False</span></tt>.</li>
</ul>
<p>Features:</p>
<ul class="simple">
<li>The <tt class="docutils literal"><span class="pre">altgraph.Graph</span></tt> constructor now accepts an argument
that contains 2- and 3-tuples instead of requireing that
all items have the same size. The (optional) argument can now
also be any iterator.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Graph.Graph.add_node</span></tt> has no effect when you
add a hidden node.</li>
<li>The private method <tt class="docutils literal"><span class="pre">altgraph.Graph._bfs</span></tt> is no longer
present.</li>
<li>The private method <tt class="docutils literal"><span class="pre">altgraph.Graph._dfs</span></tt> is no longer
present.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.ObjectGraph</span></tt> now has a <tt class="docutils literal"><span class="pre">__contains__</span></tt> methods,
which means you can use the <tt class="docutils literal"><span class="pre">in</span></tt> operator to check if a
node is part of a graph.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.GraphUtil.generate_random_graph</span></tt> will raise
<tt class="docutils literal"><span class="pre">GraphError</span></tt> instead of looping forever when it is
impossible to create the requested graph.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Dot.edge_style</span></tt> raises <tt class="docutils literal"><span class="pre">GraphError</span></tt> when
one of the nodes is not present in the graph. The method
silently added the tail in the past, but without ensuring
a consistent graph state.</li>
<li><tt class="docutils literal"><span class="pre">altgraph.Dot.save_img</span></tt> now works when the mode is
<tt class="docutils literal"><span class="pre">&quot;neato&quot;</span></tt>.</li>
</ul>
</div>
<div class="section" id="id7">
<h2>0.7.2<a class="headerlink" href="#id7" title="Permalink to this headline"></a></h2>
<p>This is a minor bugfix release</p>
<p>Bugfixes:</p>
<ul class="simple">
<li>distutils didn&#8217;t include the documentation subtree</li>
</ul>
</div>
<div class="section" id="id8">
<h2>0.7.1<a class="headerlink" href="#id8" title="Permalink to this headline"></a></h2>
<p>This is a minor feature release</p>
<p>Features:</p>
<ul class="simple">
<li>Documentation is now generated using <a class="reference external" href="http://pypi.python.org/pypi/sphinx">sphinx</a>
and can be viewed at &lt;<a class="reference external" href="http://packages.python.org/altgraph">http://packages.python.org/altgraph</a>&gt;.</li>
<li>The repository has moved to bitbucket</li>
<li><tt class="docutils literal"><span class="pre">altgraph.GraphStat.avg_hops</span></tt> is no longer present, the function had no
implementation and no specified behaviour.</li>
<li>the module <tt class="docutils literal"><span class="pre">altgraph.compat</span></tt> is gone, which means altgraph will no
longer work with Python 2.3.</li>
</ul>
</div>
<div class="section" id="id9">
<h2>0.7.0<a class="headerlink" href="#id9" title="Permalink to this headline"></a></h2>
<p>This is a minor feature release.</p>
<p>Features:</p>
<ul>
<li><p class="first">Support for Python 3</p>
</li>
<li><p class="first">It is now possible to run tests using &#8216;python setup.py test&#8217;</p>
<p>(The actual testsuite is still very minimal though)</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Release history</a><ul>
<li><a class="reference internal" href="#id1">0.11</a></li>
<li><a class="reference internal" href="#id2">0.10.2</a></li>
<li><a class="reference internal" href="#id3">0.10.1</a></li>
<li><a class="reference internal" href="#id4">0.10</a></li>
<li><a class="reference internal" href="#id5">0.9</a></li>
<li><a class="reference internal" href="#id6">0.8</a></li>
<li><a class="reference internal" href="#id7">0.7.2</a></li>
<li><a class="reference internal" href="#id8">0.7.1</a></li>
<li><a class="reference internal" href="#id9">0.7.0</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Altgraph - A basic graph library</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="license.html"
title="next chapter">License</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="license.html" title="License"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="Altgraph - A basic graph library"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,130 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>altgraph — A Python Graph Library &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="altgraph.Graph — Basic directional graphs" href="graph.html" />
<link rel="prev" title="License" href="license.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graph.html" title="altgraph.Graph — Basic directional graphs"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="license.html" title="License"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-altgraph">
<span id="altgraph-a-python-graph-library"></span><h1><a class="reference internal" href="#module-altgraph" title="altgraph: A directional graph for python"><tt class="xref py py-mod docutils literal"><span class="pre">altgraph</span></tt></a> &#8212; A Python Graph Library<a class="headerlink" href="#module-altgraph" title="Permalink to this headline"></a></h1>
<p>altgraph is a fork of <a class="reference external" href="http://pygraphlib.sourceforge.net">graphlib</a> tailored
to use newer Python 2.3+ features, including additional support used by the
py2app suite (modulegraph and macholib, specifically).</p>
<p>altgraph is a python based graph (network) representation and manipulation package.
It has started out as an extension to the <a class="reference external" href="http://www.ece.arizona.edu/~denny/python_nest/graph_lib_1.0.1.html">graph_lib module</a>
written by Nathan Denny it has been significantly optimized and expanded.</p>
<p>The <a class="reference internal" href="graph.html#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">altgraph.Graph.Graph</span></tt></a> class is loosely modeled after the <a class="reference external" href="http://www.algorithmic-solutions.com/enleda.htm">LEDA</a>
(Library of Efficient Datatypes) representation. The library
includes methods for constructing graphs, BFS and DFS traversals,
topological sort, finding connected components, shortest paths as well as a number
graph statistics functions. The library can also visualize graphs
via <a class="reference external" href="http://www.research.att.com/sw/tools/graphviz/">graphviz</a>.</p>
<dl class="exception">
<dt id="altgraph.GraphError">
<em class="property">exception </em><tt class="descclassname">altgraph.</tt><tt class="descname">GraphError</tt><a class="headerlink" href="#altgraph.GraphError" title="Permalink to this definition"></a></dt>
<dd><p>Exception raised when methods are called with bad values of
an inconsistent state.</p>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="license.html"
title="previous chapter">License</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="graph.html"
title="next chapter"><tt class="docutils literal"><span class="pre">altgraph.Graph</span></tt> &#8212; Basic directional graphs</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graph.html" title="altgraph.Graph — Basic directional graphs"
>next</a> |</li>
<li class="right" >
<a href="license.html" title="License"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,332 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>altgraph.Dot — Interface to the dot language &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="prev" title="altgraph.GraphUtil — Utility functions" href="graphutil.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphutil.html" title="altgraph.GraphUtil — Utility functions"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-altgraph.Dot">
<span id="altgraph-dot-interface-to-the-dot-language"></span><h1><a class="reference internal" href="#module-altgraph.Dot" title="altgraph.Dot: Interface to the dot language as used by Graphviz.."><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.Dot</span></tt></a> &#8212; Interface to the dot language<a class="headerlink" href="#module-altgraph.Dot" title="Permalink to this headline"></a></h1>
<p>The <a class="reference internal" href="#module-altgraph.Dot" title="altgraph.Dot: Interface to the dot language as used by Graphviz.."><tt class="xref py py-mod docutils literal"><span class="pre">Dot</span></tt></a> module provides a simple interface to the
file format used in the <a class="reference external" href="&lt;http://www.research.att.com/sw/tools/graphviz/&gt;`_">graphviz</a> program. The module is intended to
offload the most tedious part of the process (the <strong>dot</strong> file generation)
while transparently exposing most of its features.</p>
<p>To display the graphs or to generate image files the <a class="reference external" href="&lt;http://www.research.att.com/sw/tools/graphviz/&gt;`_">graphviz</a>
package needs to be installed on the system, moreover the <strong class="command">dot</strong> and <strong class="command">dotty</strong> programs must
be accesible in the program path so that they can be ran from processes spawned
within the module.</p>
<div class="section" id="example-usage">
<h2>Example usage<a class="headerlink" href="#example-usage" title="Permalink to this headline"></a></h2>
<p>Here is a typical usage:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">altgraph</span> <span class="kn">import</span> <span class="n">Graph</span><span class="p">,</span> <span class="n">Dot</span>
<span class="c"># create a graph</span>
<span class="n">edges</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span> <span class="p">]</span>
<span class="n">graph</span> <span class="o">=</span> <span class="n">Graph</span><span class="o">.</span><span class="n">Graph</span><span class="p">(</span><span class="n">edges</span><span class="p">)</span>
<span class="c"># create a dot representation of the graph</span>
<span class="n">dot</span> <span class="o">=</span> <span class="n">Dot</span><span class="o">.</span><span class="n">Dot</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
<span class="c"># display the graph</span>
<span class="n">dot</span><span class="o">.</span><span class="n">display</span><span class="p">()</span>
<span class="c"># save the dot representation into the mydot.dot file</span>
<span class="n">dot</span><span class="o">.</span><span class="n">save_dot</span><span class="p">(</span><span class="n">file_name</span><span class="o">=</span><span class="s">&#39;mydot.dot&#39;</span><span class="p">)</span>
<span class="c"># save dot file as gif image into the graph.gif file</span>
<span class="n">dot</span><span class="o">.</span><span class="n">save_img</span><span class="p">(</span><span class="n">file_name</span><span class="o">=</span><span class="s">&#39;graph&#39;</span><span class="p">,</span> <span class="n">file_type</span><span class="o">=</span><span class="s">&#39;gif&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="directed-graph-and-non-directed-graph">
<h2>Directed graph and non-directed graph<a class="headerlink" href="#directed-graph-and-non-directed-graph" title="Permalink to this headline"></a></h2>
<p>Dot class can use for both directed graph and non-directed graph
by passing <em>graphtype</em> parameter.</p>
<p>Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># create directed graph(default)</span>
<span class="n">dot</span> <span class="o">=</span> <span class="n">Dot</span><span class="o">.</span><span class="n">Dot</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">graphtype</span><span class="o">=</span><span class="s">&quot;digraph&quot;</span><span class="p">)</span>
<span class="c"># create non-directed graph</span>
<span class="n">dot</span> <span class="o">=</span> <span class="n">Dot</span><span class="o">.</span><span class="n">Dot</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">graphtype</span><span class="o">=</span><span class="s">&quot;graph&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="customizing-the-output">
<h2>Customizing the output<a class="headerlink" href="#customizing-the-output" title="Permalink to this headline"></a></h2>
<p>The graph drawing process may be customized by passing
valid <strong class="command">dot</strong> parameters for the nodes and edges. For a list of all
parameters see the <a class="reference external" href="&lt;http://www.research.att.com/sw/tools/graphviz/&gt;`_">graphviz</a> documentation.</p>
<p>Example:</p>
<div class="highlight-python"><div class="highlight"><pre># customizing the way the overall graph is drawn
dot.style(size=&#39;10,10&#39;, rankdir=&#39;RL&#39;, page=&#39;5, 5&#39; , ranksep=0.75)
# customizing node drawing
dot.node_style(1, label=&#39;BASE_NODE&#39;,shape=&#39;box&#39;, color=&#39;blue&#39; )
dot.node_style(2, style=&#39;filled&#39;, fillcolor=&#39;red&#39;)
# customizing edge drawing
dot.edge_style(1, 2, style=&#39;dotted&#39;)
dot.edge_style(3, 5, arrowhead=&#39;dot&#39;, label=&#39;binds&#39;, labelangle=&#39;90&#39;)
dot.edge_style(4, 5, arrowsize=2, style=&#39;bold&#39;)
.. note::
dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
display all graphics styles. To verify the output save it to an image
file and look at it that way.
</pre></div>
</div>
</div>
<div class="section" id="valid-attributes">
<h2>Valid attributes<a class="headerlink" href="#valid-attributes" title="Permalink to this headline"></a></h2>
<ul>
<li><p class="first">dot styles, passed via the <a class="reference internal" href="#altgraph.Dot.Dot.style" title="altgraph.Dot.Dot.style"><tt class="xref py py-meth docutils literal"><span class="pre">Dot.style()</span></tt></a> method:</p>
<div class="highlight-python"><div class="highlight"><pre>rankdir = &#39;LR&#39; (draws the graph horizontally, left to right)
ranksep = number (rank separation in inches)
</pre></div>
</div>
</li>
<li><p class="first">node attributes, passed via the <a class="reference internal" href="#altgraph.Dot.Dot.node_style" title="altgraph.Dot.Dot.node_style"><tt class="xref py py-meth docutils literal"><span class="pre">Dot.node_style()</span></tt></a> method:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">style</span> <span class="o">=</span> <span class="s">&#39;filled&#39;</span> <span class="o">|</span> <span class="s">&#39;invisible&#39;</span> <span class="o">|</span> <span class="s">&#39;diagonals&#39;</span> <span class="o">|</span> <span class="s">&#39;rounded&#39;</span>
<span class="n">shape</span> <span class="o">=</span> <span class="s">&#39;box&#39;</span> <span class="o">|</span> <span class="s">&#39;ellipse&#39;</span> <span class="o">|</span> <span class="s">&#39;circle&#39;</span> <span class="o">|</span> <span class="s">&#39;point&#39;</span> <span class="o">|</span> <span class="s">&#39;triangle&#39;</span>
</pre></div>
</div>
</li>
<li><p class="first">edge attributes, passed via the <tt class="xref py py-meth docutils literal"><span class="pre">Dot.edge_style()</span></tt> method:</p>
<div class="highlight-python"><div class="highlight"><pre>style = &#39;dashed&#39; | &#39;dotted&#39; | &#39;solid&#39; | &#39;invis&#39; | &#39;bold&#39;
arrowhead = &#39;box&#39; | &#39;crow&#39; | &#39;diamond&#39; | &#39;dot&#39; | &#39;inv&#39; | &#39;none&#39; | &#39;tee&#39; | &#39;vee&#39;
weight = number (the larger the number the closer the nodes will be)
</pre></div>
</div>
</li>
<li><p class="first">valid <a class="reference external" href="http://www.research.att.com/~erg/graphviz/info/colors.html">graphviz colors</a></p>
</li>
<li><p class="first">for more details on how to control the graph drawing process see the
<a class="reference external" href="http://www.research.att.com/sw/tools/graphviz/refs.html">graphviz reference</a>.</p>
</li>
</ul>
</div>
<div class="section" id="class-interface">
<h2>Class interface<a class="headerlink" href="#class-interface" title="Permalink to this headline"></a></h2>
<dl class="class">
<dt id="altgraph.Dot.Dot">
<em class="property">class </em><tt class="descclassname">altgraph.Dot.</tt><tt class="descname">Dot</tt><big>(</big><em>graph</em><span class="optional">[</span>, <em>nodes</em><span class="optional">[</span>, <em>edgefn</em><span class="optional">[</span>, <em>nodevisitor</em><span class="optional">[</span>, <em>edgevisitor</em><span class="optional">[</span>, <em>name</em><span class="optional">[</span>, <em>dot</em><span class="optional">[</span>, <em>dotty</em><span class="optional">[</span>, <em>neato</em><span class="optional">[</span>, <em>graphtype</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Dot.Dot" title="Permalink to this definition"></a></dt>
<dd><p>Creates a new Dot generator based on the specified
<a class="reference internal" href="graph.html#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">Graph</span></tt></a>. The Dot generator won&#8217;t reference
the <em>graph</em> once it is constructed.</p>
<p>If the <em>nodes</em> argument is present it is the list of nodes to include
in the graph, otherwise all nodes in <em>graph</em> are included.</p>
<p>If the <em>edgefn</em> argument is present it is a function that yields the
nodes connected to another node, this defaults to
<tt class="xref py py-meth docutils literal"><span class="pre">graph.out_nbr</span></tt>. The constructor won&#8217;t
add edges to the dot file unless both the head and tail of the edge
are in <em>nodes</em>.</p>
<p>If the <em>name</em> is present it specifies the name of the graph in the resulting
dot file. The default is <tt class="docutils literal"><span class="pre">&quot;G&quot;</span></tt>.</p>
<p>The functions <em>nodevisitor</em> and <em>edgevisitor</em> return the default style
for a given edge or node (both default to functions that return an empty
style).</p>
<p>The arguments <em>dot</em>, <em>dotty</em> and <em>neato</em> are used to pass the path to
the corresponding <a class="reference external" href="&lt;http://www.research.att.com/sw/tools/graphviz/&gt;`_">graphviz</a> command.</p>
</dd></dl>
<div class="section" id="updating-graph-attributes">
<h3>Updating graph attributes<a class="headerlink" href="#updating-graph-attributes" title="Permalink to this headline"></a></h3>
<dl class="method">
<dt id="altgraph.Dot.Dot.style">
<tt class="descclassname">Dot.</tt><tt class="descname">style</tt><big>(</big><em>**attr</em><big>)</big><a class="headerlink" href="#altgraph.Dot.Dot.style" title="Permalink to this definition"></a></dt>
<dd><p>Sets the overall style (graph attributes) to the given attributes.</p>
<p>See <a class="reference internal" href="#valid-attributes">Valid Attributes</a> for more information about the attributes.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Dot.Dot.node_style">
<tt class="descclassname">Dot.</tt><tt class="descname">node_style</tt><big>(</big><em>node</em>, <em>**attr</em><big>)</big><a class="headerlink" href="#altgraph.Dot.Dot.node_style" title="Permalink to this definition"></a></dt>
<dd><p>Sets the style for <em>node</em> to the given attributes.</p>
<p>This method will add <em>node</em> to the graph when it isn&#8217;t already
present.</p>
<p>See <a class="reference internal" href="#valid-attributes">Valid Attributes</a> for more information about the attributes.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Dot.Dot.all_node_style">
<tt class="descclassname">Dot.</tt><tt class="descname">all_node_style</tt><big>(</big><em>**attr</em><big>)</big><a class="headerlink" href="#altgraph.Dot.Dot.all_node_style" title="Permalink to this definition"></a></dt>
<dd><p>Replaces the current style for all nodes</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Dot.edge_style">
<tt class="descclassname">altgraph.Dot.</tt><tt class="descname">edge_style</tt><big>(</big><em>head</em>, <em>tail</em>, <em>**attr</em><big>)</big><a class="headerlink" href="#altgraph.Dot.edge_style" title="Permalink to this definition"></a></dt>
<dd><p>Sets the style of an edge to the given attributes. The edge will
be added to the graph when it isn&#8217;t already present, but <em>head</em>
and <em>tail</em> must both be valid nodes.</p>
<p>See <a class="reference internal" href="#valid-attributes">Valid Attributes</a> for more information about the attributes.</p>
</dd></dl>
</div>
<div class="section" id="emitting-output">
<h3>Emitting output<a class="headerlink" href="#emitting-output" title="Permalink to this headline"></a></h3>
<dl class="method">
<dt id="altgraph.Dot.Dot.display">
<tt class="descclassname">Dot.</tt><tt class="descname">display</tt><big>(</big><span class="optional">[</span><em>mode</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Dot.Dot.display" title="Permalink to this definition"></a></dt>
<dd><p>Displays the current graph via dotty.</p>
<p>If the <em>mode</em> is <tt class="docutils literal"><span class="pre">&quot;neato&quot;</span></tt> the dot file is processed with
the neato command before displaying.</p>
<p>This method won&#8217;t return until the dotty command exits.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Dot.save_dot">
<tt class="descclassname">altgraph.Dot.</tt><tt class="descname">save_dot</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#altgraph.Dot.save_dot" title="Permalink to this definition"></a></dt>
<dd><p>Saves the current graph representation into the given file.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>For backward compatibility reasons this method can also
be called without an argument, it will then write the graph
into a fixed filename (present in the attribute <tt class="xref py py-data docutils literal"><span class="pre">Graph.temp_dot</span></tt>).</p>
<p class="last">This feature is deprecated and should not be used.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="altgraph.Dot.save_image">
<tt class="descclassname">altgraph.Dot.</tt><tt class="descname">save_image</tt><big>(</big><em>file_name</em><span class="optional">[</span>, <em>file_type</em><span class="optional">[</span>, <em>mode</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Dot.save_image" title="Permalink to this definition"></a></dt>
<dd><p>Saves the current graph representation as an image file. The output
is written into a file whose basename is <em>file_name</em> and whose suffix
is <em>file_type</em>.</p>
<p>The <em>file_type</em> specifies the type of file to write, the default
is <tt class="docutils literal"><span class="pre">&quot;gif&quot;</span></tt>.</p>
<p>If the <em>mode</em> is <tt class="docutils literal"><span class="pre">&quot;neato&quot;</span></tt> the dot file is processed with
the neato command before displaying.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>For backward compatibility reasons this method can also
be called without an argument, it will then write the graph
with a fixed basename (<tt class="docutils literal"><span class="pre">&quot;out&quot;</span></tt>).</p>
<p class="last">This feature is deprecated and should not be used.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="altgraph.Dot.iterdot">
<tt class="descclassname">altgraph.Dot.</tt><tt class="descname">iterdot</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Dot.iterdot" title="Permalink to this definition"></a></dt>
<dd><p>Yields all lines of a <a class="reference external" href="&lt;http://www.research.att.com/sw/tools/graphviz/&gt;`_">graphviz</a> input file (including line endings).</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Dot.__iter__">
<tt class="descclassname">altgraph.Dot.</tt><tt class="descname">__iter__</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Dot.__iter__" title="Permalink to this definition"></a></dt>
<dd><p>Alias for the <a class="reference internal" href="#altgraph.Dot.iterdot" title="altgraph.Dot.iterdot"><tt class="xref py py-meth docutils literal"><span class="pre">iterdot()</span></tt></a> method.</p>
</dd></dl>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#"><tt class="docutils literal"><span class="pre">altgraph.Dot</span></tt> &#8212; Interface to the dot language</a><ul>
<li><a class="reference internal" href="#example-usage">Example usage</a></li>
<li><a class="reference internal" href="#directed-graph-and-non-directed-graph">Directed graph and non-directed graph</a></li>
<li><a class="reference internal" href="#customizing-the-output">Customizing the output</a></li>
<li><a class="reference internal" href="#valid-attributes">Valid attributes</a></li>
<li><a class="reference internal" href="#class-interface">Class interface</a><ul>
<li><a class="reference internal" href="#updating-graph-attributes">Updating graph attributes</a></li>
<li><a class="reference internal" href="#emitting-output">Emitting output</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="graphutil.html"
title="previous chapter"><tt class="docutils literal"><span class="pre">altgraph.GraphUtil</span></tt> &#8212; Utility functions</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphutil.html" title="altgraph.GraphUtil — Utility functions"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,604 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="index">Index</h1>
<div class="genindex-jumpbox">
<a href="#_"><strong>_</strong></a>
| <a href="#A"><strong>A</strong></a>
| <a href="#B"><strong>B</strong></a>
| <a href="#C"><strong>C</strong></a>
| <a href="#D"><strong>D</strong></a>
| <a href="#E"><strong>E</strong></a>
| <a href="#F"><strong>F</strong></a>
| <a href="#G"><strong>G</strong></a>
| <a href="#H"><strong>H</strong></a>
| <a href="#I"><strong>I</strong></a>
| <a href="#M"><strong>M</strong></a>
| <a href="#N"><strong>N</strong></a>
| <a href="#O"><strong>O</strong></a>
| <a href="#R"><strong>R</strong></a>
| <a href="#S"><strong>S</strong></a>
| <a href="#T"><strong>T</strong></a>
</div>
<h2 id="_">_</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.__contains__">__contains__() (altgraph.Graph.Graph method)</a>
</dt>
<dd><dl>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.__contains__">(altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
</dl></dd>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.__iter__">__iter__() (altgraph.Graph.Graph method)</a>
</dt>
<dd><dl>
<dt><a href="dot.html#altgraph.Dot.__iter__">(in module altgraph.Dot)</a>
</dt>
</dl></dd>
</dl></td>
</tr></table>
<h2 id="A">A</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.add_edge">add_edge() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.add_node">add_node() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.addNode">addNode() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.all_degree">all_degree() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.all_edges">all_edges() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.all_nbrs">all_nbrs() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.Dot.all_node_style">all_node_style() (altgraph.Dot.Dot method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="core.html#module-altgraph">altgraph (module)</a>
</dt>
<dt><a href="dot.html#module-altgraph.Dot">altgraph.Dot (module)</a>
</dt>
<dt><a href="graph.html#module-altgraph.Graph">altgraph.Graph (module)</a>
</dt>
<dt><a href="graphalgo.html#module-altgraph.GraphAlgo">altgraph.GraphAlgo (module)</a>
</dt>
<dt><a href="graphstat.html#module-altgraph.GraphStat">altgraph.GraphStat (module)</a>
</dt>
<dt><a href="graphutil.html#module-altgraph.GraphUtil">altgraph.GraphUtil (module)</a>
</dt>
<dt><a href="objectgraph.html#module-altgraph.ObjectGraph">altgraph.ObjectGraph (module)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="B">B</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.back_bfs">back_bfs() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.back_bfs_subgraph">back_bfs_subgraph() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.back_topo_sort">back_topo_sort() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="C">C</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.clust_coef">clust_coef() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.connected">connected() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.createNode">createNode() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.createReferences">createReferences() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="D">D</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graphstat.html#altgraph.GraphStat.degree_dist">degree_dist() (in module altgraph.GraphStat)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.describe_edge">describe_edge() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.describe_node">describe_node() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graphalgo.html#altgraph.GraphAlgo.dijkstra">dijkstra() (in module altgraph.GraphAlgo)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.Dot.display">display() (altgraph.Dot.Dot method)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.Dot">Dot (class in altgraph.Dot)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="E">E</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.edge_by_id">edge_by_id() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.edge_by_node">edge_by_node() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.edge_data">edge_data() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.edge_list">edge_list() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.edge_style">edge_style() (in module altgraph.Dot)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="F">F</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graphutil.html#altgraph.GraphUtil.filter_stack">filter_stack() (in module altgraph.GraphUtil)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.filterStack">filterStack() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.findNode">findNode() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.flatten">flatten() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.forw_bfs">forw_bfs() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.forw_bfs_subgraph">forw_bfs_subgraph() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.forw_topo_sort">forw_topo_sort() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="G">G</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graphutil.html#altgraph.GraphUtil.generate_random_graph">generate_random_graph() (in module altgraph.GraphUtil)</a>
</dt>
<dt><a href="graphutil.html#altgraph.GraphUtil.generate_scale_free_graph">generate_scale_free_graph() (in module altgraph.GraphUtil)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.get_edges">get_edges() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.get_hops">get_hops() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.getIdent">getIdent() (in module altgraph.ObjectGraph)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.getRawIdent">getRawIdent() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph">Graph (class in altgraph.Graph)</a>
</dt>
<dt><a href="core.html#altgraph.GraphError">GraphError</a>
</dt>
</dl></td>
</tr></table>
<h2 id="H">H</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.head">head() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.hidden_edge_list">hidden_edge_list() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.hidden_node_list">hidden_node_list() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.hide_edge">hide_edge() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.hide_node">hide_node() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="I">I</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.inc_degree">inc_degree() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.inc_edges">inc_edges() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.inc_nbrs">inc_nbrs() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.iterdata">iterdata() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.iterdfs">iterdfs() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.iterdot">iterdot() (in module altgraph.Dot)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="M">M</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.msg">msg() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.msgin">msgin() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.msgout">msgout() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="N">N</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.node_data">node_data() (in module altgraph.Graph)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.node_list">node_list() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.Dot.node_style">node_style() (altgraph.Dot.Dot method)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.nodes">nodes() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.number_of_edges">number_of_edges() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.number_of_hidden_edges">number_of_hidden_edges() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.number_of_hidden_nodes">number_of_hidden_nodes() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.number_of_nodes">number_of_nodes() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="O">O</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph">ObjectGraph (class in altgraph.ObjectGraph)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.debug">ObjectGraph.debug (in module altgraph.ObjectGraph)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.graph">ObjectGraph.graph (in module altgraph.ObjectGraph)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.out_degree">out_degree() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.out_edges">out_edges() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.out_nbrs">out_nbrs() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="R">R</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.ObjectGraph.removeNode">removeNode() (altgraph.ObjectGraph.ObjectGraph method)</a>
</dt>
<dt><a href="objectgraph.html#altgraph.ObjectGraph.removeReference">removeReference() (in module altgraph.ObjectGraph)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.restore_all_edges">restore_all_edges() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.restore_all_nodes">restore_all_nodes() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.restore_edge">restore_edge() (altgraph.Graph.Graph method)</a>
</dt>
<dt><a href="graph.html#altgraph.Graph.Graph.restore_node">restore_node() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="S">S</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="dot.html#altgraph.Dot.save_dot">save_dot() (in module altgraph.Dot)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.save_image">save_image() (in module altgraph.Dot)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graphalgo.html#altgraph.GraphAlgo.shortest_path">shortest_path() (in module altgraph.GraphAlgo)</a>
</dt>
<dt><a href="dot.html#altgraph.Dot.Dot.style">style() (altgraph.Dot.Dot method)</a>
</dt>
</dl></td>
</tr></table>
<h2 id="T">T</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="graph.html#altgraph.Graph.Graph.tail">tail() (altgraph.Graph.Graph method)</a>
</dt>
</dl></td>
</tr></table>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,491 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>altgraph.Graph — Basic directional graphs &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="altgraph.ObjectGraph — Graphs of objecs with an identifier" href="objectgraph.html" />
<link rel="prev" title="altgraph — A Python Graph Library" href="core.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="objectgraph.html" title="altgraph.ObjectGraph — Graphs of objecs with an identifier"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="core.html" title="altgraph — A Python Graph Library"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-altgraph.Graph">
<span id="altgraph-graph-basic-directional-graphs"></span><h1><a class="reference internal" href="#module-altgraph.Graph" title="altgraph.Graph: Basic directional graphs."><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.Graph</span></tt></a> &#8212; Basic directional graphs<a class="headerlink" href="#module-altgraph.Graph" title="Permalink to this headline"></a></h1>
<p>The module <a class="reference internal" href="#module-altgraph.Graph" title="altgraph.Graph: Basic directional graphs."><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.Graph</span></tt></a> provides a class <a class="reference internal" href="#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">Graph</span></tt></a> that
represents a directed graph with <em>N</em> nodes and <em>E</em> edges.</p>
<dl class="class">
<dt id="altgraph.Graph.Graph">
<em class="property">class </em><tt class="descclassname">altgraph.Graph.</tt><tt class="descname">Graph</tt><big>(</big><span class="optional">[</span><em>edges</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph" title="Permalink to this definition"></a></dt>
<dd><p>Constructs a new empty <a class="reference internal" href="#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">Graph</span></tt></a> object. If the optional
<em>edges</em> parameter is supplied, updates the graph by adding the
specified edges.</p>
<p>All of the elements in <em>edges</em> should be tuples with two or three
elements. The first two elements of the tuple are the source and
destination node of the edge, the optional third element is the
edge data. The source and destination nodes are added to the graph
when the aren&#8217;t already present.</p>
</dd></dl>
<div class="section" id="node-related-methods">
<h2>Node related methods<a class="headerlink" href="#node-related-methods" title="Permalink to this headline"></a></h2>
<dl class="method">
<dt id="altgraph.Graph.Graph.add_node">
<tt class="descclassname">Graph.</tt><tt class="descname">add_node</tt><big>(</big><em>node</em><span class="optional">[</span>, <em>node_data</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.add_node" title="Permalink to this definition"></a></dt>
<dd><p>Adds a new node to the graph if it is not already present. The new
node must be a hashable object.</p>
<p>Arbitrary data can be attached to the node via the optional <em>node_data</em>
argument.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">the node also won&#8217;t be added to the graph when it is
present but currently hidden.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.hide_node">
<tt class="descclassname">Graph.</tt><tt class="descname">hide_node</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.hide_node" title="Permalink to this definition"></a></dt>
<dd><p>Hides a <em>node</em> from the graph. The incoming and outgoing edges of
the node will also be hidden.</p>
<p>Raises <a class="reference internal" href="core.html#altgraph.GraphError" title="altgraph.GraphError"><tt class="xref py py-class docutils literal"><span class="pre">altgraph.GraphError</span></tt></a> when the node is not (visible)
node of the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.restore_node">
<tt class="descclassname">Graph.</tt><tt class="descname">restore_node</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.restore_node" title="Permalink to this definition"></a></dt>
<dd><p>Restores a previously hidden <em>node</em>. The incoming and outgoing
edges of the node are also restored.</p>
<p>Raises <a class="reference internal" href="core.html#altgraph.GraphError" title="altgraph.GraphError"><tt class="xref py py-class docutils literal"><span class="pre">altgraph.GraphError</span></tt></a> when the node is not a hidden
node of the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.restore_all_nodes">
<tt class="descclassname">Graph.</tt><tt class="descname">restore_all_nodes</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.restore_all_nodes" title="Permalink to this definition"></a></dt>
<dd><p>Restores all hidden nodes.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.number_of_nodes">
<tt class="descclassname">Graph.</tt><tt class="descname">number_of_nodes</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.number_of_nodes" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of visible nodes in the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.number_of_hidden_nodes">
<tt class="descclassname">Graph.</tt><tt class="descname">number_of_hidden_nodes</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.number_of_hidden_nodes" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of hidden nodes in the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.node_list">
<tt class="descclassname">Graph.</tt><tt class="descname">node_list</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.node_list" title="Permalink to this definition"></a></dt>
<dd><p>Return a list with all visible nodes in the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.hidden_node_list">
<tt class="descclassname">Graph.</tt><tt class="descname">hidden_node_list</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.hidden_node_list" title="Permalink to this definition"></a></dt>
<dd><p>Return a list with all hidden nodes in the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.node_data">
<tt class="descclassname">altgraph.Graph.</tt><tt class="descname">node_data</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.node_data" title="Permalink to this definition"></a></dt>
<dd><p>Return the data associated with the <em>node</em> when it was
added.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.describe_node">
<tt class="descclassname">Graph.</tt><tt class="descname">describe_node</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.describe_node" title="Permalink to this definition"></a></dt>
<dd><p>Returns <em>node</em>, the node&#8217;s data and the lists of outgoing
and incoming edges for the node.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">the edge lists should not be modified, doing so
can result in unpredicatable behavior.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.__contains__">
<tt class="descclassname">Graph.</tt><tt class="descname">__contains__</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.__contains__" title="Permalink to this definition"></a></dt>
<dd><p>Returns True iff <em>node</em> is a node in the graph. This
method is accessed through the <em>in</em> operator.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.__iter__">
<tt class="descclassname">Graph.</tt><tt class="descname">__iter__</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.__iter__" title="Permalink to this definition"></a></dt>
<dd><p>Yield all nodes in the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.out_edges">
<tt class="descclassname">Graph.</tt><tt class="descname">out_edges</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.out_edges" title="Permalink to this definition"></a></dt>
<dd><p>Return the list of outgoing edges for <em>node</em></p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.inc_edges">
<tt class="descclassname">Graph.</tt><tt class="descname">inc_edges</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.inc_edges" title="Permalink to this definition"></a></dt>
<dd><p>Return the list of incoming edges for <em>node</em></p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.all_edges">
<tt class="descclassname">Graph.</tt><tt class="descname">all_edges</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.all_edges" title="Permalink to this definition"></a></dt>
<dd><p>Return the list of incoming and outgoing edges for <em>node</em></p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.out_degree">
<tt class="descclassname">Graph.</tt><tt class="descname">out_degree</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.out_degree" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of outgoing edges for <em>node</em>.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.inc_degree">
<tt class="descclassname">Graph.</tt><tt class="descname">inc_degree</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.inc_degree" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of incoming edges for <em>node</em>.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.all_degree">
<tt class="descclassname">Graph.</tt><tt class="descname">all_degree</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.all_degree" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of edges (incoming or outgoing) for <em>node</em>.</p>
</dd></dl>
</div>
<div class="section" id="edge-related-methods">
<h2>Edge related methods<a class="headerlink" href="#edge-related-methods" title="Permalink to this headline"></a></h2>
<dl class="method">
<dt id="altgraph.Graph.Graph.add_edge">
<tt class="descclassname">Graph.</tt><tt class="descname">add_edge</tt><big>(</big><em>head_id</em>, <em>tail_id</em><span class="optional">[</span>, <em>edge data</em><span class="optional">[</span>, <em>create_nodes</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.add_edge" title="Permalink to this definition"></a></dt>
<dd><p>Adds a directed edge from <em>head_id</em> to <em>tail_id</em>. Arbitrary data can
be added via <em>edge_data</em>. When <em>create_nodes</em> is <em>True</em> (the default),
<em>head_id</em> and <em>tail_id</em> will be added to the graph when the aren&#8217;t
already present.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.hide_edge">
<tt class="descclassname">Graph.</tt><tt class="descname">hide_edge</tt><big>(</big><em>edge</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.hide_edge" title="Permalink to this definition"></a></dt>
<dd><p>Hides an edge from the graph. The edge may be unhidden at some later
time.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.restore_edge">
<tt class="descclassname">Graph.</tt><tt class="descname">restore_edge</tt><big>(</big><em>edge</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.restore_edge" title="Permalink to this definition"></a></dt>
<dd><p>Restores a previously hidden <em>edge</em>.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.restore_all_edges">
<tt class="descclassname">Graph.</tt><tt class="descname">restore_all_edges</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.restore_all_edges" title="Permalink to this definition"></a></dt>
<dd><p>Restore all edges that were hidden before, except for edges
referring to hidden nodes.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.edge_by_node">
<tt class="descclassname">Graph.</tt><tt class="descname">edge_by_node</tt><big>(</big><em>head</em>, <em>tail</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.edge_by_node" title="Permalink to this definition"></a></dt>
<dd><p>Return the edge ID for an edge from <em>head</em> to <em>tail</em>,
or <a class="reference external" href="http://docs.python.org/library/constants.html#None" title="(in Python v2.7)"><tt class="xref py py-data docutils literal"><span class="pre">None</span></tt></a> when no such edge exists.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.edge_by_id">
<tt class="descclassname">Graph.</tt><tt class="descname">edge_by_id</tt><big>(</big><em>edge</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.edge_by_id" title="Permalink to this definition"></a></dt>
<dd><p>Return the head and tail of the <em>edge</em></p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.edge_data">
<tt class="descclassname">Graph.</tt><tt class="descname">edge_data</tt><big>(</big><em>edge</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.edge_data" title="Permalink to this definition"></a></dt>
<dd><p>Return the data associated with the <em>edge</em>.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.head">
<tt class="descclassname">Graph.</tt><tt class="descname">head</tt><big>(</big><em>edge</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.head" title="Permalink to this definition"></a></dt>
<dd><p>Return the head of an <em>edge</em></p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.tail">
<tt class="descclassname">Graph.</tt><tt class="descname">tail</tt><big>(</big><em>edge</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.tail" title="Permalink to this definition"></a></dt>
<dd><p>Return the tail of an <em>edge</em></p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.describe_edge">
<tt class="descclassname">Graph.</tt><tt class="descname">describe_edge</tt><big>(</big><em>edge</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.describe_edge" title="Permalink to this definition"></a></dt>
<dd><p>Return the <em>edge</em>, the associated data, its head and tail.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.number_of_edges">
<tt class="descclassname">Graph.</tt><tt class="descname">number_of_edges</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.number_of_edges" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of visible edges.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.number_of_hidden_edges">
<tt class="descclassname">Graph.</tt><tt class="descname">number_of_hidden_edges</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.number_of_hidden_edges" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of hidden edges.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.edge_list">
<tt class="descclassname">Graph.</tt><tt class="descname">edge_list</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.edge_list" title="Permalink to this definition"></a></dt>
<dd><p>Returns a list with all visible edges in the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.hidden_edge_list">
<tt class="descclassname">Graph.</tt><tt class="descname">hidden_edge_list</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.hidden_edge_list" title="Permalink to this definition"></a></dt>
<dd><p>Returns a list with all hidden edges in the graph.</p>
</dd></dl>
</div>
<div class="section" id="graph-traversal">
<h2>Graph traversal<a class="headerlink" href="#graph-traversal" title="Permalink to this headline"></a></h2>
<dl class="method">
<dt id="altgraph.Graph.Graph.out_nbrs">
<tt class="descclassname">Graph.</tt><tt class="descname">out_nbrs</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.out_nbrs" title="Permalink to this definition"></a></dt>
<dd><p>Return a list of all nodes connected by outgoing edges.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.inc_nbrs">
<tt class="descclassname">Graph.</tt><tt class="descname">inc_nbrs</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.inc_nbrs" title="Permalink to this definition"></a></dt>
<dd><p>Return a list of all nodes connected by incoming edges.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.all_nbrs">
<tt class="descclassname">Graph.</tt><tt class="descname">all_nbrs</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.all_nbrs" title="Permalink to this definition"></a></dt>
<dd><p>Returns a list of nodes connected by an incoming or outgoing edge.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.forw_topo_sort">
<tt class="descclassname">Graph.</tt><tt class="descname">forw_topo_sort</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.forw_topo_sort" title="Permalink to this definition"></a></dt>
<dd><p>Return a list of nodes where the successors (based on outgoing
edges) of any given node apear in the sequence after that node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.back_topo_sort">
<tt class="descclassname">Graph.</tt><tt class="descname">back_topo_sort</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.back_topo_sort" title="Permalink to this definition"></a></dt>
<dd><p>Return a list of nodes where the successors (based on incoming
edges) of any given node apear in the sequence after that node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.forw_bfs_subgraph">
<tt class="descclassname">Graph.</tt><tt class="descname">forw_bfs_subgraph</tt><big>(</big><em>start_id</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.forw_bfs_subgraph" title="Permalink to this definition"></a></dt>
<dd><p>Return a subgraph consisting of the breadth first
reachable nodes from <em>start_id</em> based on their outgoing edges.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.back_bfs_subgraph">
<tt class="descclassname">Graph.</tt><tt class="descname">back_bfs_subgraph</tt><big>(</big><em>start_id</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.back_bfs_subgraph" title="Permalink to this definition"></a></dt>
<dd><p>Return a subgraph consisting of the breadth first
reachable nodes from <em>start_id</em> based on their incoming edges.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.iterdfs">
<tt class="descclassname">Graph.</tt><tt class="descname">iterdfs</tt><big>(</big><em>start</em><span class="optional">[</span>, <em>end</em><span class="optional">[</span>, <em>forward</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.iterdfs" title="Permalink to this definition"></a></dt>
<dd><p>Yield nodes in a depth first traversal starting at the <em>start</em>
node.</p>
<p>If <em>end</em> is specified traversal stops when reaching that node.</p>
<p>If forward is True (the default) edges are traversed in forward
direction, otherwise they are traversed in reverse direction.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.iterdata">
<tt class="descclassname">Graph.</tt><tt class="descname">iterdata</tt><big>(</big><em>start</em><span class="optional">[</span>, <em>end</em><span class="optional">[</span>, <em>forward</em><span class="optional">[</span>, <em>condition</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.iterdata" title="Permalink to this definition"></a></dt>
<dd><p>Yield the associated data for nodes in a depth first traversal
starting at the <em>start</em> node. This method will not yield values for nodes
without associated data.</p>
<p>If <em>end</em> is specified traversal stops when reaching that node.</p>
<p>If <em>condition</em> is specified and the condition callable returns
False for the associated data this method will not yield the
associated data and will not follow the edges for the node.</p>
<p>If forward is True (the default) edges are traversed in forward
direction, otherwise they are traversed in reverse direction.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.forw_bfs">
<tt class="descclassname">Graph.</tt><tt class="descname">forw_bfs</tt><big>(</big><em>start</em><span class="optional">[</span>, <em>end</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.forw_bfs" title="Permalink to this definition"></a></dt>
<dd><p>Returns a list of nodes starting at <em>start</em> in some bread first
search order (following outgoing edges).</p>
<p>When <em>end</em> is specified iteration stops at that node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.back_bfs">
<tt class="descclassname">Graph.</tt><tt class="descname">back_bfs</tt><big>(</big><em>start</em><span class="optional">[</span>, <em>end</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.back_bfs" title="Permalink to this definition"></a></dt>
<dd><p>Returns a list of nodes starting at <em>start</em> in some bread first
search order (following incoming edges).</p>
<p>When <em>end</em> is specified iteration stops at that node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.get_hops">
<tt class="descclassname">Graph.</tt><tt class="descname">get_hops</tt><big>(</big><em>start</em><span class="optional">[</span>, <em>end</em><span class="optional">[</span>, <em>forward</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.get_hops" title="Permalink to this definition"></a></dt>
<dd><p>Computes the hop distance to all nodes centered around a specified node.</p>
<p>First order neighbours are at hop 1, their neigbours are at hop 2 etc.
Uses <a class="reference internal" href="#altgraph.Graph.Graph.forw_bfs" title="altgraph.Graph.Graph.forw_bfs"><tt class="xref py py-meth docutils literal"><span class="pre">forw_bfs()</span></tt></a> or <a class="reference internal" href="#altgraph.Graph.Graph.back_bfs" title="altgraph.Graph.Graph.back_bfs"><tt class="xref py py-meth docutils literal"><span class="pre">back_bfs()</span></tt></a> depending on the value of
the forward parameter.</p>
<p>If the distance between all neighbouring nodes is 1 the hop number
corresponds to the shortest distance between the nodes.</p>
<p>Typical usage:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">graph</span><span class="o">.</span><span class="n">get_hops</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">[(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">5</span><span class="p">)]</span>
<span class="go"># node 1 is at 0 hops</span>
<span class="go"># node 2 is at 1 hop</span>
<span class="go"># ...</span>
<span class="go"># node 8 is at 5 hops</span>
</pre></div>
</div>
</dd></dl>
</div>
<div class="section" id="graph-statistics">
<h2>Graph statistics<a class="headerlink" href="#graph-statistics" title="Permalink to this headline"></a></h2>
<dl class="method">
<dt id="altgraph.Graph.Graph.connected">
<tt class="descclassname">Graph.</tt><tt class="descname">connected</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.connected" title="Permalink to this definition"></a></dt>
<dd><p>Returns True iff every node in the graph can be reached from
every other node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.Graph.Graph.clust_coef">
<tt class="descclassname">Graph.</tt><tt class="descname">clust_coef</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.Graph.Graph.clust_coef" title="Permalink to this definition"></a></dt>
<dd><p>Returns the local clustering coefficient of node.</p>
<p>The local cluster coefficient is the proportion of the actual number
of edges between neighbours of node and the maximum number of
edges between those nodes.</p>
</dd></dl>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#"><tt class="docutils literal"><span class="pre">altgraph.Graph</span></tt> &#8212; Basic directional graphs</a><ul>
<li><a class="reference internal" href="#node-related-methods">Node related methods</a></li>
<li><a class="reference internal" href="#edge-related-methods">Edge related methods</a></li>
<li><a class="reference internal" href="#graph-traversal">Graph traversal</a></li>
<li><a class="reference internal" href="#graph-statistics">Graph statistics</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="core.html"
title="previous chapter"><tt class="docutils literal"><span class="pre">altgraph</span></tt> &#8212; A Python Graph Library</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="objectgraph.html"
title="next chapter"><tt class="docutils literal"><span class="pre">altgraph.ObjectGraph</span></tt> &#8212; Graphs of objecs with an identifier</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="objectgraph.html" title="altgraph.ObjectGraph — Graphs of objecs with an identifier"
>next</a> |</li>
<li class="right" >
<a href="core.html" title="altgraph — A Python Graph Library"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,134 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>altgraph.GraphAlgo — Graph algorithms &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="altgraph.GraphStat — Functions providing various graph statistics" href="graphstat.html" />
<link rel="prev" title="altgraph.ObjectGraph — Graphs of objecs with an identifier" href="objectgraph.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphstat.html" title="altgraph.GraphStat — Functions providing various graph statistics"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="objectgraph.html" title="altgraph.ObjectGraph — Graphs of objecs with an identifier"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-altgraph.GraphAlgo">
<span id="altgraph-graphalgo-graph-algorithms"></span><h1><a class="reference internal" href="#module-altgraph.GraphAlgo" title="altgraph.GraphAlgo: Basic graphs algoritms"><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.GraphAlgo</span></tt></a> &#8212; Graph algorithms<a class="headerlink" href="#module-altgraph.GraphAlgo" title="Permalink to this headline"></a></h1>
<dl class="function">
<dt id="altgraph.GraphAlgo.dijkstra">
<tt class="descclassname">altgraph.GraphAlgo.</tt><tt class="descname">dijkstra</tt><big>(</big><em>graph</em>, <em>start</em><span class="optional">[</span>, <em>end</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.GraphAlgo.dijkstra" title="Permalink to this definition"></a></dt>
<dd><p>Dijkstra&#8217;s algorithm for shortest paths.</p>
<p>Find shortest paths from the start node to all nodes nearer
than or equal to the <em>end</em> node. The edge data is assumed to be the edge length.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Dijkstra&#8217;s algorithm is only guaranteed to work correctly when all edge lengths are positive.
This code does not verify this property for all edges (only the edges examined until the end
vertex is reached), but will correctly compute shortest paths even for some graphs with negative
edges, and will raise an exception if it discovers that a negative edge has caused it to make a mistake.</p>
</div>
</dd></dl>
<dl class="function">
<dt id="altgraph.GraphAlgo.shortest_path">
<tt class="descclassname">altgraph.GraphAlgo.</tt><tt class="descname">shortest_path</tt><big>(</big><em>graph</em>, <em>start</em>, <em>end</em><big>)</big><a class="headerlink" href="#altgraph.GraphAlgo.shortest_path" title="Permalink to this definition"></a></dt>
<dd><p>Find a single shortest path from the given start node to the given end node.
The input has the same conventions as <a class="reference internal" href="#altgraph.GraphAlgo.dijkstra" title="altgraph.GraphAlgo.dijkstra"><tt class="xref py py-func docutils literal"><span class="pre">dijkstra()</span></tt></a>. The output is a list
of the nodes in order along the shortest path.</p>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="objectgraph.html"
title="previous chapter"><tt class="docutils literal"><span class="pre">altgraph.ObjectGraph</span></tt> &#8212; Graphs of objecs with an identifier</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="graphstat.html"
title="next chapter"><tt class="docutils literal"><span class="pre">altgraph.GraphStat</span></tt> &#8212; Functions providing various graph statistics</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphstat.html" title="altgraph.GraphStat — Functions providing various graph statistics"
>next</a> |</li>
<li class="right" >
<a href="objectgraph.html" title="altgraph.ObjectGraph — Graphs of objecs with an identifier"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,130 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>altgraph.GraphStat — Functions providing various graph statistics &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="altgraph.GraphUtil — Utility functions" href="graphutil.html" />
<link rel="prev" title="altgraph.GraphAlgo — Graph algorithms" href="graphalgo.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphutil.html" title="altgraph.GraphUtil — Utility functions"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="graphalgo.html" title="altgraph.GraphAlgo — Graph algorithms"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-altgraph.GraphStat">
<span id="altgraph-graphstat-functions-providing-various-graph-statistics"></span><h1><a class="reference internal" href="#module-altgraph.GraphStat" title="altgraph.GraphStat: Functions providing various graph statistics"><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.GraphStat</span></tt></a> &#8212; Functions providing various graph statistics<a class="headerlink" href="#module-altgraph.GraphStat" title="Permalink to this headline"></a></h1>
<p>The module <a class="reference internal" href="#module-altgraph.GraphStat" title="altgraph.GraphStat: Functions providing various graph statistics"><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.GraphStat</span></tt></a> provides function that calculate
graph statistics. Currently there is only one such function, more may
be added later.</p>
<dl class="function">
<dt id="altgraph.GraphStat.degree_dist">
<tt class="descclassname">altgraph.GraphStat.</tt><tt class="descname">degree_dist</tt><big>(</big><em>graph</em><span class="optional">[</span>, <em>limits</em><span class="optional">[</span>, <em>bin_num</em><span class="optional">[</span>, <em>mode</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.GraphStat.degree_dist" title="Permalink to this definition"></a></dt>
<dd><p>Groups the number of edges per node into <em>bin_num</em> bins
and returns the list of those bins. Every item in the result
is a tuple with the center of the bin and the number of items
in that bin.</p>
<p>When the <em>limits</em> argument is present it must be a tuple with
the mininum and maximum number of edges that get binned (that
is, when <em>limits</em> is <tt class="docutils literal"><span class="pre">(4,</span> <span class="pre">10)</span></tt> only nodes with between 4
and 10 edges get counted.</p>
<p>The <em>mode</em> argument is used to count incoming (<tt class="docutils literal"><span class="pre">'inc'</span></tt>) or
outgoing (<tt class="docutils literal"><span class="pre">'out'</span></tt>) edges. The default is to count the outgoing
edges.</p>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="graphalgo.html"
title="previous chapter"><tt class="docutils literal"><span class="pre">altgraph.GraphAlgo</span></tt> &#8212; Graph algorithms</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="graphutil.html"
title="next chapter"><tt class="docutils literal"><span class="pre">altgraph.GraphUtil</span></tt> &#8212; Utility functions</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphutil.html" title="altgraph.GraphUtil — Utility functions"
>next</a> |</li>
<li class="right" >
<a href="graphalgo.html" title="altgraph.GraphAlgo — Graph algorithms"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,162 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>altgraph.GraphUtil — Utility functions &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="altgraph.Dot — Interface to the dot language" href="dot.html" />
<link rel="prev" title="altgraph.GraphStat — Functions providing various graph statistics" href="graphstat.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="dot.html" title="altgraph.Dot — Interface to the dot language"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="graphstat.html" title="altgraph.GraphStat — Functions providing various graph statistics"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-altgraph.GraphUtil">
<span id="altgraph-graphutil-utility-functions"></span><h1><a class="reference internal" href="#module-altgraph.GraphUtil" title="altgraph.GraphUtil: Utility functions"><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.GraphUtil</span></tt></a> &#8212; Utility functions<a class="headerlink" href="#module-altgraph.GraphUtil" title="Permalink to this headline"></a></h1>
<p>The module <a class="reference internal" href="#module-altgraph.GraphUtil" title="altgraph.GraphUtil: Utility functions"><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.GraphUtil</span></tt></a> performs a number of more
or less useful utility functions.</p>
<dl class="function">
<dt id="altgraph.GraphUtil.generate_random_graph">
<tt class="descclassname">altgraph.GraphUtil.</tt><tt class="descname">generate_random_graph</tt><big>(</big><em>node_num, edge_num[, self_loops[, multi_edges]</em><big>)</big><a class="headerlink" href="#altgraph.GraphUtil.generate_random_graph" title="Permalink to this definition"></a></dt>
<dd><p>Generates and returns a <a class="reference internal" href="graph.html#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">Graph</span></tt></a> instance
with <em>node_num</em> nodes randomly connected by <em>edge_num</em> edges.</p>
<p>When <em>self_loops</em> is present and True there can be edges that point from
a node to itself.</p>
<p>When <em>multi_edge</em> is present and True there can be duplicate edges.</p>
<p>This method raises <tt class="xref py py-class docutils literal"><span class="pre">GraphError</span> <span class="pre">&lt;altgraph.GraphError</span></tt> when
a graph with the requested configuration cannot be created.</p>
</dd></dl>
<dl class="function">
<dt id="altgraph.GraphUtil.generate_scale_free_graph">
<tt class="descclassname">altgraph.GraphUtil.</tt><tt class="descname">generate_scale_free_graph</tt><big>(</big><em>steps</em>, <em>growth_num</em><span class="optional">[</span>, <em>self_loops</em><span class="optional">[</span>, <em>multi_edges</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.GraphUtil.generate_scale_free_graph" title="Permalink to this definition"></a></dt>
<dd><p>Generates and returns a <a class="reference internal" href="graph.html#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">Graph</span></tt></a> instance that
will have <em>steps*growth_n um</em> nodes and a scale free (powerlaw)
connectivity.</p>
<p>Starting with a fully connected graph with <em>growth_num</em> nodes
at every step <em>growth_num</em> nodes are added to the graph and are connected
to existing nodes with a probability proportional to the degree of these
existing nodes.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">The current implementation is basically untested, although
code inspection seems to indicate an implementation that is consistent
with the description at
<a class="reference external" href="http://mathworld.wolfram.com/Scale-FreeNetwork.html">Wolfram MathWorld</a></p>
</div>
</dd></dl>
<dl class="function">
<dt id="altgraph.GraphUtil.filter_stack">
<tt class="descclassname">altgraph.GraphUtil.</tt><tt class="descname">filter_stack</tt><big>(</big><em>graph</em>, <em>head</em>, <em>filters</em><big>)</big><a class="headerlink" href="#altgraph.GraphUtil.filter_stack" title="Permalink to this definition"></a></dt>
<dd><p>Perform a depth-first oder walk of the graph starting at <em>head</em> and
apply all filter functions in <em>filters</em> on the node data of the nodes
found.</p>
<p>Returns (<em>visited</em>, <em>removes</em>, <em>orphans</em>), where</p>
<ul class="simple">
<li><em>visited</em>: the set of visited nodes</li>
<li><em>removes</em>: the list of nodes where the node data doesn&#8217;t match
all <em>filters</em>.</li>
<li><em>orphans</em>: list of tuples (<em>last_good</em>, <em>node</em>), where
node is not in <em>removes</em> and one of the nodes that is connected
by an incoming edge is in <em>removes</em>. <em>Last_good</em> is the
closest upstream node that is not in <em>removes</em>.</li>
</ul>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="graphstat.html"
title="previous chapter"><tt class="docutils literal"><span class="pre">altgraph.GraphStat</span></tt> &#8212; Functions providing various graph statistics</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="dot.html"
title="next chapter"><tt class="docutils literal"><span class="pre">altgraph.Dot</span></tt> &#8212; Interface to the dot language</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="dot.html" title="altgraph.Dot — Interface to the dot language"
>next</a> |</li>
<li class="right" >
<a href="graphstat.html" title="altgraph.GraphStat — Functions providing various graph statistics"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,142 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Altgraph - A basic graph library &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="#" />
<link rel="next" title="Release history" href="changelog.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="changelog.html" title="Release history"
accesskey="N">next</a> |</li>
<li><a href="#">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="altgraph-a-basic-graph-library">
<h1>Altgraph - A basic graph library<a class="headerlink" href="#altgraph-a-basic-graph-library" title="Permalink to this headline"></a></h1>
<p>altgraph is a fork of graphlib: a graph (network) package for constructing
graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
graphviz output.</p>
<p>The primary users of this package are <a class="reference external" href="http://pypi.python.org/pypi/macholib">macholib</a> and <a class="reference external" href="http://pypi.python.org/pypi/modulegraph">modulegraph</a>.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="changelog.html">Release history</a></li>
<li class="toctree-l1"><a class="reference internal" href="license.html">License</a></li>
<li class="toctree-l1"><a class="reference internal" href="core.html"><tt class="docutils literal"><span class="pre">altgraph</span></tt> &#8212; A Python Graph Library</a></li>
<li class="toctree-l1"><a class="reference internal" href="graph.html"><tt class="docutils literal"><span class="pre">altgraph.Graph</span></tt> &#8212; Basic directional graphs</a></li>
<li class="toctree-l1"><a class="reference internal" href="objectgraph.html"><tt class="docutils literal"><span class="pre">altgraph.ObjectGraph</span></tt> &#8212; Graphs of objecs with an identifier</a></li>
<li class="toctree-l1"><a class="reference internal" href="graphalgo.html"><tt class="docutils literal"><span class="pre">altgraph.GraphAlgo</span></tt> &#8212; Graph algorithms</a></li>
<li class="toctree-l1"><a class="reference internal" href="graphstat.html"><tt class="docutils literal"><span class="pre">altgraph.GraphStat</span></tt> &#8212; Functions providing various graph statistics</a></li>
<li class="toctree-l1"><a class="reference internal" href="graphutil.html"><tt class="docutils literal"><span class="pre">altgraph.GraphUtil</span></tt> &#8212; Utility functions</a></li>
<li class="toctree-l1"><a class="reference internal" href="dot.html"><tt class="docutils literal"><span class="pre">altgraph.Dot</span></tt> &#8212; Interface to the dot language</a></li>
</ul>
</div>
<div class="section" id="online-resources">
<h2>Online Resources<a class="headerlink" href="#online-resources" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><a class="reference external" href="http://bitbucket.org/ronaldoussoren/altgraph/">Sourcecode repository on bitbucket</a></li>
<li><a class="reference external" href="http://bitbucket.org/ronaldoussoren/altgraph/issues">The issue tracker</a></li>
</ul>
</div>
<div class="section" id="indices-and-tables">
<h2>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
<li><a class="reference internal" href="py-modindex.html"><em>Module Index</em></a></li>
<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="#">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Altgraph - A basic graph library</a><ul>
<li><a class="reference internal" href="#online-resources">Online Resources</a></li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
</li>
</ul>
<h4>Next topic</h4>
<p class="topless"><a href="changelog.html"
title="next chapter">Release history</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="changelog.html" title="Release history"
>next</a> |</li>
<li><a href="#">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,136 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>License &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="altgraph — A Python Graph Library" href="core.html" />
<link rel="prev" title="Release history" href="changelog.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="core.html" title="altgraph — A Python Graph Library"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="changelog.html" title="Release history"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="license">
<h1>License<a class="headerlink" href="#license" title="Permalink to this headline"></a></h1>
<p>Copyright (c) 2004 Istvan Albert unless otherwise noted.</p>
<p>Parts are copyright (c) Bob Ippolito</p>
<p>Parts are copyright (c) 2010-2014 Ronald Oussoren</p>
<div class="section" id="mit-license">
<h2>MIT License<a class="headerlink" href="#mit-license" title="Permalink to this headline"></a></h2>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the &#8220;Software&#8221;), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
so.</p>
<p>THE SOFTWARE IS PROVIDED &#8220;AS IS&#8221;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">License</a><ul>
<li><a class="reference internal" href="#mit-license">MIT License</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="changelog.html"
title="previous chapter">Release history</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="core.html"
title="next chapter"><tt class="docutils literal"><span class="pre">altgraph</span></tt> &#8212; A Python Graph Library</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="core.html" title="altgraph — A Python Graph Library"
>next</a> |</li>
<li class="right" >
<a href="changelog.html" title="Release history"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,283 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>altgraph.ObjectGraph — Graphs of objecs with an identifier &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<link rel="next" title="altgraph.GraphAlgo — Graph algorithms" href="graphalgo.html" />
<link rel="prev" title="altgraph.Graph — Basic directional graphs" href="graph.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphalgo.html" title="altgraph.GraphAlgo — Graph algorithms"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="graph.html" title="altgraph.Graph — Basic directional graphs"
accesskey="P">previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-altgraph.ObjectGraph">
<span id="altgraph-objectgraph-graphs-of-objecs-with-an-identifier"></span><h1><a class="reference internal" href="#module-altgraph.ObjectGraph" title="altgraph.ObjectGraph: A graph of objects that have a &quot;graphident&quot; attribute."><tt class="xref py py-mod docutils literal"><span class="pre">altgraph.ObjectGraph</span></tt></a> &#8212; Graphs of objecs with an identifier<a class="headerlink" href="#module-altgraph.ObjectGraph" title="Permalink to this headline"></a></h1>
<dl class="class">
<dt id="altgraph.ObjectGraph.ObjectGraph">
<em class="property">class </em><tt class="descclassname">altgraph.ObjectGraph.</tt><tt class="descname">ObjectGraph</tt><big>(</big><span class="optional">[</span><em>graph</em><span class="optional">[</span>, <em>debug</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph" title="Permalink to this definition"></a></dt>
<dd><p>A graph of objects that have a &#8220;graphident&#8221; attribute. The
value of this attribute is the key for the object in the
graph.</p>
<p>The optional <em>graph</em> is a previously constructed
<a class="reference internal" href="graph.html#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">Graph</span></tt></a>.</p>
<p>The optional <em>debug</em> level controls the amount of debug output
(see <a class="reference internal" href="#altgraph.ObjectGraph.ObjectGraph.msg" title="altgraph.ObjectGraph.ObjectGraph.msg"><tt class="xref py py-meth docutils literal"><span class="pre">msg()</span></tt></a>, <a class="reference internal" href="#altgraph.ObjectGraph.ObjectGraph.msgin" title="altgraph.ObjectGraph.ObjectGraph.msgin"><tt class="xref py py-meth docutils literal"><span class="pre">msgin()</span></tt></a> and <a class="reference internal" href="#altgraph.ObjectGraph.ObjectGraph.msgout" title="altgraph.ObjectGraph.ObjectGraph.msgout"><tt class="xref py py-meth docutils literal"><span class="pre">msgout()</span></tt></a>).</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">the altgraph library does not generate output, the
debug attribute and message methods are present for use
by subclasses.</p>
</div>
</dd></dl>
<dl class="data">
<dt id="altgraph.ObjectGraph.ObjectGraph.graph">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">graph</tt><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.graph" title="Permalink to this definition"></a></dt>
<dd><p>An <a class="reference internal" href="graph.html#altgraph.Graph.Graph" title="altgraph.Graph.Graph"><tt class="xref py py-class docutils literal"><span class="pre">Graph</span></tt></a> object that contains
the graph data.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.addNode">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">addNode</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.addNode" title="Permalink to this definition"></a></dt>
<dd><p>Adds a <em>node</em> to the graph.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">re-adding a node that was previously removed
using <a class="reference internal" href="#altgraph.ObjectGraph.ObjectGraph.removeNode" title="altgraph.ObjectGraph.ObjectGraph.removeNode"><tt class="xref py py-meth docutils literal"><span class="pre">removeNode()</span></tt></a> will reinstate the previously
removed node.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.createNode">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">createNode</tt><big>(</big><em>self</em>, <em>cls</em>, <em>name</em>, <em>*args</em>, <em>**kwds</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.createNode" title="Permalink to this definition"></a></dt>
<dd><p>Creates a new node using <tt class="docutils literal"><span class="pre">cls(*args,</span> <span class="pre">**kwds)</span></tt> and adds that
node using <a class="reference internal" href="#altgraph.ObjectGraph.ObjectGraph.addNode" title="altgraph.ObjectGraph.ObjectGraph.addNode"><tt class="xref py py-meth docutils literal"><span class="pre">addNode()</span></tt></a>.</p>
<p>Returns the newly created node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.removeNode">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">removeNode</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.removeNode" title="Permalink to this definition"></a></dt>
<dd><p>Removes a <em>node</em> from the graph when it exists. The <em>node</em> argument
is either a node object, or the graphident of a node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.createReferences">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">createReferences</tt><big>(</big><em>fromnode</em>, <em>tonode</em><span class="optional">[</span>, <em>edge_data</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.createReferences" title="Permalink to this definition"></a></dt>
<dd><p>Creates a reference from <em>fromnode</em> to <em>tonode</em>. The optional
<em>edge_data</em> is associated with the edge.</p>
<p><em>Fromnode</em> and <em>tonode</em> can either be node objects or the graphident
values for nodes.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.removeReference">
<tt class="descclassname">altgraph.ObjectGraph.</tt><tt class="descname">removeReference</tt><big>(</big><em>fromnode</em>, <em>tonode</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.removeReference" title="Permalink to this definition"></a></dt>
<dd><p>Removes the reference from <em>fromnode</em> to <em>tonode</em> if it exists.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.getRawIdent">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">getRawIdent</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.getRawIdent" title="Permalink to this definition"></a></dt>
<dd><p>Returns the <em>graphident</em> attribute of <em>node</em>, or the graph itself
when <em>node</em> is <a class="reference external" href="http://docs.python.org/library/constants.html#None" title="(in Python v2.7)"><tt class="xref py py-data docutils literal"><span class="pre">None</span></tt></a>.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.getIdent">
<tt class="descclassname">altgraph.ObjectGraph.</tt><tt class="descname">getIdent</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.getIdent" title="Permalink to this definition"></a></dt>
<dd><p>Same as <tt class="xref py py-meth docutils literal"><span class="pre">getRawIdent()</span></tt>, but only if the node is part
of the graph.</p>
<p><em>Node</em> can either be an actual node object or the graphident of
a node.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.findNode">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">findNode</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.findNode" title="Permalink to this definition"></a></dt>
<dd><p>Returns a given node in the graph, or <tt class="xref py py-data docutils literal"><span class="pre">Node</span></tt> when it cannot
be found.</p>
<p><em>Node</em> is either an object with a <em>graphident</em> attribute or
the <em>graphident</em> attribute itself.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.__contains__">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">__contains__</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.__contains__" title="Permalink to this definition"></a></dt>
<dd><p>Returns True if <em>node</em> is a member of the graph. <em>Node</em> is either an
object with a <em>graphident</em> attribute or the <em>graphident</em> attribute itself.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.flatten">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">flatten</tt><big>(</big><span class="optional">[</span><em>condition</em><span class="optional">[</span>, <em>start</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.flatten" title="Permalink to this definition"></a></dt>
<dd><p>Yield all nodes that are entirely reachable by <em>condition</em>
starting fromt he given <em>start</em> node or the graph root.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">objects are only reachable from the graph root
when there is a reference from the root to the node
(either directly or through another node)</p>
</div>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.nodes">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">nodes</tt><big>(</big><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.nodes" title="Permalink to this definition"></a></dt>
<dd><p>Yield all nodes in the graph.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.get_edges">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">get_edges</tt><big>(</big><em>node</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.get_edges" title="Permalink to this definition"></a></dt>
<dd><p>Returns two iterators that yield the nodes reaching by
outgoing and incoming edges.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.filterStack">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">filterStack</tt><big>(</big><em>filters</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.filterStack" title="Permalink to this definition"></a></dt>
<dd><p>Filter the ObjectGraph in-place by removing all edges to nodes that
do not match every filter in the given filter list</p>
<p>Returns a tuple containing the number of:
(<em>nodes_visited</em>, <em>nodes_removed</em>, <em>nodes_orphaned</em>)</p>
</dd></dl>
<div class="section" id="debug-output">
<h2>Debug output<a class="headerlink" href="#debug-output" title="Permalink to this headline"></a></h2>
<dl class="data">
<dt id="altgraph.ObjectGraph.ObjectGraph.debug">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">debug</tt><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.debug" title="Permalink to this definition"></a></dt>
<dd><p>The current debug level.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.msg">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">msg</tt><big>(</big><em>level</em>, <em>text</em>, <em>*args</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.msg" title="Permalink to this definition"></a></dt>
<dd><p>Print a debug message at the current indentation level when the current
debug level is <em>level</em> or less.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.msgin">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">msgin</tt><big>(</big><em>level</em>, <em>text</em>, <em>*args</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.msgin" title="Permalink to this definition"></a></dt>
<dd><p>Print a debug message when the current debug level is <em>level</em> or less,
and increase the indentation level.</p>
</dd></dl>
<dl class="method">
<dt id="altgraph.ObjectGraph.ObjectGraph.msgout">
<tt class="descclassname">ObjectGraph.</tt><tt class="descname">msgout</tt><big>(</big><em>level</em>, <em>text</em>, <em>*args</em><big>)</big><a class="headerlink" href="#altgraph.ObjectGraph.ObjectGraph.msgout" title="Permalink to this definition"></a></dt>
<dd><p>Decrease the indentation level and print a debug message when the
current debug level is <em>level</em> or less.</p>
</dd></dl>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#"><tt class="docutils literal"><span class="pre">altgraph.ObjectGraph</span></tt> &#8212; Graphs of objecs with an identifier</a><ul>
<li><a class="reference internal" href="#debug-output">Debug output</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="graph.html"
title="previous chapter"><tt class="docutils literal"><span class="pre">altgraph.Graph</span></tt> &#8212; Basic directional graphs</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="graphalgo.html"
title="next chapter"><tt class="docutils literal"><span class="pre">altgraph.GraphAlgo</span></tt> &#8212; Graph algorithms</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="graphalgo.html" title="altgraph.GraphAlgo — Graph algorithms"
>next</a> |</li>
<li class="right" >
<a href="graph.html" title="altgraph.Graph — Basic directional graphs"
>previous</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

Binary file not shown.

View File

@ -1,139 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Python Module Index &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="#" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1>Python Module Index</h1>
<div class="modindex-jumpbox">
<a href="#cap-a"><strong>a</strong></a>
</div>
<table class="indextable modindextable" cellspacing="0" cellpadding="2">
<tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap" id="cap-a"><td></td><td>
<strong>a</strong></td><td></td></tr>
<tr>
<td><img src="_static/minus.png" class="toggler"
id="toggle-1" style="display: none" alt="-" /></td>
<td>
<a href="core.html#module-altgraph"><tt class="xref">altgraph</tt></a></td><td>
<em>A directional graph for python</em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="dot.html#module-altgraph.Dot"><tt class="xref">altgraph.Dot</tt></a></td><td>
<em>Interface to the dot language as used by Graphviz..</em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="graph.html#module-altgraph.Graph"><tt class="xref">altgraph.Graph</tt></a></td><td>
<em>Basic directional graphs.</em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="graphalgo.html#module-altgraph.GraphAlgo"><tt class="xref">altgraph.GraphAlgo</tt></a></td><td>
<em>Basic graphs algoritms</em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="graphstat.html#module-altgraph.GraphStat"><tt class="xref">altgraph.GraphStat</tt></a></td><td>
<em>Functions providing various graph statistics</em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="graphutil.html#module-altgraph.GraphUtil"><tt class="xref">altgraph.GraphUtil</tt></a></td><td>
<em>Utility functions</em></td></tr>
<tr class="cg-1">
<td></td>
<td>&nbsp;&nbsp;&nbsp;
<a href="objectgraph.html#module-altgraph.ObjectGraph"><tt class="xref">altgraph.ObjectGraph</tt></a></td><td>
<em>A graph of objects that have a &#34;graphident&#34; attribute.</em></td></tr>
</table>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="#" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

View File

@ -1,105 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &mdash; altgraph 0.11 documentation</title>
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.11',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="top" title="altgraph 0.11 documentation" href="index.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
<script type="text/javascript" id="searchindexloader"></script>
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="index.html">altgraph 0.11 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,185 +0,0 @@
Release history
===============
0.12
----
- Added ``ObjectGraph.edgeData`` to retrieve the edge data
from a specific edge.
- Added ``AltGraph.update_edge_data`` and ``ObjectGraph.updateEdgeData``
to update the data associated with a graph edge.
0.11
----
- Stabilize the order of elements in dot file exports,
patch from bitbucket user 'pombredanne'.
- Tweak setup.py file to remove dependency on distribute (but
keep the dependency on setuptools)
0.10.2
------
- There where no classifiers in the package metadata due to a bug
in setup.py
0.10.1
------
This is a bugfix release
Bug fixes:
- Issue #3: The source archive contains a README.txt
while the setup file refers to ReadMe.txt.
This is caused by a misfeature in distutils, as a
workaround I've renamed ReadMe.txt to README.txt
in the source tree and setup file.
0.10
-----
This is a minor feature release
Features:
- Do not use "2to3" to support Python 3.
As a side effect of this altgraph now supports
Python 2.6 and later, and no longer supports
earlier releases of Python.
- The order of attributes in the Dot output
is now always alphabetical.
With this change the output will be consistent
between runs and Python versions.
0.9
---
This is a minor bugfix release
Features:
- Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
yielding all nodes in an object graph.
Bugfixes:
- The 0.8 release didn't work with py2app when using
python 3.x.
0.8
-----
This is a minor feature release. The major new feature
is a extensive set of unittests, which explains almost
all other changes in this release.
Bugfixes:
- Installing failed with Python 2.5 due to using a distutils
class that isn't available in that version of Python
(issue #1 on the issue tracker)
- ``altgraph.GraphStat.degree_dist`` now actually works
- ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
no longer create the edge when one of the nodes doesn't
exist.
- ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
- ``altgraph.Graph.back_topo_sort`` was completely broken in
previous releases.
- ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
- ``altgraph.Graph.back_bfs_subgraph`` now actually works.
- ``altgraph.Graph.iterdfs`` now returns the correct result
when the ``forward`` argument is ``False``.
- ``altgraph.Graph.iterdata`` now returns the correct result
when the ``forward`` argument is ``False``.
Features:
- The ``altgraph.Graph`` constructor now accepts an argument
that contains 2- and 3-tuples instead of requireing that
all items have the same size. The (optional) argument can now
also be any iterator.
- ``altgraph.Graph.Graph.add_node`` has no effect when you
add a hidden node.
- The private method ``altgraph.Graph._bfs`` is no longer
present.
- The private method ``altgraph.Graph._dfs`` is no longer
present.
- ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
which means you can use the ``in`` operator to check if a
node is part of a graph.
- ``altgraph.GraphUtil.generate_random_graph`` will raise
``GraphError`` instead of looping forever when it is
impossible to create the requested graph.
- ``altgraph.Dot.edge_style`` raises ``GraphError`` when
one of the nodes is not present in the graph. The method
silently added the tail in the past, but without ensuring
a consistent graph state.
- ``altgraph.Dot.save_img`` now works when the mode is
``"neato"``.
0.7.2
-----
This is a minor bugfix release
Bugfixes:
- distutils didn't include the documentation subtree
0.7.1
-----
This is a minor feature release
Features:
- Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
and can be viewed at <http://packages.python.org/altgraph>.
- The repository has moved to bitbucket
- ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
implementation and no specified behaviour.
- the module ``altgraph.compat`` is gone, which means altgraph will no
longer work with Python 2.3.
0.7.0
-----
This is a minor feature release.
Features:
- Support for Python 3
- It is now possible to run tests using 'python setup.py test'
(The actual testsuite is still very minimal though)

View File

@ -1,209 +0,0 @@
# -*- coding: utf-8 -*-
#
# altgraph documentation build configuration file, created by
# sphinx-quickstart on Tue Aug 31 11:04:49 2010.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
def get_version():
fn = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'setup.cfg')
for ln in open(fn):
if ln.startswith('version'):
version = ln.split('=')[-1].strip()
return version
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
sys.path.insert(0,
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.autodoc' ]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'altgraph'
copyright = u'2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = get_version()
# The full version, including alpha/beta/rc tags.
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'nature'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
html_show_sourcelink = False
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'altgraphdoc'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'altgraph.tex', u'altgraph Documentation',
u'Ronald Oussoren', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('http://docs.python.org/', None) }

View File

@ -1,26 +0,0 @@
:mod:`altgraph` --- A Python Graph Library
==================================================
.. module:: altgraph
:synopsis: A directional graph for python
altgraph is a fork of `graphlib <http://pygraphlib.sourceforge.net>`_ tailored
to use newer Python 2.3+ features, including additional support used by the
py2app suite (modulegraph and macholib, specifically).
altgraph is a python based graph (network) representation and manipulation package.
It has started out as an extension to the `graph_lib module <http://www.ece.arizona.edu/~denny/python_nest/graph_lib_1.0.1.html>`_
written by Nathan Denny it has been significantly optimized and expanded.
The :class:`altgraph.Graph.Graph` class is loosely modeled after the `LEDA <http://www.algorithmic-solutions.com/enleda.htm>`_
(Library of Efficient Datatypes) representation. The library
includes methods for constructing graphs, BFS and DFS traversals,
topological sort, finding connected components, shortest paths as well as a number
graph statistics functions. The library can also visualize graphs
via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_.
.. exception:: GraphError
Exception raised when methods are called with bad values of
an inconsistent state.

View File

@ -1,224 +0,0 @@
:mod:`altgraph.Dot` --- Interface to the dot language
=====================================================
.. module:: altgraph.Dot
:synopsis: Interface to the dot language as used by Graphviz..
The :py:mod:`~altgraph.Dot` module provides a simple interface to the
file format used in the `graphviz`_ program. The module is intended to
offload the most tedious part of the process (the **dot** file generation)
while transparently exposing most of its features.
.. _`graphviz`: <http://www.research.att.com/sw/tools/graphviz/>`_
To display the graphs or to generate image files the `graphviz`_
package needs to be installed on the system, moreover the :command:`dot` and :command:`dotty` programs must
be accesible in the program path so that they can be ran from processes spawned
within the module.
Example usage
-------------
Here is a typical usage::
from altgraph import Graph, Dot
# create a graph
edges = [ (1,2), (1,3), (3,4), (3,5), (4,5), (5,4) ]
graph = Graph.Graph(edges)
# create a dot representation of the graph
dot = Dot.Dot(graph)
# display the graph
dot.display()
# save the dot representation into the mydot.dot file
dot.save_dot(file_name='mydot.dot')
# save dot file as gif image into the graph.gif file
dot.save_img(file_name='graph', file_type='gif')
Directed graph and non-directed graph
-------------------------------------
Dot class can use for both directed graph and non-directed graph
by passing *graphtype* parameter.
Example::
# create directed graph(default)
dot = Dot.Dot(graph, graphtype="digraph")
# create non-directed graph
dot = Dot.Dot(graph, graphtype="graph")
Customizing the output
----------------------
The graph drawing process may be customized by passing
valid :command:`dot` parameters for the nodes and edges. For a list of all
parameters see the `graphviz`_ documentation.
Example::
# customizing the way the overall graph is drawn
dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
# customizing node drawing
dot.node_style(1, label='BASE_NODE',shape='box', color='blue' )
dot.node_style(2, style='filled', fillcolor='red')
# customizing edge drawing
dot.edge_style(1, 2, style='dotted')
dot.edge_style(3, 5, arrowhead='dot', label='binds', labelangle='90')
dot.edge_style(4, 5, arrowsize=2, style='bold')
.. note::
dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
display all graphics styles. To verify the output save it to an image
file and look at it that way.
Valid attributes
----------------
- dot styles, passed via the :py:meth:`Dot.style` method::
rankdir = 'LR' (draws the graph horizontally, left to right)
ranksep = number (rank separation in inches)
- node attributes, passed via the :py:meth:`Dot.node_style` method::
style = 'filled' | 'invisible' | 'diagonals' | 'rounded'
shape = 'box' | 'ellipse' | 'circle' | 'point' | 'triangle'
- edge attributes, passed via the :py:meth:`Dot.edge_style` method::
style = 'dashed' | 'dotted' | 'solid' | 'invis' | 'bold'
arrowhead = 'box' | 'crow' | 'diamond' | 'dot' | 'inv' | 'none' | 'tee' | 'vee'
weight = number (the larger the number the closer the nodes will be)
- valid `graphviz colors <http://www.research.att.com/~erg/graphviz/info/colors.html>`_
- for more details on how to control the graph drawing process see the
`graphviz reference <http://www.research.att.com/sw/tools/graphviz/refs.html>`_.
Class interface
---------------
.. class:: Dot(graph[, nodes[, edgefn[, nodevisitor[, edgevisitor[, name[, dot[, dotty[, neato[, graphtype]]]]]]]]])
Creates a new Dot generator based on the specified
:class:`Graph <altgraph.Graph.Graph>`. The Dot generator won't reference
the *graph* once it is constructed.
If the *nodes* argument is present it is the list of nodes to include
in the graph, otherwise all nodes in *graph* are included.
If the *edgefn* argument is present it is a function that yields the
nodes connected to another node, this defaults to
:meth:`graph.out_nbr <altgraph.Graph.Graph.out_nbr>`. The constructor won't
add edges to the dot file unless both the head and tail of the edge
are in *nodes*.
If the *name* is present it specifies the name of the graph in the resulting
dot file. The default is ``"G"``.
The functions *nodevisitor* and *edgevisitor* return the default style
for a given edge or node (both default to functions that return an empty
style).
The arguments *dot*, *dotty* and *neato* are used to pass the path to
the corresponding `graphviz`_ command.
Updating graph attributes
.........................
.. method:: Dot.style(\**attr)
Sets the overall style (graph attributes) to the given attributes.
See `Valid Attributes`_ for more information about the attributes.
.. method:: Dot.node_style(node, \**attr)
Sets the style for *node* to the given attributes.
This method will add *node* to the graph when it isn't already
present.
See `Valid Attributes`_ for more information about the attributes.
.. method:: Dot.all_node_style(\**attr)
Replaces the current style for all nodes
.. method:: edge_style(head, tail, \**attr)
Sets the style of an edge to the given attributes. The edge will
be added to the graph when it isn't already present, but *head*
and *tail* must both be valid nodes.
See `Valid Attributes`_ for more information about the attributes.
Emitting output
...............
.. method:: Dot.display([mode])
Displays the current graph via dotty.
If the *mode* is ``"neato"`` the dot file is processed with
the neato command before displaying.
This method won't return until the dotty command exits.
.. method:: save_dot(filename)
Saves the current graph representation into the given file.
.. note::
For backward compatibility reasons this method can also
be called without an argument, it will then write the graph
into a fixed filename (present in the attribute :data:`Graph.temp_dot`).
This feature is deprecated and should not be used.
.. method:: save_image(file_name[, file_type[, mode]])
Saves the current graph representation as an image file. The output
is written into a file whose basename is *file_name* and whose suffix
is *file_type*.
The *file_type* specifies the type of file to write, the default
is ``"gif"``.
If the *mode* is ``"neato"`` the dot file is processed with
the neato command before displaying.
.. note::
For backward compatibility reasons this method can also
be called without an argument, it will then write the graph
with a fixed basename (``"out"``).
This feature is deprecated and should not be used.
.. method:: iterdot()
Yields all lines of a `graphviz`_ input file (including line endings).
.. method:: __iter__()
Alias for the :meth:`iterdot` method.

View File

@ -1,305 +0,0 @@
:mod:`altgraph.Graph` --- Basic directional graphs
==================================================
.. module:: altgraph.Graph
:synopsis: Basic directional graphs.
The module :mod:`altgraph.Graph` provides a class :class:`Graph` that
represents a directed graph with *N* nodes and *E* edges.
.. class:: Graph([edges])
Constructs a new empty :class:`Graph` object. If the optional
*edges* parameter is supplied, updates the graph by adding the
specified edges.
All of the elements in *edges* should be tuples with two or three
elements. The first two elements of the tuple are the source and
destination node of the edge, the optional third element is the
edge data. The source and destination nodes are added to the graph
when the aren't already present.
Node related methods
--------------------
.. method:: Graph.add_node(node[, node_data])
Adds a new node to the graph if it is not already present. The new
node must be a hashable object.
Arbitrary data can be attached to the node via the optional *node_data*
argument.
.. note:: the node also won't be added to the graph when it is
present but currently hidden.
.. method:: Graph.hide_node(node)
Hides a *node* from the graph. The incoming and outgoing edges of
the node will also be hidden.
Raises :class:`altgraph.GraphError` when the node is not (visible)
node of the graph.
.. method:: Graph.restore_node(node)
Restores a previously hidden *node*. The incoming and outgoing
edges of the node are also restored.
Raises :class:`altgraph.GraphError` when the node is not a hidden
node of the graph.
.. method:: Graph.restore_all_nodes()
Restores all hidden nodes.
.. method:: Graph.number_of_nodes()
Return the number of visible nodes in the graph.
.. method:: Graph.number_of_hidden_nodes()
Return the number of hidden nodes in the graph.
.. method:: Graph.node_list()
Return a list with all visible nodes in the graph.
.. method:: Graph.hidden_node_list()
Return a list with all hidden nodes in the graph.
.. method:: node_data(node)
Return the data associated with the *node* when it was
added.
.. method:: Graph.describe_node(node)
Returns *node*, the node's data and the lists of outgoing
and incoming edges for the node.
.. note::
the edge lists should not be modified, doing so
can result in unpredicatable behavior.
.. method:: Graph.__contains__(node)
Returns True iff *node* is a node in the graph. This
method is accessed through the *in* operator.
.. method:: Graph.__iter__()
Yield all nodes in the graph.
.. method:: Graph.out_edges(node)
Return the list of outgoing edges for *node*
.. method:: Graph.inc_edges(node)
Return the list of incoming edges for *node*
.. method:: Graph.all_edges(node)
Return the list of incoming and outgoing edges for *node*
.. method:: Graph.out_degree(node)
Return the number of outgoing edges for *node*.
.. method:: Graph.inc_degree(node)
Return the number of incoming edges for *node*.
.. method:: Graph.all_degree(node)
Return the number of edges (incoming or outgoing) for *node*.
Edge related methods
--------------------
.. method:: Graph.add_edge(head_id, tail_id [, edge data [, create_nodes]])
Adds a directed edge from *head_id* to *tail_id*. Arbitrary data can
be added via *edge_data*. When *create_nodes* is *True* (the default),
*head_id* and *tail_id* will be added to the graph when the aren't
already present.
.. method:: Graph.hide_edge(edge)
Hides an edge from the graph. The edge may be unhidden at some later
time.
.. method:: Graph.restore_edge(edge)
Restores a previously hidden *edge*.
.. method:: Graph.restore_all_edges()
Restore all edges that were hidden before, except for edges
referring to hidden nodes.
.. method:: Graph.edge_by_node(head, tail)
Return the edge ID for an edge from *head* to *tail*,
or :data:`None` when no such edge exists.
.. method:: Graph.edge_by_id(edge)
Return the head and tail of the *edge*
.. method:: Graph.edge_data(edge)
Return the data associated with the *edge*.
.. method:: Graph.update_edge_data(edge, data)
Replace the edge data for *edge* by *data*. Raises
:exc:`KeyError` when the edge does not exist.
.. versionadded:: 0.12
.. method:: Graph.head(edge)
Return the head of an *edge*
.. method:: Graph.tail(edge)
Return the tail of an *edge*
.. method:: Graph.describe_edge(edge)
Return the *edge*, the associated data, its head and tail.
.. method:: Graph.number_of_edges()
Return the number of visible edges.
.. method:: Graph.number_of_hidden_edges()
Return the number of hidden edges.
.. method:: Graph.edge_list()
Returns a list with all visible edges in the graph.
.. method:: Graph.hidden_edge_list()
Returns a list with all hidden edges in the graph.
Graph traversal
---------------
.. method:: Graph.out_nbrs(node)
Return a list of all nodes connected by outgoing edges.
.. method:: Graph.inc_nbrs(node)
Return a list of all nodes connected by incoming edges.
.. method:: Graph.all_nbrs(node)
Returns a list of nodes connected by an incoming or outgoing edge.
.. method:: Graph.forw_topo_sort()
Return a list of nodes where the successors (based on outgoing
edges) of any given node apear in the sequence after that node.
.. method:: Graph.back_topo_sort()
Return a list of nodes where the successors (based on incoming
edges) of any given node apear in the sequence after that node.
.. method:: Graph.forw_bfs_subgraph(start_id)
Return a subgraph consisting of the breadth first
reachable nodes from *start_id* based on their outgoing edges.
.. method:: Graph.back_bfs_subgraph(start_id)
Return a subgraph consisting of the breadth first
reachable nodes from *start_id* based on their incoming edges.
.. method:: Graph.iterdfs(start[, end[, forward]])
Yield nodes in a depth first traversal starting at the *start*
node.
If *end* is specified traversal stops when reaching that node.
If forward is True (the default) edges are traversed in forward
direction, otherwise they are traversed in reverse direction.
.. method:: Graph.iterdata(start[, end[, forward[, condition]]])
Yield the associated data for nodes in a depth first traversal
starting at the *start* node. This method will not yield values for nodes
without associated data.
If *end* is specified traversal stops when reaching that node.
If *condition* is specified and the condition callable returns
False for the associated data this method will not yield the
associated data and will not follow the edges for the node.
If forward is True (the default) edges are traversed in forward
direction, otherwise they are traversed in reverse direction.
.. method:: Graph.forw_bfs(start[, end])
Returns a list of nodes starting at *start* in some bread first
search order (following outgoing edges).
When *end* is specified iteration stops at that node.
.. method:: Graph.back_bfs(start[, end])
Returns a list of nodes starting at *start* in some bread first
search order (following incoming edges).
When *end* is specified iteration stops at that node.
.. method:: Graph.get_hops(start[, end[, forward]])
Computes the hop distance to all nodes centered around a specified node.
First order neighbours are at hop 1, their neigbours are at hop 2 etc.
Uses :py:meth:`forw_bfs` or :py:meth:`back_bfs` depending on the value of
the forward parameter.
If the distance between all neighbouring nodes is 1 the hop number
corresponds to the shortest distance between the nodes.
Typical usage::
>>> print graph.get_hops(1, 8)
>>> [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
# node 1 is at 0 hops
# node 2 is at 1 hop
# ...
# node 8 is at 5 hops
Graph statistics
----------------
.. method:: Graph.connected()
Returns True iff every node in the graph can be reached from
every other node.
.. method:: Graph.clust_coef(node)
Returns the local clustering coefficient of node.
The local cluster coefficient is the proportion of the actual number
of edges between neighbours of node and the maximum number of
edges between those nodes.

View File

@ -1,26 +0,0 @@
:mod:`altgraph.GraphAlgo` --- Graph algorithms
==================================================
.. module:: altgraph.GraphAlgo
:synopsis: Basic graphs algoritms
.. function:: dijkstra(graph, start[, end])
Dijkstra's algorithm for shortest paths.
Find shortest paths from the start node to all nodes nearer
than or equal to the *end* node. The edge data is assumed to be the edge length.
.. note::
Dijkstra's algorithm is only guaranteed to work correctly when all edge lengths are positive.
This code does not verify this property for all edges (only the edges examined until the end
vertex is reached), but will correctly compute shortest paths even for some graphs with negative
edges, and will raise an exception if it discovers that a negative edge has caused it to make a mistake.
.. function:: shortest_path(graph, start, end)
Find a single shortest path from the given start node to the given end node.
The input has the same conventions as :func:`dijkstra`. The output is a list
of the nodes in order along the shortest path.

View File

@ -1,25 +0,0 @@
:mod:`altgraph.GraphStat` --- Functions providing various graph statistics
==========================================================================
.. module:: altgraph.GraphStat
:synopsis: Functions providing various graph statistics
The module :mod:`altgraph.GraphStat` provides function that calculate
graph statistics. Currently there is only one such function, more may
be added later.
.. function:: degree_dist(graph[, limits[, bin_num[, mode]]])
Groups the number of edges per node into *bin_num* bins
and returns the list of those bins. Every item in the result
is a tuple with the center of the bin and the number of items
in that bin.
When the *limits* argument is present it must be a tuple with
the mininum and maximum number of edges that get binned (that
is, when *limits* is ``(4, 10)`` only nodes with between 4
and 10 edges get counted.
The *mode* argument is used to count incoming (``'inc'``) or
outgoing (``'out'``) edges. The default is to count the outgoing
edges.

View File

@ -1,55 +0,0 @@
:mod:`altgraph.GraphUtil` --- Utility functions
================================================
.. module:: altgraph.GraphUtil
:synopsis: Utility functions
The module :mod:`altgraph.GraphUtil` performs a number of more
or less useful utility functions.
.. function:: generate_random_graph(node_num, edge_num[, self_loops[, multi_edges])
Generates and returns a :class:`Graph <altgraph.Graph.Graph>` instance
with *node_num* nodes randomly connected by *edge_num* edges.
When *self_loops* is present and True there can be edges that point from
a node to itself.
When *multi_edge* is present and True there can be duplicate edges.
This method raises :class:`GraphError <altgraph.GraphError` when
a graph with the requested configuration cannot be created.
.. function:: generate_scale_free_graph(steps, growth_num[, self_loops[, multi_edges]])
Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that
will have *steps*growth_n um* nodes and a scale free (powerlaw)
connectivity.
Starting with a fully connected graph with *growth_num* nodes
at every step *growth_num* nodes are added to the graph and are connected
to existing nodes with a probability proportional to the degree of these
existing nodes.
.. warning:: The current implementation is basically untested, although
code inspection seems to indicate an implementation that is consistent
with the description at
`Wolfram MathWorld <http://mathworld.wolfram.com/Scale-FreeNetwork.html>`_
.. function:: filter_stack(graph, head, filters)
Perform a depth-first oder walk of the graph starting at *head* and
apply all filter functions in *filters* on the node data of the nodes
found.
Returns (*visited*, *removes*, *orphans*), where
* *visited*: the set of visited nodes
* *removes*: the list of nodes where the node data doesn't match
all *filters*.
* *orphans*: list of tuples (*last_good*, *node*), where
node is not in *removes* and one of the nodes that is connected
by an incoming edge is in *removes*. *Last_good* is the
closest upstream node that is not in *removes*.

View File

@ -1,41 +0,0 @@
.. altgraph documentation master file, created by
sphinx-quickstart on Tue Aug 31 11:04:49 2010.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Altgraph - A basic graph library
================================
altgraph is a fork of graphlib: a graph (network) package for constructing
graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
graphviz output.
The primary users of this package are `macholib <http://pypi.python.org/pypi/macholib>`_ and `modulegraph <http://pypi.python.org/pypi/modulegraph>`_.
.. toctree::
:maxdepth: 1
changelog
license
core
graph
objectgraph
graphalgo
graphstat
graphutil
dot
Online Resources
----------------
* `Sourcecode repository on bitbucket <http://bitbucket.org/ronaldoussoren/altgraph/>`_
* `The issue tracker <http://bitbucket.org/ronaldoussoren/altgraph/issues>`_
Indices and tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,25 +0,0 @@
License
=======
Copyright (c) 2004 Istvan Albert unless otherwise noted.
Parts are copyright (c) Bob Ippolito
Parts are copyright (c) 2010-2014 Ronald Oussoren
MIT License
...........
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,146 +0,0 @@
:mod:`altgraph.ObjectGraph` --- Graphs of objecs with an identifier
===================================================================
.. module:: altgraph.ObjectGraph
:synopsis: A graph of objects that have a "graphident" attribute.
.. class:: ObjectGraph([graph[, debug]])
A graph of objects that have a "graphident" attribute. The
value of this attribute is the key for the object in the
graph.
The optional *graph* is a previously constructed
:class:`Graph <altgraph.Graph.Graph>`.
The optional *debug* level controls the amount of debug output
(see :meth:`msg`, :meth:`msgin` and :meth:`msgout`).
.. note:: the altgraph library does not generate output, the
debug attribute and message methods are present for use
by subclasses.
.. data:: ObjectGraph.graph
An :class:`Graph <altgraph.Graph.Graph>` object that contains
the graph data.
.. method:: ObjectGraph.addNode(node)
Adds a *node* to the graph.
.. note:: re-adding a node that was previously removed
using :meth:`removeNode` will reinstate the previously
removed node.
.. method:: ObjectGraph.createNode(self, cls, name, \*args, \**kwds)
Creates a new node using ``cls(*args, **kwds)`` and adds that
node using :meth:`addNode`.
Returns the newly created node.
.. method:: ObjectGraph.removeNode(node)
Removes a *node* from the graph when it exists. The *node* argument
is either a node object, or the graphident of a node.
.. method:: ObjectGraph.createReferences(fromnode, tonode[, edge_data])
Creates a reference from *fromnode* to *tonode*. The optional
*edge_data* is associated with the edge.
*Fromnode* and *tonode* can either be node objects or the graphident
values for nodes.
.. method:: removeReference(fromnode, tonode)
Removes the reference from *fromnode* to *tonode* if it exists.
.. method:: ObjectGraph.getRawIdent(node)
Returns the *graphident* attribute of *node*, or the graph itself
when *node* is :data:`None`.
.. method:: getIdent(node)
Same as :meth:`getRawIdent`, but only if the node is part
of the graph.
*Node* can either be an actual node object or the graphident of
a node.
.. method:: ObjectGraph.findNode(node)
Returns a given node in the graph, or :data:`Node` when it cannot
be found.
*Node* is either an object with a *graphident* attribute or
the *graphident* attribute itself.
.. method:: ObjectGraph.__contains__(node)
Returns True if *node* is a member of the graph. *Node* is either an
object with a *graphident* attribute or the *graphident* attribute itself.
.. method:: ObjectGraph.flatten([condition[, start]])
Yield all nodes that are entirely reachable by *condition*
starting fromt he given *start* node or the graph root.
.. note:: objects are only reachable from the graph root
when there is a reference from the root to the node
(either directly or through another node)
.. method:: ObjectGraph.nodes()
Yield all nodes in the graph.
.. method:: ObjectGraph.get_edges(node)
Returns two iterators that yield the nodes reaching by
outgoing and incoming edges.
.. method:: ObjectGraph.filterStack(filters)
Filter the ObjectGraph in-place by removing all edges to nodes that
do not match every filter in the given filter list
Returns a tuple containing the number of:
(*nodes_visited*, *nodes_removed*, *nodes_orphaned*)
.. method:: ObjectGraph.edgeData(fromNode, toNode):
Return the edge data associated with the edge from *fromNode*
to *toNode*. Raises :exc:`KeyError` when no such edge exists.
.. versionadded: 0.12
.. method:: ObjectGraph.updateEdgeData(fromNode, toNode, edgeData)
Replace the data associated with the edge from *fromNode* to
*toNode* by *edgeData*.
Raises :exc:`KeyError` when the edge does not exist.
Debug output
------------
.. data:: ObjectGraph.debug
The current debug level.
.. method:: ObjectGraph.msg(level, text, \*args)
Print a debug message at the current indentation level when the current
debug level is *level* or less.
.. method:: ObjectGraph.msgin(level, text, \*args)
Print a debug message when the current debug level is *level* or less,
and increase the indentation level.
.. method:: ObjectGraph.msgout(level, text, \*args)
Decrease the indentation level and print a debug message when the
current debug level is *level* or less.

View File

@ -1,36 +0,0 @@
[metadata]
name = altgraph
version = 0.12
description = Python graph (network) package
long_description_file =
README.txt
doc/changelog.rst
author = Ronald Oussoren
author_email = ronaldoussoren@mac.com
maintainer = Ronald Oussoren
maintainer_email = ronaldoussoren@mac.com
url = http://packages.python.org/altgraph
download_url = http://pypi.python.org/pypi/altgraph
license = MIT
classifiers =
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.3
Programming Language :: Python :: 3.4
Topic :: Software Development :: Libraries :: Python Modules
Topic :: Scientific/Engineering :: Mathematics
Topic :: Scientific/Engineering :: Visualization
keywords = graph
platforms = any
packages = altgraph
zip-safe = 1
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0

View File

@ -1,867 +0,0 @@
"""
Shared setup file for simple python packages. Uses a setup.cfg that
is the same as the distutils2 project, unless noted otherwise.
It exists for two reasons:
1) This makes it easier to reuse setup.py code between my own
projects
2) Easier migration to distutils2 when that catches on.
Additional functionality:
* Section metadata:
requires-test: Same as 'tests_require' option for setuptools.
"""
import sys
import os
import re
import platform
from fnmatch import fnmatch
import os
import sys
import time
import tempfile
import tarfile
try:
import urllib.request as urllib
except ImportError:
import urllib
from distutils import log
try:
from hashlib import md5
except ImportError:
from md5 import md5
if sys.version_info[0] == 2:
from ConfigParser import RawConfigParser, NoOptionError, NoSectionError
else:
from configparser import RawConfigParser, NoOptionError, NoSectionError
ROOTDIR = os.path.dirname(os.path.abspath(__file__))
#
#
#
# Parsing the setup.cfg and converting it to something that can be
# used by setuptools.setup()
#
#
#
def eval_marker(value):
"""
Evaluate an distutils2 environment marker.
This code is unsafe when used with hostile setup.cfg files,
but that's not a problem for our own files.
"""
value = value.strip()
class M:
def __init__(self, **kwds):
for k, v in kwds.items():
setattr(self, k, v)
variables = {
'python_version': '%d.%d'%(sys.version_info[0], sys.version_info[1]),
'python_full_version': sys.version.split()[0],
'os': M(
name=os.name,
),
'sys': M(
platform=sys.platform,
),
'platform': M(
version=platform.version(),
machine=platform.machine(),
),
}
return bool(eval(value, variables, variables))
return True
def _opt_value(cfg, into, section, key, transform = None):
try:
v = cfg.get(section, key)
if transform != _as_lines and ';' in v:
v, marker = v.rsplit(';', 1)
if not eval_marker(marker):
return
v = v.strip()
if v:
if transform:
into[key] = transform(v.strip())
else:
into[key] = v.strip()
except (NoOptionError, NoSectionError):
pass
def _as_bool(value):
if value.lower() in ('y', 'yes', 'on'):
return True
elif value.lower() in ('n', 'no', 'off'):
return False
elif value.isdigit():
return bool(int(value))
else:
raise ValueError(value)
def _as_list(value):
return value.split()
def _as_lines(value):
result = []
for v in value.splitlines():
if ';' in v:
v, marker = v.rsplit(';', 1)
if not eval_marker(marker):
continue
v = v.strip()
if v:
result.append(v)
else:
result.append(v)
return result
def _map_requirement(value):
m = re.search(r'(\S+)\s*(?:\((.*)\))?', value)
name = m.group(1)
version = m.group(2)
if version is None:
return name
else:
mapped = []
for v in version.split(','):
v = v.strip()
if v[0].isdigit():
# Checks for a specific version prefix
m = v.rsplit('.', 1)
mapped.append('>=%s,<%s.%s'%(
v, m[0], int(m[1])+1))
else:
mapped.append(v)
return '%s %s'%(name, ','.join(mapped),)
def _as_requires(value):
requires = []
for req in value.splitlines():
if ';' in req:
req, marker = v.rsplit(';', 1)
if not eval_marker(marker):
continue
req = req.strip()
if not req:
continue
requires.append(_map_requirement(req))
return requires
def parse_setup_cfg():
cfg = RawConfigParser()
r = cfg.read([os.path.join(ROOTDIR, 'setup.cfg')])
if len(r) != 1:
print("Cannot read 'setup.cfg'")
sys.exit(1)
metadata = dict(
name = cfg.get('metadata', 'name'),
version = cfg.get('metadata', 'version'),
description = cfg.get('metadata', 'description'),
)
_opt_value(cfg, metadata, 'metadata', 'license')
_opt_value(cfg, metadata, 'metadata', 'maintainer')
_opt_value(cfg, metadata, 'metadata', 'maintainer_email')
_opt_value(cfg, metadata, 'metadata', 'author')
_opt_value(cfg, metadata, 'metadata', 'author_email')
_opt_value(cfg, metadata, 'metadata', 'url')
_opt_value(cfg, metadata, 'metadata', 'download_url')
_opt_value(cfg, metadata, 'metadata', 'classifiers', _as_lines)
_opt_value(cfg, metadata, 'metadata', 'platforms', _as_list)
_opt_value(cfg, metadata, 'metadata', 'packages', _as_list)
_opt_value(cfg, metadata, 'metadata', 'keywords', _as_list)
try:
v = cfg.get('metadata', 'requires-dist')
except (NoOptionError, NoSectionError):
pass
else:
requires = _as_requires(v)
if requires:
metadata['install_requires'] = requires
try:
v = cfg.get('metadata', 'requires-test')
except (NoOptionError, NoSectionError):
pass
else:
requires = _as_requires(v)
if requires:
metadata['tests_require'] = requires
try:
v = cfg.get('metadata', 'long_description_file')
except (NoOptionError, NoSectionError):
pass
else:
parts = []
for nm in v.split():
fp = open(nm, 'rU')
parts.append(fp.read())
fp.close()
metadata['long_description'] = '\n\n'.join(parts)
try:
v = cfg.get('metadata', 'zip-safe')
except (NoOptionError, NoSectionError):
pass
else:
metadata['zip_safe'] = _as_bool(v)
try:
v = cfg.get('metadata', 'console_scripts')
except (NoOptionError, NoSectionError):
pass
else:
if 'entry_points' not in metadata:
metadata['entry_points'] = {}
metadata['entry_points']['console_scripts'] = v.splitlines()
if sys.version_info[:2] <= (2,6):
try:
metadata['tests_require'] += ", unittest2"
except KeyError:
metadata['tests_require'] = "unittest2"
return metadata
#
#
#
# Bootstrapping setuptools/distribute, based on
# a heavily modified version of distribute_setup.py
#
#
#
SETUPTOOLS_PACKAGE='setuptools'
try:
import subprocess
def _python_cmd(*args):
args = (sys.executable,) + args
return subprocess.call(args) == 0
except ImportError:
def _python_cmd(*args):
args = (sys.executable,) + args
new_args = []
for a in args:
new_args.append(a.replace("'", "'\"'\"'"))
os.system(' '.join(new_args)) == 0
try:
import json
def get_pypi_src_download(package):
url = 'https://pypi.python.org/pypi/%s/json'%(package,)
fp = urllib.urlopen(url)
try:
try:
data = fp.read()
finally:
fp.close()
except urllib.error:
raise RuntimeError("Cannot determine download link for %s"%(package,))
pkgdata = json.loads(data.decode('utf-8'))
if 'urls' not in pkgdata:
raise RuntimeError("Cannot determine download link for %s"%(package,))
for info in pkgdata['urls']:
if info['packagetype'] == 'sdist' and info['url'].endswith('tar.gz'):
return (info.get('md5_digest'), info['url'])
raise RuntimeError("Cannot determine downlink link for %s"%(package,))
except ImportError:
# Python 2.5 compatibility, no JSON in stdlib but luckily JSON syntax is
# simular enough to Python's syntax to be able to abuse the Python compiler
import _ast as ast
def get_pypi_src_download(package):
url = 'https://pypi.python.org/pypi/%s/json'%(package,)
fp = urllib.urlopen(url)
try:
try:
data = fp.read()
finally:
fp.close()
except urllib.error:
raise RuntimeError("Cannot determine download link for %s"%(package,))
a = compile(data, '-', 'eval', ast.PyCF_ONLY_AST)
if not isinstance(a, ast.Expression):
raise RuntimeError("Cannot determine download link for %s"%(package,))
a = a.body
if not isinstance(a, ast.Dict):
raise RuntimeError("Cannot determine download link for %s"%(package,))
for k, v in zip(a.keys, a.values):
if not isinstance(k, ast.Str):
raise RuntimeError("Cannot determine download link for %s"%(package,))
k = k.s
if k == 'urls':
a = v
break
else:
raise RuntimeError("PyPI JSON for %s doesn't contain URLs section"%(package,))
if not isinstance(a, ast.List):
raise RuntimeError("Cannot determine download link for %s"%(package,))
for info in v.elts:
if not isinstance(info, ast.Dict):
raise RuntimeError("Cannot determine download link for %s"%(package,))
url = None
packagetype = None
chksum = None
for k, v in zip(info.keys, info.values):
if not isinstance(k, ast.Str):
raise RuntimeError("Cannot determine download link for %s"%(package,))
if k.s == 'url':
if not isinstance(v, ast.Str):
raise RuntimeError("Cannot determine download link for %s"%(package,))
url = v.s
elif k.s == 'packagetype':
if not isinstance(v, ast.Str):
raise RuntimeError("Cannot determine download link for %s"%(package,))
packagetype = v.s
elif k.s == 'md5_digest':
if not isinstance(v, ast.Str):
raise RuntimeError("Cannot determine download link for %s"%(package,))
chksum = v.s
if url is not None and packagetype == 'sdist' and url.endswith('.tar.gz'):
return (chksum, url)
raise RuntimeError("Cannot determine download link for %s"%(package,))
def _build_egg(egg, tarball, to_dir):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
log.warn('Extracting in %s', tmpdir)
old_wd = os.getcwd()
try:
os.chdir(tmpdir)
tar = tarfile.open(tarball)
_extractall(tar)
tar.close()
# going in the directory
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
os.chdir(subdir)
log.warn('Now working in %s', subdir)
# building an egg
log.warn('Building a %s egg in %s', egg, to_dir)
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
finally:
os.chdir(old_wd)
# returning the result
log.warn(egg)
if not os.path.exists(egg):
raise IOError('Could not build the egg.')
def _do_download(to_dir, packagename=SETUPTOOLS_PACKAGE):
tarball = download_setuptools(packagename, to_dir)
version = tarball.split('-')[-1][:-7]
egg = os.path.join(to_dir, '%s-%s-py%d.%d.egg'
% (packagename, version, sys.version_info[0], sys.version_info[1]))
if not os.path.exists(egg):
_build_egg(egg, tarball, to_dir)
sys.path.insert(0, egg)
import setuptools
setuptools.bootstrap_install_from = egg
def use_setuptools():
# making sure we use the absolute path
return _do_download(os.path.abspath(os.curdir))
def download_setuptools(packagename, to_dir):
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
chksum, url = get_pypi_src_download(packagename)
tgz_name = os.path.basename(url)
saveto = os.path.join(to_dir, tgz_name)
src = dst = None
if not os.path.exists(saveto): # Avoid repeated downloads
try:
log.warn("Downloading %s", url)
src = urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = src.read()
if chksum is not None:
data_sum = md5(data).hexdigest()
if data_sum != chksum:
raise RuntimeError("Downloading %s failed: corrupt checksum"%(url,))
dst = open(saveto, "wb")
dst.write(data)
finally:
if src:
src.close()
if dst:
dst.close()
return os.path.realpath(saveto)
def _extractall(self, path=".", members=None):
"""Extract all members from the archive to the current working
directory and set owner, modification time and permissions on
directories afterwards. `path' specifies a different directory
to extract to. `members' is optional and must be a subset of the
list returned by getmembers().
"""
import copy
import operator
from tarfile import ExtractError
directories = []
if members is None:
members = self
for tarinfo in members:
if tarinfo.isdir():
# Extract directories with a safe mode.
directories.append(tarinfo)
tarinfo = copy.copy(tarinfo)
tarinfo.mode = 448 # decimal for oct 0700
self.extract(tarinfo, path)
# Reverse sort directories.
if sys.version_info < (2, 4):
def sorter(dir1, dir2):
return cmp(dir1.name, dir2.name)
directories.sort(sorter)
directories.reverse()
else:
directories.sort(key=operator.attrgetter('name'), reverse=True)
# Set correct owner, mtime and filemode on directories.
for tarinfo in directories:
dirpath = os.path.join(path, tarinfo.name)
try:
self.chown(tarinfo, dirpath)
self.utime(tarinfo, dirpath)
self.chmod(tarinfo, dirpath)
except ExtractError:
e = sys.exc_info()[1]
if self.errorlevel > 1:
raise
else:
self._dbg(1, "tarfile: %s" % e)
#
#
#
# Definitions of custom commands
#
#
#
try:
import setuptools
except ImportError:
use_setuptools()
from setuptools import setup
try:
from distutils.core import PyPIRCCommand
except ImportError:
PyPIRCCommand = None # Ancient python version
from distutils.core import Command
from distutils.errors import DistutilsError
from distutils import log
if PyPIRCCommand is None:
class upload_docs (Command):
description = "upload sphinx documentation"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
raise DistutilsError("not supported on this version of python")
else:
class upload_docs (PyPIRCCommand):
description = "upload sphinx documentation"
user_options = PyPIRCCommand.user_options
def initialize_options(self):
PyPIRCCommand.initialize_options(self)
self.username = ''
self.password = ''
def finalize_options(self):
PyPIRCCommand.finalize_options(self)
config = self._read_pypirc()
if config != {}:
self.username = config['username']
self.password = config['password']
def run(self):
import subprocess
import shutil
import zipfile
import os
import urllib
import StringIO
from base64 import standard_b64encode
import httplib
import urlparse
# Extract the package name from distutils metadata
meta = self.distribution.metadata
name = meta.get_name()
# Run sphinx
if os.path.exists('doc/_build'):
shutil.rmtree('doc/_build')
os.mkdir('doc/_build')
p = subprocess.Popen(['make', 'html'],
cwd='doc')
exit = p.wait()
if exit != 0:
raise DistutilsError("sphinx-build failed")
# Collect sphinx output
if not os.path.exists('dist'):
os.mkdir('dist')
zf = zipfile.ZipFile('dist/%s-docs.zip'%(name,), 'w',
compression=zipfile.ZIP_DEFLATED)
for toplevel, dirs, files in os.walk('doc/_build/html'):
for fn in files:
fullname = os.path.join(toplevel, fn)
relname = os.path.relpath(fullname, 'doc/_build/html')
print ("%s -> %s"%(fullname, relname))
zf.write(fullname, relname)
zf.close()
# Upload the results, this code is based on the distutils
# 'upload' command.
content = open('dist/%s-docs.zip'%(name,), 'rb').read()
data = {
':action': 'doc_upload',
'name': name,
'content': ('%s-docs.zip'%(name,), content),
}
auth = "Basic " + standard_b64encode(self.username + ":" +
self.password)
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
sep_boundary = '\n--' + boundary
end_boundary = sep_boundary + '--'
body = StringIO.StringIO()
for key, value in data.items():
if not isinstance(value, list):
value = [value]
for value in value:
if isinstance(value, tuple):
fn = ';filename="%s"'%(value[0])
value = value[1]
else:
fn = ''
body.write(sep_boundary)
body.write('\nContent-Disposition: form-data; name="%s"'%key)
body.write(fn)
body.write("\n\n")
body.write(value)
body.write(end_boundary)
body.write('\n')
body = body.getvalue()
self.announce("Uploading documentation to %s"%(self.repository,), log.INFO)
schema, netloc, url, params, query, fragments = \
urlparse.urlparse(self.repository)
if schema == 'http':
http = httplib.HTTPConnection(netloc)
elif schema == 'https':
http = httplib.HTTPSConnection(netloc)
else:
raise AssertionError("unsupported schema "+schema)
data = ''
loglevel = log.INFO
try:
http.connect()
http.putrequest("POST", url)
http.putheader('Content-type',
'multipart/form-data; boundary=%s'%boundary)
http.putheader('Content-length', str(len(body)))
http.putheader('Authorization', auth)
http.endheaders()
http.send(body)
except socket.error:
e = socket.exc_info()[1]
self.announce(str(e), log.ERROR)
return
r = http.getresponse()
if r.status in (200, 301):
self.announce('Upload succeeded (%s): %s' % (r.status, r.reason),
log.INFO)
else:
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
print ('-'*75)
print (r.read())
print ('-'*75)
def recursiveGlob(root, pathPattern):
"""
Recursively look for files matching 'pathPattern'. Return a list
of matching files/directories.
"""
result = []
for rootpath, dirnames, filenames in os.walk(root):
for fn in filenames:
if fnmatch(fn, pathPattern):
result.append(os.path.join(rootpath, fn))
return result
def importExternalTestCases(unittest,
pathPattern="test_*.py", root=".", package=None):
"""
Import all unittests in the PyObjC tree starting at 'root'
"""
testFiles = recursiveGlob(root, pathPattern)
testModules = map(lambda x:x[len(root)+1:-3].replace('/', '.'), testFiles)
if package is not None:
testModules = [(package + '.' + m) for m in testModules]
suites = []
for modName in testModules:
try:
module = __import__(modName)
except ImportError:
print("SKIP %s: %s"%(modName, sys.exc_info()[1]))
continue
if '.' in modName:
for elem in modName.split('.')[1:]:
module = getattr(module, elem)
s = unittest.defaultTestLoader.loadTestsFromModule(module)
suites.append(s)
return unittest.TestSuite(suites)
class test (Command):
description = "run test suite"
user_options = [
('verbosity=', None, "print what tests are run"),
]
def initialize_options(self):
self.verbosity='1'
def finalize_options(self):
if isinstance(self.verbosity, str):
self.verbosity = int(self.verbosity)
def cleanup_environment(self):
ei_cmd = self.get_finalized_command('egg_info')
egg_name = ei_cmd.egg_name.replace('-', '_')
to_remove = []
for dirname in sys.path:
bn = os.path.basename(dirname)
if bn.startswith(egg_name + "-"):
to_remove.append(dirname)
for dirname in to_remove:
log.info("removing installed %r from sys.path before testing"%(
dirname,))
sys.path.remove(dirname)
def add_project_to_sys_path(self):
from pkg_resources import normalize_path, add_activation_listener
from pkg_resources import working_set, require
self.reinitialize_command('egg_info')
self.run_command('egg_info')
self.reinitialize_command('build_ext', inplace=1)
self.run_command('build_ext')
# Check if this distribution is already on sys.path
# and remove that version, this ensures that the right
# copy of the package gets tested.
self.__old_path = sys.path[:]
self.__old_modules = sys.modules.copy()
ei_cmd = self.get_finalized_command('egg_info')
sys.path.insert(0, normalize_path(ei_cmd.egg_base))
sys.path.insert(1, os.path.dirname(__file__))
# Strip the namespace packages defined in this distribution
# from sys.modules, needed to reset the search path for
# those modules.
nspkgs = getattr(self.distribution, 'namespace_packages')
if nspkgs is not None:
for nm in nspkgs:
del sys.modules[nm]
# Reset pkg_resources state:
add_activation_listener(lambda dist: dist.activate())
working_set.__init__()
require('%s==%s'%(ei_cmd.egg_name, ei_cmd.egg_version))
def remove_from_sys_path(self):
from pkg_resources import working_set
sys.path[:] = self.__old_path
sys.modules.clear()
sys.modules.update(self.__old_modules)
working_set.__init__()
def run(self):
import unittest
# Ensure that build directory is on sys.path (py3k)
self.cleanup_environment()
self.add_project_to_sys_path()
try:
meta = self.distribution.metadata
name = meta.get_name()
test_pkg = name + "_tests"
suite = importExternalTestCases(unittest,
"test_*.py", test_pkg, test_pkg)
runner = unittest.TextTestRunner(verbosity=self.verbosity)
result = runner.run(suite)
# Print out summary. This is a structured format that
# should make it easy to use this information in scripts.
summary = dict(
count=result.testsRun,
fails=len(result.failures),
errors=len(result.errors),
xfails=len(getattr(result, 'expectedFailures', [])),
xpass=len(getattr(result, 'expectedSuccesses', [])),
skip=len(getattr(result, 'skipped', [])),
)
print("SUMMARY: %s"%(summary,))
finally:
self.remove_from_sys_path()
#
#
#
# And finally run the setuptools main entry point.
#
#
#
metadata = parse_setup_cfg()
setup(
cmdclass=dict(
upload_docs=upload_docs,
test=test,
),
**metadata
)

View File

@ -1,122 +0,0 @@
Metadata-Version: 1.1
Name: bitstring
Version: 3.1.3
Summary: Simple construction, analysis and modification of binary data.
Home-page: http://python-bitstring.googlecode.com
Author: Scott Griffiths
Author-email: scott@griffiths.name
License: The MIT License: http://www.opensource.org/licenses/mit-license.php
Download-URL: http://python-bitstring.googlecode.com
Description: ================
bitstring module
================
**bitstring** is a pure Python module designed to help make
the creation and analysis of binary data as simple and natural as possible.
Bitstrings can be constructed from integers (big and little endian), hex,
octal, binary, strings or files. They can be sliced, joined, reversed,
inserted into, overwritten, etc. with simple functions or slice notation.
They can also be read from, searched and replaced, and navigated in,
similar to a file or stream.
bitstring is open source software, and has been released under the MIT
licence.
This version supports Python 2.6 and later (including Python 3).
For Python 2.4 and 2.5 you should instead download version 1.0.
Documentation
-------------
The manual for the bitstring module is available here
<http://packages.python.org/bitstring>. It contains a walk-through of all
the features and a complete reference section.
It is also available as a PDF as part of the source download.
Installation
------------
If you have downloaded and unzipped the package then you need to run the
``setup.py`` script with the 'install' argument::
python setup.py install
You may need to run this with root privileges on Unix-like systems.
If you haven't yet downloaded the package then you can just try::
easy_install bitstring
or ::
pip install bitstring
Simple Examples
---------------
Creation::
>>> a = BitArray(bin='00101')
>>> b = Bits(a_file_object)
>>> c = BitArray('0xff, 0b101, 0o65, uint:6=22')
>>> d = pack('intle:16, hex=a, 0b1', 100, a='0x34f')
>>> e = pack('<16h', *range(16))
Different interpretations, slicing and concatenation::
>>> a = BitArray('0x1af')
>>> a.hex, a.bin, a.uint
('1af', '000110101111', 431)
>>> a[10:3:-1].bin
'1110101'
>>> 3*a + '0b100'
BitArray('0o0657056705674')
Reading data sequentially::
>>> b = BitStream('0x160120f')
>>> b.read(12).hex
'160'
>>> b.pos = 0
>>> b.read('uint:12')
352
>>> b.readlist('uint:12, bin:3')
[288, '111']
Searching, inserting and deleting::
>>> c = BitArray('0b00010010010010001111') # c.hex == '0x1248f'
>>> c.find('0x48')
(8,)
>>> c.replace('0b001', '0xabc')
>>> c.insert('0b0000')
>>> del c[12:16]
Unit Tests
----------
The 400+ unit tests should all pass for Python 2.6 and later.
----
The bitstring module has been released as open source under the MIT License.
Copyright (c) 2014 Scott Griffiths
For more information see the project's homepage on Google Code:
<http://python-bitstring.googlecode.com>
Platform: all
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Topic :: Software Development :: Libraries :: Python Modules

View File

@ -1,99 +0,0 @@
================
bitstring module
================
**bitstring** is a pure Python module designed to help make
the creation and analysis of binary data as simple and natural as possible.
Bitstrings can be constructed from integers (big and little endian), hex,
octal, binary, strings or files. They can be sliced, joined, reversed,
inserted into, overwritten, etc. with simple functions or slice notation.
They can also be read from, searched and replaced, and navigated in,
similar to a file or stream.
bitstring is open source software, and has been released under the MIT
licence.
This version supports Python 2.6 and later (including Python 3).
For Python 2.4 and 2.5 you should instead download version 1.0.
Documentation
-------------
The manual for the bitstring module is available here
<http://packages.python.org/bitstring>. It contains a walk-through of all
the features and a complete reference section.
It is also available as a PDF as part of the source download.
Installation
------------
If you have downloaded and unzipped the package then you need to run the
``setup.py`` script with the 'install' argument::
python setup.py install
You may need to run this with root privileges on Unix-like systems.
If you haven't yet downloaded the package then you can just try::
easy_install bitstring
or ::
pip install bitstring
Simple Examples
---------------
Creation::
>>> a = BitArray(bin='00101')
>>> b = Bits(a_file_object)
>>> c = BitArray('0xff, 0b101, 0o65, uint:6=22')
>>> d = pack('intle:16, hex=a, 0b1', 100, a='0x34f')
>>> e = pack('<16h', *range(16))
Different interpretations, slicing and concatenation::
>>> a = BitArray('0x1af')
>>> a.hex, a.bin, a.uint
('1af', '000110101111', 431)
>>> a[10:3:-1].bin
'1110101'
>>> 3*a + '0b100'
BitArray('0o0657056705674')
Reading data sequentially::
>>> b = BitStream('0x160120f')
>>> b.read(12).hex
'160'
>>> b.pos = 0
>>> b.read('uint:12')
352
>>> b.readlist('uint:12, bin:3')
[288, '111']
Searching, inserting and deleting::
>>> c = BitArray('0b00010010010010001111') # c.hex == '0x1248f'
>>> c.find('0x48')
(8,)
>>> c.replace('0b001', '0xabc')
>>> c.insert('0b0000')
>>> del c[12:16]
Unit Tests
----------
The 400+ unit tests should all pass for Python 2.6 and later.
----
The bitstring module has been released as open source under the MIT License.
Copyright (c) 2014 Scott Griffiths
For more information see the project's homepage on Google Code:
<http://python-bitstring.googlecode.com>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +0,0 @@
#!/usr/bin/env python
from distutils.core import setup
# from distutils.extension import Extension
# from Cython.Distutils import build_ext
import sys
kwds = {'long_description': open('README.txt').read()}
if sys.version_info[:2] < (2, 6):
raise Exception('This version of bitstring needs Python 2.6 or later. '
'For Python 2.4 / 2.5 please use bitstring version 1.0 instead.')
# macros = [('PYREX_WITHOUT_ASSERTIONS', None)]
# ext_modules = [Extension('bitstring', ["bitstring.pyx"], define_macros=macros)]
setup(name='bitstring',
version='3.1.3',
description='Simple construction, analysis and modification of binary data.',
author='Scott Griffiths',
author_email='scott@griffiths.name',
url='http://python-bitstring.googlecode.com',
download_url='http://python-bitstring.googlecode.com',
license='The MIT License: http://www.opensource.org/licenses/mit-license.php',
# cmdclass = {'build_ext': build_ext},
# ext_modules = ext_modules,
py_modules=['bitstring'],
platforms='all',
classifiers = [
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Operating System :: OS Independent',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.0',
'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Topic :: Software Development :: Libraries :: Python Modules',
],
**kwds
)

View File

@ -1 +0,0 @@
#Eg‰«Íď

Some files were not shown because too many files have changed in this diff Show More