Re: Open PDF

2005-09-23 Thread Martin Miller
IMHO, the fact that there is no way to wait for the application to
finish is major deficiency with os.startfile() -- and why I often
cannot use it instead of other techniques [such as the much more
involved but limited os.spawnv() function].

I don't if if this is just a limitation of the implementation in the
Python os module or one with the underlying OS (Windoze) -- I suspect
the latter.

Regards,
-Martin


Dennis Lee Bieber wrote:
> On Thu, 22 Sep 2005 15:16:09 +0100, Dan <[EMAIL PROTECTED]> declaimed
> the following in comp.lang.python:
>
> > > I would like to know how to open a PDF document from a python script
> >
> > You mean open it and display it to the user? Under Windows you may be
> > able to get away with just "executing" the file (as though it were an
> > executable):
> >
> >   import os
> >   os.system("c:/path/to/file.pdf")
>
>   For Windows, os.startfile() may be better...
>
> >>> help(os.startfile)
> Help on built-in function startfile:
>
> startfile(...)
> startfile(filepath) - Start a file with its associated application.
>
> This acts like double-clicking the file in Explorer, or giving the
> file
> name as an argument to the DOS "start" command:  the file is opened
> with whatever application (if any) its extension is associated.
>
> startfile returns as soon as the associated application is launched.
> There is no option to wait for the application to close, and no way
> to retrieve the application's exit status.
>
> The filepath is relative to the current directory.  If you want to
> use
> an absolute path, make sure the first character is not a slash
> ("/");
> the underlying Win32 ShellExecute function doesn't work if it is.
> 
> >>>

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


Re: Using '__mul__' within a class

2005-09-24 Thread Martin Miller
As others have pointed out, you are just reassigning a new value to the
self argument in the Square() method shown. Instead, what you need to
do is change the object that 'self' refers to within the method. To do
this, change it to:

def Square( self ):
result = self * self
self.a = result.a
self.b = result.b
self.c = result.c

You would also have to do something similar in an __imul__() method if
you decided to implement one.

Hope this helps,
-Martin


Gerard Flanagan wrote:
> Hello
>
> I'm pretty new to Python and was wondering why the 'Square' method in
> the following code doesn't work. It doesn't fail, just doesn't do
> anything ( at least, not what I'd like! ). Why doesn't 'A.a' equal 2
> after squaring?
>  TIA.
>
>
> class FibonacciMatrix:
> def __init__( self ):
> self.a = 1
> self.b = 1
> self.c = 0
>
> def __mul__( self, other ):
> result = FibonacciMatrix()
> result.a = self.a * other.a + self.b * other.b
> result.b = self.a * other.b + self.b * other.c
> result.c = self.b * other.b + self.c * other.c
> return result
>
> def Square( self ):
> self *= self
>
>
> A = FibonacciMatrix()
> A.Square()
>
> print A.a   #prints '1'
>
> A = FibonacciMatrix()
> B = A * A
> 
> print B.a   #prints '2'
> 
> --

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


Re: replacments for stdio?

2005-09-25 Thread Martin Miller
Here's a suggestion for you:
Check out the comp.lang.py thread titled "Catching stderr output from
graphical apps" at
> http://groups.google.com/group/comp.lang.python/browse_frm/thread/1d63e12e15ca528b/7bf604115b5e914e#7bf604115b5e914e

I strongly suspect that the code discussed could probably be adapted to
handle sys.stdout instead of, or in addition to, output to sys.stderr.

It also sounds like it can be made platform independent.

Best,
-Martin

P.S. Please post your results back to the newsgroup -- thanks!


[EMAIL PROTECTED] wrote:
> hi,
>i was wondering if anyone have written a GUI module that can
> function as a replacment for stdin/stdout? ie. has a file like
> interface, by which one could just assaign it to sys.stdout or
> sys.stdin and have all your prints and raw_inputs and other such things
> shown in a GUI window?
> 
> Thanks in advance,
> Ido Yehieli.

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


Re: replacments for stdio?

2005-10-05 Thread Martin Miller
Ido,

I tried Bryan Olson's code [on Windows] from his last post to the
"Catching stderr output from graphical apps" thread http://groups.google.com/group/comp.lang.python/msg/d61f1d5e02d84178>,
and it seemed to work for stdout as well as stderr output.

To enable its use with stdout, all I had to do was un-comment the last
line in Bryan's post, namely
># sys.stdout = ErrorPipe()
and the any stdout output starting would appear in a separate window.

Since it's based on Tkinter, and from what Bryan said in his post, I
believe it's a fairly portable solution. [Nice work, Bryan!]

Best,
-Martin


[EMAIL PROTECTED] wrote:
> Thanks martin,
> I'll give it a shot as soon as i get back from work!

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


Re: replacments for stdio?

2005-10-06 Thread Martin Miller
In what way would you like to get "stdin to work"? In Bryan's post in
the Application(Frame).__init__() he binds some lambda functions to key
strokes which allow control-C copying of text in the window.

Seems like additonal application-specific things might be possible, but
then the code would no longer be generic. Interaction with the main
application would likely be tricky because each output window is
lanuched as a separate process when output is first sent to it.

As far a redistribution goes, I would think anything posted to the
public comp.lang.python usenet newgroup is unencumbered unless the
author indicates otherwise -- or at most covered by the same open
source license as Python.

-Martin


[EMAIL PROTECTED] wrote:
> yes,
> I've tried it aswell - nice work indeed!
> 
> now, maybe also get stdin to work from this TK window... ;-)

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


Signals and keyboard interupts

2005-10-27 Thread Martin Miller
[Using Windows XP and Python 2.4.1]

I have question about the following code, which basically accomplished
what what I want, which is to gracefully exit the main loop when the
user presses either the control-c or control-break key:

import signal
import sys
import time
import traceback

QUIT = False

def mySigHandler(*whatever):
global QUIT # Change value of QUIT
QUIT = True
print
print "Interrupt caught and QUIT flag set"

# call the above procedure, when control-c or control-break is pressed.
old_SIGINT_Handler = signal.signal(signal.SIGINT, mySigHandler)
old_SIGBREAK_Handler = signal.signal(signal.SIGBREAK, mySigHandler)

while 1:
try:
if QUIT:
break # exit loop

print "Processing..."
time.sleep(2)

except IOError, (errno, strerror):
if errno == 4: # Interrupted function call
   # mySigHandler called, so will ignore here
continue
else: # some other IOerror -- print info and break out of loop
print "IOError[%s] exception occured: %s" % (errno,
strerror)
traceback.print_exc(file=sys.stdout)
break

print "finished"
# restore old signal handlers
signal.signal(signal.SIGINT, old_SIGINT_Handler)
signal.signal(signal.SIGBREAK, old_SIGBREAK_Handler)

My question is why is the a try/except block necessary?  If it's left
out, and unhandled exception occurs.  Seems like catching the signals
before python's default handler gets them should prevent it from being
turned into an exception.  I don't understand how this is happening in
the above code.

I read several other posts about the subject, notably the one by Bengt
Richter in
http://groups.google.com/group/comp.lang.python/msg/5b27edd0df08170a?hl=en&;,
but haven't been able to figure out why the [much more involved]
example in his post does not seem to exhibit this problem (i.e. it has
no try/except block).

Thanks in advance for any help.
-Martin

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


Re: Invoking Python from Python

2005-11-08 Thread Martin Miller
John Henry wrote:
> Hi all,
>
> I have a need to create a Python script on the fly from another Python
> program and then execute the script so created.  Do I need to invoke
> Python through os.spawnl or is there a better way?

When doing something similar to this I used the built-in 'execfile()'
function to execute the code created (and retrieve its results).

Cameron Laird wrote:
>Once I had to maintain lisp code which stored its data in lisp code, too
>(incl. conditions and loops). It was a nightmare.

This is exactly what my Python program does, but I've found it to be a
very powerful and useful technique while remaining relatively easy to
maintain (the generated code doesn't contain any conditionals or loops,
however).  Another nice by-product is that the data stored this way is
portable to different platforms.

-Martin

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


Re: about widget construction kit

2005-11-11 Thread Martin Miller
Shi Mu wrote:
> On 11/11/05, Fredrik Lundh <[EMAIL PROTECTED]> wrote:
> > 1. pass in the full path to the executable:
> >
> >cd tkinter3000-1.0-20031212
> >c:\python23\python setup.py install
> > ...
> >
> still confused by th first way you mentioned. If I cd
> tkinter3000-1.0-20031212, i will be enter the directory witht hte
> setup.py; for example, it is located as
> c:\temp\tkinter3000-1.0-20031212\setup.py
> However, I need to use c:\python23\python setup.py install to process
> the installation, how did python know where the file of "setup.py"
> located?

Since a full path was not given for the 'setup.py' file in the second
line, it will be assumed to be in the current directory which was set
by the 'cd' command in the first line.

