[Tutor] Pythonic? Building a full path from a "visual" file tree
Hey all, I would like to expand the "visual" representation of a tree hierarchy, given below, where child-ness is defined by indentation, and folder-ness is highlighted with a trailing '/' Input (test.txt): dir1/ file1 file2 1-1/ file3 file4 dir2/ file5 The desired output is a fully qualified path for each input line: dir1/ dir1/file1 dir1/file2 dir1/1-1/ dir1/1-1/file3 dir1/1-1/file4 dir2/ dir2/file5 I considered several brute-force solutions, but I persevered and came to, what I think, is a more Pythonic solution. What do you think? import string def expand_tree(filetree): indent = '\t' stack = [] for f in filetree: indents = f.count(indent) while len(stack) > indents: stack.pop() stack.append(f.strip()) yield string.join(stack,'') if not f.endswith('/'): stack.pop() lines = [line.rstrip() for line in file('test.txt')] for i in expand_tree(lines): print i Those familiar with subversion (particularly, svnlook tree /path/to/repos) may recognize the problem space and the sample input (except that I simplified things a bit here, using a tab to indicate level-of-hierarchy instead of a single space, which could appear in the filename). The real-world solution will use a regex to find run of spaces at the start of element 'f'. It will also get input from stdin instead of a file. Questions: Is the list comprehension the right idiom for getting a file into a list, without the EOL chars? I'm hard-pressed to see how it could be more concise, but this is Python :) and the rtrim() feels a little off. Is string.join() preferred to ''.join? Does importing all of string outweigh the readability of string.join()? Any subversion geeks know of way to eliminate this code with a native svn command? Did other folks choke on generators for as long as I did? I'm not going to admit, publicly, how long that was :) But I found this little test illustrative: def gen(): yield 1 yield 2 yield 3 g = gen() g.next() >>> 1 g.next() >>> 2 g.next() >>> 3 g.next() >>> [stack trace] Beyond simple, but the obviousness of it is hidden in many of the examples I saw. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic? Building a full path from a "visual" file tree
> The list comp is fine but I don't think you need it > at all, since you strip() the string before you > add it to stack. Ahh yes. I used the rstrip() in development, printing intermediary output to stdout, so I could see what my input file-to-list looked like (and it looked ugly with all those EOLs). The strip() to the stack is there primarily to remove the indentation but, of course, it can do double duty. > > string.join() is deprecated, ''.join() is preferred. > Well, I'll live with it ;-) fugly as it looks. I'm really finding that Python nudges me into pleasant code. Doing the above in somthing like VB, I would just brute-force it and it would feel right. Brute forcing it in Python ... well, it just feels wrong ... Thanks for the input. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Pythonic? Building a full path from a "visual" file tree
On 3/21/06, stv <[EMAIL PROTECTED]> wrote: > > import string > > def expand_tree(filetree): > indent = '\t' > stack = [] > for f in filetree: > indents = f.count(indent) > while len(stack) > indents: stack.pop() > stack.append(f.strip()) > yield string.join(stack,'') > if not f.endswith('/'): stack.pop() > The real-world solution will use a regex to find run > of spaces at the start of element 'f'. Hmmm, I'm having to rethink this ... regex will probably not do what I want (count instance of "indent" ... or, even if regex will do, there's probably a cleaner solution without it. Given the subversion problem space (where I can count on 1 space for each level of child-ness), are there cleaner solutions than this: indents = len(f) - len(f.lstrip()) ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Inner Class access to outer class attributes?
# So I figure out inner classes while typing the # first draft of this email, at least mostly # How do I access the "outer" class attributes from # the inner class? class GroupLocation(list): ### Note subclass of list class _Sublocation(object): def __init__(self, sublocation, action): self.sublocation = sublocation self.action = action def do_stuff(self): ### ### How would I get to GroupLocation attributes? ### print GroupLocation.name, self.sublocation def __init__(self, name, group_location): self.name = name self.group_location = group_location def add_sublocation(self, sublocation, action): self.append(GroupLocation._Sublocation(sublocation, action) group = GroupLocation('group1name', 'group1location') group.add_sublocation('sublocation1','foo') group.add_sublocation('sublocation2','bar') group.add_sublocation('sublocation3','zip') group.add_sublocation('sublocation4','foo') [sub.do_stuff() for sub in group if sub.action == 'foo'] # output (if it worked): # Group1location sublocation1 # Group1location sublocation4 # # instead I get this: # AttributeError: type object 'GroupLocation' has no attribute 'name' # Now, I suppose I could start down this road: class GroupLocation(object): def __init__(self,name, group_location): self.name = name self.group_location = group_location self.sublocations = [] def add_sublocation(self,sublocation, action): self.sublocations.append((sublocation, action)) group = GroupLocation('group1', 'group1location') group.add_sublocation('sublocation1','foo') group.add_sublocation('sublocation2','bar') group.add_sublocation('sublocation3','zip') group.add_sublocation('sublocation4','foo') for sub in group.sublocations: if sub[1] == 'foo': print group.group_location, sub[0] # output: # Group1location sublocation1 # Group1location sublocation4 # But that feels wrong in several ways: # 1) Any time I want to do_stuff() I have # to retype # 2) sub[1] & sub [0] are confusing after # not reading the code for a few hours. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Inner Class access to outer class attributes?
Hmmm, so every Sublocation object has a copy of the grouplocation data? What happens if I come around & change something: group.grouplocation = differentGroupLocationID Would I need to (forgive me here if I get some terms wrong) use a property (or a setter) & then loop over all the affected sublocations every time grouplocation is re-set? A-la de-normalized relational database Is there a better way to skin this cat? Or am I stuck with a) the non-inner class design & it's ugly indexes for sub in group.sublocations: if sub[1] == 'foo': print group.group_location, sub[0] or b) data duplication & possible un-synching. I'll take a). On 3/23/06, Kent Johnson <[EMAIL PROTECTED]> wrote: > > If you want access to a GroupLocation instance, just pass it to the > sublocation. > > > > class GroupLocation(list): > > > > class _Sublocation(object): > > def __init__(self, sublocation, action): > > self.sublocation = sublocation > > self.action = action > > def __init__(self, grouplocation, sublocation, action): >self.grouplocation = grouplocation >self.sublocation = sublocation >self.action = action ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Inner Class access to outer class attributes?
> The problem appears to be that you need to read a bit more > about Pythons handling of variable names and objects. :-) Or learn to spend a bit more time digesting the helpful advice given here ... between this & the searching between two lists thread the quality of advice has been excellent. I should have used my brain a bit more before hitting send. I have a pretty good grasp of refereces vs copies, and a few seconds of time with the interactive interpreter would have clearly shown that I was dealing with references. I'm digesting all the advice ... I think I have what I need & I appreciate everyone's thoughts. I hope, at least, my questions & first drafts have been helpful for others reading along. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning Python
If you're a bookish type, I found Magnus Lie Hetland's "Beginning Python" excellent. It's really more than a beginners books. I came to Python with a scripting background--mostly lightweight OS stuff (Applescript, DOS) as well as a lot of lightweight application programming (Filemaker, SQL, VBA for Excel, etc) and I got a lot out of the book. It covers the basics for a true beginner, but not in a dumbed-down way. It's also well indexed & somewhat useful as a reference for the most common things. Mark Pilgrim's "Dive Into Python" comes highly recommended, and is available on-line. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] List methods/comps Best Practices
I just thumped my head against the wall for a few hours on something, and I was wondering if it's just my green-ness in Python, or if I'm doing something unsavory. I had several list comprehensions that I was mucking with; these lists are working on a simple subclass of the built-in list object. They looked liked this: filelist = getFilesToAdd() filelist2 = getFilesToDel() adds = MyList('foo') dels = MyList('bar') [adds.add_changes('foo', path) for path in filelist] [dels.add_changes('bar', path) for path in filelist2] # return all changes, deletes first return dels.extend(adds) Since extend returns None, I ran into a lot of not-iterable errors when calling this code. So I fixed this with dels.extend(adds) return dels And all is good, although it took way more head scratching than typing . (In writing this, I now vaguely remember one of my tutorials warning me about something ... maybe this was that? :) So my question is this: Is this just one of those things that I learn the hard way in Pthon & that's it, or am I doing something weird? I shoulda figured this out when I was debugging the method in the interpreter and my original list comprehensions returned [adds.add_changes('foo', path) for path in filelist] >>> [None, None, None] as each call to add_changes returned no value. Alas, I'm not that smart. Is it bad form to not have an "assignment" for the list comps? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] List methods/comps Best Practices
> So don't write: > [adds.add_changes('foo', path) for path in filelist] > but: > for path in filelist: adds.add_changes('foo', path) Excellent point; new toy, got carrid away :) I feel silly on that one. And now that I've made the return list.extend(foo) mistake, I'll surely neve- ... er, wait a long time before I make that mistake again. Thanks folks. On 4/3/06, Karl Pflästerer <[EMAIL PROTECTED]> wrote: ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Books
> "Beginning Python: From Novice to Professional", by > Magnus Lie Hetland > Publisher: Apress (September 26, 2005) > ISBN: 159059519X I would heartily second this recommendation. Different folks have different learning styles, and having a good overview can make weeding out the internet information a lot easier. There's also, on-line, Dive Into Python by Mark Pilgrim, often recommended as a good intro book http://diveintopython.org/index.html ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Any Good book for python
> I am new in Python area and want to know Python concepts with more deatils. > Please suggest some good books on python. Beginning Python, by Hetland is excellent for almost any level (I think someone who has really mastered one language, and is currently working as a programmer, can simply read Guido's tutorial & use the online docs). Hetland doesn't talk down to beginner, non-programmer types, nor does he hide hard stuff; he makes it accessible. It also talks about how to program in general, how to attack problems, test, have fun.It's well indexed and organized, so it's a good reference for the noob, but as yo gain experience with Python you will migrate to the on-line docs. I have to say, however, that in the first weeks I used the book as a reference more than I used the on-line docs. Diving into Python, by Pilgrim has a lot of respect. It's available on-line http://diveintopython.org/index.html It is a Python book for "experienced programmers." Which, I assume, means experienced non-Python programmers. I learn via immersion research & doing, I've read a lot of computer books, and Hetland's is really quite good. I'll read Pilgrim's book in the near future. In general (with the notable exception of the Plone book) I've found the Apress materials excellent. (Both books happen to be Apress, no I'm not affiliated in any way). --stv ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor