Bug in 2.0b2: Tkinter (continued)

Kirby Urner urner at alumni.princeton.edu
Thu Sep 28 19:48:56 EDT 2000


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

>
>
>Transcript of a recent session.  Each time I ran testgraph(), I got my
>sine wave in a Tk canvas.  After the 5th return to IDLE, I was starting
>to type something else when:
>
> 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()
> >>> Exception in Tkinter callback
> Traceback (most recent call last):
>  File "G:\PYTHON20\lib\lib-tk\Tkinter.py", line 1287, in __call__
>    return apply(self.func, args)
> SystemError: C:\Code\python\dist\src\Objects\frameobject.c:127: bad argument to
>internal function
> Exception in Tkinter callback
> Traceback (most recent call last):
>  File "G:\PYTHON20\lib\lib-tk\Tkinter.py", line 1287, in __call__
>    return apply(self.func, args)
> SystemError: C:\Code\python\dist\src\Objects\frameobject.c:127: bad argument to
>internal function


Here's the code that's crashing, as per the above script.  Probably 
a garbage collection issue.

# 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()
        Button(self.root,text='Quit',command=self.quit).pack()
        self.drawborder()
        self.plot()
        self.root.mainloop()

    def quit(self):
        self.root.quit()
        self.root.destroy()

    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')
        
    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