HTH

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


Re: Default method arguments

2005-11-15 Thread Martin Miller
Alex Martelli wrote, in part:
> If it's crucial to you to have some default argument value evaluated at
> time X, then, by Python's simple rules, you know that you must arrange
> for the 'def' statement itself to execute at time X.  In this case, for
> example, if being able to have self.data as the default argument value
> is the crucial aspect of the program, you must ensure that the 'def'
> runs AFTER self.data has the value you desire.
>
> For example:
>
> class A(object):
> def __init__(self, n):
> self.data = n
> def f(self, x = self.data)
>  print x
> self.f = f
>
> This way, of course, each instance a of class A will have a SEPARATE
> callable attribute a.f which is the function you desire; this is
> inevitable, since functions store their default argument values as part
> of their per-function data.  Since you want a.f and b.f to have
> different default values for the argument (respectively a.data and
> b.data), therefore a.f and b.f just cannot be the SAME function object
> -- this is another way to look at your issue, in terms of what's stored
> where rather than of what evaluates when, but of course it leads to
> exactly the same conclusion.

FWIT and ignoring the small typo on the inner def statement (the
missing ':'), the example didn't work as I (and possibily others) might
expect.  Namely it doesn't make function f() a bound method of
instances of class A, so calls to it don't receive an automatic 'self''
argument when called on instances of class A.

This is fairly easy to remedy use the standard new module thusly:

import new
class A(object):
def __init__(self, n):
self.data = n
def f(self, x = self.data):
print x
self.f = new.instancemethod(f, self, A)

This change underscores the fact that each instance of class A gets a
different independent f() method.  Despite this nit, I believe I
understand the points Alex makes about the subject (and would agree).

-Martin

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


Re: Default method arguments

2005-11-17 Thread Martin Miller
Mike Meyer wrote, in part::
> "Gregory Petrosyan" <[EMAIL PROTECTED]> writes:
> ...
> > 2) Is 'foo.s = n' a correct solution? It seems to be a little more
> > elegant.  (I tested it, and it worked well)
>
> It's basically the same solution. You're replacing binding a variable
> with mutating an object bound to a name in an outer scope. In one case
> the container is named s and is a list that you're setting an element
> of. In the other case, the container is named foo and is an object
> that you're setting an attribute on.

Well, perhaps the same in the sense of name binding, but there's a
subtle difference in replacing the 's = [n]'  with 'foo.s = n'.  Namely
that in the former case (with the essay's original code) a separate
container is created when foo() is first called and is what is used in
subsequent calls to the function returned.  Whereas in the latter case
where the foo object itself is used as the container, there's only a
single container used by all returned objects -- which would cause
problems if you try accumulating two or more different totals
simultaneously.

Here's a very contrived test case which illustrates the point I'm
trying to make:

def foo(n):
foo.s = n
def bar(i):
 foo.s += i
 return foo.s
return bar

a1 = foo(0)
a2 = foo(0)
print "before a1(0):", a1(0)
print "before a2(0):", a2(0)
a1(1)
a2(1)
print "after a1(0):", a1(0)
print "after a2(0):", a2(0)

 outputs
before a1(0): 0
before a2(0): 0
after a1(0): 2
after a2(0): 2

Notice that it even though each was only incremented by 1 once, they
interacted, and show the effects of two calls.  This doesn't happen in
in Paul Graham's version, where the two 'after' calls would correctly
retrun a value of 1.

-Martin

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


Re: importing a method

2005-11-28 Thread Martin Miller
First of all,why do you think the new module is deprecated?  (I can't
find anything in the docs to indicate this.)

As for using MethodType in the types module:  There's nothing in the
module documentation that suggests that you can call MethodType as a
function as you suggest, only that it is the name of the type of
methods of user-defined class instances..  So, while calling it might
work, it sounds like you are using an undocumented feature...

Lastly, in an earlier post after Ben Finney suggested using the
new.instancemethod function, you replied:
> If you read my original post, I had no intention of atributing the
> user's method to the class, but to the instance.

I'd like to point out that the instancemethod() function returns a
method object, bound to its *instance* argument if it isn't None --
which sounds like exactly what you want/need.

-Martin


Flavio wrote:
> Addendum to my last reply:
>
> although the New Method is deprecated,
>
> new.instancemethod (from Antoon's message) can be replaced by
>
> from types import MethodType
> 
> f.show = MethodType(show,f)
> 
> and every thing still works.

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


Re: importing a method

2005-11-28 Thread Martin Miller
I'd like to point out to the OP that using a function's __get__ method
this way only works with new-style classes and their instances...not
with the example in the shown in original post.

-Martin


Alex Martelli wrote:
> Flavio <[EMAIL PROTECTED]> wrote:
>
> > This "new" module sounds pretty cool, too bad its deprecated...
> >
> > I would not want to add a dependancy to a deprecated module in my code.
> > But maybe I'll check the code for instancemethod within it and see what
> > it does.
>
> If you have a function f and want to make an instancemethod out of it,
> you can simply call f.__get__(theinstance, theclass) and that will build
> and return the new instancemethod you require.
> 
> 
> Alex

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


Re: (newbie) N-uples from list of lists

2005-11-30 Thread Martin Miller
FWIW, I found Steven Taschuk's solution easiest to understand regarding
the question posed in your original post -- namely how to solve the
problem non-recursively with generators -- because it was similar to my
own thinking about how to do it -- but suspect that Raymond Hettinger's
is the likely the "best" (as is usually the case ;-).

Best,
-Martin


[EMAIL PROTECTED] wrote:
> great thanks to all.
>
> actually i have not seen it was a cross product... :) but then there
> are already few others ideas from the web, i paste what i have found
> below...
>
> BTW i was unable to choose the best one, speaking about performance
> which one should be prefered ?
>
> ### --
>
> ### from title: variable X procuct - [(x,y) for x in list1 for y in
> list2]
> ### by author:  steindl fritz
> ### 28 mai 2002
> ### reply by:   Jeff Epler
>
> def cross(l=None, *args):
> if l is None:
> # The product of no lists is 1 element long,
> # it contains an empty list
> yield []
> return
> # Otherwise, the product is made up of each
> # element in the first list concatenated with each of the
> # products of the remaining items of the list
> for i in l:
> for j in cross(*args):
> yield [i] + j
>
> ### reply by:   Raymond Hettinger
>
> def CartesianProduct(*args):
> ans = [()]
> for arg in args:
> ans = [ list(x)+[y] for x in ans for y in arg]
> return ans
>
> """
> print CartesianProduct([1,2], list('abc'), 'do re mi'.split())
> """
>
> ### from:
> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/159975
> ### by: Raymond Hettinger
>
> def cross(*args):
> ans = [[]]
> for arg in args:
> ans = [x+[y] for x in ans for y in arg]
> return ans
>
> ### from:
> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/159975
> ### by: Steven Taschuk
> """
> Iterator version, Steven Taschuk, 2003/05/24
> """
> def cross(*sets):
> wheels = map(iter, sets) # wheels like in an odometer
> digits = [it.next() for it in wheels]
> while True:
> yield digits[:]
> for i in range(len(digits)-1, -1, -1):
> try:
> digits[i] = wheels[i].next()
> break
> except StopIteration:
> wheels[i] = iter(sets[i])
> digits[i] = wheels[i].next()
> else:
> break

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


Re: importing a method

2005-11-30 Thread Martin Miller
Sorry, I seldom look at the built-in __doc__ strings or use the
'help()' function.  Instead I usually refer to the html or winhelp
versions of the documentation, and for Python 2.4.1 there's nothing in
section 3.28 on the 'new' module that mentions that it deprecated -- so
thanks to you and Flávio for the information.

Using help on MethodType gave me the following somewhat surprising
output [truncated here]:
>>> import types
>>> help(types.MethodType)
Help on class instancemethod in module __builtin__:

class instancemethod(object)
 |  instancemethod(function, instance, class)
 |
 |  Create an instance method object.
[snip]

Which I take to mean that 'instancemethod' is no longer [just] a
function in the deprecated 'new' module but is also a built-in class.

However and somewhat confusingly (to me anyway), a search in the help
docs file turns up the following:

> 7.5.3  Method Objects
> There are some useful functions that are useful for working with method 
> objects.
>
> PyTypeObject  PyMethod_Type
>   This instance of PyTypeObject represents the Python method type. This is
>   exposed to Python programs as types.MethodType.
>   ...
[snip]

Which, as you can see, claims that types.MethodType is actually an
instance of a PyTypeObject (not the class instancemethod that
help(types.MethodType) indicated).

Best,
-Martin


