2.X functools.update_wrapper dislikes missing function attributes

2011-04-26 Thread samwyse
I noticed a behavior in Jython 2.5.2 that's arguably an implementation
bug, but I'm wondering if it's something to be fixed for all versions
of Python.  I was wanting to decorate a Java instance method, and
discovered that it didn't have a __module__ attribute.  This caused
the following message:

  File "C:\jython2.5.2\Lib\functools.py", line 33, in update_wrapper
setattr(wrapper, attr, getattr(wrapped, attr))
AttributeError: 'instancemethod' object has no attribute '__module__'

The relevant code is:
for attr in assigned:
setattr(wrapper, attr, getattr(wrapped, attr))
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))

Note that attributes to be updated get a default value.  I'm proposing
that attributes to be assigned do the same, most likely an empty
string.  A non-string value (such as None) could break anything
expecting a string value, so it seems like a bad idea.  Python 3.2
catches AttributeError and passes.  I don't like this solution.  While
it prevents any attributes from being added to the wrapper, the
wrapper likely has its own values (at least for the default
attributes) and using those values could cause confusion.

Any opinions?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 2.X functools.update_wrapper dislikes missing function attributes

2011-04-26 Thread samwyse
I just noticed an old issue that relate to this: 
http://bugs.python.org/issue3445

This dates back to 2008 and is marked as fixed, but my copies of
Python 2.5.4 and 2.7.1 don't seem to implement it.  I'll try to dig
further.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Microsoft Hatred FAQ

2005-11-01 Thread samwyse

David Schwartz wrote:
> "Mike Meyer" <[EMAIL PROTECTED]> wrote in message
> news:[EMAIL PROTECTED]

> Morally, lying in court is a tough one. For example, suppose you are in
> a court case with someone who is definitely lying in court. You are in the
> right, but it's clear the court won't believe you in the face of the lying
> and faked evidence. In this case, is lying in court fraud? Or is it
> justified in defense against an attacker willing to use fraud against you?
> So this isn't quite in the same category as force or fraud, because the
> court has the ability to balance credibility and control damage. No such
> balancing is available against a bullet in flight.

Lying in court isn't fraud.  It is perjury.  There are laws against it
with pretty stiff penalties, because it subverts the court system.
Committing perjury to defend yourself against fraud will often cause
any conviction and punishment relating to the fraud to be erased.  So,
I'd say no, it isn't justified.  Instead, you try to prove that the
other person is lying.  Lawyers do this all the time; it's part of
their job and it's called discrediting the witness.

BTW, if you want an excellent example of officers of Microsoft
falsifying evidence in a trial, you need look no further that here:
http://wired-vig.wired.com/news/politics/0,1283,17689,00.html
and here:
http://www.wired.com/news/politics/0,1283,17938,00.html

-- 
http://mail.python.org/mailman/listinfo/python-list


Python 3000: Standard API for archives?

2007-06-04 Thread samwyse
I'm a relative newbie to Python, so please bear with me.  There are 
currently two standard modules used to access archived data:  zipfile 
and tarfile.  The interfaces are completely different.  In particular, 
script wanting to analyze different types of archives must duplicate 
substantial pieces of logic.  The problem is not limited to method 
names; it includes how stat-like information is accessed.

I think it would be a good thing if a standardized interface existed, 
similar to PEP 247.  This would make it easier for one script to access 
multiple types of archives, such as RAR, 7-Zip, ISO, etc.  In 
particular, a single factory class could produce PEP 302 import hooks 
for future as well as current archive formats.

I think that an archive module adhering to the standard should adopt a 
least-common-denominator approach, initially supporting read-only access 
without seek, i.e. tar files on actual tape.  For applications that 
require a seek method (such as importers) a standard wrapper class could 
transparently cache archive members in temp files; this would fit in 
well with Python 3000's rewrite of the I/O interface to support 
stackable interfaces.  To this end, we'd need is_seekable and 
is_writable attributes for both the module and instances (moduel level 
would declare if something is possible, not if it is always true).

Most importantly, all archive modules should provide a standard API for 
accessing their individual files via a single archive_content class that 
provides a standard 'read' method.  Less importantly but nice to have 
would be a way for archives to be auto-magically scanned during walks of 
  directories.

Feedback?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: need help with re module

2007-06-22 Thread samwyse
Gabriel Genellina wrote:
> En Wed, 20 Jun 2007 17:56:30 -0300, David Wahler <[EMAIL PROTECTED]>  
> escribió:
> 
>> On 6/20/07, Gabriel Genellina <[EMAIL PROTECTED]> wrote:
>>
[snip]
>> I agree that BeautifulSoup is probably the best tool for the job, but
>> this doesn't sound right to me. Since the OP doesn't care about tags
>> being properly nested, I don't see why a regex (albeit a tricky one)
>> wouldn't work. For example:
>>
[snip]
>>
>> Granted, this misses out a few things (e.g. DOCTYPE declarations), but
>> those should be straightforward to handle.
> 
> It doesn't handle a lot of things. For this input (not very special, 
> just  a few simple mistakes):
> 
> 
> http://foo.com/baz.html>click here
> What if price<100? You lose.
> What if HitPoints<-10? You are dead.
> Assignment: target <-- any_expression
> Just a few last words.
> 
> 
> the BeautifulSoup version gives:
> 
> click here
> What if price<100? You lose.
> What if HitPoints<-10? You are dead.
> Assignment: target <-- any_expression
> Just a few last words.
> 
> and the regular expression version gives:
> 
> http://foo.com/baz.html>click here
> What if priceWhat if HitPointsAssignment: target
> 
> Clearly the BeautifulSoup version gives the "right" result, or the  
> "expected" one.
> It's hard to get that with only a regular expression, you need more 
> power;  and BeautifulSoup fills the gap.

Speak for yourself.  If I'm writing an HTML syntax checker, I think I'll 
skip BeautifulSoup and use something that gives me the results that I 
expect, not the results that you expect.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Re-raising exceptions with modified message

2007-07-07 Thread samwyse
On Jul 5, 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote:
> What is the best way to re-raise any exception with a message
> supplemented with additional information (e.g. line number in a
> template)? Let's say for simplicity I just want to add "sorry" to every
> exception message. My naive solution was this:
>
> try:
>  ...
> except Exception, e:
>  raise e.__class__, str(e) + ", sorry!"
>
> This works pretty well for most exceptions, e.g.
>
>  >>> try:
> ... 1/0
> ... except Exception, e:
> ... raise e.__class__, str(e) + ", sorry!"
> ...
> Traceback (most recent call last):
>File "", line 4, in 
> ZeroDivisionError: integer division or modulo by zero, sorry!
>
> But it fails for some exceptions that cannot be instantiated with a
> single string argument, like UnicodeDecodeError which gets "converted"
> to a TypeError:
>
>  >>> try:
> ... unicode('\xe4')
> ... except Exception, e:
> ... raise e.__class__, str(e) + ", sorry!"
> ...
> Traceback (most recent call last):
>File "", line 4, in 
> TypeError: function takes exactly 5 arguments (1 given)
>
> Another approach is using a wrapper Extension class:
>
> class SorryEx(Exception):
>  def __init__(self, e):
>  self._e = e
>  def __getattr__(self, name):
>  return getattr(self._e, name)
>  def __str__(self):
>  return str(self._e) + ", sorry!"
>
> try:
>  unicode('\xe4')
> except Exception, e:
>  raise SorryEx(e)
>
> But then I get the name of the wrapper class in the message:
>
> __main__.SorryEx: 'ascii' codec can't decode byte 0xe4 in position 0:
> ordinal not in range(128), sorry!
>
> Yet another approach would be to replace the __str__ method of e, but
> this does not work for new style Exceptions (Python 2.5).
>
> Any suggestions?
>
> -- Chris

Can "try" statements be used in "except" clauses?  It appears so, thus
a hybrid approach might work well enough.

try:
...
except Exception, e:
try:
raise e.__class__, str(e) + ", sorry!"
except TypeError:
raise SorryEx(e)

That leaves the issue of the name being changed for
UnicodeDecodeError, which might be fixable by diddling with __name__
properties.  Or perhaps SorryEx needs to be a factory that returns
exception classes; the last line would be "SorryEx(e)()".  I'll have
to play with this a bit.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Re-raising exceptions with modified message

2007-07-07 Thread samwyse
On Jul 7, 4:13 pm, samwyse <[EMAIL PROTECTED]> wrote:
> On Jul 5, 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote:
>
> > What is the best way to re-raise any exception with a message
> > supplemented with additional information (e.g. line number in a
> > template)?
[...]
> That leaves the issue of the name being changed for
> UnicodeDecodeError, which might be fixable by diddling with __name__
> properties.  Or perhaps SorryEx needs to be a factory that returns
> exception classes; the last line would be "SorryEx(e)()".  I'll have
> to play with this a bit.

OK, the following mostly works.  You probably want the factory to copy
more of the original class into the SorryEx class each time, since
someone catching an exception may expect to look at things besides its
string representation.

def SorryFactory(e):
class SorryEx(Exception):
def __init__(self):
self._e = e
def __getattr__(self, name):
return getattr(self._e, name)
def __str__(self):
return str(self._e) + ", sorry!"
SorryEx.__name__ = e.__class__.__name__
return SorryEx

def test(code):
  try:
code()
  except Exception, e:
try:
  raise e.__class__, str(e) + ", sorry!"
except TypeError:
  raise SorryFactory(e)()

test(lambda: unicode('\xe4'))


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Re-raising exceptions with modified message

2007-07-07 Thread samwyse
On Jul 5, 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote:
> What is the best way to re-raise any exception with a message
> supplemented with additional information (e.g. line number in a
> template)? Let's say for simplicity I just want to add "sorry" to every
> exception message.

OK, this seems pretty minimal, yet versatile.   It would be nice to be
able to patch the traceback, but it turns out that it's fairly hard to
do. If you really want to do that, however, go take a look at
http://lucumr.pocoo.org/cogitations/2007/06/16/patching-python-tracebacks-part-two/


# Written by Sam Denton <[EMAIL PROTECTED]>
# You may use, copy, or distribute this work,
# as long as you give credit to the original author.
def rewriten_exception(old, f):
class Empty(): pass
new = Empty()
new.__class__ = old.__class__
new.__dict__ = old.__dict__.copy()
new.__str__ = f
return new

def test(code):
try:
code()
except Exception, e:
raise rewriten_exception(e, lambda: str(e) + ", sorry!")

test(lambda: unicode('\xe4'))
test(lambda: 1/0)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what is wrong with that r"\"

