Re: [Tutor] How to invoke different member-function according to different object?

2012-01-07 Thread Peter Otten
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?

2012-01-07 Thread Alex Hall
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?

2012-01-07 Thread Chris Fuller

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?

2012-01-07 Thread Alex Hall
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?

2012-01-07 Thread Hugo Arts
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

2012-01-07 Thread Lie Ryan

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?

2012-01-07 Thread Lie Ryan

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

2012-01-07 Thread Wayne Watson
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