Steven D'Aprano wrote:
> On Mon, 28 Nov 2005 08:16:12 -0800, Martin Miller wrote:
>
> > First of all,why do you think the new module is deprecated?  (I can't
> > find anything in the docs to indicate this.)
>
> Did you try help(new) from an interactive prompt?
>
>
> py> new.__doc__.splitlines()[0]
> 'Create new objects of various types.  Deprecated.'
>
>
> --
> Steven.


Flávio wrote:
> > First of all,why do you think the new module is deprecated?  (I can't
> > find anything in the docs to indicate this.)
>
> Its in the docs of python 2.4. I dont know about older versions:
>
> Help on module new:
>
> NAME
> new - Create new objects of various types.  Deprecated.
>
> FILE
> /usr/lib/python2.4/new.py
>
> MODULE DOCS
> /usr/share/doc/python-docs-2.4.2/html/module-new.html
>
> DESCRIPTION
> This module is no longer required except for backward
> compatibility.
> Objects of most types can now be created by calling the type
> object.
>
> > As for using MethodType in the types module:  There's nothing in the
> > module documentation that suggests that you can call MethodType as a
> > function as you suggest, only that it is the name of the type of
> > methods of user-defined class instances..  So, while calling it might
> > work, it sounds like you are using an undocumented feature...
>
> If you look at new.py, all it does is import the functions from types
> and rename them. For MethodType is goes like this
>
> from types import MethodType as instancemethod
>
> so instance method *is* Methodtype.
>
> Moreover, I tried and it works ;-)
>
> So this solution is perfect once adapted not to depend on "new".
> 
> Thanks,
> 
> Flávio

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


Re: importing a method

2005-11-30 Thread Martin Miller
You're not missing anything -- it's my own [mis-]understanding that
descriptors would only work with new-style classes, not the old-style
ones used in the OP's example.

However your example certainly proves that is not the case, even if you
go one step further and call the bound method/function:
>>> o.z()
<__main__.old instance at 0x009D5F30>

So I stand corrected -- thank you.

Best,
-Martin

==
Alex Martelli wrote:
> Martin Miller <[EMAIL PROTECTED]> wrote:
>
> > I'd like to point out to the OP that using a function's __get__ method
> > this way only works with new-style classes and their instances...not
> > with the example in the shown in original post.
>
> Uh, why not?
>
> >>> class old: pass
> ...
> >>> def f(self): print self
> ...
> >>> o=old()
> >>> o.z = f.__get__(o, old)
> >>> o.z
> >
> >>>
>
> There's a million reason to avoid using old-style classes in new code,
> but it doesn't seem to me that this is one of them.  What am I missing?
> 
> 
> Alex

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


Re: (newbie) N-uples from list of lists

2005-12-02 Thread Martin Miller
I'd be interested in seeing the one liner using reduce you mentioned --
how it might be done that way isn't obvious to me.

Another aspect of Taschuk's solution I like and think is important is
the fact that it is truly iterative in the sense that calling it
returns a generator which will yield each of the combinations, one at
time.  All the others create and return all the combinations at once
(as I suspect the one liner using reduce you mention does, too).

As you point out, "best" is always in the eyes of the beholder.

"Best" regards, ;-)
-Martin


[EMAIL PROTECTED] wrote:
> Interesting, I found a reduce one liner(just one step further of
> Raymond's) easiest to understand and match my thinking about what the
> problem is about.
>
> That once again tell me that different people think and approach the
> problem differently. It is possible to talk about one "fastest" way,
> but many times there isn't such a thing of one "best" way.
>
> Martin Miller wrote:
> > FWIW, I found Steven Taschuk's solution easiest to understand regarding
> > the question posed in your original post -- namely how to solve the
> > problem non-recursively with generators -- because it was similar to my
> > own thinking about how to do it -- but suspect that Raymond Hettinger's
> > is the likely the "best" (as is usually the case ;-).
> >
> > Best,
> > -Martin
> >
> >
> > [EMAIL PROTECTED] wrote:
> > > great thanks to all.
> > >
> > > actually i have not seen it was a cross product... :) but then there
> > > are already few others ideas from the web, i paste what i have found
> > > below...
> > >
> > > BTW i was unable to choose the best one, speaking about performance
> > > which one should be prefered ?
> > >
> > > ### --
> > >
> > > ### from title: variable X procuct - [(x,y) for x in list1 for y in
> > > list2]
> > > ### by author:  steindl fritz
> > > ### 28 mai 2002
> > > ### reply by:   Jeff Epler
> > >
> > > def cross(l=None, *args):
> > > if l is None:
> > > # The product of no lists is 1 element long,
> > > # it contains an empty list
> > > yield []
> > > return
> > > # Otherwise, the product is made up of each
> > > # element in the first list concatenated with each of the
> > > # products of the remaining items of the list
> > > for i in l:
> > > for j in cross(*args):
> > > yield [i] + j
> > >
> > > ### reply by:   Raymond Hettinger
> > >
> > > def CartesianProduct(*args):
> > > ans = [()]
> > > for arg in args:
> > > ans = [ list(x)+[y] for x in ans for y in arg]
> > > return ans
> > >
> > > """
> > > print CartesianProduct([1,2], list('abc'), 'do re mi'.split())
> > > """
> > >
> > > ### from:
> > > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/159975
> > > ### by: Raymond Hettinger
> > >
> > > def cross(*args):
> > > ans = [[]]
> > > for arg in args:
> > > ans = [x+[y] for x in ans for y in arg]
> > > return ans
> > >
> > > ### from:
> > > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/159975
> > > ### by: Steven Taschuk
> > > """
> > > Iterator version, Steven Taschuk, 2003/05/24
> > > """
> > > def cross(*sets):
> > > wheels = map(iter, sets) # wheels like in an odometer
> > > digits = [it.next() for it in wheels]
> > > while True:
> > > yield digits[:]
> > > for i in range(len(digits)-1, -1, -1):
> > > try:
> > > digits[i] = wheels[i].next()
> > > break
> > > except StopIteration:
> > > wheels[i] = iter(sets[i])
> > > digits[i] = wheels[i].next()
> > > else:
> > > break

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


Re: "pickle" vs. f.write()