2007-07-08 Thread samwyse
On Jul 4, 7:15 am, Matthieu TC <[EMAIL PROTECTED]> wrote:
> May I suggest giving the possibility to use any delimiter for a raw string?  
> just like in Vi or ruby.
>
> Vi:
>  %s_a_b_g  is valid and so is  %s/a/b/g
>
> Ruby:
>  %q{dj'\ks'a\'"}   or %q-dj'\ks'a\'"-
>
> So as long as your regex does not use all the valid characters, readability 
> is maintained.

first, you'll need a way to flag that something is an arbitrarily
quoted string; 'r' is taken, so let's use 'q'.  next, you need to
distinguish strings from variables, perhaps by adding a flag to all
variables; $ should do nicely and has some historical precident.  once
you've done all that, you can write something like this:
  $q = q|this so-called "string" doesn't use conventional quotes|

congratulations!  you've just invented perl!

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: allow scripts to use .pth files?

2007-07-08 Thread samwyse
On Jul 3, 9:35 am, Alan Isaac <[EMAIL PROTECTED]> wrote:
> Suppose I have a directory `scripts`.
> I'd like the scripts to have access to a package
> that is not "installed", i.e., it is not on sys.path.
> On this list, various people have described a variety
> of tricks they use, but nobody has proposed a
> pretty way to allow this.
> I am therefore assuming there is not one. (?)
>
> How about allowing a `scripts.pth` file in such a `scripts`
> directory, to work like a path configuration file?
> (But to be used only when __name__=="__main__".)
> Drawbacks?
>
> Alan Isaac

before i can adequately shoot down your proposal, i need more
information.

first, how does the interpreter know to look in 'scripts' for your
'scripts.pyh' file and not in '.' or '~' or sys.argv[0] or someplace
else?  and you do know, don't you, that if you run 'scripts/
myscript.py' then 'scripts' is automagically prepended to the search
path for modules?

second, what's for format of this proposed file?  does it contain the
name of a single directory?  is it one directory name per line?  is it
intended to be os-specific or will the same file work on windows,
unix, vms and macos?

third, is there anything special about the name?  should i put a
myscripts.pyh file in the myscripts directory?  what if i have
multiple .pyh files?

if i may make some assumptions about the answers to the above, then
this incantation might do somewhat more than what you've asked for
(but what you actually want may be different):

if __name__ == '__main__':
import sys
from os.path import split, join, expanduser
for d in '.', split(sys.argv[0])[0], expanduser('~'):
scripts_pyh = join(d, 'scripts.pyh')
try:
for each_line in open(scripts_pyh).readlines():
sys.path.append(each_line)
except:
pass


personally, though, i would be more likely to use this and skip all of
that 'scripts.pyh' nonsense:

if __name__ == '__main__':
import sys, os.path
for d in '.', os.path.expanduser('~'):
if os.path.isdir(d): sys.path.append(d)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Rats! vararg assignments don't work

2007-07-12 Thread samwyse
On May 30, 7:29 am, Sion Arrowsmith <[EMAIL PROTECTED]>
wrote:
> samwyse <[EMAIL PROTECTED]> wrote:
> >>samwysewrote:
> >>>I thought that I'd try this:
> >>> first, *rest = arglist
> >>>Needless to say, it didn't work.
> > [ ... ]
> >My use-case is (roughtly) this:
> > first, *rest = f.readline().split()
> > return dispatch_table{first}(*rest)
>
> first, rest = f.readline().split(None, 1)
> return dispatch_table{first}(*rest.split())

Hey, I like that!  Thanks!

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: allow scripts to use .pth files?

2007-07-12 Thread samwyse
On Jul 8, 3:53 pm, John Machin <[EMAIL PROTECTED]> wrote:

> I got the impression that the OP was suggesting that the interpreter
> look in the directory in which it found the script.
[...]
> I got the impression that the problem was that the package was not
> only not on sys.path but also not in the same directory as the script
> that wanted to import it. Otherwise the OP's script.p?h file need only
> contain ".\n" (or the path to the  directory in which it resided!!),
> and I doubt that he was proposing something so silly.

And as I'm sure you realize, those two impression slightly contradict
each other.  Anyway, a small modification to my second approach would
also work in the case looking for packages in a directory that's
located somewhere relative to the one where the script was found:

if __name__ == '__main__':
import sys, os.path
base = sys.path[0]
for d in 'lib', 'modules':
d2 = os.path.join(base, d)
if os.path.isdir(d2):
sys.path.append(d2)
base = os.path.join(base, '..')
for d in 'modules', 'lib':
d2 = os.path.join(base, d)
if os.path.isdir(d2):
sys.path.append(d2)
# for debugging
print repr(sys.path)

(BTW, this is such a fun script to type.  My fingers keep typing
'os.path' where I mean 'sys.path' and vice versa.)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Re-raising exceptions with modified message

2007-07-12 Thread samwyse
On Jul 8, 8:50 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote:
> Did you run this?
> With Py < 2.5 I get a syntax error, and with Py 2.5 I get:
>
>  new.__class__ = old.__class__
> TypeError: __class__ must be set to a class
>
> -- Chris

Damn, I'd have sworn I ran the final copy that I posted, but
apparently I did manage to have a typo creep in as I was prettifying
the code.  You need to lose the '()' in the definition of Empty.  (I'd
orignally had it subclass Exception but discovered that it wasn't
needed.)

class Empty: pass

I can't figure out the other complaint, though, as old.__class_ should
be a class.  I guess I need to upgrade; I am using PythonWin 2.4.3
(#69, Apr 11 2006, 15:32:42) [MSC v.1310 32 bit (Intel)] on win32.
(Of course, at work they're still stuck on 2.4.2.)  Printing
type(old.__class__) gives me ; maybe using
setattr(new, '__class__', old.__class__)
instead of the assignment would work, or maybe it's a bug/feature
introduced in 2.5.  (Trying this code:
class Empty(old.__class__): pass
brings us back to the "TypeError: function takes exactly 5 arguments
(0 given)" message that we're trying to avoid.)


Anyway, running the corrected version under 2.4.X gives me this:

Traceback (most recent call last):
  File "C:\Python24\Lib\site-packages\pythonwin\pywin\framework
\scriptutils.py", line 310, in RunScript
exec codeObject in __main__.__dict__
  File "C:\Documents and Settings\dentos\Desktop\scripting
\modify_message.py", line 19, in ?
test(lambda: unicode('\xe4'))
  File "C:\Documents and Settings\dentos\Desktop\scripting
\modify_message.py", line 16, in test
raise modify_message(e, lambda: str(e) + ", sorry!")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position
0: ordinal not in range(128), sorry!
>>>

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: allow scripts to use .pth files?

2007-07-12 Thread samwyse
On Jul 8, 3:53 pm, John Machin <[EMAIL PROTECTED]> wrote:

> I'm curious whether you think that the OP's use of ".pth" was a typo,
> and whether you have read this:
>http://docs.python.org/lib/module-site.html

I've read it, but not recently; the syntax of the .pyh files was in
the back of my head.  I had forgotten about the sitecustomize module,
though.  Unfortunately for the OP, while the documentation states,
"After these path manipulations, an attempt is made to import a module
named sitecustomize," the import is apparently done *before* the path
to the script is prepended to sys.path.  (My name isn't Luke, so I
don't feel the need to read the source.)

I'm guessing that the OP's real question is, "How does one do site
customizations when one doesn't have write access to the site
directories?"  Lots of programs can be installed and run from ~/bin,
but locating ~/lib can be hard, at least for arbitrary values of bin
and lib.  At this point, someone usually tells me to write a PEP;
perhaps the OP would like to try his hand?  In keeping with the spirit
of the site customizations, I'd specify that all .pyh files get
imported, not just one matching the name of the script.  (This is more
robust in the face of hard-links, packages consisting of multiple
scripts, etc.)  I'd also suggest an attempt to import a module named
mycustomize after the path to the invoked script is prepended to
sys.path.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: allow scripts to use .pth files?

2007-07-12 Thread samwyse
On Jul 12, 7:20 am, John Machin <[EMAIL PROTECTED]> wrote:
> On Jul 12, 9:55 pm, samwyse <[EMAIL PROTECTED]> wrote:
>
> > On Jul 8, 3:53 pm, John Machin <[EMAIL PROTECTED]> wrote:
>
> > > I got the impression that the OP was suggesting that the interpreter
> > > look in the directory in which it found the script.
> > [...]
> > > I got the impression that the problem was that the package was not
> > > only not on sys.path but also not in the same directory as the script
> > > that wanted to import it. Otherwise the OP's script.p?h file need only
> > > contain ".\n" (or the path to the  directory in which it resided!!),
> > > and I doubt that he was proposing something so silly.
>
> > And as I'm sure you realize, those two impression slightly contradict
> > each other.
>
> Your sureness is misplaced. Please explain.


Oops, you're right.  See my other post.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Re-raising exceptions with modified message

2007-07-12 Thread samwyse
On Jul 12, 6:31 am, samwyse <[EMAIL PROTECTED]> wrote:
> On Jul 8, 8:50 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote:
>
> > With Py 2.5 I get:
>
> >  new.__class__ = old.__class__
> > TypeError: __class__ must be set to a class


Hmmm, under Python 2.4.X, printing repr(old.__class__) gives me this:
  
while under 2.5.X, I get this:
  


So, let's try sub-classing the type:

def modify_message(old, f):
class Empty: pass
new = Empty()
print "old.__class__ =", repr(old.__class__)
print "Empty =", repr(Empty)
new.__class__ = Empty

class Excpt(old.__class__): pass
print "Excpt =", repr(Excpt)
print "Excpt.__class__ =", repr(Excpt.__class__)
new.__class__ = Excpt

new.__dict__ = old.__dict__.copy()
new.__str__ = f
return new

Nope, that gives us the same message:

old.__class__ = 
Empty = 
Excpt = 
Excpt.__class__ = 
Traceback (most recent call last):
[...]
TypeError: __class__ must be set to a class

Excpt ceratinly appears to be a class.  Does anyone smarter than me
know what's going on here?

-- 
http://mail.python.org/mailman/listinfo/python-list


Assignments to __class_ broken in Python 2.5?

2007-07-12 Thread samwyse
On Jul 12, 11:48 am, samwyse <[EMAIL PROTECTED]> wrote:
> On Jul 12, 6:31 am,samwyse<[EMAIL PROTECTED]> wrote:
>
> > On Jul 8, 8:50 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote:
>
> > > With Py 2.5 I get:
>
> > >  new.__class__ = old.__class__
> > > TypeError: __class__ must be set to a class
>
> Hmmm, under Python 2.4.X, printing repr(old.__class__) gives me this:
>   
> while under 2.5.X, I get this:
>   
>
> So, let's try sub-classing the type:
>
> def modify_message(old, f):
> class Empty: pass
> new = Empty()
> print "old.__class__ =", repr(old.__class__)
> print "Empty =", repr(Empty)
> new.__class__ = Empty
>
> class Excpt(old.__class__): pass
> print "Excpt =", repr(Excpt)
> print "Excpt.__class__ =", repr(Excpt.__class__)
> new.__class__ = Excpt
>
> new.__dict__ = old.__dict__.copy()
> new.__str__ = f
> return new
>
> Nope, that gives us the same message:
>
> old.__class__ = 
> Empty = 
> Excpt = 
> Excpt.__class__ = 
> Traceback (most recent call last):
> [...]
> TypeError: __class__ must be set to a class
>
> Excpt certainly appears to be a class.  Does anyone smarter than me
> know what's going on here?

OK, in classobject.h, we find this:

#define PyClass_Check(op) ((op)->ob_type == &PyClass_Type)

That seems straightforward enough.  And the relevant message appears
in classobject.c here:

static int
instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
[...]
if (strcmp(sname, "__class__") == 0) {
if (v == NULL || !PyClass_Check(v)) {
PyErr_SetString(PyExc_TypeError,
   "__class__ must be set to a class");
return -1;
}

Back in our test code, we got these:
> Empty = 
> Excpt = 

The first class (Empty) passes the PyClass_Check macro, the second one
(Excpt) evidently fails.  I'll need to dig deeper.  Meanwhile, I still
have to wonder why the code doesn't allow __class_ to be assigned a
type instead of a class.  Why can't we do this in the C code (assuming
the appropriate PyType_Check macro):

if (v == NULL || !(PyClass_Check(v) || PyType_Check(v))) {

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Assignments to __class_ broken in Python 2.5?

2007-07-13 Thread samwyse
(Yes, I probably should have said CPython in my subject, not Python.
Sorry.)

On Jul 13, 12:56 am, samwyse <[EMAIL PROTECTED]> wrote:

> OK, in classobject.h, we find this:
>
> #define PyClass_Check(op) ((op)->ob_type == &PyClass_Type)
>
> That seems straightforward enough.  And the relevant message appears
> in classobject.c here:
>
> static int
> instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
> [...]
> if (strcmp(sname, "__class__") == 0) {
> if (v == NULL || !PyClass_Check(v)) {
> PyErr_SetString(PyExc_TypeError,
>"__class__ must be set to a class");
> return -1;
> }
>
> Back in our test code, we got these:
>
> > Empty = 
> > Excpt = 
>
> The first class (Empty) passes the PyClass_Check macro, the second one
> (Excpt) evidently fails.  I'll need to dig deeper.  Meanwhile, I still
> have to wonder why the code doesn't allow __class_ to be assigned a
> type instead of a class.  Why can't we do this in the C code (assuming
> the appropriate PyType_Check macro):
>
> if (v == NULL || !(PyClass_Check(v) || PyType_Check(v))) {

After a good night's sleep, I can see that Empty is a "real" class;
i.e. its repr() is handled by class_repr() in classobject.c.  Excpt,
on the other hand, is a type; i.e. its repr is handled by type_repr()
in typeobject.c.  (You can tell because class_repr() returns a value
formatted as "" whereas type_repr returns a value
formatted as "<%s '%s.%s'>", where the first %s gets filled with
either "type" or "class".)

This is looking more and more like a failure to abide by PEP 252/253.
I think that the patch is simple, but I'm unusre of the
ramifications.  I also haven't looked at the 2.4 source to see how
things used to work.  Still, I think that I've got a work-around for
OP's problem, I just need to test it under both 2.4 and 2.5.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Re-raising exceptions with modified message

2007-07-13 Thread samwyse
On Jul 13, 12:45 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote:
> samwyse wrote:
> > TypeError: __class__ must be set to a class
>
> > Excpt ceratinly appears to be a class.  Does anyone smarter than me
> > know what's going on here?
>
> Not that I want to appear smarter, but I think the problem here is that
> exceptions are new-style classes now, whereas Empty is an old-style
> class. But even if you define Empty as a new-style class, it will not
> work, you get:
>
> TypeError: __class__ assignment: only for heap types
>
> This tells us that we cannot change the attributes of a built-in
> exception. If it would be possible, I simply would have overridden the
> __str__ method of the original exception in the first place.
>
> -- Chris

Chris, you owe me a beer if you're ever in St. Louis, or I'm ever in
Germany.

# - CUT HERE -

# Written by Sam Denton <[EMAIL PROTECTED]>
# You may use, copy, or distribute this work,
# as long as you give credit to the original author.

# tested successfully under Python 2.4.1, 2.4.3, 2.5.1

"""
On Jul 5, 2007, at 8:53 am, Christoph Zwerschke <[EMAIL PROTECTED]>
wrote:
> What is the best way to re-raise any exception with a message
> supplemented with additional information (e.g. line number in a
> template)? Let's say for simplicity I just want to add "sorry" to
> every exception message.

Here is an example of typical usage:

>>> def typical_usage(code):
... try:
... code()
... except Exception, e:
... simplicity = lambda self: str(e) + ", sorry!"
... raise modify_message(e, simplicity)

Note that if we want to re-cycle the original exception's message,
then we need our re-formatter (here called 'simplicity') to be
defined inside the exception handler.  I tried verious approaches
to defining the re-formater, but all of them eventually needed a
closure; I decided that I liked this approach best.

This harness wraps the example so that doctest doesn't get upset.

>>> def test_harness(code):
... try:
... typical_usage(code)
... except Exception, e:
... print "%s: %s" % (e.__class__.__name__, str(e))

Now for some test cases:

>>> test_harness(lambda: 1/0)
ZeroDivisionError: integer division or modulo by zero, sorry!

>>> test_harness(lambda: unicode('\xe4'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position
0: ordinal not in range(128), sorry!

"""

def modify_message(old, f):
"""modify_message(exception, mutator) --> exception

Modifies the string representation of an exception.
"""
class NewStyle(old.__class__):
def __init__(self): pass
NewStyle.__name__ = old.__class__.__name__
NewStyle.__str__ = f
new = NewStyle()
new.__dict__ = old.__dict__.copy()
return new

def _test():
import doctest
return doctest.testmod(verbose=True)

if __name__ == "__main__":
_test()

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Can a low-level programmer learn OOP?

2007-07-13 Thread samwyse
On Jul 13, 1:05 pm, Chris Carlen <[EMAIL PROTECTED]>
wrote:
> John Nagle wrote:
> > Chris Carlen wrote:[edit]
> >> Hence, being a hardware designer rather than a computer scientist, I
> >> am conditioned to think like a machine.  I think this is the main
> >> reason why OOP has always repelled me.
>
> > Why?
>
> When pointers were first explined to me, I went "Ok."  And rather
> quickly ideas lit up in my head about what I could do with them.
>
> When I read what OOP is, that doesn't happen.  All I think is "what's
> the point of this?"  "What can this do for me that I can do already with
> the procedural way of thinking?"  And if it can't do anything new, then
> why rearrange my thinking to a new terminology?  It's results that
> matter, not the paradigm.

What can this do for me that I can do already with the procedural way
of thinking?  Absolutely nothing; it's all Turing machines under the
hood.

Why rearrange my thinking to a new terminology?  Because new
terminologies matter a lot.  There's nothing that you can do with
pointers that can't be done with arrays; I know because I wrote a lot
of FORTRAN 77 code back in the day, and withouy pointers I had to
write my own memory allocation routines that worked off of a really
big array.

Likewise, there's nothing that you can do in C that can't be done with
C++ (especially since C++ was originally a preprocessor for C);
however C++ will keep track of a lot of low-level detail for you so
you don't have to think about it.  Let's say that you have an embedded
single-board computer with a serial and a parallel port.  You probably
have two different routines that you use to talk to them, and you have
to always keep track which you are using at any given time.

It's a lot easier to have a single CommPort virtual class that you use
in all of your code, and then have two sub-classes, one for serial
ports and one for parallel.  You'll be especially happy for this when
someone decides that as well as logging trace information to a
printer, it would be nice to also log it to a technician's handhelp
diagnostic device.

-- 
http://mail.python.org/mailman/listinfo/python-list


Rats! vararg assignments don't work

2007-05-29 Thread samwyse
I'm a relative newbie to Python, so please bear with me.  After seeing 
how varargs work in parameter lists, like this:
 def func(x, *arglist):
and this:
 x = func(1, *moreargs)
I thought that I'd try this:
 first, *rest = arglist
Needless to say, it didn't work.  That leaves me with two questions.

First, is there a good way to do this?  For now, I'm using this:
 first, rest = arglist[0], arglist[1:]
but it leaves a bad taste in my mouth.

Second, is there any good reason why it shouldn't work?  It seems like 
such an obvious idiom that I can't believe that I'm the first to come up 
with the idea.  I don't really have the time right now to go source 
diving, so I can't tell if it would be wildly inefficient to implement.

Thanks!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Rats! vararg assignments don't work

2007-05-30 Thread samwyse
Gary Herron wrote:
> samwyse wrote:
> 
>>I'm a relative newbie to Python, so please bear with me.  After seeing 
>>how varargs work in parameter lists, like this:
>> def func(x, *arglist):
>>and this:
>> x = func(1, *moreargs)
>>I thought that I'd try this:
>> first, *rest = arglist
>>Needless to say, it didn't work.  That leaves me with two questions.
>>
>>First, is there a good way to do this?  For now, I'm using this:
>> first, rest = arglist[0], arglist[1:]
>>but it leaves a bad taste in my mouth.
>>  
> 
> Well, your moreargs parameter is a tuple, and there are innumerable ways
> to process a tuple. (And even more if you convert it to a list.)

My use-case is (roughtly) this:
 first, *rest = f.readline().split()
 return dispatch_table{first}(*rest)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Rats! vararg assignments don't work

2007-05-30 Thread samwyse
George Sakkis wrote:
> On May 29, 11:33 pm, Matimus <[EMAIL PROTECTED]> wrote:
> 
> 
>>Your attemtp:
>>
>>[code]
>>first, rest = arglist[0], arglist[1:]
>>[/code]
>>
>>Is the most obvious and probably the most accepted way to do what you
>>are looking for. As for adding the fucntionality you first suggested,
>>it isn't likely to be implemented. The first step would be to write a
>>PEP though.
> 
> 
> The time machine did it again: http://www.python.org/dev/peps/pep-3132/.

Thanks!  Now I just need to wait for Py3K and all of my problems will be 
solved.  ;-)

Actually, I'm surprised that the PEP does as much as it does.  If tuples 
are implemented as S-expressions, then something like this:
 car, *cdr = tuple
while leaving cdr a tuple would be trivial to implement.  Of course, I'm 
an old-school LISPer, so what I consider surprising behavior doesn't 
always surprise anyone else, and vice versa.
-- 
http://mail.python.org/mailman/listinfo/python-list


Python 2.5.1 can't find win32file?

2007-07-28 Thread samwyse
I just upgraded from 2.4.something to 2.5.1.  I get the stuff below.
I tried easy-installing pywin32; same results.  Anyone know what's
going on?

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
(Intel)] on win32
Type "copyright", "credits" or "license()" for more information.


Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer's internal loopback
interface.  This connection is not visible on any external
interface and no data is sent to or received from the Internet.


IDLE 1.2.1   No Subprocess 
>>> import win32file
Traceback (most recent call last):
  File "", line 1, in 
import win32file
ImportError: DLL load failed: The specified module could not be found.
>>> import sys
>>> sys.path
['C:\\Documents and Settings\\dentos\\Desktop\\scripting', 'C:\
\Python25\\Lib\\idlelib', 'C:\\Python25\\lib\\site-packages\
\setuptools-0.6c6-py2.5.egg', 'C:\\Python25\\lib\\site-packages\
\sqlalchemy-0.3.10-py2.5.egg', 'C:\\Python25\\lib\\site-packages\
\pil-1.1.6-py2.5-win32.egg', 'C:\\Python25\\lib\\site-packages\
\epydoc-3.0beta1-py2.5-win32.egg', 'C:\\Python25\\lib\\site-packages\
\pywin32-210-py2.5-win32.egg', 'C:\\WINNT\\system32\\python25.zip', 'C:
\\Python25\\DLLs', 'C:\\Python25\\lib', 'C:\\Python25\\lib\\plat-win',
'C:\\Python25\\lib\\lib-tk', 'C:\\Python25', 'C:\\Python25\\lib\\site-
packages']

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to programmatically insert pages into MDI.

2007-07-28 Thread samwyse
On Jul 28, 7:46 am, fynali iladijas <[EMAIL PROTECTED]> wrote:
> On Jul 24, 4:36 pm, fynali iladijas <[EMAIL PROTECTED]> wrote:
>
>
>
> > Hi, this query is regarding automating page insertions in Microsoft
> > Document Imaging.
>
[...]
>
> > All help and advice will be most appreciated.
>
> > Thank you.
>
> > s|a fynali
>
> )-:
>
> --
> s|a fynali

Perhaps you should post to a Microsoft-related newsgroup.  This is the
place for questions about the Python programming language, and the
word "Python" didn't appear anywhere in your initial question.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python 2.5.1 can't find win32file?

2007-07-28 Thread samwyse
On Jul 28, 8:16 am, samwyse <[EMAIL PROTECTED]> wrote:
> I just upgraded from 2.4.something to 2.5.1.  I get the stuff below.
> I tried easy-installing pywin32; same results.  Anyone know what's
> going on?
>

Interestingly enough, this works:

C:\Python25>path=%path%;C:\Python25\Lib\site-packages\pywin32-210-
py2.5-win32.eg
g\pywin32_system32

C:\Python25>python
Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32file
>>>

It looks like the system search path isn't getting updated so that
PYWINTYPES25.DLL can be found when win32file.pyd is loaded.

Anyone have any ideas?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python 2.5.1 can't find win32file?

2007-07-29 Thread samwyse
On Jul 28, 12:14 pm, Jay Loden <[EMAIL PROTECTED]> wrote:
> samwyse wrote:
> > Interestingly enough, this works:
>
> > C:\Python25>path=%path%;C:\Python25\Lib\site-packages\pywin32-210-
> > py2.5-win32.eg
> > g\pywin32_system32
>
> > C:\Python25>python
> > Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
> > (Intel)] on win32
> > Type "help", "copyright", "credits" or "license" for more information.
> >>>> import win32file
>
> > It looks like the system search path isn't getting updated so that
> > PYWINTYPES25.DLL can be found when win32file.pyd is loaded.
>
> > Anyone have any ideas?
>
> If you just want to update your PATH, you can do that from My Computer -> 
> Properties -> Advanced -> Environment Variables and just update PATH for your 
> user (or all users if you prefer).
>
> -Jay

Well, I was hoping for something a bit more general.  I'd've thought
that anyone loading a DLL would set the Windows path beforehand, and
that it would all be magically taken care of during the installation.
For now, I'm putting this before my 'import' statement:
os.environ['PATH'] += r';C:\Python25\Lib\site-packages\pywin32-210-
py2.5-win32.egg\pywin32_system32'

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: wxPython before MainLoop

2007-08-15 Thread samwyse
Chris Mellon wrote:
> On 8/9/07, Heikki Toivonen <[EMAIL PROTECTED]> wrote:
> 
>>[david] wrote:
>>
>>>I'd like to refresh the display before I start the main loop.

If your window isn't able to interact with the user, then I'd consider 
it a splash screen, no matter if it does look exactly like your main 
application interface.

>>We have this kind of situation in Chandler, where we display and update
>>the splash screen before we enter MainLoop.
>>
[...]
>>3. The splash screen refresh is basically: draw new stuff,
>>self.Layout(), self.Update(), wx.Yield()
>>http://lxr.osafoundation.org/source/chandler/application/Application.py#1421

Looking at the Chandler code suggests a solution to [david]'s original 
problem.  It is possible that, on Windows only, he may need to call 
Update to finish painting the display.

1432 self.Layout()
1433 if wx.Platform == '__WXMSW__':
1434 self.Update()
1435 wx.GetApp().Yield(True)

> wxYield spins the event loop in place. This can have some serious
> consequences if you aren't very careful with your usage, like
> recursively entering event handlers. I generally consider it an
> experts only interface, and avoid it.

I'll confess to being one of those old-school programmers who, back in 
the day, wrote his code around big select loops instead of using 
threads, but I'm intriged by the "experts only" designation.  Can 
someone explain further?  Thanks!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: clarification

2007-08-17 Thread samwyse
Scott David Daniels wrote:
>   lefts = set()
>   rights = set()
>   with open('sheet1', 'r') as fh:
>   for line in fh:
>   trimmed = line.strip()
>   if trimmed: # Skip blanks (file end often looks like that)
>   left, right = line.strip().split('\t')
>   lefts.add(left)
>   rights.add(right)
>   result = lefts & rights
> 
> -Scott

   # change to however many columns may later exist
   cols = [ set() for i in range(0, 2) ]
   with open('sheet1', 'r') as fh:
   for line in fh:
   for col, data in zip(cols, line.strip().split('\t')):
   col.add(data)
   result = cols[0] & cols[1]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: unexpected optparse set_default/set_defaults behavior

2007-08-18 Thread samwyse
[EMAIL PROTECTED] wrote:
> Some rather unexpected behavior in the set_default/set_defaults
> methods for OptionParser that I noticed recently:
[...]
> Why does set_default not raise an exception when passed a key that it
> doesn't recognize?
> 
> Bad typysts bewaer.
> 
> The only reason I can think not to raise an exception is so that
> defaults can be defined before the options are added. Is there some
> use case that I'm not thinking of here? I realize that changing this
> could break some existing scripts, but I'm still tempted to file this
> as a bug.

If you file it as a bug then I can assure you that you'll be told of a 
long list of use-cases that depend on that feature.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: clarification

2007-08-18 Thread samwyse
samwyse wrote:
> Scott David Daniels wrote:
> 
>>   lefts = set()
>>   rights = set()
>>   with open('sheet1', 'r') as fh:
>>   for line in fh:
>>   trimmed = line.strip()
>>   if trimmed: # Skip blanks (file end often looks like that)
>>   left, right = line.strip().split('\t')
>>   lefts.add(left)
>>   rights.add(right)
>>   result = lefts & rights
>>
>> -Scott
> 
> 
>   # change to however many columns may later exist
>   cols = [ set() for i in range(0, 2) ]
>   with open('sheet1', 'r') as fh:
>   for line in fh:
>   for col, data in zip(cols, line.strip().split('\t')):
>   col.add(data)
>   result = cols[0] & cols[1]

My laptop started complaining about low power before I was really 
finished with this last night, so I just hit Send and went to bed.  The 
last line really should be:
result = reduce(operator.and_, cols)

I'll note that using 'zip' transparently deals with handling those cases 
where there are either more or fewer columns of data than expected.

Finally, does anyone familar with P3K know how best to do the reduction 
without using 'reduce'?  Right now, sets don't support the 'add' and 
'multiply' operators, so 'sum' and (the currently ficticious) 'product' 
won't work at all; while 'any' and 'all' don't work as one might hope. 
Are there an 'intersection' and 'union' built-ins anywhere?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: clarification

2007-08-19 Thread samwyse
Alex Martelli wrote:

> Of course, hoisting the unbound method out of the loops can afford the
> usual small optimization.  But my point is that, in Python, these
> operations (like, say, the concatenation of a sequence of lists, etc)
> are best performed "in place" via loops calling mutator methods such as
> update and intersection_update (or a list's extend, etc), rather than
> "functionally" (building and tossing away many intermediate results).
> E.g., consider:
> 
> brain:~ alex$ python -mtimeit -s'sos=[set(range(x,x+4)) for x in
> range(0, 100, 3)]' 'r=set()' 'for x in sos: r.update(x)'
> 10 loops, best of 3: 18.8 usec per loop
> 
> brain:~ alex$ python -mtimeit -s'sos=[set(range(x,x+4)) for x in
> range(0, 100, 3)]' 'r=reduce(set.union, sos, set())'
> 1 loops, best of 3: 87.2 usec per loop
> 
> Even in a case as tiny as this one, "reduce" is taking over 4 times
> longer than the loop with the in-place mutator -- and it only gets
> worse, as we're talking about O(N squared) vs O(N) performance!  Indeed,
> this is part of what makes reduce an "attractive nuisance"...;-).  [[And
> so is sum, if used OTHERWISE than for the documented purpose, computing
> "the sum of a sequence of numbers": a loop with r.extend is similarly
> faster, to concatenate a sequence of lists, when compared to sum(sol,
> [])...!!!]]

Curiously, when I attempt the actual problem at hand (set intersection) 
rather than something altogether different (set union) on my Dell laptop 
running Win2K Pro, I get the following results:

stmt = 'r=reduce(set.intersection, los)'
best of 3: 21.9 usec per loop
stmt = 'r=intersect_all(los)'
best of 3: 29.3 usec per loop

So, the "nuisance" is more attractive than you thought.  Apparently, one 
can't really depend on "in place" mutator methods being more efficient 
that using functional techniques.  BTW, the above figures reflect 10,000 
iterations; using larger counts makes the difference even larger.  I 
suspect that this is because the Python interpreter has fewer chances to 
be interrupted by external processes when it's using 'reduce'.  This in 
turn indicates that both implementations actually work about same and 
your "O(n squared)" argument is irrelevant.

P.S. Here's the source I used for the timings:

from timeit import Timer

setup = """
def intersect_all(los):
 it = iter(los)
 result = set(it.next())
 for s in it: result.intersection_update(s)
 return result

not7=range(2,11)
not7.remove(7)
los=[set(range(0,360,step)) for step in not7]
"""

number = 1
repeat = 3
precision = 3

for stmt in 'r=reduce(set.intersection, los)', 'r=intersect_all(los)':
 t = Timer(stmt, setup)
 r = t.repeat(repeat, number)
 best = min(r)
 usec = best * 1e6 / number
 print "stmt =", repr(stmt)
 print "best of %d: %.*g usec per loop" % (repeat, precision, usec)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Symbolic Link

2007-08-19 Thread samwyse
mosscliffe wrote:
> I am trying to create a link to a file, which I can then use in an
> HTML page.
> 
> The system is Linux on a hosted web service, running python 2.3.
> Other than that I have no knowledge of the system.
> 
> The link is created OK, but when I try to use it as filename for the
> IMG TAG, it does not get displayed.  The page source of the created
> page is pointing to the link as temp/test1.jpg

What are you trying to do that you can't use the original file instead 
of creating a link?  There might be a way to side-step the entire problem.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Parser Generator?

2007-08-19 Thread samwyse
Jack wrote:
> Thanks for all the replies!
> 
> SPARK looks promising. Its doc doesn't say if it handles unicode
> (CJK in particular) encoding though.
> 
> Yapps also looks powerful: http://theory.stanford.edu/~amitp/yapps/
> 
> There's also PyGgy http://lava.net/~newsham/pyggy/
> 
> I may also give Antlr a try.
> 
> If anyone has experiences using any of the parser generators with CJK
> languages, I'd be very interested in hearing that.

I'm going to echo Tommy's reply.  If you want to parse natural language, 
conventional parsers are going to be worse than useless (because you'll 
keep thinking, "Just one more tweak and this time it'll work for 
sure!").  Instead, go look at what the interactive fiction community 
uses.  They analyse the statement in multiple passes, first picking out 
the verbs, then the noun phrases.  Some of their parsers can do 
on-the-fly domain-specific spelling correction, etc, and all of them can 
ask the user for clarification.  (I'm currently cobbling together 
something similar for pre-teen users.)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Searching for pixel color

2007-08-19 Thread samwyse
michael maver wrote:
> Hello, I was just wondering if anyone knew of a way to search the screen 
> for a certain color in Python.

I know of lots of ways to do this...

> I know it is possible to do this in other languages, but I'm not sure 
> how I'd go about doing this in Python. Just to let you know, I'm running 
> windows XP and I don't really need it to be a cross platform solution, 
> but if it was that'd be an extra bonus.

... but they are all platform dependent; not just Windows vs Unix, but 
PIL vs wxWin vs whatever.

def search_screen(desired_color):
   root = my_gui.root_window()
   width, height = root.get_size()
   for x in xrange(0, width):
 for y in xrange(0, height):
   if root.get_pixel(x,y) == desired_color:
 return x,y
   return -1, -1

Modify the above using the appropriate values for 'my_gui' and its 
methods, 'root_window', 'get_size' and 'get_pixel'.

 > Thanks very much for taking the time to read this and, hopefully, 
respond!

You're welcome.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 1)URL QueryString Parsing 2)Search Engine Spiders

2007-08-19 Thread samwyse
mosscliffe wrote:
> I am trying to create a back link, equivalent to the browser back
> action and I can not use java script. The target user does not allow
> java script.
> 
> I am using HTTP_REFERER.
> 
> I need to add the original Query String values.
> 
> Is there a way to get the QueryString element other than by using
> cgi.FieldStorage, as I just want to return with the values that were
> current in the calling page.
> 
> gv.orgQueryString = ""
> 
> gv.BackButton = ' gv.orgQueryString + '">BACK'

I'm not sure I understand your problem.  Does the above code not work?

> Am I right in thinking Search Engine Spiders will never see my script
> pages as they exist only for the duration of the python script's
> execution ?  And even then as they are   xxx.py, they would not be
> seen.

Anyone who accesses your web server will see the pages that you serve. 
If you serve the xxx.py files, then they can be seen and indexed, 
otherwise they are invisible.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Development for dual core machine

2007-08-19 Thread samwyse
Andy wrote:
> Hi guys,
> 
> I'm sorry, I'm not sure this is the correct group to be asking this
> kind of question...
> 
> I'm going to develop a software package that includes a web server
> (and PHP code) , a database, and some Python code of course.  I am
> being strongly suggested to make it to work on a dual- or multi-core
> computer, but I'm confused on how to take advantage of the multiple
> CPUs.
> 
>>From what I read, I think that simply by making the package run in
> several separate processes (web server, database server, Python
> interpreter, etc.), and/or using multiple threads (which I will
> anyway) the package should be able to use multiple CPUs.
> 
> Is my understanding correct?  So actually, all I have to do is just
> write my multi-threaded Python code as usual?  And how is it decided
> which process and which threads go to CPU 1, CPU 2, etc.?  Perhaps the
> BIOS?
> 
> Any advice greatly appreciated.
> Andy
> 

The Python interpreter is not multi-cpu aware, so using Python threads 
won't work on multiple CPUs.  If your tasks are CPU-bound, then fork 
multiple processes.  Most web servers (Apache) can handle this 
automatically for you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Symbolic Link

2007-09-09 Thread samwyse
mosscliffe wrote:
> On 22 Aug, 00:05, Ian Clark <[EMAIL PROTECTED]> wrote:
>>
>>>On Aug 19, 4:29 pm,mosscliffe<[EMAIL PROTECTED]> wrote:
>>>
The source file is in an area which python can see, but not the
browser.  I am trying to make a link in a browser friendly area so I
can use it to display an image file.
>>
>>My question would be why a symbolic link? Why not a hard link? Are the
>>two directories on different mount points? After the script finishes
>>does python need to see that image file again? Why not just move it?
> 
> I have tested a hard link now and it seems to work fine.  I am
> deleting the link/s at the end of the session/s.

This is a bit late, but the reason the symbolic link won't work is 
because it's the web-server that's resolving it.  The browser can only 
see things that the web-server, huh, serves, so what was meant in the 
first paragraph above was that the web server couldn't access the file 
in its original location.  If you create a sym-link, the web server 
opens the link, finds out the actual location of the file, and tries to 
open that file, which it still can't do.  A hard-link, OTOH, allows 
direct access to the contents of a file, as long as it is on the same 
filesystem.  No extra steps are required, so the process runs a few 
microseconds faster, and directory-level permissions can't get in the way.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Symbolic Link

2007-10-10 Thread samwyse
On Sep 9, 10:05 pm, Lawrence D'Oliveiro <[EMAIL PROTECTED]
central.gen.new_zealand> wrote:
> In message <[EMAIL PROTECTED]>,samwysewrote:
>
> > A hard-link, OTOH, allows
> > direct access to the contents of a file, as long as it is on the same
> > filesystem.  No extra steps are required, so the process runs a few
> > microseconds faster, and directory-level permissions can't get in the way.
>
> Hard links are best avoided, because of the confusion they can cause.

There are reasons to use hard links, there are reasons to use symbolic
links.  Depending on the circumstances, either could "cause confusion"
simply because either could do something other than what's needed.
Here's a handy chart to help decide which is appropriate:
http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/ifs/rzaaxmstlinkcmp.htm

-- 
http://mail.python.org/mailman/listinfo/python-list


BaseHTTPServer issues

2007-11-23 Thread samwyse
I've just now submitted two issues to the issue tracker:


1491BaseHTTPServer incorrectly implements response code 100

RFC 2616 sec 8.2.3 states, "An origin server that sends a 100
(Continue) response MUST ultimately send a final status code, once the
request body is received  and processed, unless it terminates the
transport connection prematurely."  The obvious way to do this is to
invoke the 'send_response' method twice, once with a code of 100, then
with the final code.  However, BaseHTTPServer will always send two
headers ('Server' and 'Date') when it send a response.  One possible
fix is to add an option to the method to suppress sending headers;
another is to add the following code to the 'send_response' method,
immediately prior to the calls to 'self.send_header':

if code == 100:
return

The more paranoid among us may wish to use this code instead:

if code == 100:
expectation = self.headers.get('Expect', "")
if expectation.lower() == '100-continue':
return


1492BaseHTTPServer hard-codes Content-Type for error messages

The send_error method always sends a Content-Type of 'text/html'.
Other content types are both possible and desirable.  For example,
someone writing a REST server might wish to send XML error messages.
Following the example of DEFAULT_ERROR_MESSAGE, I propose adding the
following in the appropriate places:

91a92,94
> # Default error content-type
> DEFAULT_ERROR_TYPE = 'text/html'
>
345c348
< self.send_header("Content-Type", "text/html")
---
> self.send_header("Content-Type", error_message_type)
351a355
> error_message_type = DEFAULT_ERROR_TYPE
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: the annoying, verbose self

2007-11-24 Thread samwyse
On Nov 23, 7:16 pm, "Patrick Mullen" <[EMAIL PROTECTED]> wrote:
> Most of the time self doesn't bother me in the slightest.  The one
> time it does bother me however, is when I am turning a function into a
> method.  In this case, often I have many local variables which I
> actually want to be instance variables, so I have to add self to all
> of them.  Of course, this is going to cause me some grief no matter
> which language I am using.  If it was enough trouble, it wouldn't be
> hard to make a filter that converts my code automatically.

I've had the same thought, along with another.  You see, on of my pet
peeves about all OO languages that that when creating new code, I
generally begin by writing something like this:

cat = 'felix'
dog = 'rover'
def example():
  global cat, dog  # not always required, but frequently needed
  return ', '.join((cat, dog))

Later, I inevitably decide to encapsulate it inside a class, which
means lots of source changes to change my function into a method:

class my_pets:
  cat = 'felix'
  dog = 'rover'
  def example(self):
return ', '.join((self.cat, self.dog))

My idea is to introduce syntax that treats top-level functions as
methods of a global, anonymous, class:

cat = 'felix'
dog = 'rover'
def example():
  return ', '.join((.cat, .dog))

(btw, we'll also stop auto-magically recognizing global variables
inside functions, forcing the use of the '.' in global names.)  Thus,
to convert the above into a class, we just need to add one line and
alter the indentation:

class my_pets:
  cat = 'felix'
  dog = 'rover'
  def example():  # anonymous 'self' is implicit inside class defs.
return ', '.join((.cat, .dog))

You'd need someway to refer to higher lexical levels, possibly by
chaining periods; this would break ellipsis but that could be replaced
by a keyword such as 'to'.  And you'd probably want to keep 'global',
but as a keyword for those rare cases where you need to force a
reference to the outer-most lexical level:

warming = 42
def generator(factiod):
def decorator(func):
def wrapper(*args, **kwds):
if ..factoid == None:
  return .func(*args, **kwds)
else:
  return ..factoid + global.warming
return wrapper
return decorator


-- 
http://mail.python.org/mailman/listinfo/python-list


setting attributes on external types (was Re: eof)

2007-11-24 Thread samwyse
On Nov 23, 2:06 am, greg <[EMAIL PROTECTED]> wrote:
> There's a fair amount of overhead associated with providing
> the ability to set arbitrary attributes on an object, which
> is almost never wanted for built-in types, so it's not
> provided by default.
>
> You can easily get it if you want it by defining a Python
> subclass of the type concerned.

Speaking of which, I've got a big file:

>>> input = open('LoTR.iso')

I'd like to get the md5 hash of the file:

>>> import md5
>>> m = md5.new()

I've also got this nifty standard module which will allow me, among
other things, to copy an arbitrary file:

>>> import shutil

I'd like to say copy the file to my object, but it doesn't quite work:

>>> shutil.copyfileobj(input, m)

Traceback (most recent call last):
  File "", line 1, in 
shutil.copyfileobj(source, m)
  File "C:\Python25\lib\shutil.py", line 24, in copyfileobj
fdst.write(buf)
AttributeError: '_hashlib.HASH' object has no attribute 'write'

No problem, I'll just add an attribute:

>>> setattr(m, 'write', m.update)
Traceback (most recent call last):
  File "", line 1, in 
setattr(m, 'write', m.update)
AttributeError: '_hashlib.HASH' object has no attribute 'write'

Anyone have an example of how to efficiently do this?  Thanks!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: the annoying, verbose self

2007-11-24 Thread samwyse
On Nov 24, 4:07 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote:
> On Sat, 24 Nov 2007 01:55:38 -0800, samwyse wrote:
> > I've had the same thought, along with another.  You see, on of my pet
> > peeves about all OO languages that that when creating new code, I
> > generally begin by writing something like this:
>
> > cat = 'felix'
> > dog = 'rover'
> > def example():
> >   global cat, dog  # not always required, but frequently needed
> >   return ', '.join((cat, dog))
>
> Ouch that's bad design IMHO.  The need to use ``global`` is a design
> smell, if needed *frequently* it starts to stink.

I'm not sure what you mean.  In the example that I gave, the 'global'
statement isn't needed.  However, here's a different example:

>>> top_score = 0
>>> def leaderboard(my_score):
  if my_score > top_score:
print "A new high score!"
top_score = myscore
  print "Top score:", top_score

Traceback (most recent call last):
  File "", line 1, in 
leaderboard(7, 'samwyse')
  File "", line 2, in leaderboard
if my_score > top_score:
UnboundLocalError: local variable 'top_score' referenced before
assignment
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How can I create customized classes that have similar properties as 'str'?

2007-11-24 Thread samwyse
On Nov 24, 5:44 am, Licheng Fang <[EMAIL PROTECTED]> wrote:
> Yes, millions. In my natural language processing tasks, I almost
> always need to define patterns, identify their occurrences in a huge
> data, and count them. [...] So I end up with unnecessary
> duplicates of keys. And this can be a great waste of memory with huge
> input data.

create a hash that maps your keys to themselves, then use the values
of that hash as your keys.

>>> store = {}
>>> def atom(str):
global store
if str not in store:
store[str] = str
return store[str]

>>> a='this is confusing'
>>> b='this is confusing'
>>> a == b
True
>>> a is b
False
>>> atom(a) is atom(b)
True
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: the annoying, verbose self

2007-11-24 Thread samwyse
On Nov 24, 7:50 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote:
> On Sat, 24 Nov 2007 02:54:27 -0800, samwyse wrote:
> > On Nov 24, 4:07 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote:
> >> On Sat, 24 Nov 2007 01:55:38 -0800, samwyse wrote:
> >> > I've had the same thought, along with another.  You see, on of my pet
> >> > peeves about all OO languages that that when creating new code, I
> >> > generally begin by writing something like this:
>
> >> > cat = 'felix'
> >> > dog = 'rover'
> >> > def example():
> >> >   global cat, dog  # not always required, but frequently needed
> >> >   return ', '.join((cat, dog))
>
> >> Ouch that's bad design IMHO.  The need to use ``global`` is a design
> >> smell, if needed *frequently* it starts to stink.
>
> > I'm not sure what you mean.  In the example that I gave, the 'global'
> > statement isn't needed.  However, here's a different example:
>
> I mean that global names that are (re)bound from within functions couple
> these functions in a non-obvious way and make the code and data flow harder
> to follow and understand.  Also it makes refactoring and testing more
> difficult because of the dependencies.

The whole point of this sub-thread is the difficulty of turning global
vars and functions into class vars and functions, and that is
something that is usually done precisely because the code and data
flow has become harder to follow and understand.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: the annoying, verbose self

2007-11-24 Thread samwyse
On Nov 24, 10:07 am, Duncan Booth <[EMAIL PROTECTED]>
wrote:
> Ton van Vliet <[EMAIL PROTECTED]> wrote:
>
> > It would boil down to choice: explicit/speed vs implicit/readability
>
> No, it would boil down to explicit+speed+readability+maintainability vs
> implicit+error prone.
>
> It would mean that as well as the interpreter having to search the
> instance to work out whether each name referenced an attribute or a global
> the reader would also have to perform the same search. It would mean that
> adding a new attribute to an instance would change the meaning of the
> methods which is a recipe for disaster.

Besides Pascal, Visual Basic also offers a 'with' statement that
behaves almost in this way.  That in itself should be an indication
that the whole thing is a bad idea.  ;-)

The way it works, however, is that you do have to prefix members with
a '.' and the interpreter tries to bind with each nested 'with'
variable in turn.  It's tolerable with one 'with' statment, but once
you start nesting them it becomes dangerous.

My idea in a parallel thread is to treat a '.' prefix like '../' in
file paths; each one moves you up a level in the symbol table.  In a
top-level function, it means a global name; in a class method it means
a member.  The @classmethod and @staticmethod decorators would need to
fix things so that '.' refers to the appropriate things.  There's no
reason why a 'using' statement couldn't perform nesting as well:  '.'
refers to the 'using' variable, '..' refers to what '.' previously
referred to, etc.

OTOH, the point of 'using' is to reduce typing, so you might instead
add 'as' clauses as an alternate way to reduce confusion:

>>> using myclass.new() as p:
p.do_something()
p.something_else()

Of course, now its starting to look more like a Python 'with'
statement, and I think there's a way to do basically this already.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How can I create customized classes that have similar properties as 'str'?

2007-11-24 Thread samwyse
On Nov 24, 10:35 am, Licheng Fang <[EMAIL PROTECTED]> wrote:
> Thanks. Then, is there a way to make python treat all strings this
> way, or any other kind of immutable objects?

The word generally used is 'atom' when referring to strings that are
set up such that 'a == b' implies 'a is b'.  This is usually an
expensive process, since you don't want to do it to strings that are,
e.g., read from a file.  Yes, it could be done only for string
constants, and some languages (starting with LISP) do this, but that
isn't what you (or most people) want.  Whether you realize it or not,
you want control over the process; in your example, you don't want to
do it for the lines read from your file, just the trigrams.

The example that I gave does exactly that.  It adds a fixed amount of
storage for each string that you 'intern' (the usual name given to the
process of generating such a string.  Let's look at my code again:

>>> store = {}
>>> def atom(str):
global store
if str not in store:
store[str] = str
return store[str]

Each string passed to 'atom' already exists.  We look to see if copy
already exists; if so we can discard the latest instance and use that
copy henceforth.  If a copy does not exist, we save the string inside
'store'.  Since the string already exists, we're just increasing its
reference count by two (so it won't be reference counted) and
increasing the size of 'store' by (an amortized) pair of pointers to
that same string.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How can I create customized classes that have similar properties as 'str'?

2007-11-24 Thread samwyse
On Nov 24, 5:44 am, Licheng Fang <[EMAIL PROTECTED]> wrote:
> Yes, millions. In my natural language processing tasks, I almost
> always need to define patterns, identify their occurrences in a huge
> data, and count them. Say, I have a big text file, consisting of
> millions of words, and I want to count the frequency of trigrams:
>
> trigrams([1,2,3,4,5]) == [(1,2,3),(2,3,4),(3,4,5)]

BTW, if the components of your trigrams are never larger than a byte,
then encode the tuples as integers and don't worry about pointer
comparisons.

>>> def encode(s):
return (ord(s[0])*256+ord(s[1]))*256+ord(s[2])

>>> def trigram(s):
return [ encode(s[i:i+3]) for i in range(0, len(s)-2)]

>>> trigram('abcde')
[6382179, 6447972, 6513765]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: the annoying, verbose self

2007-11-25 Thread samwyse
On Nov 24, 1:10 pm, "Patrick Mullen" <[EMAIL PROTECTED]> wrote:
> If there were a "using" or if the with statement would handle
> something like this, I wouldn't use it.  "s." is only 2 characters.  I
> saw chained dots mentioned.  Chained dots are 2 characters.  Why are
> we still discussing this?  "s." is the answer, or pulling the
> attributes into local vars if you are going to use them many times, to
> save lookup.  This is not a band-aid, this is an actual valid
> programming technique.  There is more to programming than typing...

Actually, the chained dots are solving a completely different problem,
that of refactoring a collection of functions that use global vars
into a class.

Although I'm now wondering if I could jigger something together using
globals() to make a top-level self-like object.  Hmmm, maybe someting
like this:

>>> class GlobalSelf(object):
def __init__(self):
self.__dict__ = globals()

>>> x = 42
>>> def myfunc(*args):
"something that I may want to refactor later"
s = GlobalSelf()
s.x += 1

>>> x
42
>>> myfunc()
>>> x
43
-- 
http://mail.python.org/mailman/listinfo/python-list


__iadd__ useless in sub-classed int

2007-12-06 Thread samwyse
For whatever reason, I need an inproved integer.  Sounds easy, let's
just subclass int:

>>> class test(int):
pass

Now let's test it:

>>> zed=test(0)
>>> zed.__class__

>>> zed
0

So far, so good.  Now let's try incrementing:

>>> zed+=1
>>> zed
1
>>> zed.__class__


WTF??!
Is this a bug or is it the inevitable result of optimizing for the
case where all integers are indistinguishable?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How can I create customized classes that have similar properties as 'str'?

2007-12-06 Thread samwyse
On Nov 24, 6:38 pm, Hrvoje Niksic <[EMAIL PROTECTED]> wrote:
> samwyse <[EMAIL PROTECTED]> writes:
> > create a hash that maps your keys to themselves, then use the values
> > of that hash as your keys.
>
> The "atom" function you describe already exists under the name
> "intern".

D'oh!  That's what I get for not memorizing "Non-essential Built-in
Functions".

In my defense, however, my function will work with anything that can
be used as a dictionary key (strings, tuples, frozen sets, etc), not
just character strings; thus we return to the original:

>>> a=(1,2,3)
>>> b=(1,1+1,1+1+1)
>>> a == b
True
>>> a is b
False
>>> atom(a) is atom(b)
True
>>> intern(a) is intern(b)
Traceback (most recent call last):
  File "", line 1, in ?
intern(a) is intern(b)
TypeError: intern() argument 1 must be string, not tuple
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: __iadd__ useless in sub-classed int

2007-12-06 Thread samwyse
On Dec 6, 1:12 pm, "Diez B. Roggisch" <[EMAIL PROTECTED]> wrote:
> samwyse schrieb:
>
> > For whatever reason, I need an inproved integer.  Sounds easy, let's
> > just subclass int:
>
> >>>> class test(int):
> >pass
>
> > Now let's test it:
>
> >>>> zed=test(0)
> >>>> zed.__class__
> > 
> >>>> zed
> > 0
>
> > So far, so good.  Now let's try incrementing:
>
> >>>> zed+=1
> >>>> zed
> > 1
> >>>> zed.__class__
> > 
>
> > WTF??!
> > Is this a bug or is it the inevitable result of optimizing for the
> > case where all integers are indistinguishable?
>
> There has been a lengthe thread over the semantics of __iadd__ a few
> weeks ago. It _can_ modify the object in question in-place (something
> not possible for ints anyway), but it will ALWAYS return a reference
> which will be set to the left-hand-side.

Thanks!  I'd missed that thread, googling found it but it didn't look
noteworthy at first glance.  I've not yet read the entire thread, but
I did see a reference to PEP 203.

)So, given the expression:
)
)  x += y
)
)The object `x' is loaded, then `y' is added to it, and the
)resulting object is stored back in the original place.

