Command config, quitting, binary, Timer

bearophileHUGS at lycos.com bearophileHUGS at lycos.com
Sun Sep 4 11:48:33 EDT 2005


Witn your suggestions and with some tests and work I've solved most of
the problems, thank you all for the comments.

Peter Hansen:

>What did you expect to happen with the infinite loop inside dogo()?<

I expected that the same memory used by the b.config(command=...) can
be used by the successive update of the command. I am ignorant about
Tkinter, but to me it seems that no new memory is really needed each
loop.

-------------------

Dennis Lee Bieber:

>you are creating an endless number of anonymous functions; they may not be garbage collected until the loop ends<

I don't know, usually the garbage collector is quite efficient :-)


>Would it not be easier to have a single callback, but change the button Label, and have the callback branch based on the current label?<

Right, thank you. It's not a perfect solution, but often it's good
enough.


>No idea -- my only Tkinter program (at work, so I can't test it), doesn't do anything like this.<

With more tests and some googling I have found the problem and the
solution. It seems that the problem was produced by commands like this:
self.canvas.delete(self.id)
Maybe they are called after the Tkinter stop, or window close, or
something like that.

To solve the problem I've added this to the main window:
self.root.protocol('WM_DELETE_WINDOW', self.quitAll)

And inside the self.quitAll method I fix something before calling
self.root.quit()


>I somehow suspect it is faster than a mass of push/pop and shifts...<

Your version is very interesting, thank you. I'll use this modified
version:

! _nibbles = {"0":"0000", "1":"0001", "2":"0010", "3":"0011",
!             "4":"0100", "5":"0101", "6":"0110", "7":"0111",
!             "8":"1000", "9":"1001", "A":"1010", "B":"1011",
!             "C":"1100", "D":"1101", "E":"1110", "F":"1111",
!             "-":"-"}
!
! def to_base2(number):
!     result = [_nibbles[nibble] for nibble in "%X"%number]
!     return int("".join(result))

This is faster than my version (but if you are using Psyco for all the
tests, for small numbers my version is faster).
This version is expecially faster for very long numbers.
But the difference between the two versions is quite little still, a C
function like the base2 conversion of GMPY is much faster, so I think
that such common operation can be added to the % formatting sintax.


>Main problem I see with this is that each call to threading.Timer() is creating a NEW thread just for one tick. Lots of overhead involved. I'd create a single thread whose main run method is a continuous loop, using time.sleep() to suspend between ticks. .Timer() is optimized for a one-time callback. Note that using _nextInterval allows me perform an adjustment for the time taken by the callback function.<

Oh, very nice, you are very gentle, thank you. I'll add few suggestion
by Roggisch, and I think it will be quite good. If I obtain something
good I'll even think about putting it in the cookbook (with your names
in it).

-------------------

Diez B. Roggisch:

>It certainly is somewhat ugly - but there might be very good reasons to do so.<

Okay.


>Instead of several metronomes, use one thread and compute the gresatest common divisor for all scheduled timings. Use that as sleep interval (your "ticks"), and count ticks for each timer. You should introduce a lower thrshold on tick-length, otherwise you can get into trouble.<

Okay, I'll follow your suggestions.

Thank you all and hugs to Dennis Lee Bieber,
bearophile




More information about the Python-list mailing list