2005-02-01 Thread Martin Miller
On 1/26/05 at 1:48 pm, Terry Reedy wrote:
> For basic builtin objects, repr(ob) generally produces a string that when 
> eval()ed will recreate the object.  IE
> eval(repr(ob) == ob # sometimes

I've found extending this property to your own classes often fairly easy
to implement (and useful). For example:

> class person:
> def __init__(self, name="", age=0, friends=None, comment=""):
> if friends is None:
> friends = []
> self.name, self.age, self.friends, self.comment = name, age, friends, 
> comment
> 
> def __repr__(self):
> return ("person(" + repr(self.name) + ", " + repr(self.age) + ", " +
> repr(self.friends) +  ", " + repr(self.comment) + ")")
> 
> me = person()
> 
> print "me =", repr(me)

Which produces the following output:
   me = person('', 0, [], '')


In addition, the following constructs are possible:

> family = [
> person("Martin", 50, ["Matt"], "eldest son"),
> person("Matt", 43, ["Martin"], "youngest son"),
> person("Merry", 72, ["Martin", "Matt"], "mother"),
> person("Luther", 82, ["Merry"], "father")
> ]
> 
> print "family =", repr(family)

Which output the following:
family = [person('Martin', 50, [], 'eldest son'), person('Matt', 43,
['Martin'], 'youngest son'), person('Merry', 72, ['Martin', 'Matt'],
'mother'), person('Luther', 82, ['Merry'], 'father')]

Basically this approach allows you to store your data in Python source
files -- which you can then import or execfile. The files can also
contain comments and are relatively easy to edit by hand. In addition
they're portable.

Best,
Martin


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


Re: "pickle" vs. f.write()

2005-02-05 Thread Martin Miller
Marc 'BlackJack' Rintsch wrote:
> ...
>
> I write __repr__() methods similar but I think a bit more readable:
>
>   def __repr__(self):
>   return "%s(%r, %r, %r, %r)" % (self.__class__.__name__,
self.name,
>  self.age, self.friends,
self.comment)
>
> And it's robust against changing the class name.  It even works in
> subclasses if the signature of the __init__() method stays the same.

Yes, that's an excellent suggestion and improvement.

Saw the following in a post by Steven Bethard on another thread

that I think would be even better (in the sense of being more
general/generic) which also ought to work in subclasses. Namely:

def __repr__(self):
return '%s(%s)' % (self.__class__.__name__,
   ', '.join('%s=%r' % (k, v)
 for k, v
 in self.__dict__.items()))

Martin

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


Re: case/switch statement?

2005-06-22 Thread Martin Miller
Skip Montanaro wrote:
> Terry> Yeah, and I find this even more so:
>
> Terry> case =  {
> Terry> 5: do_this,
> Terry> 6: do_that,
> Terry> }
> Terry> case.get(x, do_default)()
>
> Terry> Which is looking pretty close to a case statement, anyway.
>
> Sure, modulo namespace issues.
>
> Skip

The namespace issue alluded to doesn't exist when using the very
similar approach suggested earlier in this thread by Andrew Durdin --
shown again below in a [very] contrived example illustrating access to
the local namespace:

greeting = "Hello there, "
x = 2

exec {
1: """greeting += 'Tom'""",
2: """greeting += 'Dick'""",
3: """greeting += 'Harry'""",
}.get(x, """greeting += 'Unknown'""")

print greeting

Martin

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


Re: "Ordered" dicts

2005-08-10 Thread Martin Miller
[EMAIL PROTECTED] wrote:
> > Lots and lots of people want ordered dicts it seems. Or at least, they
> > want
> > to be able to access their dictionary keys in order.
> > [snipped lots of examples, nice pro-con lists, etc.]
> >  What do y'all think?
>
> I'll second the need for this. Although, what can also be useful as a
> further extension (at least I needed this capability for a project I
> worked on) is the ability to not only have the keys sorted, but have them
> arranged in an arbitrary order (I had parsed some XML data, and each
> "object" represented in the XML had certain fields, which I was storing in
> a dictionary, but I needed each object to iterate that dictionary in the
> same order, preferably the order they occured in the file).
>
> I accomplished this through subclassing dict to create a
> SpecialSortedDict, overriding keys(), values(), the iterxxx() functions,
> and any others relevant so that it had an associated key order list. It
> would return keys in the specified order (ignoring any in the order list
> that weren't in the dictionary), an then any remaing keys were sorted at
> the end.
>
> I don't know if that'd be a useful enhancement to Chris's idea, or if it's
> a really obscure corner case. But I thought I'd throw it out there.

The need to have an ordered dictionaries is fairly common, IMHO. Having
one with keys sorted alphabetically is just a specific type of
ordering.

Russell Owen of the University of Washington has long had a class that
supports exactly these capabilities in his free RO Python package
(along with a number of  other useful things), see
.

Owen's 'OrderedDict' class is [also] implemented by subclassing dict.

To avoid continued reinvention of this wheel, I'd also vote to have
this functionality be at least included in a standard module, if not
built-in.

They say necessity is the mother of invention, therefore a lack of
standards or built-ins must be the mother of reinvention. ;-)

-Martin

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


Re: launching adobe reader with arguments from os.system call

2005-09-06 Thread Martin Miller
Greg Miller wrote:
> Currently I am launching adobe reader using the following call:
> os.system("path.file.pdf")
> this works fine for opening the pdf doc at the beginning. We would like
> to enhance this and open the document to either a page or a nameddest
> in the doc.  The syntax for that in the DOS command prompt world is:
> acroRd32.exe /A "nameddest=Before You Begin" "path.file.pdf"
> However the os.system call won't allow me to call reader using that
> syntax.  Does anyone know how I can launch the Reader application and
> pass in the parameters required to allow the document to be opened to
> the named destination?  Thanks in advance!!

I'm not sure how/if you can do what you want with os.system(), but this
is what I've used to pass arguments directly to applications on
Windows:
># spawn text editor on file
>import os
>applpath = r'C:\Windows\system32\notepad.exe'
>filepath =  r'D:\My Documents\somefile.txt'
>os.spawnv(
>os.P_WAIT,
>applpath,
>[ # argument list
>applpath,
>filepath
>]
>)

A downside is that it requires you to know the full path to the
application, 'acroRd32.exe' in your case. On the other hand, I think
you could pass just about any argument values (as strings) that you
wished in the list passed as the third argument.

HTH,
-Martin

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


Re: Python linear algebra module -- requesting comments on interface

2005-09-09 Thread Martin Miller
Since one of the module's targeted applications is for 3D applications,
I think there should be some specific support for applying the
Matrix-vector product operation to a sequence of vectors instead of
only one at a time -- and it should be possible to optimize the
module's code for this common case.

I'd also like to see some special specific errors defined and raised
from the Matrix det(), inverse(), and transpose() methods when the
operation is attempted on an ill-formed matrices (e.g. for non-square,
non-invertible, singular cases). This would allow client code to handle
errors better.

Very nice work overall, IMHO.

Best,
-Martin

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


Re: Curses on Windows

2005-02-08 Thread Martin Miller
I just tried the flangy.com link and it appears to be OK now.

Martin


Peter wrote:
> ...
> One reply (in fact the only reply - thanks Tim Golden) suggested I
> look at http://flangy.com/dev/python/curses/

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


Re: Test for structure

2005-02-20 Thread Martin Miller
I don't believe you can use the test for a __iter__ attribute in this
case, for the following reason:
>>> c1 = 'abc'
>>> c2 = ['de', 'fgh', 'ijkl']
>>> hasattr(c1, '__iter__')
False
>>> hasattr(c2, '__iter__')
True
>>> for i in c1: print "i=%s is an element of c1" % repr(i)
...
i='a' is an element of c1
i='b' is an element of c1
i='c' is an element of c1

In other words, even though the c1 single string variable does not have
an __iter__ attribute, it can still be used in a for loop. I think the
right answer would depend on what exactly the OP intends to do with the
argument when it is a list (or is list-like in some way) -- i.e. he
didn't say specifically that he wanted use it in a for loop.

-Martin



Terry Hancock wrote:
> On Wednesday 16 February 2005 09:08 am, alex wrote:
> > how can I check if a variable is a structure (i.e. a list)? For my
> > special problem the variable is either a character string OR a list
of
> > character strings line ['word1', 'word2',...]
> >
> > So how can I test if a variable 'a' is either a single character
string
> > or a list?
>
> The literally correct but actually wrong answer is:
>
> if type(a) == type([]):
> print "'a' is a duck"
>
> But you probably shouldn't do that. You should probably just test to
> see if the object is iterable --- does it have an __iter__ method?
>
> Which might look like this:
>
> if hasattr(a, '__iter__'):
> print "'a' quacks like a duck"
>
> That way your function will also work if a happens to be a tuple,
> a dictionary, or a user-defined class instance which is happens to
> be  iterable.
>
> Being "iterable" means that code like:
>
> for i in a:
>print "i=%s is an element of a" % repr(i)
>
> works.  Which is probably why you wanted to know, right?
>
> Cheers,
> Terry
>
> --
> --
> Terry Hancock ( hancock at anansispaceworks.com )
> Anansi Spaceworks  http://www.anansispaceworks.com

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


Re: Test for structure

2005-02-21 Thread Martin Miller
Yes, both string and lists have a __getitem__ attribute:

>>> c1 = 'abc'
>>> c2 = ['de', 'fgh', 'ijkl']
>>> hasattr(c1, '__getitem__')
True
>>> hasattr(c2, '__getitem__')
True

In other words you could index elements of either one using [].

Likewise, both a string and list would produce a usable iterator using
the following logic:

try:
itr = iter(a)
except TypeError:
# 'a' is not iterable
else:
# 'a' is iterable

In either case, you can't tell a string and list apart, which is what
the OP wanted to know, namely how to differentiate the two. EAPF is
fine, but what operation would answer the string vs list question?

Perhaps the test for an __iter__ attribute *is* the way to go because
you can tell the difference between the two type. Again I don't know
because the OP doesn't give enough information. I suspect, but don't
know, that it could be so that either one string or a list of strings
as an argument could treated as a list of 0 or more strings and
accessed by indices by most of the rest of the code.

I think the technique suggested by Robin Munn nearly a year ago (and
referenced by the link in Simon Brunning's post):
http://groups-beta.google.com/group/comp.lang.python/msg/c8befd4bed517bbc
namely:

try:
a + ''
except TypeError:
pass
else:
a= [a]

would be a good usable solution, although it's not totally infallible.
It may not be possible to give a better answer without more real
information about the desired usage.

Martin


=
Steven Bethard wrote:
> Terry Hancock wrote:
>  > But you probably shouldn't do that. You should probably just test
to
>  > see if the object is iterable --- does it have an __iter__ method?
>  >
>  > Which might look like this:
>  >
>  > if hasattr(a, '__iter__'):
>  > print "'a' quacks like a duck"
>
> Martin Miller top-posted:
> > I don't believe you can use the test for a __iter__ attribute in
this
> > case, for the following reason:
> >
> >>>>c1 = 'abc'
> >>>>c2 = ['de', 'fgh', 'ijkl']
> >>>>hasattr(c1, '__iter__')
> > False
> >
> >>>>hasattr(c2, '__iter__')
> > True
>
> Right.  str and unicode objects support iteration through the old
> __getitem__ protocol, not the __iter__ protocol.  If you want to use
> something as an iterable, just use it and catch the exception:
>
> try:
>  itr = iter(a)
> except TypeError:
>  # 'a' is not iterable
> else:
>  # 'a' is iterable
>
> Another lesson in why EAPF is often better than LBYL in Python[1].
> 
> STeVe
> 
> [1] http://www.python.org/moin/PythonGlossary

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


Re: Test for structure

2005-02-21 Thread Martin Miller
Testing for the '__iter__' (or even '__getitem__') attribute doesn't
really address the problem, nor does trying to execute the statement
'itr = iter(a)'.

To use EAPF and answer the OP's original question, which was

> So how can I test if a variable 'a' is either a single character
> string or a list?

I think the best answer would be to use Robin Munn's suggestion (see
http://groups-beta.google.com/group/comp.lang.python/msg/c8befd4bed517bbc)
as mentioned in the link in Simon Brunning's post) namely:

try:
a + ''
except TypeError:
pass
else:
a = [a]

However, to handle the more general problem of allow *any* argument to
be either a single item or a list seems to require a combination of
both EAPF and LBYL. This is the best solution I've been able to come up
with so far:

def asList(arg):
"""Makes sure the argument it is passed is a Python list.
If it is, it is just returned, otherwise a (possibly empty)
list is created and returned with the single item in it.

asList() can used to create flexible interfaces which allow
arguments to be passed to them that are either single items or
lists of items. By applying this function before using the
values in arguments, single and multi-valued cases can be
handled by general list-handling code in the function or
method.

As a special case, a single argument with the value None is
converted into an empty list (instead of converted into the
list [None]).

asList(arg) ==> list
"""

if arg is None:
return []
elif isinstance(arg, basestring): # special case strings (to
  # avoid list())
return [arg]
else:
try:
return list(arg)
except TypeError:
return [arg]


if __name__ == "__main__":

def example(items=None):
"""Sample function that can be called with a single argument
that can be a single or list of items.
"""
itemList = asList(items)
if not itemList:
print "example() called with empty list or None argument"
else:
print "example() called with argument containing %d " \
  "thing%s" % \
  (len(itemList), ('','s')[len(itemList)>1])
for i, item in enumerate(itemList):
print "  items[%d] = %s" % (i, repr(item))

example(42)
example((1,2,3))
example([4,5,6,7])
example('abc')
example(u'def')
example(["aaa", 111, (4,5), 2.01])
example(None) #  Note that this will become an empty list
example() #  same in this case

Which produces the following output:

example() called with argument containing 1 thing
  items[0] = 42
example() called with argument containing 3 things
  items[0] = 1
  items[1] = 2
  items[2] = 3
example() called with argument containing 4 things
  items[0] = 4
  items[1] = 5
  items[2] = 6
  items[3] = 7
example() called with argument containing 1 thing
  items[0] = 'abc'
example() called with argument containing 1 thing
  items[0] = u'def'
example() called with argument containing 4 things
  items[0] = 'aaa'
  items[1] = 111
  items[2] = (4, 5)
  items[3] = 2.0098
example() called with empty list or None argument
example() called with empty list or None argument

Can this be improved or is there anything wrong or overly limiting
about it?

TIA,
Martin


=
Steven Bethard wrote:
> Terry Hancock wrote:
>  > But you probably shouldn't do that. You should probably just test
to
>  > see if the object is iterable --- does it have an __iter__ method?
>  >
>  > Which might look like this:
>  >
>  > if hasattr(a, '__iter__'):
>  > print "'a' quacks like a duck"
>
> Martin Miller top-posted:
> > I don't believe you can use the test for a __iter__ attribute in
this
> > case, for the following reason:
> >
> >>>>c1 = 'abc'
> >>>>c2 = ['de', 'fgh', 'ijkl']
> >>>>hasattr(c1, '__iter__')
> > False
> >
> >>>>hasattr(c2, '__iter__')
> > True
>
> Right.  str and unicode objects support iteration through the old
> __getitem__ protocol, not the __iter__ protocol.  If you want to use
> something as an iterable, just use it and catch the exception:
>
> try:
>  itr = iter(a)
> except TypeError:
>  # 'a' is not iterable
> else:
>  # 'a' is iterable
>
> Another lesson in why EAPF is often better than LBYL in Python[1].
> 
> STeVe
> 
> [1] http://www.python.org/moin/PythonGlossary

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


Re: Test for structure

2005-02-22 Thread Martin Miller
At the end of his last post, Steve Bethard wrote:
> That said, I find that in most cases, the better option is to use
*args
> in the original function though.  For example:
>
>  def f(arg):
>  args = aslist(arg)
>  ...
>  f(42)
>  f(['spam', 'eggs', 'ham'])
>
> could probably be more easily written as:
>
>  def f(*args):
>  ...
>  f(42)
>  f('spam', 'eggs', 'ham')
>
> Of course this won't work if you have multiple list arguments.

Very interesting, but it also doesn't let you specify a default
argument value...however this gave me the idea that it would be
possible to use the *args idea to greatly simplify the proposed
aslist() function -- when one was needed to allow default argument
values and/or for handling multiple list arguments. Namely:

def aslist(*args):
return list(args)

def f(arg=None):
args = aslist(arg)
...

f()
f(42)
f('tanstaafl')
f(['spam', 'eggs', 'ham'])

This seems fairly lean and mean, with no if, isinstance, hasattr, or
try/excepts required -- although aslist() might need a check for the
single argument of None case, depending on whether it should return []
or something besides [None] in that situation.

Best,
Martin

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


Re: Execute a list

2005-02-22 Thread Martin Miller
Here is how to execute code in a string, similar to what was shown in
your example:

>>> s = 'print "hello"'
>>> exec s
hello

Hope this helps.

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


Re: Test for structure

2005-02-22 Thread Martin Miller
Ooops. I left out an "*" on a statement in the new aslist() function. I
should have written:

def aslist(*args):
   return list(*args) # corrected

def f(arg):
args = aslist(arg)
...

Sorry,
Martin

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


Re: Test for structure

2005-02-22 Thread Martin Miller
Nope, that isn't right either, in the sense that it handles all the
cases properly, including "single string" vs "list of strings'. Guess
this overly simplistic aslist() does not work after. I should have been
more suspicious and cautious before posting. Sorry.

Martin

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


'class' argument optional for new.instancemethod?

2005-03-11 Thread Martin Miller
In section "3.27 new -- Creation of runtime internal objects" of the
documentation that comes with Python 2.4 it says:

> instancemethod(function, instance, class)
>
> This function will return a method object, bound to instance, or
unbound if
> instance is None. function must be callable.

However, some simple experiments I've tried seem to indicate that the
last argument, 'class' can be left off with no ill effects, and is
therefore optional.

Doesn't anyone know if this is a documention problem? Personally, I
don't understand how the argument gets used when it *is* provided -- if
nothing else, having it seems somewhat redundant given the presence of
the 'instance' argument.

TIA,
Martin

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


Add Properties to Instances?

2005-03-12 Thread Martin Miller
I'm trying to create some read-only instance specific properties, but
the following attempt didn't work:

> class Foobar(object):
> pass
>
> foobar = Foobar()
> foobar.x = property(fget=lambda: 42)
>
> print "foobar.x:", foobar.x

Which results in the following ouput instead of '42':
  foobar.x: 

I also tried this:
> foobar.__dict__['x'] = property(fget=lambda: 42)
but get the same behavior.

Can anyone tell me what's wrong with this approach (and perhaps the
correct way to do it, if there is one)?

TIA,
Martin

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


Re: Add Properties to Instances?

2005-03-12 Thread Martin Miller
So far a couple of people have asked:
> What's the situation in which you think you want different properties
> for different instances of the same class?

Fair enough -- here goes:

Essentially what I'm doing is implementing (yes, yet another ;-)
'enumeration' class using an an approach which involves an instance
factory function which returns a customized version of a predefined
generic '_Enum' class instance.

It does this by first creating an instance of the generic class and
then adds attributes (enumerator ids and corresponding values among
others) to it which are specific to the enumeration being created. This
all works pretty well, but I would like to make the values associated
with the ids immutable -- through normal means, at least.

It's not feature complete, but I would be happy post the current code
if there is interest in more of the details. Meanwhile, I'm going to
study the replies so far and think about the whole issue (and design) a
little more.

Thanks to all who have replied,
Martin

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


Re: Add Properties to Instances?

2005-03-14 Thread Martin Miller
In answer to my question about instance properties not working, Bengt
Richter suggest using:
> > >>> class InstProp(object):
> > ... def __getattribute__(self, attr):
> > ... p = object.__getattribute__(self, attr)
> > ... if isinstance(p, property): return p.__get__(self)
> > ... return p

and more generally for any descriptor object:

>  >>> class InstProp(object):
>  ... def __getattribute__(self, attr):
>  ... p = object.__getattribute__(self, attr)
>  ... if hasattr(p, '__get__'): return p.__get__(self,
type(self))
>  ... return p

Both the above makes the '__get__' method of any property attributes of
the instance to be used. However, it does not cause attempts to be made
to access their "__set__' methods when assigning to them (which should
fail in my case because my properties don't have such a method because
they are read-only).