That agrees with what I'm seeing, all right.  The problem is, the
resulting object has a different type, which seems to violate the
spirit of a later paragraph:

)Writing the above expression as
)
) = 
)
)is both more readable and less error prone, because it is
)instantly obvious to the reader that it is  that is being
)changed, and not  that is being replaced by something almost,
)but not quite, entirely unlike .

And that's my complaint.  The value in  is being replaced by
something almost, but not quite, identical to the original value.
Python's internal implementation of __iadd__ for  isn't returning
, it's returning a new value belonging to the super-class.  My
whole point is overloading  was that I'd hoped to avoid having to
write a bunch of methods to perform in-place modifications.  Looks
like I stuck, however.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Terminology: "script" versus "program"

2008-01-24 Thread samwyse
Ben Finney wrote:
> George Sakkis <[EMAIL PROTECTED]> writes:
> 
> 
>>On Jan 23, 8:14 pm, [EMAIL PROTECTED] wrote:
>>
>>>The annual Linux Journal survey is online now for any Linux users
>>>who want to vote for Python.
>>>http://www.linuxjournal.com/node/1006101
>>
>>...
>>18. What is your favorite programming language?
>>(15 choices, Python not included)
>>
>>19. What is your favorite scripting language?
>>o Python
>>o Perl
>>(5 more choices)
>>
>>Python is much more than a "scripting language" (whatever this
>>means, other than a semi-derogatory term used by clueless PHBs).
>>Sorry, I'll pass.
> 
> 
> I agree entirely.
> 
> The term "script" has the strong connotation of a limited-purpose
> program designed to solve a problem expressed almost entirely as a
> simple series of steps. Languages that are often used to write such
> scripts are usually referred to as "scripting languages", which
> becomes a denigration because such a language need not have support
> for much else.

I strongly disagree with your interpretation.  Scritping languages 
provide high-level facilites for process control.  Historically, they 
were purely interpretive but now they tend to compile to some sort of 
byte code.  Examples include the various shells, Rexx, and various 
languages whose names start with "P".  Languages which only express a 
"series of steps" are generally called batch languages.  I've never 
heard anyone refer to a .BAT file as a script.

In scripting languages, speed of execution is often less important than 
speed of implementation.  When speed of execution is important, it is 
easier to invoke an external module than to patch or rewrite the 
interpreter.  In Python, PERL and BASH, these modules can be dynamically 
linked libraries as well as stand-alone executables.

Finally, the provided process control facilities are often generalized 
into quite powerful support for "programming in the large", especially 
both object-oriented and functional programming.  This leads to supprot 
for a much broader set of practices and solutions than any mere 
programming language can easily provide.

The only drawback I've ever found to this is that it's easy to 
accidentally use huge amounts of memory, for instance by 'slurping' 
files into memory in a single command.

 > This term seems quite prevalent among the Python core developers,
 > unfortunately. The 'distutils' module even has the term 'script' used
 > in its interface, to refer to the programs that are to be distributed.

Apparently the core developers agree with my interpretation, not yours.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python noob SOS (any [former?] Perlheads out there?)

