Re: Re: PyQt QCalendarWidget events question

2012-07-16 Thread John Posner
On 7/16/2012 12:28 PM, [email protected] wrote:
> [email protected] wrote:
>> I am trying to use the PyQt4 calendar widget to perform some different
>> actions on specific dates.  There are three events available:-
>>
>> selectionChanged()
>> activated(QDate)
>> clicked(QDate)
>>
>> On trying all these out it would appear that the event handlers get
>> called as follows:-
>>
>> The clicked(QDate) event gets called if you click on an already
>> selected date.
>>
>> The selectionChanged() and then the clicked(QDate) events are
>> called when you click on a new date.
>>
>> The selectionChanged(), then the clicked(QDate) and then the
>> activated(QDate) events are called if you double-click on a new date.
>>
>> The clicked(QDate) and then the activated(QDate) events are called
>> if you double-click on an already selected date.
>>
>>
>> How can I get a single-click on a date to get 'Action1' and double-click
>> on a date to get 'Action2'?
> I'm sorry, this got sent a bit before I'd completed it.  The trouble
> is that I want to run Action1 if I single-click on a date whether or
> not it's a changed date and I want to run Action2 if I double-click on
> a date whether or not it's a changed date.  However I don't see how I
> can do this because of the order in which the event handlers are
> called.
>
> Is there any way to manipulate this so I can get the result I want? 
> At the moment the only way I can see to do it is to wait a while after
> a click and then look at what actions occurred but this seems a real
> bodge.

I suspect that the consensus would be "don't do that" -- having
single-click and double click perform unrelated actions. But here's an
implementation based on the advice at
http://www.qtcentre.org/threads/7858-Double-Click-Capturing

(use Ctrl-Break to break out of the event loop)

import PyQt4.QtCore as C
import PyQt4.QtGui as G

class Button(G.QPushButton):
def __init__(self, text):
G.QPushButton.__init__(self, text)

# flag to suppress second mouseReleaseEvent
# in this double-click event sequence:
# 1. mousePressEvent
# 2. mouseReleaseEvent
# 3. mouseDoubleClickEvent
# 4. mouseReleaseEvent
self.double_clicked = False

def mouseReleaseEvent(self, evt):
# executed for first mouseReleaseEvent
if not self.double_clicked:
self.first_click_timer = C.QTimer()
self.first_click_timer.setSingleShot(True)
# double-click must occur within 1/4 second of first-click
release
self.first_click_timer.setInterval(250)
self.first_click_timer.timeout.connect(self.single_click_action)
self.first_click_timer.start()
# executed for second mouseReleaseEvent
else:
# reset the flag
self.double_clicked = False

def single_click_action(self):
print "Performing single-click action"

def mouseDoubleClickEvent(self, evt):
# suppress the single-click action; perform double-click action
instead
self.first_click_timer.stop()
print "Performing double-click action"

# prepare for second mouseReleaseEvent
self.double_clicked = True

# main program

app = G.QApplication([])
button = Button("Click or double-click me")
button.show()
app.exec_()


HTH,
John

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


Re: calling a simple PyQt application more than once

2012-01-27 Thread John Posner
Jabba Laci wrote:
> Hi,
>
> I have a simple PyQt application that creates a webkit instance to
> scrape AJAX web pages. It works well but I can't call it twice. I
> think the application is not closed correctly, that's why the 2nd call
> fails. Here is the code below. I also put it on pastebin:
> http://pastebin.com/gkgSSJHY .
>
> The question is: how to call this code several times within a script.

You want to create/execute/quit a QApplication just once, not multiple
times.

I don't know either WebKit  or AJAX. In fact, I've never done any
networking with PyQt. But a little playing with the QtNetwork module
yielded this, using the QNetworkAccessManager and QNetworkRequest classes:

from PyQt4.QtCore import QUrl
from PyQt4.QtGui import QApplication, QPushButton
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest

def process_page(reply_obj):
resp = reply_obj.readAll()
reply_obj.close()
print str(resp).strip()

def do_click():
req = QNetworkRequest(QUrl(MYURL))
mgr.finished.connect(process_page)
mgr.get(req)

MYURL = 'http://simile.mit.edu/crowbar/test.html'

if __name__ == "__main__":
# we need only one application object and one net-access mgr
app = QApplication([])
mgr = QNetworkAccessManager()

# the entire GUI is one button
btn = QPushButton("Press me")
btn.clicked.connect(do_click)
btn.show()

# start the event loop
app.exec_()

You can click the "Press me" button as many times as you wish; it
retrieves and displays/prints the same HTML file on each click.

HTH,
John

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


Re: calling a simple PyQt application more than once

2012-01-29 Thread John Posner
Jabba Laci wrote:

> Hi, Thanks for your reply. I forgot to mention that my first solution
> created a headless browser, i.e. it didn't create any GUI. I would
> like to keep it that way, thus I could scrape (AJAX-powered) webpages
> in batch mode without any user interaction.

No head, no problem. Just use a QCoreApplication instead of a
QApplication, and use a QTimer instead of a QPushButton to invoke
do_click():

from PyQt4.QtCore import QUrl, QCoreApplication, QTimer
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest

def process_page(reply_obj):
resp = reply_obj.readAll()
reply_obj.close()
print str(resp).strip()

def do_click():
req = QNetworkRequest(QUrl(MYURL))
mgr.finished.connect(process_page)
mgr.get(req)

MYURL = 'http://simile.mit.edu/crowbar/test.html'

if __name__ == "__main__":
# we need only one application object and one net-access mgr
app = QCoreApplication([])
mgr = QNetworkAccessManager()

# use timer instead of button to retrieve web page repeatedly
timer = QTimer()
timer.timeout.connect(do_click)
timer.start(5 * 1000)
 
# start the event loop
app.exec_()

Another thought: if you don't need a GUI, you might consider using plain
old Python, rather than PyQt. Here's some code adapted from
http://www.boddie.org.uk/python/HTML.html:

import urllib

WEBPAGE = "http://simile.mit.edu/crowbar/test.html";
SEVERAL_TIMES = 3

for _ in range(SEVERAL_TIMES):
# Get a file-like object for the Python Web site's home page.
f = urllib.urlopen(WEBPAGE)
# Read from the object, storing the page's contents in 's'.
s = f.read()
f.close()
print s

Best,
John

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


Re: Re: what is the difference between @property and method

2012-02-09 Thread John Posner
On 2:59 PM, Devin Jeanpierre wrote:


> It is kind of funny that the docs don't ever explicitly say what a
> property is. http://docs.python.org/library/functions.html#property --
> Devin 

Here's a writeup that does:
http://wiki.python.org/moin/AlternativeDescriptionOfProperty

-John

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


Re: Formate a number with commas

2012-02-09 Thread John Posner
On 2:59 PM, noydb wrote:
> How do you format a number to print with commas?

I would readily admit that both the "locale" module and "format" method
are preferable to this regular expression, which certainly violates the
"readability counts" dictum:

r"(?<=\d)(?=(\d\d\d)+$)"

# python 2.6.6
import re
find_blocks = re.compile(r"(?<=\d)(?=(\d\d\d)+$)")
for numstr in "1 12 123 1234 12345 123456 1234567 12345678".split():
print find_blocks.sub("," , numstr)

output is:

1
12
123
1,234
12,345
123,456
1,234,567
12,345,678

-John

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


Re: Re: Python Gotcha's?

2012-04-05 Thread John Posner
On 4/4/2012 7:32 PM, Chris Angelico wrote:
> Don't know if it's what's meant on that page by the += operator,

Yes, it is.

>> a=([1],)
>> a[0].append(2) # This is fine

[In the following, I use the term "name" rather loosely.]

The append() method attempts to modify the object whose name is "a[0]".
That object is a LIST, so the attempt succeeds.

>> a[0]+=[3] # This is not.

The assignment attempts to modify the object whose name is "a". That
object is a TUPLE, so the attempt fails. This might be a surprise, but
I'm not sure it deserves to be called a wart.

 Note the similarity to:

temp = a[0] + [3]   # succeeds
a[0] = temp # fails

-John




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


Re: Lambda question

2011-06-05 Thread John Posner
On 2:59 PM, Ian Kelly wrote:
> On Sat, Jun 4, 2011 at 12:09 PM, Chris Angelico  wrote:
>> Python doesn't seem to have an inbuilt function to divide strings in
>> this way. At least, I can't find it (except the special case where n
>> is 1, which is simply 'list(string)'). Pike allows you to use the
>> division operator: "Hello, world!"/3 is an array of 3-character
>> strings. If there's anything in Python to do the same, I'm sure
>> someone else will point it out.
> Not strictly built-in, but using the "grouper" recipe from the
> itertools docs, one could do this:
>
> def strsection(x, n):
> return map(''.join, grouper(n, x, ''))

As Ian discovered, the doc string for grouper() [on page
http://docs.python.org/library/itertools.html] is wrong:

"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"

grouper() doesn't return a string directly -- hence the need for
"map('', join ..."

Here's another implementation:

def group(stg, count):
return [ stg[n:n+count] for n in range(len(stg)) if n%count==0 ]

print group('abcdefghij', 3)  # ['abc', 'def', 'ghi', 'j']
print group('abcdefghijk' * 2, 7) # ['abcdefg', 'hijkabc',
'defghij', 'k']
print group('', 42)   # []


-John


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


Re: Dynamic Zero Padding.

2011-06-07 Thread John Posner
Friedrich:



>> I would be much obliged if someone can give me some tips on how to
>> achieve a variably pad a number.
> :)
>
> ('%%0%dd' % (pads,)) % (n,)
>
> Probably be good to wrap it in a function.  It looks kind of obscure as it 
> is.

You might want to try "new style" string formatting [1], which I think
is better than the "old style" in this particular case:

>>> "Testing {0:0{1}d}".format(42, 4)
'Testing 0042'
>>> "Testing {0:0{1}d}".format(42, 9)
'Testing 00042'



HTH,
John

[1] http://docs.python.org/library/string.html, Section 7.1.2 "String
Formatting"

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


Re: Using decorators with argument in Python

2011-06-29 Thread John Posner
On 2:59 PM, Lie Ryan wrote:
>> Can any of you guys explain me advantages and disadvantages of
>> using each of them
> Simplicity is one, using @decor() means you have at least three-level
> nested functions, which means the code is likely to be very huge and
> perhaps unnecessarily.

Bruce Eckel pointed out (
http://www.artima.com/weblogs/viewpost.jsp?thread=240808) that the
result of "decoration" need not be a function. Instead, it can be an
object (instance of a user-defined class) that's callable (because the
class implements a __call__ method).

Investigating how this fact fit in with the current thread, I came up
with an alternative to the three levels of "def" (pronounced "three
levels of death"). Following is code for two decorators:

* the first one encloses the output of a function with lines of "#"
characters, and is used like this:

 @enclose
 myfun(...

* the second one encloses the output of a function with lines of a
user-specified character, and is used like this:

 @enclose("&")
 myfun(...

Here's the Python2 code for each one:

## decorator to be called with no argument

class enclose:
"""
class that can be used as a function decorator:
prints a line of "#" before/after the function's output
"""
def __init__(self, funarg):
self.func = funarg
def __call__(self, *args, **kwargs):
print "\n" + "#" * 50
self.func(*args, **kwargs)
print "#" * 50 + "\n"

## decorator to be called with argument

def enclose(repeat_char):
"""
function that returns a class that can be used as a decorator:
prints a line of  before/after the function's output
"""
class _class_to_use_as_decorator:
def __init__(self, funarg):
self.func = funarg
def __call__(self, *args, **kwargs):
print "\n" + repeat_char * 50
self.func(*args, **kwargs)
print repeat_char * 50 + "\n"

return _class_to_use_as_decorator


Best,
John

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


Re: Using decorators with argument in Python

2011-07-01 Thread John Posner
On 2:59 PM, Ethan Furman wrote:



> def __call__(self, func=None):
> if func is None:
> return self._call()
> self.func = func
> return self
> def _call(self):
> print("\n" + self.char * 50)
> self.func()
> print(self.char * 50 + '\n')
>

I believe the "if" block should be:

  if func is None:
  self._call()
  return

Or perhaps the _call() method should be revised:

  def _call(self):
  print("\n" + self.char * 50)
  retval = self.func()
  print(self.char * 50 + '\n')
  return retval

-John

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


Re: Property setter and lambda question

2011-07-11 Thread John Posner
On 2:59 PM, Anthony Kong wrote:


> So the question: is it possible to use lambda expression at all for
> the setter? (As in the last, commented-out line)
>
> Python interpreter will throw an exception right there if I use the
> last line ('SyntaxError: lambda cannot contain assignment'). I'd use
> pass a setter method anyway.  
>
> What is your preferred solution?

Anthony, you might take a look at this alternative writeup for
"property", which I placed on the Python Wiki:

http://wiki.python.org/moin/AlternativeDescriptionOfProperty

HTH,
John



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


Re: Tkinter/py2exe with installer

2011-07-25 Thread John Posner
On 2:59 PM, Kevin Walzer wrote:
> Can anyone point me in the direction of a Tkinter/Python app that has
> been wrapped with py2exe and is deployed on Windows as a standalone
> using one of the standard installer tools? (MSI, NSIS, Inno Setup,
> etc.) I'm working on a Tkinter app for Windows and have had a
> surprisingly hard time finding such apps to use as
> examples/benchmarks, etc. (The only one I've found, in fact, is
> Webgobbler at http://sebsauvage.net/python/webgobbler/index.html; a
> nice app, but I'd like more examples.)
>
I used Inno Setup 5.4.0(a) to create the "ClixTur" executable at
http://www.jjposner.net/5273.html

Inno Setup gives the executable an execrable name (looks like a GUID),
but it works fine.

HTH,
John

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


Re: Tkinter/py2exe with installer

2011-07-25 Thread John Posner
On 2:59 PM, Kevin Walzer wrote:
> Can anyone point me in the direction of a Tkinter/Python app that has
> been wrapped with py2exe and is deployed on Windows as a standalone
> using one of the standard installer tools? (MSI, NSIS, Inno Setup,
> etc.) I'm working on a Tkinter app for Windows and have had a
> surprisingly hard time finding such apps to use as
> examples/benchmarks, etc. (The only one I've found, in fact, is
> Webgobbler at http://sebsauvage.net/python/webgobbler/index.html; a
> nice app, but I'd like more examples.)
>

I used Inno Setup 5.4.0(a) to create the "ClixTur" executable at
http://www.jjposner.net/5273.html

Inno Setup gives the .exe file a GUID for a name (ugh!) but it works fine.

HTH,
John

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


Re: how to separate a list into two lists?

2011-08-06 Thread John Posner
On 2:59 PM, smith jack wrote:
> if a list L is composed with tuple consists of two elements, that is
> L = [(a1, b1), (a2, b2) ... (an, bn)]
>
> is there any simple way to divide this list into two separate lists , such 
> that
> L1 = [a1, a2... an]
> L2=[b1,b2 ... bn]
>
> i do not want to use loop, any methods to make this done?
>

The official Python documentation [1] notes that "zip()
 in conjunction with
the * operator can be used to unzip a list". Ex:

   >>> L = [ (1,'a'), (2,'b'), (3,'c'), (4,'d') ]
   >>> zip(*L)
   [(1, 2, 3, 4), ('a', 'b', 'c', 'd')]


HTH,
John

[1] http://docs.python.org/library/functions.html

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


Re: how to separate a list into two lists?

2011-08-06 Thread John Posner
On 2:59 PM, smith jack wrote:
> if a list L is composed with tuple consists of two elements, that is
> L = [(a1, b1), (a2, b2) ... (an, bn)]
>
> is there any simple way to divide this list into two separate lists , such 
> that
> L1 = [a1, a2... an]
> L2=[b1,b2 ... bn]
>
> i do not want to use loop, any methods to make this done?
>

The official Python documentation [1] notes that "zip()
 in conjunction with
the * operator can be used to unzip a list". Ex:

   >>> L = [ (1,'a'), (2,'b'), (3,'c'), (4,'d') ]
   >>> zip(*L)
   [(1, 2, 3, 4), ('a', 'b', 'c', 'd')]


HTH,
John

[1] http://docs.python.org/library/functions.html

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


Re: testing if a list contains a sublist

2011-08-16 Thread John Posner
On 2:59 PM, Nobody wrote:
> On Tue, 16 Aug 2011 01:26:54 +0200, Johannes wrote:
>
>> what is the best way to check if a given list (lets call it l1) is
>> totally contained in a second list (l2)?
> "Best" is subjective. AFAIK, the theoretically-optimal algorithm is
> Boyer-Moore. But that would require a fair amount of code, and Python
> isn't a particularly fast language, so you're likely to get better results
> if you can delegate most of the leg-work to a native library (along the
> lines of Roy's suggestion of using regexps).
>
>
How about using Python's core support for "==" on list objects:

def contains(alist, slist):
"""
predicate: is *slist* a sublist of *alist*?
"""
alist_sz = len(alist)
slist_sz = len(slist)
   
# special cases
if slist_sz == 0:   
return True # empty list *is* a sublist
elif slist_sz == alist_sz and alist == slist:
return True
elif slist_sz > alist_sz:
return False

# standard case
for i in range(alist_sz - slist_sz + 1):
if slist == alist[i:i+slist_sz]:
return True
# fell through "for" loop: no match found
return False

-John

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


Re: testing if a list contains a sublist

2011-08-16 Thread John Posner
On 2:59 PM, Nobody wrote:
> On Tue, 16 Aug 2011 01:26:54 +0200, Johannes wrote:
>
>> what is the best way to check if a given list (lets call it l1) is
>> totally contained in a second list (l2)?
> "Best" is subjective. AFAIK, the theoretically-optimal algorithm is
> Boyer-Moore. But that would require a fair amount of code, and Python
> isn't a particularly fast language, so you're likely to get better results
> if you can delegate most of the leg-work to a native library (along the
> lines of Roy's suggestion of using regexps).
>
>
How about using Python's core support for "==" on list objects:

def contains(alist, slist):
"""
predicate: is *slist* a sublist of *alist*?
"""
alist_sz = len(alist)
slist_sz = len(slist)
   
# special cases
if slist_sz == 0:   
return True # empty list *is* a sublist
elif slist_sz == alist_sz and alist == slist:
return True
elif slist_sz > alist_sz:
return False

# standard case
for i in range(alist_sz - slist_sz + 1):
if slist == alist[i:i+slist_sz]:
return True
# fell through "for" loop: no match found
return False

-John

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


Re: Py2exe problem with pyqt+matplotlib

2011-03-15 Thread John Posner
On 2:59 PM, Massi wrote:
> I everyone,
>
> I'm trying to write a setup file for py2exe (0.6.9) to convert my
> script into a windows (on win 7) executable. In my script (python2.6)
> I use PyQt and matplotlib. Here is the setup.py file:

> ImportError: No module named Tkinter
>
> Obviously Tkinter is not imported since I'm using pyqt, so can anyone
> point me out what I'm doing wrong?
> Thanks in advance!

PyQt doesn't use Tkinter, but matplotlib does!

-John


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


Re: How best to convert a string "list" to a python list

2011-05-13 Thread John Posner
On 5/13/2011 3:38 PM, noydb wrote:

> I want some code to take the items in a semi-colon-delimted string
> "list" and places each in a python list.  I came up with below.  In
> the name of learning how to do things properly,

No big deal that you weren't aware of the split() method for strings.
Since you asked for pointers, here are some notes on your code -- which
is just fine, overall!

> x = "red;blue;green;yellow" ## string of semi-colon delimited colors
>
> color_list = []
> ## sc = semi-colon
>
> while x.find(";") <> -1:
> sc_pos = x.find(";")
> current_color = x[0:sc_pos] ## color w/o sc
> current_color_sc = x[0:sc_pos+1] ## color with sc

You don't really need the variable "current_color_sc", since you use it
only once. For example, your invocation of replace() could look like this:

  x = x.replace(current_color + ";", "")

But if you really want the extra variable, the following definition is
clearer (and also avoids a slice operation):

current_color_sc = current_color + ";"


> color_list.append(current_color) ## append color to list
> x = x.replace(current_color_sc, "") ## remove color and sc from string

Here's another reason why you don't need the variable
"current_color_sc": instead of using replace(), why not just chop off
the first N characters of the string:

 x = x[len(current_color)+1:]

(The "+1" takes care of the semicolon.)


> print current_color
> print color_list
> print x + "\n"
>
> color_list.append(x) # append last color left in x (no sc at end of >
string)

Does that last append(), outside the loop, offend you?  You can get rid
of it by modifying the original string:

   x = "red;blue;green;yellow"
   x += ";"

Now, the final component of the string is no longer a special case, but
is terminated by ";" -- just like all the other components.

HTH,
John

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


Re: all() is slow?

2011-11-08 Thread John Posner
On 2:59 PM, Chris Angelico wrote:

>>> So really, it's not "all() is slow" but "function calls are slow".
>>> Maybe it'd be worthwhile making an all-factory:
>> PLEASE say you're joking. If I saw code like that on any of our project,
>> this would definitely qualify for a DailyWTF.
> For the benefit of anyone who was actually in doubt: YES, I was
> joking. Do *not* put code like this into any production project.

Because an all-factory would produce code smell? :-)

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


Re: Insert comma in number?

2013-03-07 Thread John Posner
Peter Otten wrote:

> Last not least there's the option to employ locale-aware formatting:


Not quite last ... there's the mind-bending regular expression route:

   import re
   re.sub(r"(?<=\d)(?=(\d\d\d)+$)", ",", "12345678")   # 12,345,678
   re.sub(r"(?<=\d)(?=(\d\d\d)+$)", ",", "-54321") # -54,321

-John



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


Re: Tkinter w.pack()?

2009-01-28 Thread John Posner
The difference between the fill=, expand=, and anchor= options to the pack()
function takes a while to get used to. In brief:

* fill= controls the size of a control itself

* expand= controls the size of the space into which the pack() function
places a control

* anchor= comes into play if the size of the space exceeds the size of the
control

This Google Doc might be helpful:

   http://docs.google.com/Doc?id=dhmzfrmj_0c685rrdb

It shows the effects of progressively adding various fill= and expand=
clause within three statements that create and place Button controls.

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.11640
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Changing the Image on a button

2009-02-16 Thread John Posner
 >> from Tkinter import *
 >> 
 >> def do():
 >> btn.configure(image = None)
 >> 
 >> root = Tk()
 >> img1 = PhotoImage(file="bacon.gif")
 >> 
 >> btn = Button(image = img1, command = do, text = "hello" )
 >> btn.img = img1
 >> btn.pack()
 >> root.mainloop()
 >> 

Try this change:

  from: btn.configure(image = None)
to: img1.blank()

-John







E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.11770
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Changing the Image on a button

2009-02-17 Thread John Posner
 >> > Try this change:
 >> >
 >> >   from: btn.configure(image = None)
 >> >     to: img1.blank()
 >> >
 >> 
 >> This does in fact clear the image out, however it isn't causing the
 >> text to display... Do i have have to create a new button and swap it
 >> out?

I knew you were gonna ask that! :-) I haven't worked in this area before,
but I
found this at http://effbot.org/tkinterbook/button.htm:

In earlier versions of Tkinter, the image option overrides the text
option.
If you specify both, only the image is displayed. In later versions, you
can
use the compound option to change this behavior. To display text on top
of
an image, set compound to CENTER:
 
 b = Button(master, text="Click me", image=pattern, compound=CENTER)

So here's a reworking, in which the text and image are both toggled by
pressing the button:

### button that toggles both text and image
from Tkinter import *

def pushed():
"""callback: button push"""

global toggle

if toggle:
btn.config(text="", image=img_empty)
toggle = not toggle
else:
btn.config(text=msg, image=img_good)
toggle = not toggle

### main program
toggle = True
msg = "hello"

root = Tk()

### store two versions of an image in global variables:
# 1. original image
img_good = PhotoImage(file="bacon.gif")

# 2. blank image, created by copying and erasing
img_empty = img_good.copy()
img_empty.blank()

### create toggle button
btn = Button(root, compound=CENTER,
text="hello", font="helvetica 14 bold",
image=img_good,
command=pushed)
btn.pack()

### go
root.mainloop()





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.11780
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Re: Peculiar swap behavior

2009-02-23 Thread John Posner
>>  m,n = [1,2,3],[4,5,6]
>>  m[:],n[:] = n,m

I believe this is an RTFM situation. In the Python 2.6.1 help topic "Simple 
Statements" > "Assignment Statements", see this para:

If the target is a slicing: The primary expression in the reference is 
evaluated. It should yield a mutable sequence object (such as a list). The 
assigned object should be a sequence object of the same type. Next, the lower 
and upper bound expressions are evaluated, insofar they are present; defaults 
are zero and the sequence’s length. The bounds should evaluate to (small) 
integers. If either bound is negative, the sequence’s length is added to it. 
The resulting bounds are clipped to lie between zero and the sequence’s length, 
inclusive. Finally, the sequence object is asked to replace the slice with the 
items of the assigned sequence. The length of the slice may be different from 
the length of the assigned sequence, thus changing the length of the target 
sequence, if the object allows it.

The crucial sentence is:
 Finally, the sequence object is asked to replace the slice with the items
 of the assigned sequence.
In our example, this means that the assignment of the 3-item slicing
m[:] = n
... has this result:
 * the identifier m[0] now refers to the same object as the identifier n[0]
 * the identifier m[1] now refers to the same object as the identifier n[1]
 * the identifier m[2] now refers to the same object as the identifier n[2]
Although m and n are still different list objects, all of the "slots" in both 
lists now contain the same (sub)objects.
I've verified the above analysis to my own satisfaction using IDLE 2.6.1:
-
def list_ids(mylist):
return id(mylist), map(id, mylist)

m,n = [1,2,3],[4,5,6]
print m,n

print "m:", list_ids(m)
print "n:", list_ids(n)

m[:], n[:] = n, m
print m,n

print "m:", list_ids(m)
print "n:", list_ids(n)
-

output:

[1, 2, 3] [4, 5, 6]
m: (4589728, [10970688, 10970676, 10970664])
n: (11311344, [10970652, 10970640, 10970628])
[4, 5, 6] [4, 5, 6]
m: (4589728, [10970652, 10970640, 10970628])
n: (11311344, [10970652, 10970640, 10970628])


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


RE: Delete all items in the list

2009-02-26 Thread John Posner
 >> 
 >> > L = filter('a'.__ne__,L)
 >> 
 >> And this is probably the fastest. But not all types define 
 >> __ne__ so a  
 >> more generic answer would be:
 >> 
 >>  from functools import partial
 >>  from operator import ne
 >> L = filter(partial(ne, 'a'), L)
 >> 

And don't forget this "traditional" solution:

>>> L=['a', 'b', 'c', 'a']
>>> filter(lambda arg: arg != 'a', L)
['b', 'c']

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.11850
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


functools.partial (was: Delete all items in the list)

2009-02-26 Thread John Posner
 >> 
 >>  from functools import partial
 >>  from operator import ne
 >> L = filter(partial(ne, 'a'), L)
 >> 

I learned about functools.partial only recently (on this list). functools is
implemented in C, not Python, so I couldn't answer this question for myself:

  Is functools.partial completely equivalent to a manually-coded closure?

Help, please.

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.11850
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: A Simple Menu , Stretching the Window Width--Tkinter

2009-03-03 Thread John Posner
 >> 
 >> I'd like to create a simple Menu bar with one item in it, 
 >> say, called "My 
 >> Menu", and have a few submenu items on it like "Change 
 >> Data" and "Exit". I 
 >> can do that but I'd like the title I put on the enclosing 
 >> window to be 
 >> completely visible. The title is, for example, "Hello, out 
 >> there. This is a 
 >> simple menu". Presently the window shrinks in width the 
 >> accommodate "My 
 >> Menu", and I see "Hello, out th". How do I force the width 
 >> to accommodate 
 >> the whole title?

If you're having trouble with the size of the overall ("root" or "toplevel")
window, this might help:

  rootwin = Tk()
  # width=500, height=350, upper-left-corner at (50,50) -- revise to suit
  rootwin.geometry('500x350+50+50')
  rootwin.resizable(False, False)
  rootwin.title("Hello, out there")

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.11880
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Re: wxPython fast and slow

2009-03-08 Thread John Posner

> def move_panel(self, evt):
> def gen():
> for x in range(200):
> yield x
> for x in range(200, 0, -1):
> yield x
> for x in gen():
> self.square.SetPosition((x, 30))
> time.sleep(0.005)
> 

I can't help with the performance problem, but you don't really need a 
generator for your x-values. This works:

def move_panel(self, evt):
for i in xrange(400):
x = 200-abs(i-200)
self.square.SetPosition((x, 30))
time.sleep(0.005)

The generator *does* make for clearer code, though!

-John

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


Re:

2009-03-13 Thread John Posner

> I have 2 lists
> a = [(4, 1), (7, 3), (3, 2), (2, 4)]
> b = [2, 4, 1, 3]
> 
> Now, I want to order _a_ (a[1]) based on _b_.
> i.e. the second element in tuple should be the same as
> b.
> i.e. Output would be [(3, 2), (2, 4), (4, 1), (7, 3)]
> 
> I did the same as follows:
> >>> l = len(a) * [None]
> >>> for (k, v) in a:
> ...   for i, e in enumerate(b):
> ... if e == v:
> ...l[i] = (k, v)
> 

Essentially, you're sorting a list. The Pythonic approach is to use the sort() 
function, hiding the details in a "custom comparison function":

def compare_func(first, second):
b = [2, 4, 1, 3]
return cmp(b.index(first[1]), b.index(second[1]))

if __name__ == '__main__':
a = [(4, 1), (7, 3), (3, 2), (2, 4)]
a.sort(cmp=compare_func)
print a 

-John

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


Re: An ordering question

2009-03-13 Thread John Posner

> If you don't want to build the intermediary dict, a
> less efficient
> version that runs in O(n^2):
> 
> a.sort(key=lambda k: b.index(k[1]))
> 
> Which is mostly similar to John's solution, but still
> more efficient
> because it only does a b.index call once per 'a'
> item instead of twice
> per comparison.
> 

Very nice! This solution is pretty much a direct transliteration of the 
original problem, as the OP *might* have articulated it:

  List A consists of ordered pairs. Sort list A according to the
  position in list B of the pair's second member.

A solution is truly "Pythonic" when it possesses this directness.

-John

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


Re: Style question - defining immutable class data members

2009-03-15 Thread John Posner

(My apologies if the thread has already covered this.) I believe I understand 
the WHAT in this situation, but I don't understand the WHY ...

Given this class definition:

  class Cls(object):
  x = 345

... I observe the following, using IDLE 2.6.1:

>>> inst = Cls()
>>> Cls.x is inst.x
True

>>> Cls.x += 1
>>> Cls.x is inst.x
True

>>> inst.x += 1
>>> Cls.x is inst.x
False

My question is ... WHY does the interpreter silently create the instance 
attribute at this point, causing a "surprising decoupling" from the class 
attribute? WHY doesn't the interpreter behave as it would with a simple, 
non-instance variable:

  > python
  Python 2.6.1 ...
  Type "help", "copyright", "credits" or "license" for more information.

  >>> x += 1
  Traceback (most recent call last):
File "", line 1, in 
  NameError: name 'x' is not defined

Is there a beneficial effect of silently creating the instance attribute, which 
outweighs the detrimental effects: (1) inconsistency, (2) the "surprising" 
decoupling?

Tx,
John


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


Re: Style question - defining immutable class data members

2009-03-15 Thread John Posner

Matthew Woodcraft said:

> I doubt it's because anyone particularly wanted this
> behaviour; it just
> falls out of the way '+=' is defined.
> 
> At the point where 'inst.x += 1' is compiled,
> Python doesn't know
> whether 'inst.x' is going to turn out to be a class
> attribute or an
> instance attribute or a property. So really the only thing
> it can do is
> generate code to read inst.x in the usual way and then
> assign to inst.x
> in the usual way (where 'the usual way' for CPython
> is LOAD_ATTR and
> STORE_ATTR).

That sounds reasonable to me.


Matthew Woodcraft also said:

>> Is there any actual advantage to self.attribute picking up
>> Class.attribute instead of raising a NameError?

> You use that any time you call an ordinary method using syntax like
> 'self.foo()'.

Yes, but that's performing a read (and call) operation on an attribute. My 
question concerned itself with potential confusion when you perform a write 
operation on an attribute.


Bruno Desthuilliers said:

>> My question is ... WHY does the interpreter  silently create the
>> instance attribute at this point,

> Becaause that's how you create instance attributes in Python. Why do you
> think 'self' - that is, a reference to some object - is mandatory in
> "methods" (really, functions) arguments list ?

> Or do you mean that the existence of a synonym class attribute should be
> checked on each instance variable assignement ? This would probably be a
> big performance hit, ...

Yes, Bruno, I'm persuaded by this argument. Ideally, I'd like the interpreter 
to prevent the programmer from shooting him/herself in the foot, but it's not 
worth the performance hit.

> and it would make per-instance method overloading
> impossible (remember that OOP is about objects, not classes).

Yes again. While I was writing the above comment ("write operation on an 
attribute"), it *did* cross my mind that you might want to write 
self.attribute, even if it names a method, not a data-item.


Summary: I no longer suspect that "Python is broken". I *do* think that there's 
a situation that is potentially quite confusing:

 * In the statement "self.x = self.x + 1", the two "self.x" names can sometimes 
refer to different objects.

 * Even worse, in the equivalent statement "self.x += 1", the single name 
"self.x" can sometimes refer to two different objects!

I think this situation should be handled in documentation. (I'm a tech writer 
in my day job ... oh wait, I forgot ... I got laid off from my day job in 
December.) I'll look into what the standard Python doc set says on this matter.

-John

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


Re: Style question - defining immutable class data members

2009-03-15 Thread John Posner

Earlier, I said:

> I'll look into what the standard Python doc set says on this
> matter.
> 

RTFM, in section "Augmented assignment statements" of python301.chm:

---
For targets which are attribute references, the initial value is retrieved with 
a getattr() and the result is assigned with a setattr(). Notice that the two 
methods do not necessarily refer to the same variable. When getattr() refers to 
a class variable, setattr() still writes to an instance variable. For example:

class A:
x = 3# class variable
a = A()
a.x += 1 # writes a.x as 4 leaving A.x as 3
---

So, this case is closed ... almost. I believe a similar explanation, with a 
similar example, should appear in the preceding/parent section, "Assignment 
statements". Here's my proposed example:

   class A:
   x = 3 # class variable
   a = A()
   a.x = a.x + 1 # a.x on RHS gets value of class variable (3)
 # a.x on LHS creates instance variable with
   value of RHS expression (4)

Others' thoughts on this?

-John

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


Re: converting pipe delimited file to fixed width

2009-03-19 Thread John Posner

[snip]
 
> field_widths = [14, 6, 18, 21, 21, 4, 6]
> 
> out = open("/home/chatdi/ouptut.csv", 'w')
> for line in open("/home/chatdi/input.csv", "r"):
> fields = line.rstrip().split('|')
> padded_fields = [field.ljust(width) for field, width in zip(fields, 
> field_widths)]
> out.write("".join(padded_fields) + "\n")
> 
> out.close()

How about a version that uses Python 3.0 string formatting:

  field_widths = [14, 6, 18, 21, 21, 4, 6]

  out = open(r"c:\temp\output.csv", 'w')
  for line in open(r"c:\temp\input.csv", "r"):
  fields = line.rstrip().split('|')
  outline = ""
  for pair in zip(fields, field_widths):
  outline += "{0:{1}}".format(*pair)
  out.write(outline + "\n")
  out.close()

Or, if you hate NLs (and, perhaps, like obfuscation):

  field_widths = [14, 6, 18, 21, 21, 4, 6]

  out = open(r"c:\temp\output.csv", 'w')
  for line in open(r"c:\temp\input.csv", "r"):
  fields = line.rstrip().split('|')
  out.write("".join(["{0:{1}}".format(*pair) for pair in \
zip(fields, field_widths)]) + "\n")
  out.close()

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


Re: Generator

2009-03-22 Thread John Posner

[snip]
> > If you want next(g) to yield 3, you'd have to do something like:
> > 
> > g = (x for x in s[:])
> > 
> > where s[:] makes a copy of s that is then iterated over.
 

BTW, this simpler statement works, too:

   g = iter(s[:])

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


Re: Style question - defining immutable class data members

2009-03-25 Thread John Posner
On Mon Mar 16 03:42:42, I said:

> RTFM, in section "Augmented assignment statements" of python301.chm:
> 
> ---
> For targets which are attribute references, the initial value is retrieved

> with a getattr() and the result is assigned with a setattr(). Notice that
the 
> two methods do not necessarily refer to the same variable. When getattr() 
> refers to a class variable, setattr() still writes to an instance
variable. 
> For example:
> 
> class A:
> x = 3# class variable
> a = A()
> a.x += 1 # writes a.x as 4 leaving A.x as 3
> ---
> 
> So, this case is closed ... almost. I believe a similar explanation, with
a 
> similar example, should appear in the preceding/parent section,
"Assignment 
> statements". Here's my proposed example:
> 
>class A:
>x = 3 # class variable
>a = A()
>a.x = a.x + 1 # a.x on RHS gets value of class variable (3)
>  # a.x on LHS creates instance variable with
>value of RHS expression (4)

Following is a draft of my proposed addendum to the "Assignment statements"
section of the Python documentation (for both Python 2 and Python 3). I've
included reStructured Text markup. The first paragraph is what's already in
the documentation. Everything else is mine:

  * If the target is an attribute reference: The primary expression in 
the reference is evaluated. It should yield an object with 
assignable attributes; if this is not the case, TypeError is raised. 
That object is then asked to assign the assigned object to the given 
attribute; if it cannot perform the assignment, it raises an 
exception (usually but not necessarily AttributeError).

If the object is a class instance and the attribute reference occurs
on both sides of the assignment operator; for example::

self.x = self.x + 1

... in the RHS expression, ``self.x`` is evaluated with 
``getattr()``, which can access either an instance attribute or (if 
no instance attribute exists) a class attribute. The LHS target 
``self.x`` is assigned with ``setattr()``, which *always* accesses 
an instance attribute, creating it if necessary. Thus, the two 
occurrences of ``self.x`` do not necessarily refer to the same 
variable. If the RHS expression refers to a class attribute, the LHS 
creates a new instance attribute as the target of the assignment.

See section "Augmented assignment statements" for a similar note on 
attribute references. 


If anyone would like to suggest changes to this write-up, have at it. I plan
to submit a SourceForge issue within a day or so.

(BTW, I searched through the existing issues, to see if it has already been
reported. AFAIK, it hasn't. But #4246 is a cousin, referencing
UnboundLocalError exceptions.

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12040
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Style question - defining immutable class data members

2009-03-26 Thread John Posner
[snip]
 >> > If the object is a class instance and the attribute reference
occurs
 >> > on both sides of the assignment operator; for example::
 >> > 
 >> > self.x = self.x + 1
 >> >
 >> > ... in the RHS expression, ``self.x`` is evaluated with 
 >> > ``getattr()``, which can access either an instance attribute or
(if 
 >> > no instance attribute exists) a class attribute. The LHS target 
 >> > ``self.x`` is assigned with ``setattr()``, which *always* accesses

 >> > an instance attribute, creating it if necessary. Thus, the two 

Steve Holden said: 

 >> Is this true in the case of read-write properties? This 
 >> seems a little
 >> simplistic for what's actually a pretty complex piece of logic.

It's not true for the read-write property example in the official property()
function description:

class C(object):
def __init__(self):
self._x = None

def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")


But it *is* true if you revise this class definition to follow the pattern
under discussion: a class attribute provides the "initial value" of an
instance attribute:

class C(object):
_x = 0

def __init__(self):
pass
def getx(self):
return self._x
def setx(self, value):
self._x = value
x = property(getx, setx)


My intent was to fix an obvious omission: a special case was discussed in
the "Augmented assignment statements" section, but an almost-identical
special case was omitted from the "Assignment statements" section.

Neither section currently mentions property attributes. Do you think both
sections should be changed to cover property attributes? Or maybe it would
be simpler just to revise my first sentence:

  from: If the object is a class instance
to: If the object is a (non-property) class instance





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12050
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Cannot register to submit a bug report

2009-03-29 Thread John Posner
I've tried twice to register myself at bugs.python.org. But the confirmation
email message never arrives. (Yes, I checked my spam folder.) What do I do
now?






E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12060
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: tkinter questions: behavior of StringVar, etc

2009-03-29 Thread John Posner
Scott David Daniels said:

 >> You ask, "What exactly is the role of ...", rather than saying
 >> something like, "I don't understand the role of ...", and continue
 >> to ask why the code is not architected the way you first expected
 >> it to be architected, calling those things you do not understand
 >> "magic"  (not "magically" which would at least invoke a sense of
 >> wonder, rather than indignation).

I agree with Scott that Alan could use a little attitude adjustment. OTOH,
the following IDLE transcript does suggest that some "magic" is occurring:

 >>>  RESTART

 >>> from Tkinter import *
 >>> root = Tk()
 >>> ss = StringVar()
 >>>  RESTART

 >>> from Tkinter import *
 >>> ss = StringVar()

 Traceback (most recent call last):
  File "", line 1, in 
ss = StringVar()
  File "C:\Python26\lib\lib-tk\Tkinter.py", line 251, in __init__
Variable.__init__(self, master, value, name)
  File "C:\Python26\lib\lib-tk\Tkinter.py", line 182, in __init__
self._tk = master.tk
 AttributeError: 'NoneType' object has no attribute 'tk'

Here's the "magic" in this situation, which is not exactly highlighted in
existing Tkinter documentation:

   If you do not specify a master object in the StringVar() statement, the
Tk object becomes
   the variable's master. If no Tk object exists, an error occurs.
   
   You can create a Tk object explicitly with the Tk() statement. A Tk
object is created
   implicitly when you create a widget -- for example, with Frame() or
Entry().

I *did* find this in the "Configuration Interface" section of 
Fredrik Lundh's "An Introduction to Tkinter"
(http://www.pythonware.com/media/data/an-introduction-to-tkinter.pdf):

  widgetclass(master, option=value, ...)   ->  widget

  Create an instance of this widget class, as a child to the given 
  master, and using the given options. All options have default 
  values, so in the simplest case, you only have to specify the 
  master. You can even leave that out if you really want; Tkinter 
  then uses the most recently created root window as master.

BTW, the last sentence appears to be false in Python 2.6.1 -- the *first*
root window is used as the master.





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12060
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Cannot register to submit a bug report

2009-03-29 Thread John Posner
 >> 
 >> We can try to debug this :)
 >> 
 >> > E-mail message checked by Spyware Doctor (6.0.0.386)
 >> > Database version: 
 >> 5.12060http://www.pctools.com/en/spyware-doctor-antivirus/
 >> 
 >> Any chance it's Spyware Doctor or some anti-virus flagging 
 >> the message
 >> and hiding it?
 >> 

Thanks for the suggestion, but that's probably not it. No message appears on
my ISP mail server (Yahoo), either. That's beyond the reach of my machine's
Spyware Doctor.

I plan to take Terry's suggestion: send a message to the Webmaster.

Tx,
John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12060
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: tkinter questions: behavior of StringVar, etc

2009-03-30 Thread John Posner
Eric Brunel said:

 >> The Tk instance is registered in a hidden variable in the 
 >> Tkinter module. When
 >> you don't specify a master, it'll use the latest created Tk 
 >> instance one by
 >> default. BTW, the latest should be the only one: it is 
 >> quite unsafe to create
 >> several Tk instances in the same application.

Again, "latest" is incorrect for IDLE 2.6.1:

>>> from Tkinter import *
>>> root1 = Tk()
>>> root2 = Tk()
>>> root3 = Tk()
>>> frm = Frame()   # no master specified
>>> frm.master is root3
False
>>> frm.master is root1
True

 >> Well, I personnally don't see any point on doing any master creation
 >> implicitely, so I never use this master auto-creation for 
 >> anything.

+1. "Explicit is better than implicit."

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12070
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Cannot register to submit a bug report

2009-03-31 Thread John Posner
 >>  >> We can try to debug this :)
 >>  >> 
 >>  >> > E-mail message checked by Spyware Doctor (6.0.0.386)
 >>  >> > Database version: 
 >>  >> 5.12060http://www.pctools.com/en/spyware-doctor-antivirus/
 >>  >> 
 >>  >> Any chance it's Spyware Doctor or some anti-virus flagging 
 >>  >> the message and hiding it?

I said:

 >> Thanks for the suggestion, but that's probably not it. No 
 >> message appears on my ISP mail server (Yahoo), either. 
 >> That's beyond the reach of my machine's Spyware Doctor.
 >> 
 >> I plan to take Terry's suggestion: send a message to the Webmaster.

My ISP (AT&T/Yahoo) was blocking email from the Python bug-tracker: "The
sending system has been identified as a source of spam". I took a suggestion
from Martin Lowis on the "tracker-discuss" list: register under a different
email address. That solution worked fine.





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12080
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Style question - defining immutable class data members

2009-03-31 Thread John Posner
I said:

 >> > My intent was to fix an obvious omission: a special case 
 >> was discussed in
 >> > the "Augmented assignment statements" section, but an 
 >> almost-identical
 >> > special case was omitted from the "Assignment statements" section.

After finally getting registered at bugs.python.org (as described in another
thread), I submitted  my suggested change to the Python documentation. It's
issue 5621.

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12080
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Cannot register to submit a bug report

2009-03-31 Thread John Posner
Terry Ready said: 

 >> > My ISP (AT&T/Yahoo) was blocking email from the Python bug-tracker:
"The
 >> > sending system has been identified as a source of spam".
 >> 
 >> I hope you were able to suggest to them that that 
 >> identification must be 
 >> an error.  Frustrating given the spam sources that somehow 
 >> do not get 
 >> identified.

The AT&T web site carefully explained that only administrators, not mere
mortals, would be able to submit a "this is not spam" appeal. So I forwarded
the appropriate info to Martin Lowis, my Tracker-discuss benefactor.

 >> > I took a suggestion
 >> > from Martin Lowis on the "tracker-discuss" list: register under a
different
 >> > email address. That solution worked fine.
 >> 
 >> Better than waiting for AT&T to wise up. ;-)

Fuggedaboudit! :-)






E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12080
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Which is more Pythonic? (was: Detecting Binary content in files)

2009-04-01 Thread John Posner
Dennis Lee Bieber presented a code snippet with two consecutive statements
that made me think, "I'd code this differently". So just for fun ... is
Dennis's original statement or my "_alt" statement more idiomatically
Pythonic? Are there even more Pythonic alternative codings?

   mrkrs = [b for b in block 
 if b > 127 
   or b in [ "\r", "\n", "\t" ] ]

   mrkrs_alt1 = filter(lambda b: b > 127 or b in [ "\r", "\n", "\t" ],
block)
   mrkrs_alt2 = filter(lambda b: b > 127 or b in list("\r\n\t"), block)


(Note: Dennis's statement converts a string into a list; mine does not.)

---

   binary = (float(len(mrkrs)) / len(block)) > 0.30

   binary_alt = 1.0 * len(mrkrs) / len(block) > 0.30

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12090
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Which is more Pythonic? (was: Detecting Binary content in files)

2009-04-01 Thread John Posner
 >> >    mrkrs_alt2 = filter(lambda b: b > 127 or b in list("\r\n\t"),
block)
 >> >
 >> 
 >> Never tested my 'pythonicity', but I would do:
 >> 
 >> def test(b) : b > 127 or b in r"\r\n\t"

Oops! Clearly, 

   b in "\r\n\t"

 is preferable to ...

   b in list("\r\n\t")


You do *not* want to use a raw string here:

>>> len ("\n\r\t")
3
>>> len (r"\n\r\t")
6





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12090
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Generators/iterators, Pythonicity, and primes

2009-04-04 Thread John Posner
Inspired by recent threads (and recalling my first message to Python
edu-sig), I did some Internet searching on producing prime numbers using
Python generators. Most algorithms I found don't go for the infinite,
contenting themselves with "list all the primes below a given number".

Here's a very Pythonic (IMHO) implementation that keeps going and going and
going ...:

from itertools import count
from math import sqrt

def prime_gen():
"""
Generate all prime numbers
"""
primes = []
for n in count(2):
if all(n%p for p in primes if p < sqrt(n)):
primes.append(n)
yield n

The use of all() is particularly nifty (see
http://code.activestate.com/recipes/576640/). And so is the way in which the
list comprehension easily incorporates the sqrt(n) optimization.

Question: Is there a way to implement this algorithm using generator
expressions only -- no "yield" statements allowed?

BTW -- thank you, John Machin, for the spanking ('I'd worry about "correct"
before "Pythonic"') in a previous message. I *did* manage to post a
correction to the needless conversion of a string to a list:

   b in list("\r\n\t")

... a few hours before your message arrived (Wed Apr 1 19:44:01 CEST 2009)!





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12110
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: Generators/iterators, Pythonicity, and primes

2009-04-04 Thread John Posner
Mark Tolonen said:

 >> p <= sqrt(n) works a little better :^)
 >> 
 >> -Mark
 >> 

Right you are -- I found that bug in my last-minute check, and then I forgot
to trannscribe the fix into the email message. Duh -- thanks!

-John 






E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12110
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


RE: possible pairings in a set

2009-04-04 Thread John Posner
 >> Also, if my code is considered ugly or redundant by this community,
 >> can you make suggestions to clean it up?

Python is pretty mature: if you have a simple, generic problem, the chances
are that someone else has already solved it, packaging the solution in a
library (or "module"). For your job, the "itertools" module includes the
function "combinations":

import itertools
for comb in itertools.combinations([0,1,2,3], 2):
print comb

output:
(0, 1)
(0, 2)
(0, 3)
(1, 2)
(1, 3)
(2, 3)

Note that the output of itertools.combinations() is not a list but an
iterator. If you need the entire list, use the list() function to have the
iterator deliver all the goods at once:

mylist = list(itertools.combinations([0,1,2,3], 2))





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12110
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Re: Generators/iterators, Pythonicity, and primes

2009-04-05 Thread John Posner

Kay Schluehr said:

> g = (lambda primes = []:
>   (n for n in count(2) \
>  if
>  (lambda n, primes: (n in primes if primes and 
n<=primes[-1] \

>  else
>  (primes.append(n) or True \
>  if all(n%p for p in primes if p <= sqrt(n)) \
>  else False)))(n, primes)))()

Um ... did you say "easy"? :-) This is prodigious, and it's definitely a 
solution to the generator-expression-only challenge I laid down. But I 
think this is a case in which using a generator expression causes a loss 
in "Pythonicity", rather than a gain. Many, many thanks for this!



Steven D'Aprano said:

> In other words, this is a crappy way to generate primes. It's a trick,
> not a good algorithm: slow and inefficient, as well as obfuscated.

I wasn't thinking at all about efficiency, so I'm not surprised that my 
implementation -- a pretty simple adaptation of 
http://code.activestate.com/recipes/576640 -- scores low in that 
dimension. I was mainly looking for Pythonicity. I'm sure this means 
different things to different people, PEP 20 notwithstanding. To me, 
this is an important aspect of Pythonicity:


The final Python code looks like your initial back-of-the-napkin pseudo 
code.


In the old days, that meant using filter(), because this function 
mirrors the "sieve" concept in the Sieve of Eratosthenes. These days, I 
believe that this condition:


  if all(n%p for p in primes if p < sqrt(n)):

... closely resembles this pseudo code:

  if the number cannot be evenly divided by all the primes we've
  generated so far (and we can stop testing at the square root)

So I believe this algorithm is the *opposite* of obfuscated. It's 
crystal clear (albeit a slowpoke).



Miles (and others) said:

> P.S. Gmail shows all your messages with a blank body and a text
> attachment containing your message; this is perhaps because your
> mailer includes an invalid blank Content-disposition header.

It might be my ISP (AT&T Yahoo), or it might be MS-Outlook. I'm sending 
this message using Thunderbird 2.0.0.21. Any better?


-John

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


Re: Generators/iterators, Pythonicity, and primes

2009-04-05 Thread John Posner

Kay Schluehr wrote:

> That's because it is *one* expression. The avoidance of named
> functions makes it look obfuscated or prodigious. Once it is properly
> dissected it doesn't look that amazing anymore.
>
> Start with:
>
> (n for n in count(2) if is_prime(n, primes))
>
> The is_prime function has following implementation:
>
> def is_prime(n, primes):
> if primes and n<=primes[-1]:
> return n in primes
> else:
> if all(n%p for p in primes if p <= sqrt(n)):
> primes.append(n)
> return True
> else:
> return False

Your explication is excellent, Kay! In the is_prime() function, can't we 
omit the first three lines (if ... else), because it will *always* be 
the case that "n" exceeds all the primes we've gathered so far. I've 
tested the code with these lines omitted -- both with the separate 
is_prime() function and with the generator-expression-only 
implementation. It seems to work fine. Ex:


---
from itertools import count
from math import sqrt

g = (lambda primes = []:
   (n for n in count(2) if
   (lambda x, primes:
   (primes.append(x) or True
if all(x%p for p in primes if p <= sqrt(x))
else False)
   )(n, primes)
   )
   )()

for i in range(500):
   print g.next(),
---

Note that we don't need any backslashes, either.

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


Re: Generators/iterators, Pythonicity, and primes

2009-04-05 Thread John Posner

>> > g = (lambda primes = []:
>> > (n for n in count(2) if
>> > (lambda x, primes:
>> > (primes.append(x) or True
>> >  if all(x%p for p in primes if p <= sqrt(x))
>> >  else False)
>> > )(n, primes)
>> > )
>> > )()
>>
>> This is of course much more accessible and doesn't even look weird.
>>

Thanks! I think the only weirdness remaining is:

  primes.append(x) or True

... which is a trick to force a True value after primes.append(x) 
returns None.


BTW, for extra cleanliness, the parentheses can be omitted around lines 
4-7, the inner lambda expression.



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


Re: Weird Tk Canvas coordinate issue

2009-04-06 Thread John Posner

Tim Shannon wrote:

I'm new to python, so keep that in mind.
 
I have a tk Canvas that I'm trying to draw on, and I want to start my 
drawing at an offset (from 0) location.  So I can tweak this as I 
code, I set this offset as a class level variable:
 
def ClassName:

OFFSET = 20

def __init__(self, master)):
self.canvas = Canvas(master)
self.canvas.create_rectangle(self.OFFSET,
 self.OFFSET,
 300 + self.OFFSET,
 300 + self.OFFSET,
 width=2)
  
 
The weird thing is, it doesn't offset.  If I set my offset to 10, 
it still starts drawing at 0,0. 
Here's the really weird part (at least to me), if I put a print line 
right about my drawing statements to print the value of the offset, it 
works like it should, and offsets the drawing.

If I remove the print line, the offset goes away.
 
This makes no sense to me.

Tim Shannon wrote:

I'm new to python, so keep that in mind.
 
I have a tk Canvas that I'm trying to draw on, and I want to start my 
drawing at an offset (from 0) location.  So I can tweak this as I 
code, I set this offset as a class level variable:
 
def ClassName:

OFFSET = 20

def __init__(self, master)):
self.canvas = Canvas(master)
self.canvas.create_rectangle(self.OFFSET,
 self.OFFSET,
 300 + self.OFFSET,
 300 + self.OFFSET,
 width=2)
  
The above code wouldn't even compile. Please be careful to cut-and-paste 
working code into your email message. (I've made this mistake myself!) 
Changes to make:


1. first line: change "def" to "class"

2. def __init__(self, master)):<--- get rid of extra ")"

3. Make sure to "pack" the canvas into the overall Tk window:

   self.canvas = Canvas(master)
   self.canvas.pack()<--- add this line

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


Re: Re: How can I change size of GUI?

2009-04-07 Thread John Posner



For what definition of 'did not work'? Seems perfectly fine to me. Just try to
add the lines:

root = Tk()
  


Try adding a line like this:

root.geometry("400x300+100+75")

... which means: "make the window 400 pixels wide and 300 pixels high,
with the upperleft corner at point (100,75)"


frm = ScrolledFrame(root)
frm.pack()
root.mainloop()
  

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


Re: Re: Why does Python show the whole array?

2009-04-09 Thread John Posner

Lawrence D'Oliveiro wrote:

> Fine if it only happened once. But it's a commonly-made mistake. At some
> point you have to conclude that not all those people are stupid, there
> really is something wrong with the design.

I think "something wrong with the design" is overstating the case a bit, 
and is likely to elicit some negative reactions in this forum. But I 
agree with your point, to this extent: this situation illustrates the 
way in which Python "overloads" the number zero:


 Realm A:  "0" indicates the first position in a sequence
 Realm B:   "0" indicates the Boolean value "False"

You just need to remember that the find() function works in Realm A, and 
the "in" operator works in Realm B.


Q: Has anyone on the python-dev list ever proposed a "string"-module 
function that does the job of the "in" operator? Maybe this:


 if test.contains(item) # would return a Boolean value

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


Re: Re: Why does Python show the whole array?

2009-04-09 Thread John Posner

Hrvoje Niksic wrote:

>  if test.contains(item) # would return a Boolean value
>

>> That's a string method, not a function in the string module.

Oops, of course.

 import operator
 operator.contains('foo', 'o')

That's pretty good, and IMHO a bit better than John Machin's suggestion 
to use the __contains__() method. (I have this prejudice that using the 
__XXX__ methods in "everyday code" is cheating.)


Given how common string maniuplations are, I guess I'm surprised that 
Python hasn't yet made "contains()" into both a "string"-module function 
*and* a string-object method.



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


Re: Re: Re: Why does Python show the whole array?

2009-04-09 Thread John Posner

> Peter Otten wrote:

>> Could you explain why you prefer 'contains(belly, beer)'
>> or 'belly.contains(beer)' over 'beer in belly'? The last form may be 
a bit

>> harder to find in the documentation, but once a newbie has learned about
>> it he'll find it easy to remember.

andrew cooke wrote:

> i don't know why i get involved in this type of discussion, but


I sense growing exasperation, and I do *not* have strong feelings on 
this matter, so I promise this will be my last message on this topic.


I don't really prefer 'contains(belly, beer)' over 'beer in belly'. 
Rather, it's a completeness/consistency argument: a language that 
includes these methods for string objects:


  belly.startswith(arg)
  belly.endswith(arg)

... should also include:

  belly.contains(arg)

The lack of this method increases the likelihood that a user will 
mistakenly use the find() method as a predicate.


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


Re: Re: Generators/iterators, Pythonicity, and primes

2009-04-11 Thread John Posner

Arnaud Delobelle wrote:

You could do something like this with the help of itertools.ifilter:

prime_gen = ifilter(
  lambda n, P=[]: all(n%p for p in P) and not P.append(n),
  count(2)
)

Formidable! (both the English and French meanings) This is the most 
elegant, Sieve of Eratosthenes-like solution.

I omitted the 'if p <= sqrt(n)' as it doesn't help the generator go
faster. You could use itertools.takewhile for that:

prime_gen = ifilter(
lambda n, P=[]:
all(n%p for p in takewhile(lambda p, s=n**0.5: p<=s, P))
and not P.append(n),
count(2)
)
  


Do know what in the itertools implementation causes adding a 'if p <= sqrt(n)'
clause to *decrease* performance, while adding a 'takewhile()' clause 
*increases* performance?


Of course there is no excuse for writing Python like that :)

+1 (but it's fun every once in a while, eh?)

Thanks a lot!  -John


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


Re: Re: Re: Generators/iterators, Pythonicity, and primes

2009-04-12 Thread John Posner

Duncan Booth wrote:

John Posner  wrote:
  

Do know what in the itertools implementation causes adding a 'if p <=
sqrt(n)' clause to *decrease* performance, while adding a
'takewhile()' clause *increases* performance? 



I haven't timed it, but I would guess that the takewhile was faster 
only because the sqrt(n) had been factored out of the loop. Try the 
original loop again precalculating the sqrt(n) and see how that compares.
Here's my "timeit" scorecard, with repeat=5 (only the minimum value 
reported) and number=5000:


 all prev. primes
3.97347791658

 prev. primes that don't exceed SQRT
6.23250413579

 [CACHED] prev. primes that don't exceed SQRT
3.45557325672

 [TAKEWHILE] prev. primes that don't exceed SQRT
0.371197373201

 [TAKEWHILE] squares, using *, of prev. primes that don't exceed N
0.358001074011

 [TAKEWHILE] squares, using **, of prev. primes that don't exceed N
0.383540147515

 [TAKEWHILE, CACHED] squares, using *, of prev. primes that don't 
exceed N

0.410309506343

 [TAKEWHILE, CACHED] squares, using **, of prev. primes that don't 
exceed N

0.401269222462


So ... adding the SQRT optimization degrades the performance 
significantly, but adding CACHING to the SQRT optimization swings the 
performance pendulum back to the "benefit" side. TAKEWHILE is a big win, 
but adding CACHING to TAKEWHILE degrades performance.


The code (110 lines) is at http://cl1p.net/python_prime_generators/

-John

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


Re: any(), all() and empty iterable

2009-04-14 Thread John Posner

Tim Chase wrote:
I still prefer "Return False if any element of the iterable is not 
true" or "Return False if any element in the iterable is false" 
because that describes exactly what the algorithm does. Granted, 
anybody with a mote of Python skills can tell that from the algorithm, 
but if you're going to go to the trouble of documenting, you might as 
well document what it does.  The code in the docs do not check the 
truthiness of each element, it checks for the falseness (not-trueness) 
of each element.  One might be able to defend it using logical 
manipulations, but since Python strives for clarity...

Arnaud Delobelle wrote:

Return False as soon as the first false element in the iterable is
found.  Otherwise return True when the iterable is exhausted.

Unfortunately it makes it much less obvious what the function is for and
the Python implementation is a clearer explanation IMHO.

So in the end, I think the doc reaches a good compromise: a short easy
to understand english description that gives a clear idea of what all()
is for, and a sample implementation for those who need/want the exact
behaviour.
  
IMO, you can't get around the essential ambiguity of the words "all", 
"any", "every", "no", etc. in the plain-English realm. The only way 
around this is to have the definition focus on the *individual* element 
of the iterable, not on the *collection* of elements. So I think Arnaud 
is headed in the right direction. My own choice would be to ignore his 
(very reasonable) objection to a definition that "makes it much less 
obvious what the function is for", and go with these:


 all(iterable) -- Return True if there does not exist an element in 
iterable that is False
 any(iterable) -- Return False if there does not exist an element in 
iterable that is True


These definitions *imply* the functions' short-circuiting behavior, but 
aren't as good as Arnaud's definition, which makes the short-circuiting 
explicit.


-John

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


Re: Re: How to check all elements of a list are same or different

2009-04-15 Thread John Posner

Chris Rebert wrote:

Ah, okay. Then you want:

def all_same(lst):
return len(set(lst)) == 1

def all_different(lst):
return len(set(lst)) == len(lst)

Note that these require all the elements of the list to be hashable.
  

This solution relies on the object ID -- no hashability required:

 # get list of object-IDs
 ids = map(lambda x: id(x), mylist)
 # ALL THE SAME? ... test whether "average ID" matches "first ID"
 sum(ids)/len(ids) == ids[0]

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


Re: Re: How to check all elements of a list are same or different

2009-04-15 Thread John Posner

Scott David Daniels wrote:

Assuming you really are going for "is" comparison, how about:
max(id(x) for x in mylist) == min(id(x) for x in mylist)

It has the advantage that if [id(x) for x in mylist] = [2N, 1N, 3N],
you get the answer you desire.


Oops -- got me!  -John
--
http://mail.python.org/mailman/listinfo/python-list


Re: any(), all() and empty iterable

2009-04-16 Thread John Posner

Tim Chase wrote:

I will probably leave the lead-in sentence as-is but may
add another sentence specifically covering the case for
an empty iterable.


as one of the instigators in this thread, I'm +1 on this solution.

Thanks for weighing in, Raymond. As long as people are getting in their 
last licks on this one ...


Including the word "all" in the definition of "all()" is suboptimal. 
Especially since the everyday meaning of "all" is ambiguous. Sure, leave 
in the code-equivalent to clarify things, but why not clarify in text, 
also? Here's a compromise:


 all(iterable) -- Return True if all elements of the /iterable/ are 
true -- more
 precisely, if there does not exist an element of the iterable that is 
False.

 Equivalent to ...

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


Re: color propagation in tkinter

2009-04-22 Thread John Posner

Alan G Isaac wrote:

Yes, that's what I am currently doing.
But it seems that that is exactly the kind of thing
we are enabled to avoid with e.g., named fonts.
So I was hoping for an equivalent functionality
for colors.  From your answer, I am guessing there
is none.
Not sure this would help, but Tkinter supports the X Window System 
"resources" facility, calling it the "option database". [1]  So it's 
pretty easy to create a subclass of Tkinter.Frame whose instances get a 
user-configured background color, e.g. cyan:


 class Aframe(Frame):
 def __init__(self, master, **kwargs):
 Frame.__init__(self, master, class_="Aframe", **kwargs)
...
 root.option_add("*Aframe*background", "cyan")

Notes:

* The class name "Aframe" in the option_add() statement does not refer 
to the Python subclass "Aframe". Rather, it refers to the value of 
"class_=" in the __init__() method.


* The "class_=" keyword argument must appear in the call to the parent 
class's __init__() method. You can't reconfigure an existing object, 
e.g.: myobj.config(class_="Aframe").


* As far as I can tell, the "class_=" keyword argument is supported only 
by the Frame widget initializer. You cannot, for example, use this 
facility to specify the background color of a Tkinter.Label subclass. :=(


* This facility initializes a new widget, but cannot be used to 
reconfigure an existing widget. [2]


Sounds useful, huh?  :-) Anyway, here's a proof-of-concept:

from Tkinter import *

class Aframe(Frame):
   def __init__(self, master, **kwargs):
   Frame.__init__(self, master, class_="Aframe", **kwargs)

class Bframe(Frame):
   def __init__(self, master, **kwargs):
   Frame.__init__(self, master, class_="Bframe", **kwargs)

root = Tk()
root.geometry("200x300")

# set backgrounds for different classes
root.option_add("*Aframe*background", "cyan")
root.option_add("*Bframe*background", "pink")

# overall frame
panel = Frame(root)
panel.pack(padx=25, pady=20, expand=YES, fill=BOTH)

# vertical padding factor
p = 10

# created colored frames
Aframe(panel).pack(pady=p, expand=YES, fill=BOTH)
Bframe(panel).pack(pady=p, expand=YES, fill=BOTH)
Aframe(panel).pack(pady=p, expand=YES, fill=BOTH)
Aframe(panel).pack(pady=p, expand=YES, fill=BOTH)
Aframe(panel).pack(pady=p, expand=YES, fill=BOTH)
Bframe(panel, relief=GROOVE, bd=4).pack(pady=p, expand=YES, fill=BOTH)

# go
root.mainloop()



This is an example where different behavior by
StringVar could have been put to good use, I think.

I don't follow this. Would you elaborate?


[1] http://infohost.nmt.edu/tcc/help/pubs/tkinter/option-database.html
[2] http://www.cs.man.ac.uk/~fellowsd/tcl/option-tutorial.html says 
"Note that there is no automatic update of existing widgets when the 
database is modified. If you want this, you will need to implement it 
yourself."


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


Re: and [True,True] --> [True, True]?????

2009-04-26 Thread John Posner

jazbees wrote:

> I'm surprised to see that the use of min and max for element-wise
> comparison with lists has not been mentioned.  When fed lists of True/
> False values, max will return True if there is at least one True in
> the list, while min will return False if there is at least one False.
> Going back to the OP's initial example, one could wrap a min check on
> each list inside another min.

I agree with Duncan Booth that any() is equivalent to -- and better than 
-- max() for handling boolean values. But what boolean-oriented function 
is equivalent to min()? How about this, which returns the negation of 
the min() result:


def at_least_one_false(value_list):
  """
  return True if at least one value in value_list is logically FALSE
  """
  return any( [not val for val in value_list] )

This works, but the short-circuit feature of any() is undermined by the 
process-the-whole-sequence behavior of the list comprehension. So, let's 
delete the square brackets, converting the list comprehension into a 
generator expression:


  return any( not val for val in value_list )

According to timeit.Timer.timeit(), this change improves performance 
from 14.59 seconds to 10.49 seconds, with a long value_list:


  [True]*20 + [False] + [True]*30

But the generator expression produces worse performance with a shorter 
value_list:


  [True]*2 + [False] + [True]*3


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


Re: and [True,True] --> [True, True]?????

2009-04-26 Thread John Posner

Arnaud Delobelle wrote:

  return any( not val for val in value_list )



This is the same as:

return not all(value_list)

  

Yes, I should have remembered De Morgan's Theorem. Thanks!

-John

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


Re: Re: sorted() erraticly fails to sort string numbers

2009-04-28 Thread John Posner

uuid wrote:
I am at the same time impressed with the concise answer and 
disheartened by my inability to see this myself.

My heartfelt thanks!
Don't be disheartened! Many people -- myself included, absolutely! -- 
occasionally let a blind spot show in their messages to this list. BTW:


   container[:] = sorted(container, key=getkey)

... is equivalent to:

   container.sort(key=getkey)

(unless I'm showing *my* blind spot here)

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


Re: Please explain this strange Python behaviour

2009-04-30 Thread John Posner

Duncan Booth wrote:

Tim Chase  wrote:
  
There _are_ cases where it's a useful behavior, but they're rare, 
so I don't advocate getting rid of it.  But it is enough of a 
beginner gotcha that it really should be in the Python FAQ at 
www.python.org/doc/faq/general/

That's an excellent idea!

So excellent in fact that it already is:
http://www.python.org/doc/faq/general/#why-are-default-values-shared-between-objects
  


A couple of minor quibbles:

* This writeup, and the virtually identical one at effbot.org that Diez 
referenced, address the *what* of default arguments, but don't really 
address the *why*, beyond the statement that "Default values are created 
exactly once, when the function is defined (by executing the *def* 
 statement)". After all, if parameter 
values are supplied to a function when it is called, a newly minted set 
of default values could be supplied at that time, also. So *why* was 
Python designed one way instead of the other?


* I'd change this sentence near the beginning of the writeup, because 
it's just ambiguous enough in the exact area that the writeup is 
attempting to clarify:


from:

 The first time you call this function, D contains a single item.
 The second time, D contains two items ...

to:

 After the first call to this function, D contains a single item.
 After the second call, D contains two items ...

-John

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


Re: Re: Please explain this strange Python behaviour

2009-04-30 Thread John Posner

Stephen Hansen wrote:
I have a feeling this might start one of those uber-massive "pass by 
value / reference / name / object / AIEE" threads where everyone goes 
around in massive circles explaining how Python uses one or another 
parameter passing paradigm and why everyone else is wrong... but... :)

Believe me, I don't want that to happen!
The thing is, parameter values are NOT supplied to a function when it 
is called.


When you call a function, there's no creation or copying of any values 
of any kind. The objects you pass in are passed in and the function 
receives those exact same objects. Within the function a local name is 
made which binds to an existing object that is specified when it is 
called-- or if a default is provided, that. In all cases these objects 
already exist before the call happens.
This is the kind of explanation I was looking for in the "why are 
default values shared" writeup.


Despite the fact that using mutable objects as default arguments is a 
frequent source of quirked-eyebrows and head-scratching for those new 
to Python, to do anything else would be weirdly magical. You'd 
basically have to go and call copy() on any default arguments 
specified in the function; at which point why are you copying those 
and not the other arguments?
The interpreter *could* take the extra trouble to do that with default 
arguments, because many users seems to expect that behavior. But I now 
understand how the decision *not* to treat default arguments as special 
cases produces the actual behavior. Many thanks, Stephen.


-John

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


Re: Re: list comprehension question

2009-05-01 Thread John Posner

Shane Geiger wrote:

   if type(el) == list or type(el) is tuple:

A tiny improvement:

   if type(el) in (list, tuple):

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


Re: tkinter and widget placement after resizing

2009-05-08 Thread John Posner

jamieson wrote:

i.e. start out with a window like this:

[1][4][7]
[2][5][8]
[3][6][9]


make the main window larger and end up with this:

[1][6]
[2][7]
[3][8]
[4][9]
[5


Here's a solution, using Label widgets for clarity. The keys are:

* start numbering from zero, not one
* use divmod() on an item's index within the list to determine the 
item's column/row position

* bind the  event for window resizing

# redo_layout.py

import sys
from Tkinter import *

CHAR_WIDTH = 10
PAD = 3
INIT_COL_COUNT = 3

def grid_positions(count, numcols):
   """
   return a generator for (colnum, rownum) position tuples,
   given the total number of items and the number of columns

   the first column is filled with items, then the second, etc.
   """
   numrows, rem = divmod(count, numcols)
   # need an extra row if there was a remainder
   if rem:
   numrows += 1

   # return value is a generator
   return ( divmod(i, numrows) for i in range(count) )

def place_labels(event):
   """
   reposition all the items in the sequence "label_list"
   """
   # assumption: all labels have same width
   label_width = label_list[0].winfo_width()
   window_width = frm.winfo_width()

   # calculate new column count
   new_col_count = window_width // (label_width+PAD)

   # get new position iterator
   pos_iter = grid_positions(LABEL_COUNT, new_col_count)

   # redo layout
   for lab in label_list:
   lab.grid_forget()
   colnum, rownum = pos_iter.next()
   lab.grid(column=colnum, row=rownum, padx=PAD, pady=PAD)

def create_labels(count):
   """
   create a list of Label items,
   with text "1", "2", etc.
   """
   return [ Label(frm, bg='cyan', width=CHAR_WIDTH, text="%d" % i)
for i in range(count) ]

if __name__ == "__main__":
   try:
   LABEL_COUNT = int(sys.argv[1])
   except (ValueError, IndexError):
   print "ERROR: Must specify number of labels"
   sys.exit(1)

   # Tkinter window and whole-window Frame
   root = Tk()
   frm = Frame(root)
   frm.pack(expand=True, fill=BOTH)

   # create some labels
   label_list = create_labels(LABEL_COUNT)

   # perform initial layout
   pos_iter = grid_positions(LABEL_COUNT, INIT_COL_COUNT)
   for lab in label_list:
   coloff, rowoff = pos_iter.next()
   lab.grid(column=coloff, row=rowoff, padx=PAD, pady=PAD)
   del pos_iter

   # event configuration: redo the layout when the window size changes
   frm.bind('', place_labels)

   # go
   root.mainloop()

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


Re: Noobie python shell question

2009-11-30 Thread John Posner

On Sun, 29 Nov 2009 22:03:09 -0500, tuxsun  wrote:


I've been working in the shell on and off all day, and need to see if
a function I defined earlier is defined in the current shell I'm
working in.

Is there a shell command to get of list of functions I've defined?



How about this:


##


python
Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit  
(Intel)] on win32

Type "help", "copyright", "credits" or "license" for more information.


a,b,c = 1,2,3



def spam(): return None

...


def eggs(): return None

...


dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'b', 'c',  
'eggs', 'spam']



locals()
{'a': 1, 'c': 3, 'b': 2, 'spam': ,  
'__builtins__':  '__builtin__' (built-in)>, 'eggs': ,  
'__package__': None,

 '__name__': '__main__', '__doc__': None}


[name for name in locals() if callable(locals()[name])]

Traceback (most recent call last):
  File "", line 1, in 
RuntimeError: dictionary changed size during iteration


[name for name in locals() if callable(locals()[name])]

['spam', 'eggs']


##

To avoid the harmless RuntimeError, define "name" before using it in the  
list comprehension (the final expression) -- e.g.:


   name = 1


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


Re: Moving from Python 2 to Python 3: A 4 page "cheat sheet"

2009-12-02 Thread John Posner
On Wed, 02 Dec 2009 10:55:23 -0500, Mark Summerfield   
wrote:



On Dec 1, 2:03 pm, Mark Summerfield  wrote:

I've produced a 4 page document that provides a very concise summary
of Python 2<->3 differences plus the most commonly used new Python 3
features. It is aimed at existing Python 2 programmers who want to
start writing Python 3 programs and want to use Python 3 idioms rather
than those from Python 2 where the idioms differ.


Mark, I add my thanks to those of the other responders. If you find space,  
you might consider adding another str.format() feature:


 Goal: place integer 456 flush-right in a field of width 8

  Py2: "%%%dd" % 8 % 456
  Py3: "{0:{1}d}".format(456, 8)

With str.format(), you don't need to nest one formatting operation within  
another. A little less mind-bending, and every little bit helps!


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


Re: Moving from Python 2 to Python 3: A 4 page "cheat sheet"

2009-12-02 Thread John Posner
On Wed, 02 Dec 2009 13:34:11 -0500, Carsten Haese  
 wrote:




With string interpolation, you don't need to do that, either.

'%*d' % (8,456)

' 456'



Thanks, Carsten and Mark D. -- I'd forgotten about the use of "*" in  
minimum-field-width specs and precision specs (doh). How about this:


  "pi={1:.{0}f} e={2:.{0}f}".format(5, math.pi, math.e)

  (result: 'pi=3.14159 e=2.71828')

Can the Python2 %-formating facility handle this without repeating the "5"  
argument?


Even if it can, I stand by my original suggestion: include an example to  
show that the arguments to str.format() can be used on both the left and  
the right of a ":" in a replacement field.


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


Re: How to create a self-destructing Tkinter dialog box?

2009-12-17 Thread John Posner
On Thu, 17 Dec 2009 02:09:03 -0500, Martin P. Hellwig  
 wrote:



mrstevegross wrote:

Ok, I would like to put together a Python/Tkinter dialog box that
displays a simple message and self-destructs after N seconds. Is there
a simple way to do this?
 Thanks,
 --Steve


Just, thinking aloud, I probably would do something like registering the  
[place|grid|pack]_forget() function by using the alarm callback  
'after()' function of that frame.




Yup, after() is your friend:

#---
from Tkinter import *
from functools import partial

def RemoveWindow(win):
win.destroy()

# root window
root = Tk()
Label(root, text="this is the main window").pack()

# another top-level window, to be removed in 2 seconds
top = Toplevel()
Label(top, text="this is the window to be removed").pack()
root.after(2000, partial(RemoveWindow, top))

# go
root.mainloop()
#---

HTH,
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

2009-12-19 Thread John Posner
On Fri, 18 Dec 2009 13:00:48 -0500, Alf P. Steinbach   
wrote:




Chapter 2 is about Basic Concepts (of programming). It's the usual:  
variables, ...


1. Overall suggestion

You have a tendency to include non-pertinent asides [1]. But then,  
rambling a bit endows a manuscript with the author's distinctive voice.  
Fortunately, we live in a hypertext-enabled world, where you can have your  
cake and eat it, too. I suggest that you go over your manuscript with a  
ruthless eye, and turn your rambles into hypertext-accessible "sidebars".  
See how much you can reduce the length of Chapter 2, which current runs 98  
pages!


2. Comments on Section 2.6.7, "References & automatic garbage collection"