Just overriding '__getattribute__' alone is insufficent to make
instance property/descriptor attributes fully function. To do so also
requires overriding the __setattr__ method so it checks for a '__set__'
method and then uses it if one is found (or delegates it to
object.__setattr__ if not).

Similarily, an override for '__delattr__' would also be need for
complete property functionality, I believe.

For just making instance attributes read-only, it seems to be that the
simplist solution would be to override __setattr__ and make it check to
see if the attribute is write protected or not, which is really all I
need for the specific task I'm trying to accomplish (which is
esstentially what Jeremy Bowers said in his reply).

What still puzzles me, though, is why all the above to make properties
work on instances is necessary in the first place. It's certainly not
clear (to me) from what is said in the How-to at:
>
http://users.rcn.com/python/download/Descriptor.htm#invoking-descriptors
I suspect that it may be simply a performance issue, in other words, it
was considered too slow to check for instance property/discriptors --
although *why* is not clear to me.

Best Regards,
Martin

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


Re: Add Properties to Instances?

2005-03-14 Thread Martin Miller
Bengt Richter wrote, in part:
> On 14 Mar 2005 01:19:23 -0800, "Martin Miller"
<[EMAIL PROTECTED]>
> wrote, in part:
> >What still puzzles me, though, is why all the above to make
properties
> >work on instances is necessary in the first place. It's certainly
not
> >clear (to me) from what is said in the How-to at:
> >>
>
>http://users.rcn.com/python/download/Descriptor.htm#invoking-descriptors
> >I suspect that it may be simply a performance issue, in other words,
it
> >was considered too slow to check for instance property/discriptors
--
> >although *why* is not clear to me.
>
> I suspect the desired semantics re precedence have evolved to make
normal
> programs easily implementable, and that probably drove the
implementation:
> """
> For objects, the machinery is in object.__getattribute__ which
transforms
> b.x into type(b).__dict__['x'].__get__(b, type(b)).
> The implementation works through a precedence chain that gives (my
added
> [1,2,3])
>
> [1] data descriptors priority over instance variables,
> [2] instance variables priority over non-data descriptors,
> [3] and assigns lowest priority to __getattr__ if provided.
>
> The full C implementation can be found in PyObject_GenericGetAttr()
in
> Objects/object.c.
> """

I haven't examined the C code in Objects/object.c to see *how* the
semantics are implemented because that's not really the point...which
is the descriptions of what's suppose to happen don't seem to match
what actually does. To illustrate, consider:
> class Foobar(object):
> pass
>
> def myget(self, obj, type=None):
> return 42
>
> def myset(self, value):
> raise AttributeError("this is a read-only property")
>
> foobar = Foobar()
> foobar.x = property(myget, myset)
>
> print "foobar.x:", foobar.x

Which prints:
> foobar.x: 

Ignoring "why" issue, my question becomes:

foobar.x is a data descriptor property, however object.__getattribute__
does *not* seem to be treating it as such and handling it the way
described either by you or in what is written in the how-to.
Specifically the statements that:
> For objects, the machinery is in object.__getattribute__ which
transforms
> b.x into type(b).__dict__['x'].__get__(b, type(b)).

This doesn't seem to be occuring. Am I missing something?

Thanks,
Martin

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


Re: Add Properties to Instances?

2005-03-19 Thread Martin Miller
Bengt Richter wrote:
> On 14 Mar 2005 13:07:29 -0800, "Martin Miller"
<[EMAIL PROTECTED]> wrote:
>
> >Bengt Richter wrote, in part:
> >> On 14 Mar 2005 01:19:23 -0800, "Martin Miller"
> ><[EMAIL PROTECTED]>
> >> wrote, in part:
> >> >What still puzzles me, though, is why all the above to make
> >properties
> >> >work on instances is necessary in the first place. It's certainly
> >not
> >> >clear (to me) from what is said in the How-to at:
> >> >>
> >>
>
>>http://users.rcn.com/python/download/Descriptor.htm#invoking-descriptors
> >> >I suspect that it may be simply a performance issue, in other
words,
> >it
> >> >was considered too slow to check for instance
property/discriptors
> >--
> >> >although *why* is not clear to me.
> >>
> >> I suspect the desired semantics re precedence have evolved to make
> >normal
> >> programs easily implementable, and that probably drove the
> >implementation:
> >> """
> >> For objects, the machinery is in object.__getattribute__ which
> >transforms
> >> b.x into type(b).__dict__['x'].__get__(b, type(b)).
> >> The implementation works through a precedence chain that gives (my
> >added
> >> [1,2,3])
> >>
> >> [1] data descriptors priority over instance variables,
> >> [2] instance variables priority over non-data descriptors,
> >> [3] and assigns lowest priority to __getattr__ if provided.
> >>
> >> The full C implementation can be found in
PyObject_GenericGetAttr()
> >in
> >> Objects/object.c.
> >> """
> >
> >I haven't examined the C code in Objects/object.c to see *how* the
> >semantics are implemented because that's not really the
point...which
> >is the descriptions of what's suppose to happen don't seem to match
> >what actually does. To illustrate, consider:
> >> class Foobar(object):
> >> pass
> >>
> >> def myget(self, obj, type=None):
> >> return 42
> >>
> >> def myset(self, value):
> >> raise AttributeError("this is a read-only property")
> >>
> >> foobar = Foobar()
> >> foobar.x = property(myget, myset)
> >>
> >> print "foobar.x:", foobar.x
> >
> >Which prints:
> >> foobar.x: 
> >
> >Ignoring "why" issue, my question becomes:
> >
> >foobar.x is a data descriptor property, however
object.__getattribute__
> It is a property, and it has the requisite methods (__get__ and
__set__) to be
> a data descriptor, but it is not a data descriptor unless it is
visible as
> an attribute of type(foobar), which foobar.x is not.
>
> >does *not* seem to be treating it as such and handling it the way
> >described either by you or in what is written in the how-to.
> >Specifically the statements that:
> >> For objects, the machinery is in object.__getattribute__ which
> >transforms
> >> b.x into type(b).__dict__['x'].__get__(b, type(b)).
> >
> >This doesn't seem to be occuring. Am I missing something?
> >
> I think so. Following your example:
>
>  >>> class Foobar(object):
>  ... pass
>  ...
>  >>> def myget(self, obj, type=None):
>  ... return 42
>  ...
>  >>> def myset(self, value):
>  ... raise AttributeError("this is a read-only property")
>  ...
>  >>> foobar = Foobar()
>  >>> foobar.x = property(myget, myset)
>  >>> print "foobar.x:", foobar.x
>  foobar.x: 
>  >>>
>  >>> type(foobar).__dict__['x']
>  Traceback (most recent call last):
>File "", line 1, in ?
>  KeyError: 'x'
>
> meaning
>b.x into type(b).__dict__['x'].__get__(b, type(b)).
> does not apply, and the attempt to get foobar.x falls back to
> ordinary attribute access. I.e., foobar.x will be whatever
>
> BTW, I'm not sure type(b).__dict__['x'].__get__(b, type(b))
> is really fully correct, since that would not find foobar.x in a
Foobar base class:
>
>  >>> class Base(object): pass
>  ...
>  >>> Base.x = property(myget, myset)
>  >>> class Sub(Base): pass
>  ...
>  >>> sub = Sub()
>  >>> sub.x
>  Traceback (most recent call last):
>File "", line 1, in ?
>  TypeError: myget() takes at least 2 arguments (1 given)
>
> (At least it was foun

Re: Python IDE (was: PythonWin troubleshooting)

2005-12-15 Thread Martin Miller
You might want to also to consider the Komodo IDE from ActiveState (the
same company that produces ActivePython and hosts the ASPN Cookbook).
This isn't an endorsement -- I have no experience with it --  but its
feature set looks good  [see http://activestate.com/Products/Komodo].

If someone with actual experience using Komodo with Python is
listening, I'd be very interested in hearing what you think of it or
other alternatives (I plan on taking a look at PyScripter and any
others I hear about).

Best,
-Martin


==
chuck wrote:
> Apparently not too many people use or are interested in PythonWin.  I'm
> giving up on it.  It used to work pretty good.
>
> I'm lucky that I have found PyScripter (http://www.mmm-experts.com/) a
> python IDE for the windows platform which is much more stable and has
> more features that PythonWin.  If you are doing Python development on
> Windows I'd recommend taking a look at it.
>
> I'm also evaluating Wing IDE.  I may have another post with comments on
> it for anyone who might be interested.

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


Re: How do I redirect output to a file and to the console screen?

2005-12-28 Thread Martin Miller
The basic way to redirect output is to reassign a value to sys.stdout
-- something along these lines:

# redirect stdout to a disk file
import sys
saveout = sys.stdout
outfile = open('output.txt', 'w')
sys.stdout = outfile

# output stuff
print 'hello world'

# restore stdout
outfile.flush()
outfile.close()
sys.stdout = saveout:

Essentially what you want is to have output redirected to *two*
different streams at the same time, the original stdout and a file.
Here's a link to a (very old) post on the subject that should help (see
'class Tee') if coupled with the above:

> http://groups.google.com/group/comp.lang.python/msg/5ab52448c1cbc10e

-Martin

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


Re: batch tiff to jpeg conversion script

2006-01-11 Thread Martin Miller
[EMAIL PROTECTED] wrote:
> Hi Peter. The guy who takes the pictures uses Photoshop to convert
> tiffs to jpegs one by one. When he does a 'Maxium Quality' conversion
> in Photoshop and I do a 100% quality conversion with Python and PIL,
> the two converted files are almost identical and this is what he
> wants... that's the only reason I'm using 100% quality. Thanks for the
> info!

Allow me interject two observations:

1) You should tell the guy using Photoshop what Peter pointed out
regarding the Jpeg Quality setting.

