Bug in 2.0b2: Tkinter (continued)

Kirby Urner urner at alumni.princeton.edu
Fri Sep 29 08:30:38 CEST 2000


Kirby Urner <urner at alumni.princeton.edu> wrote:

>    def drawborder(self):
>        top_l = (self.border,)*2
>        top_r = (self.dim - self.border,self.border)
>        bot_l = (self.border,self.dim - self.border)
>        bot_r = (self.dim-self.border,)*2
>        self.canvas.create_line([(top_l,top_r),(top_r,bot_r),(bot_r,bot_l),(bot_l,top_l)],fill='black')
>        

OK, for one thing, the little border-maker (draws a picture frame around
the sine wave) was completely out to lunch.  The create_line function
just wants to play connect the dots, whereas I was giving it these 
(vertex,vertex) tuples.  So the program was barfing on drawborder.

For another thing, as I posted below, someone tells me to do a root.mainloop(1)
instead of root.mainloop(), and then the close box will return me to IDLE.
Well, that works.

With these changes to the code, my tkgraph.py (simple, home grown, not 
competing with anything at sourceforge) seems pretty stable.  

 Python 2.0b2 (#6, Sep 26 2000, 14:59:21) [MSC 32 bit (Intel)] on win32
 Type "copyright", "credits" or "license" for more information.
 IDLE 0.6 -- press F1 for help
 >>> import tkgraph
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> 2+2
 4
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()
 >>> tkgraph.testgraph()

Look ma, no crash!

I don't think it was the border glitch that was crashing me before.
If you scan back in the postings, I was having trouble with 2.0b1 
and Fredrik explained it was garbage collection and variably sized
sequences that were to blame -- said it'd be fixed in 2.0b2.  So
of course I was looking forward to 2.0b2 and disappointed when I
got similar kinds of crashes (and before adding the bogus border).

So I'm still somewhat mystified as to what I can expect trying to
use IDLE as a platform for Tk programming.  Dave on edu-sig implies
it's not stable.  That was my experience, but now I've learned a 
new trick, squished a bug, and things are working a lot better.

I'd appreciate any straight-talkin' jive turkey python guru 
coming along and spelling it all out for me.  Dave seems to 
really know what he's talking about, so I gather IDLE has 
limitations as a Tk programming environment -- I just don't 
yet know when I've hit these limits, and when I'm still fighting
my own code and/or ignorance of mainloop(1)-type features.

Inquisitively,

Kirby

PS:  Here's the more stable code (not that I expect anyone to run it):

# simple graphing

from Tkinter import *
import math
from operator import getitem

class graph:

    def __init__(self,dim=410,border=5):
        self.dim = dim
        self.border = border
        self.scaled = []
        self.sf = 0
        self.functions = []

    def addf(self,function):
        dom     = map(getitem,function,[0]*len(function))
        rng     = map(getitem,function,[1]*len(function)) 
        maxval  = math.ceil(max(map(abs,dom+rng)))
        self.sf = max(self.sf,(self.dim-self.border*2)/(maxval*2))    
        self.functions.append(function)
            
    def drawgraph(self):
        self.root = Tk()        
        self.canvas = Canvas(self.root,height=self.dim,width=self.dim,
bg='white')
        self.canvas.pack()
        self.drawborder()
        self.plot()
        self.root.mainloop(1)

    def drawborder(self):
        top_l = (self.border,)*2
        top_r = (self.dim - self.border,self.border)
        bot_l = (self.border,self.dim - self.border)
        bot_r = (self.dim-self.border,)*2        
        self.canvas.create_line([top_l,top_r,bot_r,bot_l,top_l],fill='black')
        
    def plot(self):
        for graph in self.functions:
           scaled = self.scaleinput(graph)           
           self.canvas.create_line(scaled, fill='royalblue')
                   
    def scaleinput(self,graph):        
        dom     = map(getitem,graph,[0]*len(graph))
        rng     = map(getitem,graph,[1]*len(graph)) 
        return zip(map(self.pixel,dom),map(self.pixel,rng))

    def pixel(self,val):
        return int(round(self.sf * val)) + self.border + (self.dim)/2
        
def testgraph():
    dom  = mkdomain(-math.pi,math.pi,0.1)  # note step by 0.1    
    sine = zip(dom,[math.sin(x) for x in dom]) # sine function
    mygraph = graph()
    mygraph.addf(sine)
    mygraph.drawgraph()
            
def mkdomain(low, high, interval):
    # create list of domain values, from low to high
    # stepping by interval       
    output = []     # the output list
    i=0
    while 1:        # just keep looping... (assume parameters ok)
        output.append(low + i*interval)
        i=i+1
        if output[-1]>=high: break # ...until high reached
    return output





More information about the Python-list mailing list