2008-02-02 Thread samwyse
kj wrote:
> I'd written a Perl module to facilitate the writing of scripts.
> It contained all my boilerplate code for parsing and validating
> command-line options, generating of accessor functions for these
> options, printing of the help message and of the full documentation,
> testing, etc.

A lot of people seem to have gotten hung up on this paragraph.  kj 
remarks in one reply that he *does* use optparse, but there still seems 
to be much confusion.  I've long done something similar, so I'll attempt 
to clarify.  For most of the programming languages that I use, my first 
exercise is to write a program that accepts a 'getopt' string and 
creates a program around it.  Here's a simple version that I just 
whipped out; the version that I commonly use is a bit more complicated.

"""%s [-h] [optionstring]

The program generates boilerplate for a Python script. It accepts a
single argument consisting of a string of option letters that you
wish the script to recognize, with options that require an argument
followed by a colon (i.e., the same format that Unix getopt() uses).

Written by samwyse
Created on Feb 02, 2008
"""

import sys
import getopt

class UserError(Exception):
 def __init__(self, msg):
 self.msg = msg

class Usage(UserError):
 pass

def main(argv=None):
 if argv is None:
 argv = sys.argv
 # parse command line options
 try:
 try:
 opts, args = getopt.getopt(argv[1:], "h")
 except getopt.error, msg:
  raise Usage(msg)
 # process options
 for o, a in opts:
 if o == '-h':
 print __doc__ % argv[0]
 return 0
 except UserError, err:
 print >>sys.stderr, err.msg
 print >>sys.stderr, "for help use --help"
 if type(err) is Usage:
 return 2
 else:
 return 1

 # process arguments
 for arg in args:
 # process() is defined elsewhere
 process(arg)

#######

def process(shortopts):
 from time import strftime

 prolog = '''\
"""Module docstring.

This serves as a long usage message.

Written by %(author)s
Created on %(date)s
"""

import sys
import getopt

class UserError(Exception):
 def __init__(self, msg):
 self.msg = msg

class Usage(UserError):
 pass

def main(argv=None):
 if argv is None:
 argv = sys.argv
 # parse command line options
 try:
 try:
 opts, args = getopt.getopt(argv[1:], "%(opts)s")
 except getopt.error, msg:
  raise Usage(msg)
 # process options
 for o, a in opts:'''

 has_arg = '''\
 if o == '-%(opt)s':
 opt_%(opt)s = a'''

 no_arg = '''\
 if o == '-%(opt)s':
 opt_%(opt)s = True'''

 epilog = '''\
 except UserError, err:
 print >>sys.stderr, err.msg
 print >>sys.stderr, "for help use --help"
 if type(err) is Usage:
 return 2
 else:
 return 1

 # process arguments
 for arg in args:
 # process() is defined elsewhere
 process(arg)

if __name__ == "__main__":
 sys.exit(main())
'''

 values = {
 'date': strftime('%b %d, %Y'),
 'author': 'samwyse',
 'opts': shortopts
 }
 print prolog % values
 for i in range(len(shortopts)):
 c = shortopts[i]
 if c != ':':
 if shortopts.startswith(':', i+1):
 print has_arg % { 'opt': c }
 else:
 print no_arg % { 'opt': c }
 print epilog % values

#######

if __name__ == "__main__":
 sys.exit(main())
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Does anyone else use this little idiom?

2008-02-03 Thread samwyse
[EMAIL PROTECTED] wrote:
> My apologies if any attributions are messed up.
> 
> On Feb 3, 1:28 am, Steven D'Aprano <[EMAIL PROTECTED]
> cybersource.com.au> wrote:
> 
>>If you want an explicit name, try a variation of "dontcare". Assuming
>>that you're an English speaker.

I'm with Steven here.  I typically use 'dontcare' or 'ignore', or 
occasionally 'asdf'.  I also tend to use variables whose name-length is 
proportional to the size of their scope.

> I'd really
> prefer something like the Ruby syntax because all you have to write is
> the number of times you want to do something, and then the thing you
> want to do.  (I guess, in that respect, I'd even consider the xrange
> call a redundancy.)

I'd like to see a '..' operator that does what 'xrange' does, but I'm 
not going to hold my breath.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sharing/swapping items between lists

2009-04-15 Thread samwyse
On Apr 14, 7:01 pm, Aaron Brady  wrote:
> Here is an idea.  Create a list of all possible pairs, using
> itertools.combinations.  You'll notice everyone gets equal play time
> and equal time against each other on a pair-by-pair basis.  Then, call
> random.shuffle until one player isn't playing on two courts in one
> day.
>
> It has the disadvantage that you might end up with player A playing
> lots early on and rarely at the end, and B rarely early on and lots at
> the end.  Perhaps you could generate a few to several correct
> solutions, then choose the most evenly distributed.  Does this make
> sense?

Here's my idea:  generate all possible pairs:
>>> import itertools
>>> players = [chr(c) for c in xrange(ord('a'),ord('z')+1)]
>>> all_pairs = list(itertools.combinations(players,2))

partition the list:
>>> def choose_nonoverlapping(pairs):
chosen, leftover, used = list(), list(), list()
for p in pairs:
a, b = p
if a in used or b in used:
leftover.append(p)
else:
chosen.append(p)
used.append(a)
used.append(b)
return chosen, leftover

>>> court_count = 10
>>> week_count = 10
>>> pairs = all_pairs
>>> for week in xrange(week_count):
print 'week', week+1
this_week, pairs = choose_nonoverlapping(pairs)
print ', '.join(map(lambda t: ' vs '.join(t), this_week
[:court_count]))
pairs[0:0] = this_week[court_count:]


week 1
a vs b, c vs d, e vs f, g vs h, i vs j, k vs l, m vs n, o vs p, q vs
r, s vs t
week 2
u vs v, w vs x, y vs z, a vs c, b vs d, e vs g, f vs h, i vs k, j vs
l, m vs o
week 3
n vs p, q vs s, r vs t, a vs d, b vs c, e vs h, f vs g, i vs l, j vs
k, m vs u
week 4
o vs v, w vs y, x vs z, a vs e, b vs f, c vs g, d vs h, i vs m, j vs
n, k vs p
week 5
l vs q, r vs s, t vs u, a vs f, b vs e, c vs h, d vs g, i vs n, j vs
m, k vs o
week 6
p vs v, w vs z, x vs y, a vs g, b vs h, c vs e, d vs f, i vs o, j vs
q, k vs m
week 7
l vs n, r vs u, a vs h, b vs g, c vs f, d vs e, i vs p, j vs o, k vs
q, m vs s
week 8
t vs v, a vs i, b vs j, c vs k, d vs l, e vs m, f vs n, g vs o, h vs
p, q vs u
week 9
r vs w, s vs x, a vs j, b vs i, c vs l, d vs k, e vs n, f vs m, g vs
p, h vs o
week 10
q vs t, u vs y, v vs z, a vs k, b vs l, c vs i, d vs j, e vs o, f vs
p, g vs m
--
http://mail.python.org/mailman/listinfo/python-list


Re: sharing/swapping items between lists

2009-04-15 Thread samwyse
On Apr 15, 8:13 am, Aaron Brady  wrote:
> On Apr 15, 6:57 am, samwyse  wrote:
>
> > Here's my idea:  generate all possible pairs:
>
> > >>> import itertools
> > >>> players = [chr(c) for c in xrange(ord('a'),ord('z')+1)]
> > >>> all_pairs = list(itertools.combinations(players,2))
>
> > partition the list:
> > >>> def choose_nonoverlapping(pairs):
> > chosen, leftover, used = list(), list(), list()
> > for p in pairs:
> > a, b = p
> > if a in used or b in used:
> > leftover.append(p)
> > else:
> > chosen.append(p)
> > used.append(a)
> > used.append(b)
> > return chosen, leftover
>
> > >>> court_count = 10
> > >>> week_count = 10
> > >>> pairs = all_pairs
> > >>> for week in xrange(week_count):
> > print 'week', week+1
> > this_week, pairs = choose_nonoverlapping(pairs)
> > print ', '.join(map(lambda t: ' vs '.join(t), this_week
> > [:court_count]))
> > pairs[0:0] = this_week[court_count:]
>
> snip
>
> Your idea arrives at a sub-optimal solution on players= 'abcdef',
> court_count= 3.
>
> Correct, by hand (5 weeks):
>
> ab cd ef
> ac be df
> ad ce bf
> ae bd cf
> af bc de
>
> Program (7 weeks):
>
[snip]
>
> However, you do correctly arrive at all the combinations, in better
> than the naive 'one pair per week' solution.  Further, you produced
> the correct solution for players= 'abcdef', for court_count= 1 and
> court_count= 2, which I also tested.  Damage report?

It does work better when there are a limited number of courts, but
since that was in the original description, I didn't worry too much.

One could product several random shuffles of the list of combinations
and see which produced the shortest list of results.  That would add
indeterminancy without guaranteeing an optimal result.  But I think
that other people have algorithms for that case, so I'm not too
worried.

I've tried generalizing to competitions  with more than two player
(e.g. the Pinewood Derby, where up four cars are in each heat), but
the algorithm falls apart, mostly due to the way
itertools.combinations returns its results.
--
http://mail.python.org/mailman/listinfo/python-list


Re: sharing/swapping items between lists

2009-04-15 Thread samwyse
On Apr 15, 8:56 am, Aaron Brady  wrote:
>
> The randomizing solution isn't quite suitable for 16 teams.  With 5
> teams/1 court, and 5 teams/2 courts, 6 teams/2 courts, the solution
> comes within seconds.  For 7 teams/3 courts, the solution takes a few
> minutes.

7 teams/3 courts is the same as 8 teams/4 courts, where the extra
player is named "bye".  In other words, it's an uncontrained problem.
--
http://mail.python.org/mailman/listinfo/python-list


How do I change the behavior of the 'python-docs' action in IDLE?

2009-04-16 Thread samwyse
In the Windows version of Python 2.5, pressing F1 brought up the
python.chm file.  I've just installed 2.6, and the same action opens
http://www.python.org/doc/current/.  I'd prefer the former behavior.
I know how to change the key bindings in config-keys.def, but I think
I want to change the action, not the key binding.  Thanks.
--
http://mail.python.org/mailman/listinfo/python-list


creating classes with mix-ins

2009-05-11 Thread samwyse
I'm writing a class that derives it's functionality from mix-ins.
Here's the code:

def boilerplate(what):   # This used to be a decorator, but all of
the
##what = f.__name__  # function bodies turned out to be
'pass'.
'Validate the user, then call the appropriate plug-in.'
def template(self, which, username, password, *args):
if not self.security.isAuthorised(username, password,
which, what):
raise Exception('Unauthorised access')
return getattr(self.blog, what)(which, *args)
template.__name__ = what
template.__doc__ = getattr(self.blog, what).__doc__
return template

class MetaWeblog(object):
def __init__(self,
 securityHandler=SimpleSecurityHandler,
 blogHandler=SimpleBlogHandler):
self.security = securityHandler()
self.blog = blogHandler()
newPost = boilerplate('newPost')
editPost = boilerplate('editPost')
getPost = boilerplate('getPost')
# etc, etc, etc

