Re: [Tutor] How to invoke different member-function according to different object?
daedae11 wrote: > I was asked to write a program to move files between ZIP(.zip) and > TAR/GZIP(.tgz/.tar.gz) or TAR/BZIP2(.tbz/.tar.bz2) archive. > > my code is: > > > import zipfile; > import tarfile; > import os; > from os import path ; > > def showAllFiles(fileObj): > if fileObj.filename.endswith("zip"): > if isinstance(fileObj, zipfile.ZipFile): > print "j"*20; > for name in fileObj.namelist(): > print name; > else: > for name in fileObj.getnames(): > print name; > > def moveFile(srcObj, dstObj): > fileName = raw_input("input the name of the file to move: "); > srcObj.extract(fileName); > if isinstance(dstObj, zipfile.ZipFile): > dstObj.write(fileName); > else: > dstObj.addfile(tarfile.TarInfo(fileName)); > os.remove(fileName); > > def main(): > intro = """ > enter a choice > (M)ove file from source file to destinatiom file > (S)how all the files in source file > (Q)uit > your choice is: """ > srcFile = raw_input("input the source file name: "); > dstFile = raw_input("input the destination file name: "); > while True: > with ( zipfile.ZipFile(srcFile, "r") if srcFile.endswith("zip") > else tarfile.open(srcFile, "r"+":"+path.splitext(srcFile)[1][1:]) > ) as srcObj, \ ( zipfile.ZipFile(dstFile, "r") if >dstFile.endswith("zip") else > tarfile.open(dstFile, "w"+":"+path.splitext(dstFile)[1][1:]) ) > as dstObj: > choice = raw_input(intro)[0].lower(); > if choice == "s": > showAllFiles(srcObj); > elif choice == "m": > moveFile(srcObj, dstObj); > elif choice == "q": > break; > else: > print "invalid command!" > > if __name__ == '__main__': > main(); > > But there are some problems. > 1. It could extract file successfully, but can't add files to .tar.gz > file. 2. I think it's a little tedious, but I don't know how to improve > it. > > Please give me some help , thank you! First, but least: don't pollute your code with trailing semicola. Second: what Steven says, plus it will always take you longer to implement a script than you initially think. I ran into that for the umpteenth time when trying to reorganize your script. Now to your code: - Try to separate the user interface (aka raw_input()) from the other functionality of your script. moveFile() will be easier to test when you pass the filename as an argument rather than asking the user for it. - Don't overuse inlined if-else expressions. A separate if complex condition: var = ... else: var = ... is easier to read -- and easier to extend with another elif. - If you have a lot of if-else switches consider classes # wrong animal = dog_or_duck() if its_a_dog(animal): bark() elif its_a_duck(animal): quack() # right animal = dog_or_duck() animal.make_some_noise() In your case there already are classes, but with incompatible interfaces. You can solve that by subclassing or making wrapper classes. Another approach that addresses the same problem is table-driven: def quack(): print "quack" def bark(): print "wuff" lookup_noise = { Dog: bark, Duck: quack, } animal = dog_or_duck() lookup_noise[animal.__class__]() In my rewritten version of your script I use both approaches. It is still incomplete and has already become almost too long to post. It is probably a bit too complex for a beginner, too, but the idea is simple and if you have questions I'm willing to answer. Basically there is a class for every archive type which has to implement an open(name) method which has to return a file-like object and an add(name, file) which has to add a file-like object as name to the archive. You can ask if a certain archive class can deal with a file with e. g. ZipArchive.can_handle(filename) The script features an adhoc test that you can invoke with python scriptname.py --test Look into http://docs.python.org/library/unittest.html if you are serious about testing. I think you should be ;) import os import shutil import sys import tarfile import zipfile def _not_implemented(obj, methodname): typename = obj.__class__.__name__ print >> sys.stderr, "{}.{}() not implemented".format(typename, methodname) class Archive(object): @classmethod def can_handle(class_, filename): return filename.lower().endswith(class_.suffixes) def __init__(self, filename, mode): if mode not in ("r", "w"): raise ValueError("Mode {} not understood".format(mode)) self.filename = filename self.mode = mode self._archive = self._open_archive() def getnames(self): return self._archive.getnames() def __enter__(self): return self def __exit__(self, *args): self._archive.close() def _open_archive(
[Tutor] making a custom file parser?
Hello all, I have a file with xml-ish code in it, the definitions for units in a real-time strategy game. I say xml-ish because the tags are like xml, but no quotes are used and most tags do not have to end. Also, comments in this file are prefaced by an apostrophe, and there is no multi-line commenting syntax. For example: 'this line is a comment The game is not mine, but I would like to put together a python interface to more easily manage custom units for it. To do that, I have to be able to parse these files, but elementtree does not seem to like them very much. I imagine it is due to the lack of quotes, the non-standard commenting method, and the lack of closing tags. I think my only recourse here is to create my own parser and tell elementtree to use that. The docs say this is possible, but they also seem to indicate that the parser has to already exist in the elementtree package and there is no mention of making one's own method for parsing. Even if this were possible, though, I am not sure how to go about it. I can of course strip comments, but that is as far as I have gotten. Bottom line: can I create a method and tell elementtree to parse using it, and what would such a function look like (generally) if I can? Thanks! -- Have a great day, Alex (msg sent from GMail website) mehg...@gmail.com; http://www.facebook.com/mehgcap ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] making a custom file parser?
If it's unambiguous as to which tags are closed and which are not, then it's pretty easy to preprocess the file into valid XML. Scan for the naughty bits (single quotes) and insert escape characters, replace with something else, etc., then scan for the unterminated tags and throw in a "/" at the end. Anyhow, if there's no tree structure, or its only one level deep, using ElementTree is probably overkill and just gives you lots of leaking abstractions to plug for little benefit. Why not just scan the file directly? Cheers On Saturday 07 January 2012, Alex Hall wrote: > Hello all, > I have a file with xml-ish code in it, the definitions for units in a > real-time strategy game. I say xml-ish because the tags are like xml, > but no quotes are used and most tags do not have to end. Also, > comments in this file are prefaced by an apostrophe, and there is no > multi-line commenting syntax. For example: > > > > > > > 'this line is a comment > > > The game is not mine, but I would like to put together a python > interface to more easily manage custom units for it. To do that, I > have to be able to parse these files, but elementtree does not seem to > like them very much. I imagine it is due to the lack of quotes, the > non-standard commenting method, and the lack of closing tags. I think > my only recourse here is to create my own parser and tell elementtree > to use that. The docs say this is possible, but they also seem to > indicate that the parser has to already exist in the elementtree > package and there is no mention of making one's own method for > parsing. Even if this were possible, though, I am not sure how to go > about it. I can of course strip comments, but that is as far as I have > gotten. > > Bottom line: can I create a method and tell elementtree to parse using > it, and what would such a function look like (generally) if I can? > Thanks! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] making a custom file parser?
I had planned to parse myself, but am not sure how to go about it. I assume regular expressions, but I couldn't even find the amount of units in the file by using: unitReg=re.compile(r"\(*)\") unitCount=unitReg.search(fileContents) print "number of units: "+unitCount.len(groups()) I just get an exception that "None type object has no attribute groups", meaning that the search was unsuccessful. What I was hoping to do was to grab everything between the opening and closing unit tags, then read it one at a time and parse further. There is a tag inside a unit tag called AttackTable which also terminates, so I would need to pull that out and work with it separately. I probably just have misunderstood how regular expressions and groups work... On 1/7/12, Chris Fuller wrote: > > If it's unambiguous as to which tags are closed and which are not, then it's > pretty easy to preprocess the file into valid XML. Scan for the naughty > bits > (single quotes) and insert escape characters, replace with something else, > etc., then scan for the unterminated tags and throw in a "/" at the end. > > Anyhow, if there's no tree structure, or its only one level deep, using > ElementTree is probably overkill and just gives you lots of leaking > abstractions to plug for little benefit. Why not just scan the file > directly? > > Cheers > > On Saturday 07 January 2012, Alex Hall wrote: >> Hello all, >> I have a file with xml-ish code in it, the definitions for units in a >> real-time strategy game. I say xml-ish because the tags are like xml, >> but no quotes are used and most tags do not have to end. Also, >> comments in this file are prefaced by an apostrophe, and there is no >> multi-line commenting syntax. For example: >> >> >> >> >> >> >> 'this line is a comment >> >> >> The game is not mine, but I would like to put together a python >> interface to more easily manage custom units for it. To do that, I >> have to be able to parse these files, but elementtree does not seem to >> like them very much. I imagine it is due to the lack of quotes, the >> non-standard commenting method, and the lack of closing tags. I think >> my only recourse here is to create my own parser and tell elementtree >> to use that. The docs say this is possible, but they also seem to >> indicate that the parser has to already exist in the elementtree >> package and there is no mention of making one's own method for >> parsing. Even if this were possible, though, I am not sure how to go >> about it. I can of course strip comments, but that is as far as I have >> gotten. >> >> Bottom line: can I create a method and tell elementtree to parse using >> it, and what would such a function look like (generally) if I can? >> Thanks! > > -- Have a great day, Alex (msg sent from GMail website) mehg...@gmail.com; http://www.facebook.com/mehgcap ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] making a custom file parser?
On Sat, Jan 7, 2012 at 8:22 PM, Alex Hall wrote: > I had planned to parse myself, but am not sure how to go about it. I > assume regular expressions, but I couldn't even find the amount of > units in the file by using: > unitReg=re.compile(r"\(*)\") > unitCount=unitReg.search(fileContents) > print "number of units: "+unitCount.len(groups()) > > I just get an exception that "None type object has no attribute > groups", meaning that the search was unsuccessful. What I was hoping > to do was to grab everything between the opening and closing unit > tags, then read it one at a time and parse further. There is a tag > inside a unit tag called AttackTable which also terminates, so I would > need to pull that out and work with it separately. I probably just > have misunderstood how regular expressions and groups work... > Parsing XML with regular expressions is generally very bad idea. In the general case, it's actually impossible. XML is not what is called a regular language, and therefore cannot be parsed with regular expressions. You can use regular expressions to grab a limited amount of data from a limited set of XML files, but this is dangerous, hard, and error-prone. As long as you realize this, though, you could possibly give it a shot (here be dragons, you have been warned). > unitReg=re.compile(r"\(*)\") This is probably not what you actually did, because it fails with a different error: >>> a = re.compile(r"\(*)\") Traceback (most recent call last): File "", line 1, in File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.py", line 188, in compile File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.py", line 243, in _compile sre_constants.error: nothing to repeat I'll assume that said "(.*)". There's still a few problems: < and > shouldn't be escaped, which is why you're not getting any matches. Also you shouldn't use * because it is greedy, matching as much as possible. So it would match everything in between the first and the last tag in the file, including other tags that might show up. What you want is more like this: unit_reg = re.compile(r"(.*?)") Test it carefully, ditch elementtree, use as little regexes as possible (string functions are your friends! startswith, split, strip, et cetera) and you might end up with something that is only slightly ugly and mostly works. That said, I'd still advise against it. turning the files into valid XML and then using whatever XML parser you fancy will probably be easier. Adding quotes and closing tags and removing comments with regexes is still bad, but easier than parsing the whole thing with regexes. HTH, Hugo ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Subclassing Exceptions
On 01/07/2012 03:56 PM, Steven D'Aprano wrote: Chris Fuller wrote: You probably shouldn't inherit from SyntaxError, since it represents syntax errors in the Python code being interpreted or compiled. Any syntax error in your own data structures should be independent of SyntaxError. I'd say a syntactical error in your own data structure is a kind of ValueError. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] making a custom file parser?
On 01/08/2012 04:53 AM, Alex Hall wrote: Hello all, I have a file with xml-ish code in it, the definitions for units in a real-time strategy game. I say xml-ish because the tags are like xml, but no quotes are used and most tags do not have to end. Also, comments in this file are prefaced by an apostrophe, and there is no multi-line commenting syntax. For example: 'this line is a comment The format is closer to sgml than to xml, except for the tag being able to have values. I'd say you probably would have a better chance of transforming this into sgml than transforming it to xml. Try this re: s = re.sub('<([a-zA-Z]+)=([^>]+)>', r'<\1 __attribute__="\2">', s) and use an SGML parser to parse the result. I find Fredrik Lundh's sgmlop to be easier to use for this one, just use easy_install or pip to install sgmlop. import sgmlop class Unit(object): pass class handler: def __init__(self): self.units = {} def finish_starttag(self, tag, attrs): attrs = dict(attrs) if tag == 'unit': self.current = Unit() elif tag == 'number': self.current.number = int(attrs['__attribute__']) elif tag == 'canmove': self.current.canmove = attrs['__attribute__'] == 'True' elif tag in ('name', 'cancarry'): setattr(self.current, tag, attrs['__attribute__']) else: print 'unknown tag', tag, attrs def finish_endtag(self, tag): if tag == 'unit': self.units[self.current.name] = self.current del self.current def handle_data(self, data): if not data.isspace(): print data.strip() s = ''' 'this line is a comment 'this line is a comment 'this line is a comment 'this line is a comment ''' s = re.sub('<([a-zA-Z]+)=([^>]+)>', r'<\1 __attribute__="\2">', s) parser = sgmlop.SGMLParser() h = handler() parser.register(h) parser.parse(s) print h.units ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Return to my python26.dll & python.dll problems on bootup
You are right about posting here, but I was hoping someone might have related to the problem. I went to the WinAmp forum for help. But who would have guessed that WinAmp would have provided a program not ready for prime time, and nothing buy an advertisement to get you to buy the latest drivers for your PC. Lesson learned. Someone on their forum suggested hijackthis.log, which will fix a registry. Five stars by CNET, but it may not be quite free. Ah, I just got through to uniblue's tech support by mail. As an aside, I've noticed that a lot of downloadable freebies have pages that are thick with other $ products advertising. Once you get through several pages of them, you then find the download. On 1/5/2012 10:25 AM, Steven D'Aprano wrote: Wayne Watson wrote: I have two problems upon bootup of my Win7 PC, 64-bit. Wayne, I sympathize with your problems, but they are Windows problems, not Python problems, and have absolutely nothing to do with learning to program Python. You are spamming this mailing list with off-topic questions about fixing your Windows system. This list is about learning Python programming, not "we'll fix any problem that has some vague connection to Python, no matter how slight". Have you tried asking for help on Windows-related forums or mailing lists? It has been many years since I've used Windows regularly, but I can tell you this: you don't do yourself any favours by installing and uninstalling programs under Windows. I know it is less than helpful, but my advice is *never* install any program you aren't sure you will want to keep, because uninstalling always leaves traces of crud behind, eventually leading to exactly the sorts of problems you are experiencing. -- Wayne Watson (Watson Adventures, Prop., Nevada City, CA) (121.015 Deg. W, 39.262 Deg. N) GMT-8 hr std. time) Obz Site: 39° 15' 7" N, 121° 2' 32" W, 2700 feet CE 1955 October 20 07:53:32.6 UT -- "The Date" The mystery unfolds. Web Page: ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor