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