Permalink
Browse files

Sources Added

  • Loading branch information...
moisespsena committed Oct 4, 2012
1 parent bded807 commit 10aacfe96ba0761b0b0f1a2310c42d38f733b830
View
@@ -0,0 +1,2 @@
+include *.md
+recursive-include examples *.md *.py
View
113 README.md
@@ -0,0 +1,113 @@
+# Py_SDAG2 - Python Simple Directed Acyclic Graph
+
+The Python Simple Directed Graph whith Cicle Detector and TopoloGical sorter utilities.
+
+## Authors
+- [Moises P. Sena](http://moisespsena.com)
+
+## Install
+
+```bash
+sudo pip install py_sdag2
+```
+
+## Scripts
+
+### tsort.py
+
+Sources from Standard Input:
+
+```bash
+echo -e 'C A\nA B\nB D\nC D' | tsort.py
+```
+
+Sources from another file:
+
+```bash
+echo -e 'C A\nA B\nB D\nC D' > verticies.txt
+```
+
+```bash
+tsort.py verticies.txt
+```
+
+More Options:
+
+```bash
+tsort.py --help
+Usage: tsort.py [options] [FILE [OUT_FILE]]
+
+Options:
+ -h, --help show this help message and exit
+ -f FILE, --file=FILE With no FILE, or when FILE is -, read standard input.
+ -o OUT_FILE, --out-file=OUT_FILE
+ Write result to OUT_FILE, default is standard output.
+ -s SEP, --separator=SEP
+ Items separator, default is \s regex.
+ -q QUIT_SEQ, --quit-sequence=QUIT_SEQ
+ Stop read FILE where line equals QUIT_SEQ, default is
+ :quit.
+```
+
+## Tests
+
+```python
+import unittest
+from sdag2 import DAG, CycleDetectedException
+
+class DAGTest(unittest.TestCase):
+ def test_simple(self):
+ '''
+ Tests the verticles order in:
+
+ C --> A --> B --> D
+ '''
+
+ dag = DAG()
+ a = dag.add("A")
+ b = dag.add("B")
+ c = dag.add("C")
+ d = dag.add("D")
+
+ dag.add_edge(c, a)
+ dag.add_edge(a, b)
+ dag.add_edge(b, d)
+ dag.add_edge(c, d)
+
+ rs = dag.topologicaly()
+
+ self.assertTrue(rs.index("C") < rs.index("A"))
+ self.assertTrue(rs.index("A") < rs.index("B"))
+ self.assertTrue(rs.index("B") < rs.index("D"))
+ self.assertTrue(rs.index("C") < rs.index("D"))
+
+ def test_cicle_detect(self):
+ '''
+ Tests the verticles order in:
+
+ C --> A --> B --> D -> C
+ '''
+
+ dag = DAG()
+ a = dag.add("A")
+ b = dag.add("B")
+ c = dag.add("C")
+ d = dag.add("D")
+
+ dag.add_edge(c, a)
+ dag.add_edge(a, b)
+ dag.add_edge(b, d)
+ dag.add_edge(c, d)
+
+ try:
+ # add cicle at A --> C --> A
+ dag.add_edge(a, c)
+ raise Exception("Cycle not detected")
+ except CycleDetectedException: pass
+
+def main():
+ unittest.main()
+
+if __name__ == "__main__":
+ main()
+```
View
@@ -0,0 +1,11 @@
+# Examples
+
+## Topological Sorter Example
+
+Simple Topological DAG Sorter example.
+
+Run example:
+
+```bash
+python topological_sorter.py
+```
@@ -0,0 +1,26 @@
+'''
+Created on Oct 3, 2012
+
+@author: Moises P. Sena
+'''
+from sdag2 import DAG
+
+dag = DAG()
+a = dag.add("A")
+b = dag.add("B")
+c = dag.add("C")
+d = dag.add("D")
+
+dag.add_edge(c, a)
+dag.add_edge(a, b)
+dag.add_edge(b, d)
+dag.add_edge(c, d)
+
+rs = dag.topologicaly()
+# Order is: C --> A --> B --> D
+print("Order is: %s" % (" --> ".join(rs)))
+
+assert rs.index("C") < rs.index("A")
+assert rs.index("A") < rs.index("B")
+assert rs.index("B") < rs.index("D")
+assert rs.index("C") < rs.index("D")
View
@@ -0,0 +1,25 @@
+#!/bin/bash
+_ci() {
+ echo -e "\033[34;1m[INFO] ${1}\033[m"
+}
+_ce() {
+ echo -e "\033[31;1m[ERROR] ${1}\033[m" 1>&2
+}
+
+ag="$@"
+
+_cmd() {
+ [ `which $1` ] && {
+ _ci "================================== $1 ===================================="
+ _ci "$1 test" && \
+ $1 setup.py test && {
+ _ci "$1 bdist_egg"
+ $1 setup.py bdist_egg $ag && \
+ _ci "$1 sdist" && \
+ $1 setup.py sdist $ag
+ }
+ } || _ce "$1 not found"
+}
+
+_cmd python2
+_cmd python3
View
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+from optparse import OptionParser
+from sys import stdout, stdin, stderr
+from codecs import open as copen
+from sdag2 import DAG, CycleDetectedException
+from re import split
+
+usage = "usage: %prog [options] [FILE [OUT_FILE]]"
+parser = OptionParser(usage=usage)
+parser.add_option("-f", "--file", dest="filename",
+ help="With no FILE, or when FILE is -, read standard input.",
+ metavar="FILE", default="STDIN")
+parser.add_option("-o", "--out-file", dest="out_filename",
+ help="Write result to OUT_FILE, default is standard output.",
+ metavar="OUT_FILE", default="STDOUT")
+parser.add_option("-s", "--separator", dest="separator",
+ help="Items separator, default is \s regex.",
+ metavar="SEP", default="\s")
+parser.add_option("-q", "--quit-sequence", dest="quit_sequence",
+ help="Stop read FILE where line equals QUIT_SEQ, default "
+ "is %default.",
+ metavar="QUIT_SEQ", default=":quit")
+
+(options, args) = parser.parse_args()
+
+if len(args) > 0:
+ options.filename = args[0]
+
+ if len(args) > 1:
+ options.out_filename = args[1]
+
+if options.filename in ("STDIN", "-", ""):
+ inf = stdin
+else:
+ inf = copen(options.filename, "rb")
+
+if options.out_filename in ("STDOUT", "-", ""):
+ outf = stdout
+else:
+ outf = copen(options.out_filename, "wb")
+
+dag = DAG()
+
+line = inf.readline()
+i = 0
+
+while line:
+ line = line.strip()
+ i += 1
+ if not line:
+ stderr.write("[WARN]: Line %s is empty.\n" % i)
+ continue
+ elif line == options.quit_sequence:
+ break
+
+ parts = split(options.separator, line)
+
+ try:
+ if len(parts) == 2:
+ dag.add_edge(parts[0], parts[1])
+ elif len(parts) == 1:
+ dag.add(parts[0])
+ else:
+ stderr.write("[ERROR]: Line %s contains more 2 items.\n" % i)
+ exit(1)
+
+ line = inf.readline()
+ except CycleDetectedException as ex:
+ stderr.write("[ERROR]: %s.\n" % ex)
+ exit(1)
+
+for l in dag.topologicaly(gen=True):
+ outf.write(l)
+ outf.write("\n")
View
@@ -0,0 +1,7 @@
+__author__ = "Moises P. Sena"
+__license__ = "BSD"
+__version__ = "1.0"
+__maintainer__ = "Moises P. Sena"
+__email__ = "moisespsena@gmail.com"
+
+from .sdag2 import *
Oops, something went wrong.

0 comments on commit 10aacfe

Please sign in to comment.