2) Although it wouldn't be as flexible as your Python script, it's
completely possible and fairly easy to automate such a conversion
within Photoshop using 'Actions', which are like recorded macros,
coupled with the Automate | Batch... submenu.

Best,
-Martin

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


Re: batch tiff to jpeg conversion script

2006-01-12 Thread Martin Miller
[EMAIL PROTECTED] wrote:
> Just curious... is PhotoShop _really_ recursive? We have dozens of
> levels of sub-folders where the pics have been sorted and thousands of
> pics. That's one reason I used os.walk()

Yes, in the sense that there is an "Include All Subfolders" option for
batch operation source files that recursively locates input files.
However, at least in the version I have (CS), there is no obvious way
to get it to recreate the input folder hierarchy with a different root
folder specified as the destination (all the output files get put in
single folder specified) -- something that could be fairly easily
accomplished using a Python script.

Since in this case you are doing file *conversions*, the output files
will have a different extension than the orginals, and can therefore
exist in the same folders (assuming there's enough disk space).  This
makes it possible to record a "Save As" command in the Action which to
simply save the converted image back into the same folder as the
orginal in a different format, thus preserving the file & folder
layout.

Sorry, but I feel any more detail on the process would be getting way
too off-topic for this newsgroup.  Feel free to contact me directly if
you would like to discuss in more detail how to do this sort of thing
from within Photoshop.

Best,
-Martin

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


Re: Make all files extension lower by a given directory name

2006-11-03 Thread Martin Miller
Tim Chase wrote, in part:
> ...
> I've found that Win32 doesn't often take a rename if the origin
> and destination differ only in case[*].  Thus, to change the
> case, I've had to do *two* renames...one to, say, prefix with an
> underscore and change the case to my desired case, and then one
> to strip off the leading underscore.  You might try a similar
> song-and-dance to strong-arm Windows into specifying the case of
> the file.  ...

FWIW, I just tried a file name case-only os.rename() on a file running
Win XP SP2 with Python 2.5 and it worked just fine -- i.e. changed
'TextFile.TXT' to 'TextFile.txt') with just a single call to
os.rename(), no error was raised, and the case of the letters in the
file name were changed properly. (I can also do the same thing at the
command line with a similar results.)

Perhaps you were using a different version of Windows or the os module
(silently) handles the situation. I do agree that this is arguably
strange behavior given how the OS mostly ignores case...

-mm

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


Re: Character Encodings and display of strings

2006-11-14 Thread Martin Miller
It is possible derive your own string class from the built-in one and
override what 'repr' does (and make it do whatever you want). Here's an
example of what I mean:

# Sample #

# -*- coding: iso-8859-1 -*-

# Special string class to override the default
# representation method. Main purpose is to
# prefer using double quotes and avoid hex
# representation on chars with an ord > 128
class MsgStr(str):

def __repr__(self):
asciispace = ord(' ')
if self.count("'") >= self.count('"'):
quotechar = '"'
else:
quotechar = "'"

rep = [quotechar]
for ch in self:
if ord(ch) < asciispace:
rep += repr(str(ch)).strip("'")
elif ch == quotechar:
rep += "\\"
rep += ch
else:
rep += ch
rep += quotechar

return "".join(rep)

if __name__ == "__main__":
s = MsgStr("\tWürttemberg\"")
print s
print repr(s)
print str(s)
print repr(str(s))

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

Re: Class constant for extension

2006-12-23 Thread Martin Miller
[EMAIL PROTECTED] wrote:
> Hi,
>
>   I have written a small prototype Python extension for a C-library.
>
>   I have the methods all sorted out and it is working fine.
>
>   In the C-library, they are various constants of types like string,
> integer, float and matrix. I'd like to expose them as READONLY values.
>
>   Is the use of PyMemberDefs a suitable way to provide such access?
>
>   I'd like the user of the extension to be able to do something like
> the follow
>
>   import MyExtension
>
>   MyExtension.begin()
>   mv = MyExtension.minValue
>   MyExtension.process(MyExtension.versionStr)
>   MyExtension.end()
>
>   Is someone able to point me to an example code of how I can write my
> extension so that the references to those constants can be used in the
> above way.
>
> Regards

A couple of years ago I wanted to do something similar for a project I
was working on.
Below is a snippet of some sample C code from the module's
initialization function which should give you an idea of the approach
used. It's a limited example and only creates module identifiers for
simple integer values, not the more complex types you are interested
in, nor does it do anything to make them read only, but it might help
get you started.

If you find something that addresses these deficiencies, please post
your findings.

Best,
-Martin

// snippet
#include "Python.h"

enum METAtags
{
kMETA_MojikumiX4051 = 0,
kMETA_UNIUnifiedBaseChars = 1,
kMETA_BaseFontName = 2
}

void initPyExtension()
{
PyObject *m, *d, *o;
m = Py_InitModule4("PyExtension", pyis_methods,
PySING_module_documentation,
(PyObject*)NULL, PYTHON_API_VERSION);

// Add some symbolic constants to the module
d = PyModule_GetDict(m); // get modules dictionary

PyObject* o = PyInt_FromLong(kMETA_MojikumiX4051);
PyDict_SetItemString(d, "idMojikumiX4051", o);
Py_INCREF(o); // for dictionary ref

PyObject* o = PyInt_FromLong(kMETA_UNIUnifiedBaseChars);
PyDict_SetItemString(d, "idUNIUnifiedBaseChars", obj);
Py_INCREF(o);

PyObject* o = PyInt_FromLong(kMETA_BaseFontName);
PyDict_SetItemString(d, "idBaseFontName", obj);
Py_INCREF(o);
   .
   .
   .

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


Re: (newbie) Is there a way to prevent "name redundancy" in OOP ?

2007-01-05 Thread Martin Miller
Stef Mientki wrote:
> Not sure I wrote the subject line correct,
> but the examples might explain if not clear
>
>
> *** first attempt ***
> class pin:
>def __init__ (self):
>  self.Name  = 'Unknown Pin'
>
> aap = pin() # create an instance
> aap.Name = 'aap'# set it's name
> print aap.Name  # print it's name
>   # but why should I set it's name ??
> print 'aap'   # I can just as well print a constant string !!
>  # (ok there will be an extra check)

While I agree that it's likely you're confusing Python objects and
names, Python *is* an interpreted language and therefore very flexible.
Here's a snippet showing one way to remove the 'redundancy'. (Be
forewarned that doing things like this is highly distasteful to some
people.)

### non-redundant example ###
import sys

class Pin:
def __init__(self, name, namespace=None):
self.name = name
if namespace == None:
# default to caller's globals
namespace = sys._getframe(1).f_globals
namespace[name] = self

Pin('aap')   # create a Pin object named 'aap'
Pin('aap2') # create a Pin object named 'aap2'
print aap.name
print aap2.name

-Martin

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


Re: (newbie) Is there a way to prevent "name redundancy" in OOP ?

2007-01-06 Thread Martin Miller
Carl Banks wrote:

> Martin Miller wrote:
> > ### non-redundant example ###
> > import sys
> >
> > class Pin:
> > def __init__(self, name, namespace=None):
> > self.name = name
> > if namespace == None:
> > # default to caller's globals
> > namespace = sys._getframe(1).f_globals
> > namespace[name] = self
> >
> > Pin('aap')  # create a Pin object named 'aap'
> > Pin('aap2') # create a Pin object named 'aap2'
> > print aap.name
> > print aap2.name
>
> The problem with this is that it only works for global namespaces,
> while failing silently and subtly if used in a local namespace:

Oh, contrair. It would work fine with local namespaces simply by
overriding the default value of the optional 'namepace' parameter (see
below).

