473,387 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Arranging a dependency tree

I'm working on a little practice program, but I've become stuck and am
now utterly confused :?

I've created a jumble of python modules, in each one is a tuple that
goes something like,

deps = ("file10","file7","file3").

And some have no dependencies at all. I have one file called "start",
and the whole thing makes a tree of dependencies as each file has deps
and their deps might have deps, and so on. What I'm trying to do is
"straighten" them or put them in order as if they were to be
installed. Basically I'm trying to replicate the way portage does it.
:)

I've been thinking about this for a few days but I always get lost.
So far I have a has_deps(filename) function, and not much else. I get
stuck on the actual changing the files from the random jumble to a
into a nice orderly list of files. One problem that I can't
overcome is when I'm a couple of deps in and I finally get to the
files that don't require anything, I have no way of getting back to do
the parent file's other deps. (Does that make any sense?)

Basically I was wondering if anyone had any tips or pointers, or knew
of any dependency resolving algorithms...

Thanks,
Kyle
Jul 18 '05 #1
9 3777
Basically, dependencies (should) create a tree structure, except when you have
circular dependencies. Now, what you have to do to resolve the tree structure
in case there are no circular dependencies is to walk the edges of the graph,
from leaf to top.

Example graph:

x
| ----> y
| ----> z | ----> a
| | ----> b
| ----> a

Now, you need a way to store this in Python, I'd use dictionaries:

deps = {"x":
{"y":{},
"z":{"a":{}}
}}

Reading the data into a format like this is pretty simple too:

<code>
def makeTree(files):
"""Pass in a list of files for which dependency info
should be generated."""

deps = {}
cur_files = [(fname,deps) for fname in files]
all_deps = {}
while cur_files:
cur_file, cur_deps = cur_files.pop()
if cur_file in all_deps:
cur_deps[cur_file] = all_deps[cur_file]
continue
new_deps = {}
# getDeps returns the dependencies needed by cur_file.
for dep in getDeps(cur_file):
cur_files.append((dep,new_deps))
cur_deps[cur_file] = new_deps
all_deps[cur_file] = new_deps
return deps
</code>

Now, reading in the dependency list as done above properly takes care of
circular dependencies, and might create dictionaries which contain themselves
at some depth. It won't read dependency info more than once for a given file,
too.

The following code will walk the tree generated by makeTree, but it will barf
on circular dependencies. You'll have to devise some means to deal with
these, the most common form being simply to break tree walking at the current
level in case you encounter a circular dependency. The algorithm is
recursive. Doing it iteratively would be possible too, but at quite some
cost.

<code>
def _walkTree(tree,cur_files,walked_files):
for cur_file, cur_deps in tree.iteritems():
if cur_file in walked_files:
continue
elif cur_file in cur_files:
# Deal with circular deps here. You might just do:
# raise StopIteration
raise ValueError, "Circular tree structure."
if cur_deps:
for sub_file in _walkTree(cur_deps,cur_files+(cur_file,),walked_fi les):
yield sub_file
walked_files.append(cur_file)
yield cur_file

def walkTree(tree):
"""Walk a tree as generated by makeTree."""

for f in _walkTree(tree,(),[]):
yield f
</code>

Well, hope this helps and gives you some hints!

Heiko.
Jul 18 '05 #2
Kyle Root wrote:
I've created a jumble of python modules, in each one is a tuple that
goes something like,

deps = ("file10","file7","file3").

And some have no dependencies at all. I have one file called "start",
and the whole thing makes a tree of dependencies as each file has deps
and their deps might have deps, and so on. What I'm trying to do is
"straighten" them or put them in order as if they were to be
installed. Basically I'm trying to replicate the way portage does it.
:) [...] Basically I was wondering if anyone had any tips or pointers, or knew
of any dependency resolving algorithms...


This may be too abstract to help, but I guess it couldn't
hurt...

'Depends' is a binary relation (a set of pairs) where (a, b) is
an element of Depends if and only if b is in a's "deps"
list/tuple.

If you want an ordering in which each module follows the
modules on which it depends, you want a 'topological sort' based
on the depends relation.

If you want to find all the modules on which a module depends,
you want the 'transitive closure' of the depends relation.
If you want to know if the dependencies can or cannot possibly
work, look up the work of Bertrand Meyer and his Eiffel team
on possibly-circular dependencies.
--
--Bryan
Jul 18 '05 #3
Heiko Wundram wrote:
Basically, dependencies (should) create a tree structure, except when
you have circular dependencies. [...]


Non-circular dependencies create a directed acyclic graph (DAG),
not necessarily a tree.

I'm sure Heiko actually knew this, but being the kind of smart-
ass I am, I can't resist the chance to correct him on things he
already knew twice in one day. Earlier he wrote "large prime"
where he clearly meant "large integer". I trust he will take
this post in the spirit in which it is intended.
--
--Bryan
Jul 18 '05 #4
Bryan Olson wrote:
....
If you want an ordering in which each module follows the
modules on which it depends, you want a 'topological sort' based
on the depends relation.


There's a module here:
http://www.vrplumber.com/programming/
which provides two implementations of topological sorting in Python.
With that, should be a trivial task to do a dependency sort on the OP's
graph.

HTH,
Mike

________________________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://www.vrplumber.com
http://blog.vrplumber.com