I'd like to replace the method definitions with a loop:
for what in attr_list:
setattr(klass, what, boilerplate(what))

That begs the question of where I define 'klass' and 'attr_list'.
Should I use a class decorator, or a metaclass?  In favor of
decorators is that I can see how to do it; in favor of a metaclass is
that I get to learn how to use them.  ;-)  What are the other pros and
cons for each choice?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: creating classes with mix-ins

2009-05-11 Thread samwyse
On May 11, 1:16 pm, samwyse  wrote:
> I'm writing a class that derives it's functionality from mix-ins.

While waiting, I gave a try at using class decorators.  Here's what I
came up with:

def add_methods(*m_list, **kwds):
def wrapper(klass):
for m_name in m_list:
def template(self, which, username, password, *args):
if not self.security.isAuthorised(username, password,
which, m_name):
raise Exception('Unauthorised access')
return getattr(self.blog, m_name)(which, *args)
dotted_name = kwds.get('prefix', '') + m_name
template.__name__ = dotted_name
template.__doc__ = dotted_name
setattr(klass, dotted_name, template)
return klass
return wrapper

@add_methods('newPost', 'editPost', 'getPost', 'newMediaObject',
 'getCategories', 'getRecentPosts',
 prefix='metaWeblog.')
class MetaWeblog(object):
def __init__(self,
 securityHandler=SimpleSecurityHandler,
 blogHandler=SimpleBlogHandler):
self.security = securityHandler()
self.blog = blogHandler()

if __name__ == '__main__':
server = SimpleXMLRPCServer(("localhost", 8080))
server.register_instance(MetaWeblog())
server.register_introspection_functions()
server.serve_forever()

The problem that I'm having is that when I call newPost,
SimpleBlogHandler.getRecentPosts gets invoked.  Apparently add_methods
isn't generating unique templates.  I think I need to move 'template'
into another function, but I'm starting to wonder if metaclasses might
work better.  Any ideas?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: creating classes with mix-ins

2009-05-12 Thread samwyse
On May 11, 9:01 pm, Carl Banks  wrote:
> On May 11, 11:16 am, samwyse  wrote:
>
> > Should I use a class decorator, or a metaclass?
>
> Here's the thing: unless you have advance knowledge of the methods
> defined by self.blog, you can't get the attr_list at class definition
> time, which means neither the metaclass nor the decorator would be a
> good approach.  If that's the case, you should define newPost,
> editPost, and whatever other methods of self.blog as ordinary
> attributes of self, within the init function.  boilerplate would be
> the same except you would pass self to it and allow template to use it
> from its nested scope (it would no longer be an instance method since
> it's an ordinary attribute).
>
> If you do know what the methods of self.blog will be, then that's
> where you get attr_list from.  So, for instance, if blogHandler always
> returns an object of type Blog, then you could inspect Blog's type
> dict to see what methods are defined in it; in fact you probably want
> to check the whole MRO for Blog, like this (untested):
>
> attr_list = []
> for cls in Blog.__mro__:
>     for value in cls.__dict__:
>         if is_wrapped_method(value):
>             attr_list.append(value)
>
> A metaclass is probably overkill to assign the wrapped blog methods.
> I probably wouldn't even bother with the decorator, and just write the
> loop after the class definition.  Then you can use MetaBlog directly
> for klass.
>
> class MetaBlog(object):
>     ...
>
> for what in attr_list:
>     setattr(MetaBlog, what, boilerplate(what))
>
> If it were the kind of thing I found myself doing often I'd refactor
> into a decorator.

Unfortunately, 'boilerplate()' uses the handlers that I provide when
MetaBlog is instantiated.  I tried the following, but it didn't work
(for reasons that were obvious in retrospect).

def instantiate_template(m_name, instance):
isAuthorised = instance.security.isAuthorised
method_to_wrap = getattr(instance.blog, m_name)
def template(self, which, username, password, *args):
if not isAuthorised(username, password, which, m_name):
raise Exception('Unauthorised access')
return method_to_wrap(which, *args)
template.__name__ = method_to_wrap.__name__
template.__doc__ = method_to_wrap.__doc__
return template

class MetaWeblog(object):
def __init__(self,
 securityHandler=SimpleSecurityHandler,
 blogHandler=SimpleBlogHandler):
self.security = securityHandler()
self.blog = blogHandler()
# from http://www.xmlrpc.com/metaWeblogApi
m_prefix = 'metaWeblog.'
m_list = ('newPost', 'editPost', 'getPost', 'newMediaObject',
  'getCategories', 'getRecentPosts', )

# Here's where things fell apart
for m_name in m_list:
dotted_name = m_prefix + m_name
method = instantiate_template(m_name, self)
setattr(self, dotted_name, method)

So, I replaced that last for-loop with this:

# Since we're about to monkey-patch the class, we should
# make certain that all instances use the same handlers.
handlers = (self.security, self.blog)
try:
assert getattr(self.__class__, '_handlers') == handlers
except AttributeError:
for m_name in m_list:
dotted_name = m_prefix + m_name
method = instantiate_template(m_name, self)
setattr(self.__class__, dotted_name, method)
setattr(self.__class__, '_handlers', handlers)

This is good enough for now, since I can't conceive of a reason why
MetaBlog would be instantiated more than once.  If it were, on the
other hand, it would probably be because you wanted to use different
handlers.  In that case, I think I'd want to use a class factory,
something like this:
server.register_instance(
MetaWeblogFactory(securityHandler, blogHandler)()
)

Anyway, thanks for getting me over a conceptual hump.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How do I change the behavior of the 'python-docs' action in IDLE?

2009-05-31 Thread samwyse
On Apr 16, 2:02 pm, samwyse  wrote:
> In the Windows version of Python 2.5, pressing F1 brought up the
> python.chm file.  I've just installed 2.6, and the same action 
> openshttp://www.python.org/doc/current/.  I'd prefer the former behavior.
> I know how to change the key bindings in config-keys.def, but I think
> I want to change the action, not the key binding.  Thanks.

I just installed Python 3.0.1 via the Windows 32-bit installer.
Opening "Python Docs" takes me to http://docs.python.org/dev/3.0/,
which doesn't exist.  Renaming python301.chm to python30.chm or
python300.chm doesn't seem to help find that file.  HELP!
-- 
http://mail.python.org/mailman/listinfo/python-list


Turning HTMLParser into an iterator

2009-05-31 Thread samwyse
I'm processing some potentially large datasets stored as HTML.  I've
subclassed HTMLParser so that handle_endtag() accumulates data into a
list, which I can then fetch when everything's done.  I'd prefer,
however, to have handle_endtag() somehow yield values while the input
data is still streaming in.  I'm sure someone's done something like
this before, but I can't figure it out.  Can anyone help?  Thanks.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: how to find the last decorator of a chain

2009-05-31 Thread samwyse
On May 30, 6:16 pm, Gabriel  wrote:

> I have something like this:
>
> @render(format="a")
> @render(format="b")
> @
> def view(format, data):
>   return data

> In my understanding this equivalent to:
>
> render('a',
>  render('b',
>   view(***)))

Not quite.  'render' is a function of one argument that returns a
decorator. So, the equivalent is more like this:
  view = render('a')(render('b')(view))
or more simply:
  fb = render('b')
  view = fb(view)
  fa = render('a')
  view = fa(view)

> Is there any way to know, in this case, that 'a' is the 'default' format?

Will this do?  (In case the formatting gets messed up, I've also
posted the code to http://python.pastebin.com/f7f229d9d)

##from functools import wraps

def render(c):
def decorator(f):
##@wraps(f)
def wrapper(*args, **kwds):
if getattr(wrapper, 'outermost', False):
print('outer wrapper', c)
else:
print('inner wrapper', c)
return f(*args, **kwds)
return wrapper
return decorator

def mark_as_top(f):
print('marking', f)
f.outermost = True
##@wraps(f)
return f

@mark_as_top
@render('a')
@render('b')
@render('c')
@render('d')
def f():
pass

f()

-- 
http://mail.python.org/mailman/listinfo/python-list


Missing codecs in Python 3.0

2009-06-02 Thread samwyse
I have a Python 2.6 program (a code generator, actually) that tries
several methods of compressing a string and chooses the most compact.
It then writes out something like this:
  { encoding='bz2_codec', data = '...'}

I'm having two problems converting this to Py3.  First is the absence
of the bz2_codec, among others.  It was very convenient for my program
to delay selection of the decoding method until run-time and then have
an easy way to load the appropriate code.  Is this gone forever from
the standard libraries?

Second, I would write my data out using the 'string_escape' codec.
It, too, has been removed; there's a 'unicode_escape' codec which is
similar, but I would rather use a 'byte_escape' codec to produce
literals of the form b'asdf'.  Unfortunately, there isn't one that I
can find.  I could use the repr function, but that seems less
efficient.  Does anyone have any ideas?  Thanks.
-- 
http://mail.python.org/mailman/listinfo/python-list


Logging to zero or more destinations

2008-07-08 Thread samwyse
In the Python 2.5 Library Reference, section 14.5.3 (Logging to
multiple destinations), an example is given of logging to both a file
and the console.  This is done by using logging.basicConfig() to
configure a log file, and then calling
logging.getLogger('').addHandler(console) to add the console.

However, in section 14.5.4 (Sending and receiving logging events
across a network), a call is made to
rootLogger.addHandler(socketHandler), and later it is stated that "On
the client side, nothing is printed on the console".

Finally, back in section 14.5.2 (Basic example), it's stated that "by
default, the root logger is configured to only handle messages with a
severity of WARNING or above. The message format is also a
configuration default, as is the output destination of the messages -
sys.stderr."

The only way that I can see for all three statements to be consistent
is that the root logger starts with an empty list of handlers, and
doesn't instantiate a default handler until either
logging.basicConfig()  is called, or the first time that a message is
logged.  This would also seem to imply that there's no way to use an
empty handler list (say, if you want to suppress all logging), because
the root handler will instantiate a handler for you.  Is this correct?

P.S.  I tried researching this further by myself, but the logging
module doesn't come with source (apparently it's written in C?) and I
don't have the time to find and download the source to my laptop.

Thanks!
--
http://mail.python.org/mailman/listinfo/python-list


Re: re.search much slower then grep on some regular expressions

2008-07-08 Thread samwyse
On Jul 4, 6:43 am, Henning_Thornblad <[EMAIL PROTECTED]>
wrote:
> What can be the cause of the large difference between re.search and
> grep?

> While doing a simple grep:
> grep '[^ "=]*/' input                  (input contains 156.000 a in
> one row)
> doesn't even take a second.
>
> Is this a bug in python?

You might want to look at Plex.
http://www.cosc.canterbury.ac.nz/greg.ewing/python/Plex/

"Another advantage of Plex is that it compiles all of the regular
expressions into a single DFA. Once that's done, the input can be
processed in a time proportional to the number of characters to be
scanned, and independent of the number or complexity of the regular
expressions. Python's existing regular expression matchers do not have
this property. "

I haven't tested this, but I think it would do what you want:

from Plex import *
lexicon = Lexicon([
(Rep(AnyBut(' "='))+Str('/'),  TEXT),
(AnyBut('\n'), IGNORE),
])
filename = "my_file.txt"
f = open(filename, "r")
scanner = Scanner(lexicon, f, filename)
while 1:
token = scanner.read()
print token
if token[0] is None:
break
--
http://mail.python.org/mailman/listinfo/python-list


Re: numeric emulation and __pos__

2008-07-08 Thread samwyse
On Jul 7, 6:12 pm, Ethan Furman <[EMAIL PROTECTED]> wrote:
> Greetings, List!
>
> I'm working on a numeric data type for measured values that will keep
> track of and limit results to the number of significant digits
> originally defined for the values in question.
>
> I am doing this primarily because I enjoy playing with numbers, and also
> to get some experience with unit testing.
>
> At this point I have the __init__ portion finished, and am starting on
> the various operator functions.
>
> Questions for the group:
>
> 1) Any reason to support the less common operators?
>         i.e. <<, >>, &, ^, |
>
> 2) What, exactly, does .__pos__() do?  An example would help, too.

1)  Those make much less sense for non-integers.  I'd say skip them.

2)  It's an overridable no-op that implements the unary plus
operator.  Unary plus returns its value unchanged, as does __pos__.
--
http://mail.python.org/mailman/listinfo/python-list


Re: numeric emulation and __pos__

2008-07-09 Thread samwyse
On Jul 8, 12:34 pm, Ethan Furman <[EMAIL PROTECTED]> wrote:

> Anybody have an example of when the unary + actually does something?
> Besides the below Decimal example.  I'm curious under what circumstances
> it would be useful for more than just completeness (although
> completeness for it's own sake is important, IMO).

Well, as in Decimal, it would be a good operator to use for
canonization.  Let's say you implement complex numbers as an angle and
radius.  Then, unary plus could be used to normalize the angle to +/-
Pi and the radius to a positive number (by inverting the angle).
--
http://mail.python.org/mailman/listinfo/python-list


Re: Logging to zero or more destinations

2008-07-09 Thread samwyse
On Jul 8, 3:01 pm, Rob Wolfe <[EMAIL PROTECTED]> wrote:
> samwyse <[EMAIL PROTECTED]> writes:

> > P.S.  I tried researching this further by myself, but the logging
> > module doesn't come with source (apparently it's written in C?) and I
> > don't have the time to find and download the source to my laptop.
>
> Hmmm... that's strange. It is a pure Python package.
>
> $ ls /usr/lib/python2.5/logging/
> config.py  config.pyc  handlers.py  handlers.pyc  __init__.py  __init__.pyc
>
> HTH,
> Rob

Oops, my bad.  I was using IDLE and tried the "Open Module..." command
on logging, not logging.something.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Impossible to change methods with special names of instances of new-style classes?

2008-07-09 Thread samwyse
On Jul 8, 4:56 pm, Joseph Barillari <[EMAIL PROTECTED]> wrote:

> My question is: did something about the way the special method names are
> implemented change for new-style classes?

Just off the top of my head, I'd guess that it's due to classes
already having a default __call__ method, used when you instatiate.
Remember, the Python compiler doesn't know the difference between
this:
  a = MyClass
  instance = a()
and this:
  a = myFunc
  result = a()
--
http://mail.python.org/mailman/listinfo/python-list


Re: re.search much slower then grep on some regular expressions

2008-07-09 Thread samwyse
On Jul 8, 11:01 am, Kris Kennaway <[EMAIL PROTECTED]> wrote:
> samwyse wrote:

> > You might want to look at Plex.
> >http://www.cosc.canterbury.ac.nz/greg.ewing/python/Plex/
>
> > "Another advantage of Plex is that it compiles all of the regular
> > expressions into a single DFA. Once that's done, the input can be
> > processed in a time proportional to the number of characters to be
> > scanned, and independent of the number or complexity of the regular
> > expressions. Python's existing regular expression matchers do not have
> > this property. "