> def fun():
> Pin('aap')
> aap1 = aap
> fun2()
> aap2 = aap
> print aap1 is aap2
>
> def fun2():
> Pin('aap')
>
> If it's your deliberate intention to do it with the global namespace,
> you might as well just use globals() and do it explicitly, rather than
> mucking around with Python frame internals.  (And it doesn't make the
> class unusable for more straightforward uses.)

You could be more explicit by just passing 'globals()' as a second
parameter to the __init__ constructor (which is unnecessary, since
that's effectively the default).

It's not clear to me how the example provided shows the technique
"failing silently and subtly if used in a local namespace" because what
happens is exactly what I would expect if the constructor is called
twice with the same string and defaulted namespace -- namely create
another object and make the existing name refer to it. If one didn't
want the call to Pin in fun2 to do this, just change fun2 to this:

def fun2():
Pin('aap', locals())

This way the "print aap1 is aap2" statement in fun() would output
"true" since the nested call to Pin would now (explicitly) cause the
name of the new object to be put into fun2's local namespace leaving
the global one created by the call in fun() alone.

Obviously, this was not an objection I anticipated. An important one I
would think is the fact that the current documentation says that
f_globals is a special *read-only* attribute of a frame object implying
that it shouldn't be changed (even though doing so 'works' as my
example illustrates).

I think other valid arguments against this practice might include
whether it's an example of good OOP, or a good programming practice at
all, since it involves possibly subtle side-effects, the use of global
variables, and/or is 'unpythonic'.

Certainly the approach is not without caveats. Despite them, I believe
it can be useful in some contexts, as long as what is going on is
clearly understood. The point of my reply to the OP was mainly just to
illustrate the power and flexibility of Python to the newbie. I guess
to that I should have also added that it gives you "enough rope to
shoot yourself" as Allen Holub said regarding C++.

Cheers,
-Martin

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


Re: Re:[OT] (newbie) Is there a way to prevent "name redundancy" in OOP ?

2007-01-07 Thread Martin Miller
Bruno Desthuilliers wrote:

> Martin Miller a écrit :
> (snip)
> >
> > Oh, contrair.
>
> I guess you mean "au contraire" ?-)
>
> (snip)

FWIW "contrair" is how it's spelled in the Oxford English dictionary (I
actually did look it up before posting because it seemed like there
ought be an 'e' on the end). The dictionary also says it's chiefly
Scottish but the etymology indicates from the Old French "contraire".

Technically I suppose I should have written "Oh, *on* contrair" or
better yet just "On the contrary". ;-)

-Martin

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


Re: Python cheatsheets

2007-01-07 Thread Martin Miller
gonzlobo wrote:

> Curious if anyone has a python cheatsheet* published? I'm looking for
> something  that summarizes all commands/functions/attributes. Having
> these printed on a 8" x 11" double-sided laminated paper is pretty
> cool.
>
> * cheatsheet probably isn't the right word, but you get the idea. :)

Richard Gruet publishes an excellent Quick Reference in multiple
formats, available from .

-Martin

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


Re: PDF rendering toolkit?

2007-01-07 Thread Martin Miller
Jorge Vargas wrote:
> Hi
>
> I'm looking for a tool to take an actual .pdf file and display it in a
> window (I'm using wxwidgets at the moment)
>
> [snip]

How about just using Adobe's Acrobat Reader application which is freely
available on most platforms?

There's some related information about doing this in the following
thread that might help get you started :
> http://groups.google.com/group/comp.lang.python/browse_frm/thread/3a578c032ff72d46/c1ddf40bf738cd7f?&hl=en#c1ddf40bf738cd7f

HTH,
-Martin

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


Re: (newbie) Is there a way to prevent "name redundancy" in OOP ?

2007-01-10 Thread Martin Miller
Carl Banks wrote:
> Martin Miller wrote:
> > Carl Banks wrote:
> >
> > > Martin Miller wrote:
> > > > ### non-redundant example ###
> > > > import sys
> > > >
> > > > class Pin:
> > > > def __init__(self, name, namespace=None):
> > > > self.name = name
> > > > if namespace == None:
> > > > # default to caller's globals
> > > > namespace = sys._getframe(1).f_globals
> > > > namespace[name] = self
> > > >
> > > > Pin('aap')  # create a Pin object named 'aap'
> > > > Pin('aap2') # create a Pin object named 'aap2'
> > > > print aap.name
> > > > print aap2.name
> > >
> > > The problem with this is that it only works for global namespaces,
> > > while failing silently and subtly if used in a local namespace:
> >
> > Oh, contrair. It would work fine with local namespaces simply by
> > overriding the default value of the optional 'namepace' parameter (see
> > below).
>
> Did you try it?

Yes, but I misinterpreted the results which seemed to support my
claim. Therefore I must retract what I wrote and now have to agree
with what you said about it not working in a local namespace --
specifically in the sense that it is unable to bind the instance the
name in the caller's local namespace.

I'm not sure that this is a critical flaw in the sense that it may
not matter for some usages. For example I've seen it used to define
(yet another) Enum class which facilitated the creation of names
bound to a range or sequence of values. The fact that these couldn't
be defined local to code block wasn't apparently a big issue.


> > > def fun():
> > > Pin('aap')
> > > aap1 = aap
> > > fun2()
> > > aap2 = aap
> > > print aap1 is aap2
> > >
> > > def fun2():
> > > Pin('aap')
> > >
> > > If it's your deliberate intention to do it with the global namespace,
> > > you might as well just use globals() and do it explicitly, rather than
> > > mucking around with Python frame internals.  (And it doesn't make the
> > > class unusable for more straightforward uses.)
> >
> > You could be more explicit by just passing 'globals()' as a second
> > parameter to the __init__ constructor (which is unnecessary, since
> > that's effectively the default).
> >
> > It's not clear to me how the example provided shows the technique
> > "failing silently and subtly if used in a local namespace" because what
> > happens is exactly what I would expect if the constructor is called
> > twice with the same string and defaulted namespace -- namely create
> > another object and make the existing name refer to it. If one didn't
> > want the call to Pin in fun2 to do this, just change fun2 to this:
>
> Because the usage deceptively suggests that it defines a name in the
> local namespace.  Failing may be too strong a word, but I've come to
> expect a consistent behavior w.r.t. namespaces, which this violates, so
> I think it qualifies as a failure.

I don't see how the usage deceptively suggests this at all. In this
case -- your sample code for fun() and fun2() -- all were simply
Pin('aap'). Since no additional namespace argument was supplied, the
same name was bound in the defaulted global namespace each time but
to different objects. In other words the 'print aap1 is aap2'
statement produced 'false' because the call to fun2() changed the
(global) object to which 'aap' was previously bound.

>
> > def fun2():
> > Pin('aap', locals())
>
> Did you actually try this?  ...

As I said, yes, I did, and the addition of the 'locals()' parameter
does make the 'print aap1 is aap2' statement in fun() output 'true'.
This lead me to take for granted that it had bound the name in the
local namespace. However this assumption was incorrect, but that
wasn't obvious since there were no further statements in fun2().

The problem is that there fundamentally doesn't seem to be a way to
create local variables except directly by using an assignment
statement within the block of a function or method. Modifying the
mapping returned from locals() does not accomplish this -- normally
anyway, although interestingly, it will currently if there's an exec
statement anywhere in the function, even a dummy one, but this is
not a documented feature and from what I've read just si

Re: New os.path.exists() behavior - bug or feature?

2007-01-24 Thread Martin Miller
FWIW, your code works correctly for me in all respects with Python 2.5
on Windows XP Pro.
I no longer have Python 2.4.x installed, so can't easily do a
comparison.

Perhaps the problem has something to do with Python 2.5 with Windows
2K.

-Martin


On Dec 17 2006, 4:29 pm, "klappnase" <[EMAIL PROTECTED]> wrote:
> Hi all,
> yesterday I installed Python-2.5 and python-2.4.4 on my windows2k box.
> When trying to use os.path.exists() to detect which drives are present
> on the system I noticed that
> these behave differently:
>
> Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)]
> on win32
> Type "copyright", "credits" or "license()" for more information.
>
> >>> import os
> >>> for char in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':if 
> >>> os.path.exists('%s:\\' % char):
> print '%s:\\' % char
>
> A:\
> C:\
> D:\
> E:\
>
> ###
>
> Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit
> (Intel)] on win32
> Type "copyright", "credits" or "license()" for more information.
>
> >>> import os
> >>> for char in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':if 
> >>> os.path.exists('%s:\\' % char):
> print '%s:\\' % char
>
> C:\
>
> When I insert a floppy into A: os.path.exists('A:\\') will return True
> on Python-2.5, too.
> Does anyone know, is this inconsistent behavior a bug or a new feature?
>
> I also noticed that theTixbinaries are no longer present in 2.5, does
> anyone know if it is
> planned to remove them pemanently?
> 
> Thanks in advance
> 
> Michael

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