Jul 18 '05 #5
Am Donnerstag, 12. August 2004 08:22 schrieb Bryan Olson:
I'm sure Heiko actually knew this, but being the kind of smart-
ass I am, I can't resist the chance to correct him on things he
already knew twice in one day. Earlier he wrote "large prime"
where he clearly meant "large integer". I trust he will take
this post in the spirit in which it is intended.


I bow before the master. ;-)

Heiko.
Jul 18 '05 #6
Am Donnerstag, 12. August 2004 08:34 schrieb Heiko Wundram:
I bow before the master. ;-)


No, but seriously, I guess I shouldn't be the one to teach computer science or
maths... I'm much better at "real" programming. And that's why Python is so
much fun: just try it out and see... :-)

Heiko.
(who is currently writing his first big exams in medicine)
Jul 18 '05 #7
ky******@gmail.com (Kyle Root) writes:
I've created a jumble of python modules, in each one is a tuple that
goes something like,

deps = ("file10","file7","file3").

And some have no dependencies at all. I have one file called "start",
and the whole thing makes a tree of dependencies as each file has deps
and their deps might have deps, and so on. What I'm trying to do is
"straighten" them or put them in order as if they were to be
installed. Basically I'm trying to replicate the way portage does it. :)


Suppose that deps list is for file5. I'm reading your example to mean
file5 depends on file10, file7, and file3, and not the other way around.

As others have mentioned, what you want to do is called topological
sorting. Since nobody's described the algorithm, it goes something
like this:

1) Make a dictionary indexed by filename, whose entry deps[f] will
be the set of files f depends on. In the above example,
deps["file5"] = Set(["file10", "file7", "file3"]). You can
also use a dict instead of a Set in the obvious way.

1) Make another dictionary indexed by filename, whose entry d[f] for
filename f will be a list of the files that depend on f. For
example, if the deps for file5 are ("file10","file7","file3"), then
you'll put "file5" into d["file10"], d["file7"], and d["file3"].
You can straightforwardly build this dict when you scan the deps lists.

2) Also when you scan the deps lists, make a list U of all the files
that don't depend on anything.

3. while U is not empty, do the following:
choose an f from U
output f
remove f from U
for g in d[f]: # for each file depending on f
remove f from deps[g]
if deps[g] is now empty, add g to U

If there are no circular dependencies and if I haven't goofed up (it's
late here), then the above scheme should output all the filenames in
topologically sorted order, in running time linear in the # of
filenames plus the # of dependencies.

You can probably find a clearer explanation in any intro CS text with
a chapter about graph algorithms.
Jul 18 '05 #8
Well thank you all that helps very much, I should have this done soon :D
And also thanks to Paul Foley who sent me tha topological sorter :)

Jul 18 '05 #9
"Kyle Root" <ky******@gmail.com> wrote in message
news:6c**************************@posting.google.c om...
I'm working on a little practice program, but I've become stuck and am
now utterly confused :?

I've created a jumble of python modules, in each one is a tuple that
goes something like,

deps = ("file10","file7","file3").

And some have no dependencies at all. I have one file called "start",
and the whole thing makes a tree of dependencies as each file has deps
and their deps might have deps, and so on. What I'm trying to do is
"straighten" them or put them in order as if they were to be
installed. Basically I'm trying to replicate the way portage does it.
:)

I've been thinking about this for a few days but I always get lost.
So far I have a has_deps(filename) function, and not much else. I get
stuck on the actual changing the files from the random jumble to a
into a nice orderly list of files. One problem that I can't
overcome is when I'm a couple of deps in and I finally get to the
files that don't require anything, I have no way of getting back to do
the parent file's other deps. (Does that make any sense?)

Basically I was wondering if anyone had any tips or pointers, or knew
of any dependency resolving algorithms...

Thanks,
Kyle


Look into using pydot if you want to actually draw the trees/graphs.

-- Paul
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: mike | last post by:
Hi I am trying to find a tool that shows a dependency tree for method calls from an assembly. If the method call chain goes across assemblies, this would also be shown I have looked at dependency...
1
by: Kurt Schwemmer | last post by:
I've been tasked with cleaning up a big C++ project that extensively uses global variables. What would be very useful is a tool that would parse the code and create a dependency tree of...
2
by: Dr Evil | last post by:
Greetings. Has anyone ever seen a tool that will read directories of header file source code and generate a dependency tree? I've often encountered large projects where such a tool would be useful....
3
by: Ironside | last post by:
Can someone give me a basic script example for arranging thumbnails on a page. I have always put them in tables that CSS is obviously better. Also, I like to put writing underneath the thumbnails...
1
by: Bob Sparks | last post by:
I found this in a FAQ How can I locate the dependencies of an SQL procedure? A: The dependencies are stored in the package of the stored procedure. After creating a stored procedure, determine...
3
by: DJTN | last post by:
I'm getting the following error when I try to compile my setup project in VS 2002. I have re-installed the .net framework 1.1 and it didnt solve the problem. WARNING: Unable to find dependency...
0
by: Baron Samedi | last post by:
I want to understand the structure of some legacy code. A good call tree program would be welcome. As would something similar, but which shows the relationship of files. So, if I have a.c and...
3
by: ashimk1 | last post by:
Hi All, I have an array that contains duplicates as well unique numbers. ex- (21, 33, 35, 21, 33, 70, 33, 35, 50) I need to arrange it in such a way that all the duplicates will come up first...
0
by: kasthurirangan.balaji | last post by:
Hello, I have some items in memory(character array) separarted with the newline character and the items are sorted inside the array. I already have a version of the code using a multimap object....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.