> Hmm, unfortunately it's still orders of magnitude slower than grep in my
> own application that involves matching lots of strings and regexps
> against large files (I killed it after 400 seconds, compared to 1.5 for
> grep), and that's leaving aside the much longer compilation time (over a
> minute).  If the matching was fast then I could possibly pickle the
> lexer though (but it's not).

That's funny, the compilation is almost instantaneous for me.
However, I just tested it to several files, the first containing
4875*'a', the rest each twice the size of the previous.  And you're
right, for each doubling of the file size, the match take four times
as long, meaning O(n^2).  156000*'a' would probably take 8 hours.
Here are my results:

compile_lexicon() took 0.0236021580595 secs
test('file-0.txt') took 24.8322969831 secs
test('file-1.txt') took 99.3956799681 secs
test('file-2.txt') took 398.349623132 secs

And here's my (probably over-engineered) testbed:

from __future__ import with_statement
from os.path import exists
from timeit import Timer

from Plex import *

filename = "file-%d.txt"

def create_files(n):
for x in range(0,n):
fname = filename % x
if not exists(fname):
print 'creating', fname
with open(fname, 'w') as f:
print >>f, (4875*2**x)*'a',

def compile_lexicon():
global lexicon
lexicon = Lexicon([
(Rep(AnyBut(' "='))+Str('/'),  TEXT),
(AnyBut('\n'), IGNORE),
])

def test(fname):
with open(fname, 'r') as f:
scanner = Scanner(lexicon, f, fname)
while 1:
token = scanner.read()
#print token
if token[0] is None:
break

def my_timed_test(func_name, *args):
stmt = func_name + '(' + ','.join(map(repr, args)) + ')'
t = Timer(stmt, "from __main__ import "+func_name)
print stmt, 'took', t.timeit(1), 'secs'

if __name__ == '__main__':
create_files(6)
my_timed_test('compile_lexicon')
for x in range(0,4):
my_timed_test('test', filename%x)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Loading just in time

2008-07-10 Thread samwyse
On Jul 10, 9:45 am, "D'Arcy J.M. Cain" <[EMAIL PROTECTED]> wrote:
> I am trying to create a utility module that only loads functions when
> they are first called rather than loading everything.  I have a bunch
> of files in my utility directory with individual methods and for each I
> have lines like this in __init__.py:
>
> def calc_tax(*arg, **name):
>     from calc_tax import calc_tax as _func_
>     calc_tax = _func_
>     return _func_(*arg, **name)

This doesn't do what you think.  The line "calc_tax = _func_" is
probably modifying a local variable that is then thrown away.  I've
got a slightly different (simpler) version to illustrate:

=== main.py ===

def calc_tax(*arg, **name):
from calc_tax import calc_tax as _func_
#global calc_tax
calc_tax = _func_
print '_func_ is', repr(_func_)
print 'calc_tax is', repr(calc_tax)
return _func_(*arg, **name)

print 'before: calc_tax is', repr(calc_tax)
result = calc_tax()
print 'after: calc_tax is', repr(calc_tax)

=== calc_tax.py ===

def calc_tax(*arg, **name):
return 42

=== end of files ===

Running main.py gives this:

  before: calc_tax is 
  _func_ is 
  calc_tax is 
  after: calc_tax is 

Note that the value of calc_test is the same in the first and last
lines.

If you uncomment the line "#global calc_tax" and run it again, you get
this:

  before: calc_tax is 
  _func_ is 
  calc_tax is 
  after: calc_tax is 

Interestingly, neither version gives me a TypeError, no matter how
many times I call calc_tax.

(BTW, you might want to look up Memoization; it's very similar to what
you want to do, and might give you a way to more efficiently code
things.)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Problems Returning an HTTP 200 Ok Message

2008-07-10 Thread samwyse
On Jul 10, 1:50 pm, Guy Davidson <[EMAIL PROTECTED]> wrote:
> Hi Folks,
>
> I'm having some issues with an small socket based server I'm writing,
> and I was hoping I could get some help.
>
> My code (attached below) us supposed to read an HTTP Post message
> coming from a power meter, parse it, and return a proper HTTP 200 Ok
> message. The problem is that the socket fails to send the entire
> message as one message, creating a fragmented message which the power
> meter then fails to read and accept.
>
> Is there any way to force the socket to send the entire message at
> once? Am I doing anything wrong? Is there an easier way to implement
> this functionality?

By 'message', do you mean a single IP datagram?  In general, the
answer is no.  Each call to 'connection.send()' will (in general, see
the next paragraph) transmit as much data as will fit into a single IP
datagram, given the current MTU for the transmission circuit.  The
fact that you're calling it in a loop indicates that the data being
sent may be larger than will fit into a datagram.

Or, by 'message', do you mean a single TCP segment?  Again, the answer
is no.  Your network stack will try to make the TCP segments the right
size to fit within a single IP datagram, leading to the same result as
above.

>From your description, I get the feeling that your power meter has a
broken network stack, and you're trying to program around it.  You
need to repair the meter.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Problems Returning an HTTP 200 Ok Message

2008-07-14 Thread samwyse
On Jul 10, 4:10 pm, Guy Davidson <[EMAIL PROTECTED]> wrote:

> I try to send the following message, using the socket.send() command:
>
> 'HTTP/1.1 200 OK\r\nDate: Thu, 10 July 2008 14:07:50 GMT\r\nServer:
> Apache/2.2.8 (Fedora)\r\nX-Powered-By: PHP/5.2.4\r\nContent-Length: 4\r
> \nConnection: close\r\nContent-Type: text/html; charset=UTF-8\r\n\r
> \n[0]\n'
>
> However, when I snoop on the packets in wireshark, here's what I see:
>
> HTTP/1.1 200 Ok:
>
> HTTP/1.1 200 OK
> Date: Wed, 09 July 2008 14:55:50 GMT
> Server: Apache/2.2.8 (Fedora)
> X-Powered-By:
>
> Continuation or non-HTTP traffic:
>
> PHP/5.2.4
> Content-Length: 4
> Connection: close
> Content-Type: text/html; charset=UTF-8
>
> [0]
>
> It splits into two packages, which the meter can't read, and the
> communication breaks down there.

OK, it looks like a single TCP segment is being sent by you (which is
consistent with only one socket.send() command being needed), but
something along the way to the meter is using an MTU (Maximum
Transmission Unit) of about 100 bytes, producing two IP datagrams.
How many hops are there between the PC and the meter?  Are you
sniffing on the same subnet as the PC, the meter, or somewhere in
between?  MTU is normally set to about 1500 (and MSS is generally
MTU-40), but you can generally change these values.

You should be able to set the do-not-fragment flag on your IP packets,
but that may cause them to get dropped instead of sent.  You could
also try setting a smaller ICP MSS (Maximum Segment Size), which the
meter might be able to assemble, even if it can't handle fragmented IP
datagrams.  Try 
http://www.cisco.com/en/US/tech/tk870/tk877/tk880/technologies_tech_note09186a008011a218.shtml#prob_desc
for more help.

You really need to get a networking guru involved if you want to go
down this path.  I used to be one, but that was years ago.  Or, you
can take Gabriel Genellina's advice and try coding smaller responses.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Problems Returning an HTTP 200 Ok Message

2008-07-14 Thread samwyse
On Jul 11, 3:46 am, "Gabriel Genellina" <[EMAIL PROTECTED]>
wrote:

> As Guy Davidson has already pointed out, this is a problem in the meter  
> TCP implementation, and you should ask the vendor to fix it.

That would have been me, not Guy.
--
http://mail.python.org/mailman/listinfo/python-list


creating ZIP files on the cheap

2009-12-23 Thread samwyse
I've got an app that's creating Open Office docs; if you don't know,
these are actually ZIP files with a different extension.  In my case,
like many other people, I generating from boilerplate, so only one
component (content.xml) of my ZIP file will ever change.  Instead of
creating the entire ZIP file each time, what is the cheapest way to
accomplish my goal?  I'd kind-of like to just write the first part of
the file as a binary blob, then write my bit, then write most of the
table of contents as another blob, and finally write a TOC entry for
my bit.  Has anyone ever done anything like this?  Thanks.
-- 
http://mail.python.org/mailman/listinfo/python-list


class version of func_globals?

2009-12-29 Thread samwyse
Is there any way to get the global namespace of the module in which a
class was defined?  Answers for both Python 2.x and 3.x will be
cheerfully accepted.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: class version of func_globals?

2009-12-29 Thread samwyse
On Dec 29, 5:18 am, Dave Angel  wrote:
> samwyse wrote:
> > Is there any way to get the global namespace of the module in which a
> > class was defined?  Answers for both Python 2.x and 3.x will be
> > cheerfully accepted.
>
> I don't know if it's the same in general, but consider the following
> sequence in 2.6:
>
> import sys
>
> class MyClass(object):
>     pass
>
> print "class--", dir(MyClass)
> print "module--", dir(MyClass.__module__)
> mod = sys.modules[MyClass.__module__]
> print mod
> print "globals--", dir(mod)
>
> DaveA

Excellent!  Exactly what I wanted, but wasn't clever enough to figure
out for myself.  Thank you very much.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Bare Excepts

2009-12-30 Thread samwyse
On Dec 30, 7:23 am, Jean-Michel Pichavant 
wrote:

> Rule N°2:
> dont use BARE EXCEPT, or you'll piss off MRAB for good :o). Beside from
> kidding, don't use bare except.

I inherited some code that used bare excepts *everywhere*.  There were
about 4K lines of code, IIRC, and I think that they were more except
clauses than elses.  Eventually, I used sed to add a print_exc() after
each one, just so I could figure out what the expected exceptions
were.  It was so bad that I seriously considered writing a program
just to parse all the tracebacks from my instrumented version and then
revise the source code for me, but I didn't want to accidentally miss
any "real" errors.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to test a URL request in a "while True" loop

2009-12-30 Thread samwyse
On Dec 30, 10:00 am, Brian D  wrote:

> What I don't understand is how to test for a valid URL request, and
> then jump out of the "while True" loop to proceed to another line of
> code below the loop. There's probably faulty logic in this approach. I
> imagine I should wrap the URL request in a function, and perhaps store
> the response as a global variable.
>
> This is really more of a basic Python logic question than it is a
> urllib2 question.

There, I've condensed your question to what you really meant to say.
You have several approaches.  First, let's define some useful objects:
>>> max_attempts = 5
>>> def do_something(i):
assert 2 < i < 5

Getting back to original question, if you want to limit the number of
attempts, don't use a while, use this:

>>> for count in xrange(max_attempts):
print 'attempt', count+1
do_something(count+1)

attempt 1
Traceback (most recent call last):
  File "", line 3, in 
do_something(count+1)
  File "", line 2, in do_something
assert 2 < i < 5
AssertionError

If you want to keep exceptions from ending the loop prematurely, you
add this:

>>> for count in xrange(max_attempts):
print 'attempt', count+1
try:
do_something(count+1)
except StandardError:
pass

Note that bare except clauses are *evil* and should be avoided.  Most
exceptions derive from StandardError, so trap that if you want to
catch errors.  Finally, to stop iterating when the errors cease, do
this:

>>> try:
for count in xrange(max_attempts):
print 'attempt', count+1
try:
do_something(count+1)
raise StopIteration
except StandardError:
pass
except StopIteration:
pass

attempt 1
attempt 2
attempt 3


Note that StopIteration doesn't derive from StandardError, because
it's not an error, it's a notification.  So, throw it if and when you
want to stop iterating.

BTW, note that you don't have to wrap your code in a function.
do_something could be replaced with it's body and everything would
still work.
-- 
http://mail.python.org/mailman/listinfo/python-list


enhancing 'list'

2010-01-17 Thread samwyse
Consider this a wish list.  I know I'm unlikely to get any of these in
time for for my birthday, but still I felt the need to toss it out and
see what happens.

Lately, I've slinging around a lot of lists, and there are some simple
things I'd like to do that just aren't there.

s.count(x[, cmp[, key]])
- return number of i‘s for which s[i] == x.  'cmp' specifies a custom
comparison function of two arguments, as in '.sort'.  'key' specifies
a custom key extraction function of one argument.
s.index(x[, i[, j[, cmp[, key)
- return smallest k such that s[k] == x and i <= k < j.  'cmp' and
'key' are as above.
s.rindex(x[, i[, j[, cmp[, key)
- return largest k such that s[k] == x and i <= k < j.  'cmp' and
'key' are as above.

There are two overlapping proposals here.  One is to add the .rindex
method, which strings already have.  The other is to extend the
optional arguments of .sort to all other methods that test for item
equality.

One last thing, the Python 2.6.2 spec says .count and .index only
apply to mutable sequence types.  I see no reason why they
(and .rindex) couldn't also apply to immutable sequences (tuples, in
particular).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: enhancing 'list'

2010-01-18 Thread samwyse
On Jan 18, 1:56 am, Terry Reedy  wrote:
> On 1/17/2010 5:37 PM, samwyse wrote:
>
>
>
>
>
> > Consider this a wish list.  I know I'm unlikely to get any of these in
> > time for for my birthday, but still I felt the need to toss it out and
> > see what happens.
>
> > Lately, I've slinging around a lot of lists, and there are some simple
> > things I'd like to do that just aren't there.
>
> > s.count(x[, cmp[, key]])
> > - return number of i‘s for which s[i] == x.  'cmp' specifies a custom
> > comparison function of two arguments, as in '.sort'.  'key' specifies
> > a custom key extraction function of one argument.
> > s.index(x[, i[, j[, cmp[, key)
> > - return smallest k such that s[k] == x and i<= k<  j.  'cmp' and
> > 'key' are as above.
> > s.rindex(x[, i[, j[, cmp[, key)
> > - return largest k such that s[k] == x and i<= k<  j.  'cmp' and
> > 'key' are as above.
>
> > There are two overlapping proposals here.  One is to add the .rindex
> > method, which strings already have.  The other is to extend the
> > optional arguments of .sort to all other methods that test for item
> > equality.
>
> > One last thing, the Python 2.6.2 spec says .count and .index only
> > apply to mutable sequence types.  I see no reason why they
> > (and .rindex) couldn't also apply to immutable sequences (tuples, in
> > particular).
>
> In 3.x, tuple does have those methods, even though the doc is not clear
> (unless fixed by now).

That's good to hear.  Perhaps I should have tried them directyly, but
my 3.1 docs still echo the 2.x docs, which only show them for
immutable sequences.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: enhancing 'list'

2010-01-18 Thread samwyse
On Jan 18, 3:06 am, Peter Otten <__pete...@web.de> wrote:
> samwyse wrote:
> > Lately, I've slinging around a lot of lists, and there are some simple
> > things I'd like to do that just aren't there.
>
> > s.count(x[, cmp[, key]])
> > - return number of i‘s for which s[i] == x.  'cmp' specifies a custom
> > comparison function of two arguments, as in '.sort'.  'key' specifies
> > a custom key extraction function of one argument.
>
> What's your use case exactly? If I were to enhance count/index/rindex I
> would go for the simpler
>
> >>> missing = object()                                                  
> >>> class List(list):                                                
>
> ...     def count(self, value=missing, predicate=missing):            
> ...             if value is missing:
> ...                     if predicate is missing:
> ...                             raise TypeError
> ...                     return sum(1 for item in self if predicate(item))
> ...             else:
> ...                     if predicate is not missing:
> ...                             raise TypeError
> ...                     return list.count(self, value)
> ...>>> items = List(range(10))
> >>> items.count(7)
> 1
> >>> items.count(predicate=lambda item: item%3)
>
> 6
>
> which nicely covers all applications I can imagine.
>
> Peter

That is a good idea.  However, I was looking more at the simplicity of
building of ideas that are already present in .sort.  And this
implementation is pretty simple as well.

>>> class List(list):
import __builtin__
def count(self, value, cmp=__builtin__.cmp):
return sum(1 for item in self if not cmp(item, value))


>>> items = List(range(10))
>>> items.count(7)
1
>>> items.count(3, lambda a, b: not a%b)  # My way
6
>>> items.count(Ellipsis, lambda a, b: not a%3)  # Your way
6

As a side note, wouldn't it be nice if '...' could be used in more
places than just slices?  IMHO, a useful idiom would be to use it to
signify "irrelevant" or "don't care", as opposed to 'None' which (in
my mind, at least) signifies "missing" or "unknown".
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: enhancing 'list'

2010-01-18 Thread samwyse
On Jan 17, 11:30 pm, Asun Friere  wrote:
> On Jan 18, 9:37 am, samwyse  wrote:
>
> > Consider this a wish list.  I know I'm unlikely to get any of these in
> > time for for my birthday, but still I felt the need to toss it out and
> > see what happens.
>
> > Lately, I've slinging around a lot of lists, and there are some simple
> > things I'd like to do that just aren't there.
>
> If memory serves me correctly, it has been possible to subclass 'built-
> in' types since Py2.2 or thereabouts.

True, but I've had bad experiences doing that.  See, for example,
http://groups.google.com/group/comp.lang.python/browse_thread/thread/10cfe2affc265ac
where I tried to subclass 'int'.  More importantly, subclassing means
that people have to keep re-inventing the same methods.  Having a
single implementation would save time, not to mention the speed
advantages of implementing them in the hosting language (C,
Java, .NET, etc).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: The answer

2010-01-18 Thread samwyse
On Jan 17, 8:30 pm, Jive Dadson  wrote:
> Okay, with your help I've figured it out.  Instructions are below, but
> read the caveat by Ben Fenny in this thread.  All this stuff is good for
> one default version of Python only.  The PYTHONPATH described below, for
> example, cannot specify a version number.  Yes, that's a pain in the
> butt, but there's no way around it.  If you switch versions, you may
> have to delete all the .pyc files that will show up in the module
> folders.  Python ought to check them to see if they are valid, but I do
> not know if it does so.
>
> These instructions are for MS Windows.
>
> 1) Create your modules folder. Let's say it's named "Modules."  The
> documentation calls it a "package."
>
> 2) In an explorer window or on the desktop, right click on My Computer,
> and select Properties.
>
> 3) Select the Advanced tab, and click on Environment Variables near the
> bottom.
>
> 4) Look for an environment variable named PYTHONPATH.
>
>     a) If you do not find one, create one using the New button(s). I
> don't know if it has to be in User Variables or System Variables.  To
> save time experimenting, I just put one in both. For the value, put the
> full path of the folder Modules.
>
>     b) If there's already a PYTHONPATH,  Edit it, adding a semi-colon
> and the full path of folder Module to the end.
>
> 5) Put your module folders into the folder Module.
>
> 6) (Here's a really arcane bit.) Into each module folder, put a file
> named __init__.py.  It will be executed when you load the module.  It
> can be empty, but it has to be there or else the module folder will be
> ignored.

In your original thread, you never quite said why you can't use site-
packages and .pth files.  Are you not allowed to modify your local
installation?  If you are writing something for distribution to
others, then site-packages and .pth files are the best way to go,
since they don't assume any particular operating system.  If you can't
(or won't) use them, then just create Module as a sub-directory of
wherever your program lives, since that directory is always prepended
to PYTHONPATH.  If you need to use the same module from multiple
directories, most modern operating systems support symbolic links; if
you're using Windows, well, here's a nickel kid, get yourself a better
computer (http://farm1.static.flickr.com/
89/240711122_f9888e5a3b_o.jpg).

I don't think that __init__.py is very arcane, since it is described
in detail in the documentation.  It's also a great place to use the
standard site.addsitedir() function, which is another platform
independent way to manipulate Python's search path.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: enhancing 'list'

2010-01-18 Thread samwyse
On Jan 18, 6:20 am, Peter Otten <__pete...@web.de> wrote:
> Note that the cmp() builtin and the cmp parameter for list.sort() are gone
> in Python 3.

I've got Python 3 installed, and am using it for most new
development.  In this case case, however, I'm writing for the Google
App Engine, which is stuck at 2.5.  :(  (Curiously, no matter how I
order my PATH, the wrong version seems to appear first more than half
the time!  I'm seriously considering renaming all my Python 3 code to
use a .py3 file extension.)

> samwyse wrote:
> > As a side note, wouldn't it be nice if '...' could be used in more
> > places than just slices?  IMHO, a useful idiom would be to use it to
> > signify "irrelevant" or "don't care", as opposed to 'None' which (in
> > my mind, at least) signifies "missing" or "unknown".
>
> That is a pretty subtle distinction...

Hey, I'm a pretty subtle person...

> I prefer keyword arguments, but in Python 3 you can use the ellipsis literal
> freely:
>
> >>> ... == ...
> True
> >>> [..., 42, ...].count(...)
>
> 2
>
> Peter

I must have either missed or forgotten about that.  Thanks!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Parse a log file

2010-01-18 Thread samwyse
On Jan 18, 6:52 am, "kak...@gmail.com"  wrote:
> Hello to all!
> I want to parse a log file with the following format for
> example:
>               TIMESTAMPE            Operation     FileName
> Bytes
> 12/Jan/2010:16:04:59 +0200   EXISTS       sample3.3gp   37151
> 12/Jan/2010:16:04:59 +0200  EXISTS        sample3.3gp   37151
> 12/Jan/2010:16:04:59 +0200  EXISTS        sample3.3gp   37151
> 12/Jan/2010:16:04:59 +0200  EXISTS        sample3.3gp   37151
> 12/Jan/2010:16:04:59 +0200  EXISTS        sample3.3gp   37151
> 12/Jan/2010:16:05:05 +0200  DELETE      sample3.3gp   37151
>
> How can i count the operations for a month(e.g total of 40 Operations,
> 30 exists, 10 delete?)
> Any tips?
>
> Thanks in advance
> Antonis

time.strptime(string[, format])
Parse a string representing a time according to a format. The return
value is a struct_time as returned by gmtime() or localtime().

The format parameter uses the same directives as those used by strftime
(); it defaults to "%a %b %d %H:%M:%S %Y" which matches the formatting
returned by ctime(). If string cannot be parsed according to format,
or if it has excess data after parsing, ValueError is raised. The
default values used to fill in any missing data when more accurate
values cannot be inferred are (1900, 1, 1, 0, 0, 0, 0, 1, -1).

>>> import time
>>> ts='12/Jan/2010:16:04:59 +0200'
>>> time.strptime(ts[:-6], '%d/%b/%Y:%H:%M:%S')
time.struct_time(tm_year=2010, tm_mon=1, tm_mday=12, tm_hour=16,
tm_min=4, tm_sec=59, tm_wday=1, tm_yday=12, tm_isdst=-1)

I leave the conversion of the last six characters (the time zone
offset) as an exercise for the student.  :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Looking for a buffered/windowed iterator

2009-10-12 Thread samwyse
I have Python program that lets me interact with a bunch of files.
Unfortunately, the program assumes that the bunch is fairly small, and
I have thousands of files on relatively slow storage.  Just creating a
list of the file names takes several minutes, so I'm planning to
replace the list with an iterator in another thread.  However, each
file requires several seconds to load before I can work with it.  The
current code alleviates this via a thread that loads the next file
while I'm examining the current one.  I'd like my new iterator to
provide a fixed window around the current item.  I've looked at the
pairwise recipe, but it doesn't allow me to peek at items within the
window (to generate thumbnails, etc), and I've looked at arrayterator,
but it divides the stream into small contiguous blocks where crossing
a block boundary is relatively expensive.

Previous discussions in c.l.py (primarily those that propose new
functions to be added to itertools) claim that people do this all the
time, but seem woefully short of actual examples.  Before I possibly
re-invent the wheel(*), could someone point me to some actual code
that approximates what I want to do?  Thanks.

(*) Re-inventing a wheel is generally pretty simple.  But then you
discover that you also need to invert axle grease, a leaf spring
suspension, etc.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: python along or bash combined with python (for manipulating files)

2009-10-13 Thread samwyse
On Oct 13, 9:13 pm, Peng Yu  wrote:
> Bash is easy to use on manipulating files and directories (like change
> name or create links, etc) and on calling external programs. For
> simple functions, bash along is enough. However, bash does not support
> the complex functions. Python has a richer library that could provide
> support for complex functions (such compute the relative path between
> two paths).
>
> I'm wondering for a task that can not be done with bash along whether
> it would be better to do in pure python or with a mix of both python
> and bash. What I care is mostly coding speed and a little bit
> maintainability (but not much). Can somebody provide some experience
> on when to combine python and bash and when to use pure python?

Scripting languages try to optimize gluing disparate programs together
to accomplish a task; bash excels at this.  Programing languages try
to optimize finding the solution to a problem; Python excels at this.

Generally, I try to stick to one language per problem, be it bash, C+
+, Java, Perl or Python.  Bash scripts translate easily into the
others, so you don't lose much time if you decide you started with the
wrong language.

Countering that, I also maintain a "toolbox" of programs that I can
call upon when needed.  In those cases, I don't hesitate to call a
program that I've written in any language from a bash script.

BTW, I actually prefer ksh to bash, but YMMV.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: New syntax for blocks

2009-11-11 Thread samwyse
On Nov 10, 1:23 pm, r  wrote:
> Forgive me if i don't properly explain the problem but i think the
> following syntax would be quite beneficial to replace some redundant
> "if's" in python code.
>
> if something_that_returns_value() as value:
>     #do something with value
>
> # Which can replace the following syntactical construct...
>
> value = something_that_returns_value()
> if value:
>     #do something with value

I don't like the proposed syntax.  I know, it's copied from the "with"
statement, but it makes the assignment look like an afterthought.
Plus, it's not good English when read aloud.

If you want something useful, wait two years for the moratorium to
expire and then figure out how to augment the "for" statement with an
"if" clause, as is currently done in comprehensions.  In other words,
instead of this:
  "for" target_list "in" expression_list ":" suite
let's have this:
  "for" target_list "in" expression_list [ "if" expression_nocond ]
":" suite

You don't save much typing, but you really do save one indention
level.  OTOH, I can see the use of an else-clause following the 'for'
as being even more confusing to anyone new to the language.

And there's also the fact that an expression_list consists of
conditional_expressions, which potentially use "if".  You could
probably get the parser to figure it out based on the presence of the
"else" clause, but it wouldn't be easy.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python C api: create a new object class

2009-11-11 Thread samwyse
On Nov 10, 1:09 pm, "lallous"  wrote:
> Hello
>
> I have 3 questions, hope someone can help:
>
> 1)
> How can I create an instance class in Python, currently I do:
>
> class empty:
>   pass
>
> Then anytime I want that class (which I treat like a dictionary):
>
> o = empty()
> o.myattr = 1
> etc
>
> Is there is a one line syntax to instantiate an instance?

I think that you want this:

class c(object):
def __init__(self, **kwds):
self.__dict__ = kwds

x = c(a=1, b=2)
print x.a, x.b
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: python simply not scaleable enough for google?

2009-11-12 Thread samwyse
On Nov 11, 3:57 am, "Robert P. J. Day"  wrote:
> http://groups.google.com/group/unladen-swallow/browse_thread/thread/4...
>
>   thoughts?

Google's already given us its thoughts:
http://developers.slashdot.org/story/09/11/11/0210212/Go-Googles-New-Open-Source-Programming-Language
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: UnicodeDecodeError? Argh! Nothing works! I'm tired and hurting and...

2009-11-24 Thread samwyse
On Nov 24, 4:43 pm, Steven D'Aprano  wrote:

> Oh yes, and people using Windows can't use maildir because (1) it doesn't
> allow colons in names, and (2) it doesn't have atomic renames. Neither of
> these are insurmountable problems: an implementation could substitute
> another character for the colon, and while that would be a technical
> violation of the standard, it would still work. And the lack of atomic
> renames would simply mean that implementations have to be more careful
> about not having two threads writing to the one mailbox at the same time.

A common work around for the former is to URL encode the names, which
let's you stick all sorts of odd characters.

I'm afraid I can't help with the latter, though.
-- 
http://mail.python.org/mailman/listinfo/python-list


optparse/argparse for cgi/wsgi?

2010-12-10 Thread samwyse
Has anyone ever built some sort of optparse/argparse module for cgi/
wsgi programs?  I can see why a straight port wouldn't work, but a
module that can organize parameter handling for web pages seems like a
good idea, especially if it provided a standard collection of both
client- and server-side validation processes, easy
internationalization, and a way to create customizable help pages.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Proposed changes to logging defaults

2010-12-14 Thread samwyse
On Dec 9, 6:12 pm, Vinay Sajip  wrote:
> Some changes are being proposed to how logging works in default
> configurations.
>
> Briefly - when a logging event occurs which needs to be output to some
> log, the behaviour of the logging package when no explicit logging
> configuration is provided will change, most likely to log those events
> to sys.stderr with a default format.

I'm in favor of this change.  I've long wished that I could just add
lots of warning/error/info logging to a script and have it just work
without having to spend time configuring the logging system.
-- 
http://mail.python.org/mailman/listinfo/python-list


simple (I hope!) problem

2010-08-02 Thread samwyse
I'm writing for the Google app engine and have stubbed my toe yet
again on a simple obstacle.  Non-trivial app engines programs require
the import of several modules that aren't normally in my PYTHONPATH.
I'd like to be able to test my code outside of the app engine
framework.  I've tried several solutions in the past that worked but
weren't particularly elegant or portable.  Now I've had a new idea.
Here's my latest attempt:

import os, re
if __name__ == '__main__':
pass
else
from google.appengine.ext import webapp
register = webapp.template.create_template_register()

This works great, except my code makes use of the resister object in
several places, like this:

register.filter(emptylines)

Fortunately, I don't need the functionality of the object, I just want
something that won't generate an error when I use it.  So, what is the
quickest way to to create such an object (replacing the 'pass' in my
first snippet).  My solution is this:

class C:
def filter(self, *args, **kwds):
pass
register = C()

but it seems like I should be able to do something "better", as
measured by lines of code, faking more than just a 'filter' method, or
both.  Any ideas?  Thanks!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simple integer subclass

2010-08-02 Thread samwyse
On Aug 2, 6:52 pm, Andreas Pfrengle  wrote:
> I'm trying to define a subclass of int called int1. An int1-object
> shall behave exactly like an int-object, with the only difference that
> the displayed value shall be value + 1 (it will be used to display
> array indices starting at 1 instead of 0). Right now I have:
>
> class int1(int):
>     def __str__(self):
>         return int.__str__(self + 1)
>
> However, if I calculate with int1 and int- (or other number) objects,
> the result is always coerced to an int (or other number object), e.g:
> a = int1(5)
> b = 5
> print a      # "6"
> print a+b  #"10"
>
> How can I tell int1 to be the "default integer object"? Do I need to
> overload *every* mathematical operation method of int, or is there an
> easier way?

I had a similar problem a few years ago, and couldn't find a solution
then.  The thread from back then may shed some light on your problem.
http://groups.google.com/group/comp.lang.python/browse_thread/thread/10cfe2affc265ac/2ad03b121c1c6489
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Behavior of re.split on empty strings is unexpected

2010-08-02 Thread samwyse
On Aug 2, 12:34 pm, John Nagle  wrote:
> The regular expression "split" behaves slightly differently than string
> split:

I'm going to argue that it's the string split that's behaving oddly.
To see why, let's first look at some simple CSV values:
cat,dog
,missing,,values,

How many fields are on each line and what are they?  Here's what
re.split(',') says:

>>> re.split(',', 'cat,dog')
['cat', 'dog']
>>> re.split(',', ',missing,,values,')
['', 'missing', '', 'values', '']

Note that the presence of missing values is clearly flagged via the
presence of empty strings in the results.  Now let's look at string
split:

>>> 'cat,dog'.split(',')
['cat', 'dog']
>>> ',missing,,values,'.split(',')
['', 'missing', '', 'values', '']

It's the same results.  Let's try it again, but replacing the commas
with spaces.

>>> re.split(' ', 'cat dog')
['cat', 'dog']
>>> re.split(' ', ' missing  values ')
['', 'missing', '', 'values', '']
>>> 'cat dog'.split(' ')
['cat', 'dog']
>>> ' missing  values '.split(' ')
['', 'missing', '', 'values', '']

It's the same results; however many people don't like these results
because they feel that whitespace occupies a privileged role.  People
generally agree that a string of consecutive commas means missing
values, but a string of consecutive spaces just means someone held the
space-bar down too long.  To accommodate this viewpoint, the string
split is special-cased to behave differently when None is passed as a
separator.  First, it splits on any number of whitespace characters,
like this:

>>> re.split('\s+', ' missing  values ')
['', 'missing', 'values', '']
>>> re.split('\s+', 'cat dog')
['cat', 'dog']

But it also eliminates any empty strings from the head and tail of the
list, because that's what people generally expect when splitting on
whitespace:

>>> 'cat dog'.split(None)
['cat', 'dog']
>>> ' missing  values '.split(None)
['missing', 'values']
-- 
http://mail.python.org/mailman/listinfo/python-list


  1   2   >