There's a spell-check evader on page 2:49: "trough" s.b. "through". And  
your spell-checker should have caught "adressable" on page 2:48.


I find your sequence-of-attribute-lookups approach to the topic of  
"variable assignment" interesting. The directed-graph illustration on page  
2:49 even hints at the fact that in the world of Python, names ("turtle",  
"forward", etc.) and objects (various kinds of yellow boxes) are very  
different things.


(I suggest getting rid of the callout "Very small fixed size variable".  
That way, only objects, not names, have the italicized callouts.)


But using the term "references" and the directed-graph metaphor has its  
drawbacks. Avoiding the term "reference" will make it easier to navigate  
the turbulent waters of call-by-reference vs. call-by-value vs.  
call-by-name. (You don't even stick a toe in those waters in Section  
2.7.5.) Combining memory addresses with the directed graph metaphor  
invites the reader to think at way too low a level, IMHO.


Another metaphor just occurred to me: a scavenger hunt. It even fits in  
with your potentially-infinite-attribute-access approach to the topic. A  
sequence of attribute accesses:


   turtle.forward.__doc__

... is like a sequence of scavenger-hunt instructions:

   1. Get your next clue at the big oak tree
   2. Get your next clue at the back door of the Valley Bank
   3. Get your next clue under Dad's Oldsmobile

It's clear that the scavenger hunt's clues (short characters strings --  
like Python names) are different from the physical objects that you access  
as the hunt progresses (tree, bank building, automobile -- like Python  
objects). I haven't lived with this metaphor long enough to form an  
opinion as to where it might reside on the brain-dead <---> brilliant  
scale.


As I've said in this forum (and the edu-sig forum) before, I think the  
best metaphor for understanding Python variable assignment is John Zelle's  
yellow-sticky-note metaphor. [2]


I hope these comments help.

-John

--
[1] Examples:

Section 2, page 2:1

It's almost impossible, but, as Robert A. Heinlein remarked,
"A Paradox May Be Paradoctored".

Section 2, page 2:3

(I believe the original text comes from the "Jargon file")
 about how arbitrary, undesirable and downright dangerous DWIM
 guessing can be: ...

Section 2.5.1, page 2:14

a natural extension is to make that into a square spiral with
far more windings; I recall it as a common theme in 1970’s
pop-art and it can be quite impressive!

Section 2.6.7, page 2:46

(some flat-Earthers once thought that the flat Earth rested
 on four turtles, which in turn stood on four larger
 turtles, and so on all the way down)

[2] "Python Programming: An Introduction to Computer Science" by John  
Zelle (Franklin, Biddle & Associates, 2004) See Section 2.5.1, "Simple  
Assignment"

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


Re: Class variables static by default?

2009-12-19 Thread John Posner

On Sat, 19 Dec 2009 19:10:13 -0500, KarlRixon  wrote:


Given the following script, I'd expect p1.items to just contain
["foo"] and p2.items to contain ["bar"] but they both contain ["foo",
"bar"].

Why is this? Are object variables not specific to their instance?

---
#!/usr/bin/env python

class Parser:
items = []
def add_item(self, item):
self.items.append(item)





You're using a *class attribute* instead of an *instance attribute*.
Change the class definition to:

class Parser:
def __init__(self):
self.items = []

def add_item(self, item):
self.items.append(item)

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


Re: PyQt Signals and multiple sources

2009-12-20 Thread John Posner

On Sun, 20 Dec 2009 16:59:11 -0500, Zabin  wrote:


I am beginner in programming in pyqt. I have been trying to call the
same function from multiple events- but each event results in a
different instance of the function. I am just unable to figure out how
to retrieve the source which calls the function:

My source signal declarations are as below:
QtCore.QObject.connect(self.ui.Button_Process, QtCore.SIGNAL("clicked
()"), self.activate_tab)
QtCore.QObject.connect(self.ui.Button_Material, QtCore.SIGNAL("clicked
()"), self.activate_tab)
QtCore.QObject.connect(self.ui.Button_Geometry, QtCore.SIGNAL("clicked
()"), self.activate_tab)

for each of the above source i want to activate a different instance
of the activate_tab function. Any help would be greatly appreciated!


In the self.activate_tab() method, use self.sender() to determine which  
object sent the signal.


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


Re: How to iterate the input over a particular size?

2009-12-28 Thread John Posner
On Sun, 27 Dec 2009 09:44:17 -0500, joy99   
wrote:



Dear Group,

I am encountering a small question.

Suppose, I write the following code,

input_string=raw_input("PRINT A STRING:")
string_to_word=input_string.split()
len_word_list=len(string_to_word)
if len_word_list>9:
 rest_words=string_to_word[9:]
 len_rest_word=len(rest_words)
 if len_rest_word>9:
  remaining_words=rest_words[9:]



Here's an issue that has not, I think, been addressed in this thread. The  
OP's problem is:


1. Start with an indefinitely long string.

2. Convert the string to a list, splitting on whitespace.

3. Repeatedly return subslices of the list, until the list is exhausted.

This thread has presented one-chunk-at-a-time (e.g. generator/itertools)  
approaches to Step #3, but what about Step #2? I've looked in the Python  
documentation, and I've done some Googling, but I haven't found a  
generator version of the string function split(). Am I missing something?


Tx,
John


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


Re: How to iterate the input over a particular size?

2009-12-29 Thread John Posner
On Tue, 29 Dec 2009 01:35:41 -0500, Steven D'Aprano  
 wrote:



On Tue, 29 Dec 2009 00:49:50 -0500, John Posner wrote:


On Sun, 27 Dec 2009 09:44:17 -0500, joy99 
wrote:


Dear Group,

I am encountering a small question.

Suppose, I write the following code,

input_string=raw_input("PRINT A STRING:")
string_to_word=input_string.split()
len_word_list=len(string_to_word)
if len_word_list>9:
 rest_words=string_to_word[9:]
 len_rest_word=len(rest_words)
 if len_rest_word>9:
  remaining_words=rest_words[9:]



Here's an issue that has not, I think, been addressed in this thread.
The OP's problem is:

1. Start with an indefinitely long string.

2. Convert the string to a list, splitting on whitespace.

3. Repeatedly return subslices of the list, until the list is exhausted.

This thread has presented one-chunk-at-a-time (e.g. generator/itertools)
approaches to Step #3, but what about Step #2? I've looked in the Python
documentation, and I've done some Googling, but I haven't found a
generator version of the string function split(). Am I missing
something?


"Indefinitely long" doesn't mean you can't use split.

But if you want a lazy splitter, here's a version which should do what
you want:


def lazy_split(text):
accumulator = []
for c in text:
if c in string.whitespace:
if accumulator:
yield ''.join(accumulator)
accumulator = []
else:
accumulator.append(c)
if accumulator:
yield ''.join(accumulator)



Thanks -- I coded a similar generator, too. Yours handles the corner cases  
and end-of-string more elegantly, so I won't share mine. :-)




Other alternatives are to use a regex to find runs of whitespace
characters, then yield everything else; or to use the itertools.groupby
function.


Yup, that approach occurred to me as I was falling asleep last night (OMG,  
get a life, buddy!):


def groupby_split(text):
whitespace_grouper = itertools.groupby(
text,
lambda(c): c not in string.whitespace)
for boolval, group_iter in itertools.ifilter(
  lambda pair: pair[0] == True,
  whitespace_grouper):
yield "".join(group_iter)

Tx,
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to iterate the input over a particular size?

2009-12-29 Thread John Posner

On Tue, 29 Dec 2009 01:35:41 -0500, Steven D'Aprano
 wrote:


On Tue, 29 Dec 2009 00:49:50 -0500, John Posner wrote:


On Sun, 27 Dec 2009 09:44:17 -0500, joy99 
wrote:


Dear Group,

I am encountering a small question.

Suppose, I write the following code,

input_string=raw_input("PRINT A STRING:")
string_to_word=input_string.split()
len_word_list=len(string_to_word)
if len_word_list>9:
 rest_words=string_to_word[9:]
 len_rest_word=len(rest_words)
 if len_rest_word>9:
  remaining_words=rest_words[9:]



Here's an issue that has not, I think, been addressed in this thread.
The OP's problem is:

1. Start with an indefinitely long string.

2. Convert the string to a list, splitting on whitespace.

3. Repeatedly return subslices of the list, until the list is exhausted.

This thread has presented one-chunk-at-a-time (e.g. generator/itertools)
approaches to Step #3, but what about Step #2? I've looked in the Python
documentation, and I've done some Googling, but I haven't found a
generator version of the string function split(). Am I missing
something?


"Indefinitely long" doesn't mean you can't use split.

But if you want a lazy splitter, here's a version which should do what
you want:


def lazy_split(text):
accumulator = []
for c in text:
if c in string.whitespace:
if accumulator:
yield ''.join(accumulator)
accumulator = []
else:
accumulator.append(c)
if accumulator:
yield ''.join(accumulator)



Thanks -- I coded a similar generator, too. Yours handles the corner cases
and end-of-string more elegantly, so I won't share mine. :-)



Other alternatives are to use a regex to find runs of whitespace
characters, then yield everything else; or to use the itertools.groupby
function.


Yup, that approach occurred to me as I was falling asleep last night (OMG,
get a life, buddy!):

def groupby_split(text):
  whitespace_grouper = itertools.groupby(
  text,
  lambda(c): c not in string.whitespace)
  for boolval, group_iter in itertools.ifilter(
lambda pair: pair[0] == True,
whitespace_grouper):
  yield "".join(group_iter)

Tx,
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to iterate the input over a particular size?

2009-12-29 Thread John Posner

On Tue, 29 Dec 2009 01:35:41 -0500, Steven D'Aprano
 wrote:


On Tue, 29 Dec 2009 00:49:50 -0500, John Posner wrote:


On Sun, 27 Dec 2009 09:44:17 -0500, joy99 
wrote:


Dear Group,

I am encountering a small question.

Suppose, I write the following code,

input_string=raw_input("PRINT A STRING:")
string_to_word=input_string.split()
len_word_list=len(string_to_word)
if len_word_list>9:
 rest_words=string_to_word[9:]
 len_rest_word=len(rest_words)
 if len_rest_word>9:
  remaining_words=rest_words[9:]



Here's an issue that has not, I think, been addressed in this thread.
The OP's problem is:

1. Start with an indefinitely long string.

2. Convert the string to a list, splitting on whitespace.

3. Repeatedly return subslices of the list, until the list is exhausted.

This thread has presented one-chunk-at-a-time (e.g. generator/itertools)
approaches to Step #3, but what about Step #2? I've looked in the Python
documentation, and I've done some Googling, but I haven't found a
generator version of the string function split(). Am I missing
something?


"Indefinitely long" doesn't mean you can't use split.

But if you want a lazy splitter, here's a version which should do what
you want:


def lazy_split(text):
accumulator = []
for c in text:
if c in string.whitespace:
if accumulator:
yield ''.join(accumulator)
accumulator = []
else:
accumulator.append(c)
if accumulator:
yield ''.join(accumulator)



Thanks -- I coded a similar generator, too. Yours handles the corner cases
and end-of-string more elegantly, so I won't share mine. :-)



Other alternatives are to use a regex to find runs of whitespace
characters, then yield everything else; or to use the itertools.groupby
function.


Yup, that approach occurred to me as I was falling asleep last night (OMG,
get a life, buddy!):

def groupby_split(text):
whitespace_grouper = itertools.groupby(
text,
lambda(c): c not in string.whitespace)
for boolval, group_iter in itertools.ifilter(
  lambda pair: pair[0] == True,
  whitespace_grouper):
yield "".join(group_iter)

Tx,
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Dynamic text color

2009-12-30 Thread John Posner
On Wed, 30 Dec 2009 12:58:06 -0500, Dave McCormick   
wrote:



Hi All,

I am new to Python and the list so I hope  I am posting this correctly...

I am working on a way to have text automatically formated in a Tkiniter  
Text widget and would like some input on my code.
Currently I am using Python 2.5 because the server I use has that  
installed. Tkinter is tk8.4.


Most of the time when I type red, blue, or green the code works as  
expected.  When I copy paste text into the widget the last line is  
parsed with part of the previous lines

So I guess the problem is in the "looping"?

Here is my code:
from Tkinter import *
root = Tk()
def get_position(event):
start = 1.0


A couple of problems here: you define "start", but then never use it.  
Worse, it looks like you don't understand that a line-column index into a  
Tkinter Text widget is a STRING, not a FLOAT.




while 1:   pos = Tbox.search("red",END,backwards=TRUE)


I suggest that you use Tbox.get() instead of Tbox.search(), and then use  
Python's more powerful text-search tools. More on this below.




if not pos:
break
red = pos + "-1c"
Tbox.tag_add("red", pos, float(pos)+.03)
Tbox.tag_config("red", foreground="red")


You don't want to define the "red" tag every time get_position() is  
executed -- that is, every time the user presses a key. Define the  
red/green/blue tags just once, right after you create the Text widget.




 pos = Tbox.search("blue",END,backwards=TRUE)
if not pos:
break
blue = pos + "-1c"
Tbox.tag_add("blue", pos, float(pos)+.04)
Tbox.tag_config("blue", foreground="blue")

pos = Tbox.search("green",END,backwards=TRUE)
if not pos:
break
green = pos + "-1c"
Tbox.tag_add("green", pos, float(pos)+.05)
Tbox.tag_config("green", foreground="green")


The previous 6 lines are almost identical to the 6 lines that precede  
them. This is fine for prototyping, but when you find yourself writing  
code like this, think about using a loop or a parameterized function call.  
For example, you might write this function:


  def insert_color_markup(color):
  ...

... and then call it as many times as you need to:

  insert_color_markup("red")
  insert_color_markup("green")
  insert_color_markup("blue")

Now, about those text-search tools: the "re" (regular expression) module  
include the function "finditer". This is a real power tool, combining  
regular expressions and Python iterators -- both of which can be  
intimidating to newcomers. But it's just what you want, IMHO. I hope the  
following annotated IDLE transcript convinces you:


Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit  
(Intel)] on win32

import re



text = """The red ball is red, not green. On other other

... hand, the green ball has both red and blue highlights.
... Thank you.
... """


re.finditer("red", text)



... not too exciting, but this is better:


list(re.finditer("red", text))
[<_sre.SRE_Match object at 0x00C01F70>, <_sre.SRE_Match object at  
0x00C06E20>, <_sre.

SRE_Match object at 0x00C06E58>]

... this list indicates that we got three hits on the word "red"


[ matchobj.span() for matchobj in re.finditer("red", text) ]

[(4, 7), (16, 19), (77, 80)]

... paydirt: a list of (start,end) pairs for an invocation of  
Text.tag_add()


One more hint: forget about the line-column indexes into the contexts of a  
Text widget. Just count characters from the beginning, e.g.:


   "1.0 + %d chars" % start_position


break

Tbox = Text(root,width=40, height=15, wrap=CHAR)
Tbox.grid(column=0, row=0, sticky=(N+W+E+S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
Tbox.bind("", get_position)
Tbox.focus()
root.mainloop()

Thank you,
Dave


I hope this set of hints is helpful, and not too disjointed, terse, or  
cryptic. I think this is a cute little app!


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


Re: Dynamic text color

2009-12-31 Thread John Posner

On Thu, 31 Dec 2009 10:24:44 -0500, Dave McCormick 
wrote:


John,

Thank you for the tips.
I was changing the line-column index to a FLOAT because the search would  
return the starting position (pos) of the string, then by making it a  
FLOAT and adding the string length I was able to get the end position.

If "red" was on line 1 column 0..
  Tbox.tag_add("red", pos, float(pos)+.03)
   =
  Tbox.tag_add("red", 1.0, 1.3)
It was all I could come up with.


Yup, Dave, I've dug this kind of hole for myself many times!



You have convinced me about the re.finditer for this,  I think... Still  
in the prototyping mode:


   def get_position(event):
pos = Tbox.get(1.0, END)
match = [ matchobj.span() for matchobj in  
re.finditer("red", pos) ]

print "match ",match  #debug to shell


Notes:

* Variable "pos" should be "text" or "complete_text" or something similar.

* The first argument to the get() function must be a string:

  wrong ... complete_text = Tbox.get(1.0, END)
  right ... complete_text = Tbox.get("1.0", END)

But there's a more important problem. Is this function supposed to handle  
*one* word to be colored red, or *all the words* to be colored red? Here's  
what you want to do on each user keystroke:


1. Use get() to place the entire contents of the Text widget in a
variable, say "complete_text".

2. Use re.finditer() to generate START,END pairs for the substrings to
be colored red. You might find it easier to create a list from the  
iterator, though it isn't really necessary:


 start_end_pairs = list(re.finditer("red", complete_text))

3. Loop over the START,END pairs in this list. In each loop, use
tag_add() to tag one of the substrings.

[OOPS: I apologize if my suggestion in the previous post misled you. I  
described the output of finditer() as "a list of (start,end) pairs for an  
invocation of Text.tag_add()". I should have said "a list of (start,end)  
pairs, *WHICH CAN BE LOOPED OVER, FOR A SERIES OF INVOCATIONS* of  
Text.tag_add()".]


Note that the 3 steps above only handle the color red. So you want to  
place these steps in a function, then call the function for each color:


   insert_color_markup(text, "red")
   insert_color_markup(text, "green")
   insert_color_markup(text, "blue")

For each call, pass in the contents of complete_text as the first argument.

So the function-call hierarchy would be:

 get_position()<--- invoked on each keystroke
insert_color_markup()  <--- called once for each color
   get() then finditer() then loop-driven calls to tag_add()

I hope that makes sense to you!


Gives all of START,END pairs just fine. It is the last hint about  
line-column indexes that I am have problems with.  All of the  
documentation I can find about "text.tag_add()" uses line-column for  
coordinates.


Lie Ryan has already pointed you to clarifying documentation. Be sure to  
bookmark http://infohost.nmt.edu/tcc/help/pubs/tkinter/ in your Web  
browser!


If I count characters from the beginning how do I know what line the  
text is on? Would you mind making your last hint a bit stronger...


The point is that *you don't need to*. Handling the text as a simple  
sequence of characters is much simpler than worrying about line/column  
pairs. (If you were using a different shade of red on different lines, you  
*would* need to worry about line/column pairs.)


One more suggestion, which I forgot to make in the previous round. Your  
code includes this:


   Tbox.grid(column=0, row=0, sticky=(N+W+E+S))
   root.grid_columnconfigure(0, weight=1)
   root.grid_rowconfigure(0, weight=1)

You're working too hard here. This is sufficient:

   Tbox.pack()

Keep at it, Dave. I've posted a complete solution at  
http://cl1p.net/jjp_dynamic_text_color/. But I suggest that you put in a  
couple of more hours of coding before peeking at it.


Best,
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: multivariable assignment

2009-12-31 Thread John Posner

On Thu, 31 Dec 2009 11:32:04 -0500, Andreas Waldenburger
 wrote:


On Thu, 31 Dec 2009 08:13:35 -0800 (PST) davidj411
 wrote:


I am not sure why this behavior is this way.
at beginning of script, i want to create a bunch of empty lists and
use each one for its own purpose.
however, updating one list seems to update the others.

>>> a = b = c = []

No, you're only creating one list (and giving that one list three
names). Creating three lists would be:

a = []
b = []
c = []

or, alternatively

a, b, c = [], [], []

Just remember: Python "variables" are just names that point to the
actual data. "x = y" just means "make 'x' a synonym for 'y'".



Revising/expanding Andreas's last paragraph (trying to be correct, but not
trying to be complete):

Python deals with NAMEs and OBJECTs. A NAME is "bound" or "assigned" to an
OBJECT. Each OBJECT can have any number of NAMEs. A NAME cannot be
assigned to another NAME -- only to an OBJECT.

Objects are created by EXPRESSIONS, such as:

   42
   42 + 3*othernum
   "spam"
   "spam" + "eggs"
   empname[4:10] <-- slice of a string or other sequence
   cook("spam" + "eggs", 7)  <-- calling a function
   "spam".split()  <-- calling an object method
   Brunch("spam", veggie, dessert)  <-- instantiating a class

NAMEs are created by assignment statements. You can also reuse an existing
NAME in a subsequent assignment statement.

Some assignment statements are of the form:

NAME = EXPRESSION

Ex:

grand_total = 42
paragraph = " ".join(sentence1, sentence2)
grand_total = 42 + 3*othernum
sunday_brunch = Brunch(Eggs(2), "broccoli", "cookie")

This form:

   1a. Creates a new NAME,
 or
   1b. Removes an existing NAME from the OBJECT to which it is currently
assigned.
2. Assigns the NAME to the OBJECT created by the EXPRESSION.

Other assignment statements are of the form:

NAME2 = NAME1

This form does not create a new OBJECT. Instead, it assigns NAME2 as an
additional name for the object to which NAME1 is currently assigned. Ex:

   y = x
   tenth_item = mylist[9]  <-- a list's items have auto-assigned integer
NAMEs
   clr = colors["sea foam"] <-- a dict has user-devised NAMEs called "keys"
   red_comp = rgb_color.red <-- a class instance has user-devised NAMEs
called "attributes"

My favorite metaphor for Python's NAMEs-and-OBJECTs scheme is the
Post-It(r). NAMEs are like Post-Its; you can stick any number of Post-Its
to any object.

HTH (and sorry if the above is overly pedantic),
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Dynamic text color

2010-01-02 Thread John Posner

On Sat, Jan 2, 2010 at 1:47 PM, Dave McCormick wrote:


WooHoo!!!
I got it!!! Yup, I am sure it can be optimized but it works!!!


Dave, please ignore a couple of my bogus complaints in the previous 
message:


   ... you call function new_Rword() before you define it

   ... this version also has the advantage of defining each function 
just once, instead of multiple times on each keystroke



But I stand by my overall statement that the program didn't work for me, 
and that rearranging the lines produces a working program.


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


Re: Dynamic text color

2010-01-02 Thread John Posner

On Sat, Jan 2, 2010 at 1:47 PM, Dave McCormick wrote:


WooHoo!!!
I got it!!! Yup, I am sure it can be optimized but it works!!!


Hmmm ... it doesn't work for me ...



 RED

   for word in redList:
   new_Rword(complete, word)  def new_Rword(complete, word):
   Tbox.tag_remove(word, "1.0", END)
   for matchobj in re.finditer(word, complete):
   start,end =  matchobj.span()   Tbox.tag_add("red", 
"1.0 + %d chars" % start,"1.0 + %d chars" % end)

   Tbox.tag_config("red", foreground="red")


How *could* this work, Dave, since you call function new_Rword() before 
you define it? I rearranged the statements in your program, and it now 
works for me:


#-
from Tkinter import *
import re

redList = "red dog".split()
blueList = "blue ball".split()
greenList = "green grass".split()

def get_position(event):
complete = Tbox.get("1.0", END)
for word in redList:
new_Rword(complete, word)
for word in blueList:
new_Bword(complete, word)
for word in greenList:
new_Gword(complete, word)

def new_Rword(complete, word):
Tbox.tag_remove(word, "1.0", END)
for matchobj in re.finditer(word, complete):
start,end =  matchobj.span()
Tbox.tag_add("red", "1.0 + %d chars" % start,"1.0 + %d chars" % 
end)


def new_Bword(complete, word):
Tbox.tag_remove(word, "1.0", END)
for matchobj in re.finditer(word, complete):
start,end =  matchobj.span()
Tbox.tag_add("blue", "1.0 + %d chars" % start,"1.0 + %d chars" 
% end)


def new_Gword(complete, word):
Tbox.tag_remove(word, "1.0", END)
for matchobj in re.finditer(word, complete):
start,end =  matchobj.span()
Tbox.tag_add("green", "1.0 + %d chars" % start,"1.0 + %d chars" 
% end)


root = Tk()
Tbox = Text(root, width=40, height=15, wrap=CHAR,
   font="Times 14 bold", bg="#dd")
Tbox.tag_config("red", foreground="red")
Tbox.tag_config("blue", foreground="blue")
Tbox.tag_config("green", foreground="green")

Tbox.pack()
Tbox.bind("", get_position)
Tbox.focus()
root.mainloop()
#-

This version also has the advantage of defining each function just once, 
instead of multiple times on each keystroke! Still to-do:


* rename get_position() to get_complete_text()

* replace new_Rword(), new_Bword(), and new_Gword() with a single 
function that has an extra parameter, "color".


Keep at it!

-John

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


Re: Dynamic text color

2010-01-04 Thread John Posner
On Fri, 01 Jan 2010 21:01:04 -0500, Cousin Stanley  
 wrote:





I was not familiar with the re.finditer method
for searching strings ...


Stanley and Dave --

So far, we've just been using finditer() to perform standard-string  
searches (e.g. on the word "red"). Since Dave now wants to color multiple  
words the same color (e.g. the words in redList), we can use a single  
regular-expression search to locate *all* the words in a list. This  
eliminates the need to use a "for" loop to handle the list. Here's what I  
mean:


 >>> import re
 >>> s = "it is neither red nor crimson, but scarlet, you see"

## individual searches

 >>> [matchobj.span() for matchobj in re.finditer("red", s)]
 [(14, 17)]
 >>> [matchobj.span() for matchobj in re.finditer("crimson", s)]
 [(22, 29)]
 >>> [matchobj.span() for matchobj in re.finditer("scarlet", s)]
 [(35, 42)]

## one "swell foop"

 >>> redList = "red crimson scarlet".split()
 >>> redList_regexp = "|".join(redList)
 >>> redList_regexp
 'red|crimson|scarlet'
 >>> [matchobj.span() for matchobj in re.finditer(redList_regexp, s)]
 [(14, 17), (22, 29), (35, 42)]

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


Re: A null program - what is it doing?

2010-01-05 Thread John Posner




No doubt a dumb question from a noob:

The following program (a cut down version of some test code) uses no 
CPU, and does not terminate:


import sys
from PyQt4.QtCore import *

if __name__=="__main__":
app = QCoreApplication(sys.argv)
sys.exit(app.exec_())

What is the program doing?  What is the correct way to terminate the 
execution?




Are you trying to understand QCoreApplication()? I can't help you there, 
since I've never used it. If you're just trying to get started with 
PyQt, use QApplication() instead:


import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

if __name__=="__main__":
   app = QApplication(sys.argv)
   window = QLabel("I'm a PyQt window")
   window.show()
   sys.exit(app.exec_())

To terminate execution, just close the window by clicking the "X" in the 
window banner.


HTH,
John

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


Re: Dynamic text color

2010-01-05 Thread John Posner
On Tue, 05 Jan 2010 10:31:09 -0500, Dave McCormick   
wrote:



... But this is what I have so far.
##
file = 'red.txt'
file = open("red.txt","r")
rList = file.readlines()
file.close()
redList = str(rList).split()


Dave, you're doing exactly the right thing: gradually expanding your  
program, to provide more functionality and to learn more about the  
available programming tools. It's also very good that you take care to  
close() the file after processing it. Now for the bad news ...


1. Don't use "file" as a variable name -- it's a built-in object type.  
(Some people don't like the fact that Python allows you to redefine such  
"reserved words".)


2. It's probably not the best idea to use a single variable (you use  
"file") to do double-duty: to hold the name of a file, and to hold the  
open-file object returned by the open() function. It's perfectly legal,  
but it hides information that might be useful when you're debugging a  
program. This is better:


  fname = 'red.txt'
  inpf = open(fname, "r")

3. It might be better to use read() rather than readlines() to process the  
"red.txt" file. It depends on what that file is supposed to contain. For  
example, if you expect "red.txt" to contain exactly one line, which has  
one or more words, you can process the open-file object like this:


  file_contents = inpf.read()
  redList = file_contents.split()

   ... or ...

  redList = inpf.read().split()

It's certainly a mistake to use the expression "str(rList).split()". Using  
str() to convert the list "rList" into a string creates a mess that  
includes square-bracket characters. Did this actually work for you?


Best,
John

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


Re: parsing an Excel formula with the re module

2010-01-05 Thread John Posner

On Tue, 05 Jan 2010 13:12:00 -0500, vsoler  wrote:


Hello,

I am acessing an Excel file by means of Win 32 COM technology.
For a given cell, I am able to read its formula. I want to make a map
of how cells reference one another, how different sheets reference one
another, how workbooks reference one another, etc.

Hence, I need to parse Excel formulas. Can I do it by means only of re
(regular expressions)?

I know that for simple formulas such as "=3*A7+5" it is indeed
possible. What about complex for formulas that include functions,
sheet names and possibly other *.xls files?

For example"=Book1!A5+8" should be parsed into ["=","Book1", "!",
"A5","+","8"]

Can anybody help? Any suggestions?


It seems like you want to recreate data structures that Excel, itself,  
must maintain in order to recalculate cells in the correct order. As long  
as you're using COM, you might be able to tap into those data structures.  
My 15-year-old (!) "Using Excel Visual Basic for Applications" book wasn't  
any help. :-( After a short Google session, I came up with one possible  
lead: http://www.decisionmodels.com/


Good luck!
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Dynamic text color

2010-01-05 Thread John Posner
On Tue, 05 Jan 2010 15:08:04 -0500, Dave McCormick   
wrote:




It's certainly a mistake to use the expression "str(rList).split()".  
Using str() to convert the list "rList" into a string creates a mess  
that includes square-bracket characters. Did this actually work for you?


It sort of worked.  With one color file it seemed fine but after I  
posted I added another color file and things fell apart.
Now with the above fixes it works with three colors from three files.   
When the list are printed to the shell the list look like this:

redList ['red', 'dog', 'apple', '#']
blueList ['blue', 'ball', 'berry']
greenList ['green', 'grass', 'do']

But another problem is noticed.  It does not matter if the list is built  
in code or from a file.
If dog is entered, "do" will be green with the "g" being red.  Back to  
the drawing board.


It sounds like the program is doing exactly what you TOLD it to do (which  
might not be what you WANT it to do):


 1. In an earlier pass on the text, color the string "dog" red.
 2. In a later pass, color the string "do" green.

You need to decide what you WANT to happen if one word to be colored is a  
substring of another word to be colored differently. Or maybe you want to  
outlaw such situations. After making that decision, you can start to think  
about how to write the appropriate code.


Best,
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Dynamic text color

2010-01-06 Thread John Posner
On Tue, 05 Jan 2010 16:54:44 -0500, Dave McCormick   
wrote:


But it is not what I am wanting. I first thought to make it look for a  
space but that would not work when a single character like "#" is to be  
colored if there is a "string" of them.  Or if all of the characters  
between quotes are to be colored.


Regular expressions are good at handling searches like:

* all the characters between quotes
* the two-character string "do", but only if it's a complete word

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


Re: QDoubleValidator

2010-01-06 Thread John Posner

On Wed, 06 Jan 2010 17:47:37 -0500, Zabin  wrote:


On Jan 7, 10:23 am, Zabin  wrote:

Hey!

I am new PyQt programmer and want to restrict users to allow only
numeric values into a table and lineedit boxes. I found the
QDoubleValidator class but am unsure as to how to implement it. (I am
a little shaky on the concept of parent and how to define them). Any
help would be much appreciated!


You'll probably get more help in these Qt-specific forums:

   http://lists.trolltech.com/mailman/listinfo/qt-interest

   http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Good luck,
John

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


Re: Dynamic text color

2010-01-08 Thread John Posner
On Fri, 08 Jan 2010 14:28:57 -0500, MRAB   
wrote:



Dave McCormick wrote:
  On Wed, Jan 6, 2010 at 9:18 AM, John Posner <mailto:[email protected]>> wrote:

 On Tue, 05 Jan 2010 16:54:44 -0500, Dave McCormick
mailto:[email protected]>> wrote:
 But it is not what I am wanting. I first thought to make it  
look

for a space but that would not work when a single character like
"#" is to be colored if there is a "string" of them.  Or if all
of the characters between quotes are to be colored.
  Regular expressions are good at handling searches like:
 * all the characters between quotes
* the two-character string "do", but only if it's a complete word
 -John
 -- http://mail.python.org/mailman/listinfo/python-list
 I need another hint...
 Been doing some reading and playing and it looks like
r'\bxxx\b'
is what I need. But I can not figure out how to pass a variable between
\b___\b
If the word in question is between the "\b \b" and in the list then it  
works like I want it to.

 The below does not work.
 greenList_regexp = "|".join(greenList)
for matchobj in re.finditer(r'\bgreenList_regexp\b', complete_text):
start,end = matchobj.span()


The regex r'\bgreenList_regexp\b' will match the string
'greenList_regexp' if it's a whole word.

What you mean is "any of these words, provided that they're whole
words". You'll need to group the alternatives within "(?:...)", like
this:

 r'\b(?:' + greenList_regexp + ')\b'


Oops, MRAB, you forgot to make the last literal a RAW string -- it should  
be r')\b'


Dave, we're already into some pretty heavy regular-expression work, huh?.  
Here's another approach -- not nearly as elegant as MRAB's:


Given this list:

  greenList = ['green', 'grass', 'grump']

... you currently are using join() to construct this regexp search string:

  'green|grass|grump'

... but you've decided that you really want this similar regexp search  
string:


  r'\bgreen\b|\bgrass\b|\bgrump\b'

You can achieve this by transforming each item on the list, then invoking  
join() on the transformed list to create the search string. Here are a  
couple of ways to transform the list:


* List comprehension:

  whole_word_greenList = [ r'\b' + word + r'\b' for word in greenList]

* map() and a user-defined function:

  def xform_to_wholeword_searchstring(word):
  return r'\b' + word + r'\b'

  whole_word_greenList = map(xform_to_wholeword_searchstring, greenList)


HTH,
John
--
http://mail.python.org/mailman/listinfo/python-list


Re: [2.5.1.1/dictionary] Change sorting order?

2010-01-22 Thread John Posner

On 1/22/2010 7:17 AM, Gilles Ganault wrote:

Hello

I use a dictionary to keep a list of users connected to a web site.

To avoid users from creating login names that start with digits in
order to be listed at the top, I'd like to sort the list differently
every minute so that it'll start with the next letter, eg. display the
list from A...Zdigits the first time, then B...ZAdigits, etc.



I don't believe anyone has suggested customizing the way that the 
dictionary's keys are sorted. How about using a string-like object 
("RotaKey"), with a changeable sort order:


#--
import string, time

class RotaKey(object):
"""
string with rotating sort order
"""
LETTERS = string.ascii_uppercase

def __init__(self, instring):
self.string = instring

@staticmethod
def RotateSortOrder():
"""
rotate the letter sequence for sorting RotaKey objects
"""
RotaKey.LETTERS = RotaKey.LETTERS[1:] + RotaKey.LETTERS[0]

def __repr__(self): return "<%s>" % self.string

def __cmp__(self, other):
self_first, self_rest = self.string[0], self.string[1:]
other_first, other_rest = other.string[0], other.string[1:]
result = cmp(self.LETTERS.index(self_first.upper()),
 self.LETTERS.index(other_first.upper()))
if result != 0:
# first letters differ
return result
else:
# first letters same, compare rest of strings
return cmp(self_rest, other_rest)

if __name__ == "__main__":
# create dictionary: keys are RotaKey's, values in range 1001 - ...
names = map(RotaKey,
"Ant Zebra Bob Cat2 Ant2 Eagle Bob3 Bob2 Cat Dog".split())
datadict = dict(zip(names, range(1001, 1001+len(names

# TEST: print, rotate, print, rotate, ...
for i in range(7):
if i > 0: RotaKey.RotateSortOrder()
print "=" * 15, i
for k in sorted(datadict): print k, datadict[k]
#--

NOTE: I tried implementing RotaKey as a subclass of "str", but found 
that the redefinition of __cmp__() was ignored.


You can invoke RotaKey.RotateSortOrder() every minute (or whatever) to 
change the sort order.


Program output:

=== 0
 1001
 1005
 1003
 1008
 1007
 1009
 1004
 1010
 1006
 1002
=== 1
 1003
 1008
 1007
 1009
 1004
 1010
 1006
 1002
 1001
 1005
=== 2
 1009
 1004
 1010
 1006
 1002

 ... etc.

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


Re: pylint and the 'missing docstring' warning

2010-01-26 Thread John Posner

On 1/26/2010 8:43 AM, Jean-Michel Pichavant wrote:

Hello,

Does anyone using pylint knows a way to make pylint ignore these
'missing docstring' warnings when the base class version of the method
actually defines the docstring ?
'Cause my doc builder (epydoc) handle it properly and propagate
docstrings if asked to. Too bad pylint is complaining about it.
I don't want to deactivate this warning.



Look for this setting in the pylint configuration file:

  # not require a docstring
  no-docstring-rgx=__.*__

-John


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


Re: pylint and the 'missing docstring' warning

2010-01-26 Thread John Posner

On 1/26/2010 9:22 AM, Jean-Michel Pichavant wrote:

John Posner wrote:

On 1/26/2010 8:43 AM, Jean-Michel Pichavant wrote:

Hello,

Does anyone using pylint knows a way to make pylint ignore these
'missing docstring' warnings when the base class version of the method
actually defines the docstring ?
'Cause my doc builder (epydoc) handle it properly and propagate
docstrings if asked to. Too bad pylint is complaining about it.
I don't want to deactivate this warning.



Look for this setting in the pylint configuration file:

# not require a docstring
no-docstring-rgx=__.*__

-John



If I'm no wrong this just disables docstring checks for methods matching
__.*__
I'd like to disable it for any method which base class version already
defines the docstring.



I'm a Pylint newbie myself. The only (half-baked) idea I can come up 
with is to use a naming convention for such derived classes. For 
example, if all such class names ended with "_d" (ugh!), you could 
modify the configuration setting like this:


  no-docstring-rgx=(__.*__|.*_d)

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


Re: Need help with a program

2010-01-28 Thread John Posner

On 1/28/2010 10:50 AM, evilweasel wrote:

I will make my question a little more clearer. I have close to 60,000
lines of the data similar to the one I posted. There are various
numbers next to the sequence (this is basically the number of times
the sequence has been found in a particular sample). So, I would need
to ignore the ones containing '0' and write all other sequences
(excluding the number, since it is trivial) in a new text file, in the
following format:


seq59902

TTTATTATATAGT


seq59903

TTTATTTCTTGGCGTTGT


seq59904

TTTGGTTGCCCTGCGTGG


seq59905

TTTGTTTATGGG

The number next to 'seq' is the line number of the sequence. When I
run the above program, what I expect is an output file that is similar
to the above output but with the ones containing '0' ignored. But, I
am getting all the sequences printed in the file.

Kindly excuse the 'newbieness' of the program. :) I am hoping to
improve in the next few months. Thanks to all those who replied. I
really appreciate it. :)


Your program is a good first try. It contains a newbie error (looking 
for the number 0 instead of the string "0"). But more importantly, 
you're doing too much work yourself, rather than letting Python do the 
heavy lifting for you. These practices and tools make life a lot easier:


* As others have noted, don't accumulate output in a list. Just write 
data to the output file line-by-line.


* You don't need to initialize every variable at the beginning of the 
program. But there's no harm in it.


* Use the enumerate() function to provide a line counter:

  for counter, line in enumerate(file1):

This eliminates the need to accumulate output data in a list, then use 
the index variable "j" as the line counter.


* Use string formatting. Each chunk of output is a two-line string, with 
the line-counter and the DNA sequence as variables:


  outformat = """seq%05d
  %s
  """

  ... later, inside your loop ...

  resultsfile.write(outformat % (counter, sequence))

HTH,
John
--
http://mail.python.org/mailman/listinfo/python-list


  1   2   3   >