Seite 1 von 1

Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 08:29
von Jaga
Ich bräuchte mal wieder Eure Hilfe.
Gebe ich bei dem Funktionsplotter wie er unten steht die Funktion mit Startwert, Endwert und Genauigkeit ein und drücke den plot - Button tut sich gar nichts.
Ändere ich allerdings den command vom button von

Code: Alles auswählen

command = lambda: plot
zu

Code: Alles auswählen

command = self.plot
funktioniert auch nichts aber ich erhalte die Fehlermeldung:
AttributeError: App instance has no attribute 'plot'

Wenn ihr Ideen habt immer her damit :D

Außerdem kommt nach einer gewissen Zeit, in der das Programm läuft immer die Meldung Windows Runtime Error.
Wär cool wenn ihr mir dabei auch helfen könntet.


Hier mein Programmcode:

Code: Alles auswählen

import matplotlib.pyplot as plt
import numpy as np
import Tkinter
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import parser
import re

REPLACE_DIC = {'sin' : 'np.sin',
               'arcsin' : 'np.arcsin',
               'sinh' : 'np.sinh',
               'arcsinh' : 'np.arcsinh',
               'cos' : 'np.cos',
               'arccos' : 'np.arccos',
               'cosh' : 'np.cosh',
               'arccosh' : 'np.arccosh',
               'tan' : 'np.tan',
               'arctan' : 'np.arctan',
               'tanh' : 'np.tanh',
               'arctanh' : 'np.arctanh',
               'ln' : 'np.log',
               'log' : 'np.log',
               'log10' : 'np.log10',
               'log2' : 'np.log2',
               'exp' : 'np.exp',
               '^' : '**',
               'sqrt' : 'np.sqrt',
               'pi' : 'np.pi',
               'PI' : 'np.pi',
               }
class App():

    def __init__(self, master):

        self.master = master
        self.initUI()

    def initUI(self):
        

        
        self.master.title("Funktionsplotter")
        
        self.label_funktion = Tkinter.Label(self.master, text = "Funktion")
        self.label_funktion.grid(row = 0, column = 0)

        self.entry_funktion = Tkinter.Entry(self.master, width = 50)
        self.entry_funktion.grid(row = 0, column = 1)

        self.label_startwert = Tkinter.Label(self.master, text = "Startwert der Funktion")
        self.label_startwert.grid(row = 2, column = 0)

        self.entry_startwert = Tkinter.Entry(self.master, width = 15)
        self.entry_startwert.grid(row = 3, column = 0)

        self.label_endwert = Tkinter.Label(self.master, text = "Endwert der Funktion")
        self.label_endwert.grid(row = 4, column = 0)

        self.entry_endwert = Tkinter.Entry(self.master, width = 15)
        self.entry_endwert.grid(row = 5, column = 0)

        self.label_genauigkeit = Tkinter.Label(self.master, text = "Abstand zwischen zu berechnenden Punkten")
        self.label_genauigkeit.grid(row = 6, column = 0)

        self.entry_genauigkeit = Tkinter.Entry(self.master, width = 15)
        self.entry_genauigkeit.grid(row = 7, column = 0)

        self.plot_button = Tkinter.Button(self.master, text = "Funktion Plotten", command = lambda:plot)
        self.plot_button.grid(row = 0, column = 4)

        fig = plt.figure()
        canvas = FigureCanvasTkAgg(fig, master=self.master)
        toolbar = NavigationToolbar2TkAgg(canvas, self.master)
        canvas.get_tk_widget().grid(row=3, column=1)
        toolbar.grid(row=7, column=1)



        def formel_berechnen(self,):
            self.x = np.arrange(float(entry_startwert.get()),
                                float(entry_endwert.get()),
                                float(entry_genauigkeit.get()))

            x = self.x
            formula_raw = self.formula.get().replace('e^x', 'exp(x)')
            formula_list = re.split('(\W)', formula_raw_exp)
            formula_replace = [REPLACE_DIC.get(item,item) for item in formula_list]
            formula_finish = ''.join(formula_replace)
            form = parser.expr(formula_finish).compile()
            try:
                self.y = eval(form)
                self.legend = self.formula.get()
            except NameError:
                self.y = np.sin(self.x)
                self.legend = 'sin(x)'
            
            return (self.x,self.y,self.legend)
        
    
        
        def plot(self):
            self.formel_berechnen(0.01)
            plt.clf()
            plt.plot(self.x,self.y, label=self.legend)
            plt.grid('on')
            plt.legend()
            plt.gcf().canvas.draw()


def main():
     
     root = Tkinter.Tk()
     app = App(root)
     root.mainloop()

if __name__ == '__main__':
    main()
Vielen Dank schonmal für Eure Hilfe (:

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 08:34
von BlackJack
@Jaga: Schau Dir noch mal die Einrückung von dem Quelltext an, dann sollte klar sein warum `App` keine `plot()`-Methode besitzt.

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 08:46
von Jaga
Sorry für die blöde Frage hab ich leider übersehen.
Hier die geänderte Version. Hierbei erhalte ich allerdings die Meldung:
AttributeError: 'module' object has no attribute 'arrange'
Eine kurze Erklärung was das bedeute wäre super (:

Code: Alles auswählen

import matplotlib.pyplot as plt
import numpy as np
import Tkinter
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import parser
import re

REPLACE_DIC = {'sin' : 'np.sin',
               'arcsin' : 'np.arcsin',
               'sinh' : 'np.sinh',
               'arcsinh' : 'np.arcsinh',
               'cos' : 'np.cos',
               'arccos' : 'np.arccos',
               'cosh' : 'np.cosh',
               'arccosh' : 'np.arccosh',
               'tan' : 'np.tan',
               'arctan' : 'np.arctan',
               'tanh' : 'np.tanh',
               'arctanh' : 'np.arctanh',
               'ln' : 'np.log',
               'log' : 'np.log',
               'log10' : 'np.log10',
               'log2' : 'np.log2',
               'exp' : 'np.exp',
               '^' : '**',
               'sqrt' : 'np.sqrt',
               'pi' : 'np.pi',
               'PI' : 'np.pi',
               }
class App():

    def __init__(self, master):

        self.master = master
        self.initUI()

    def initUI(self):
        

        
        self.master.title("Funktionsplotter")
        
        self.label_funktion = Tkinter.Label(self.master, text = "Funktion")
        self.label_funktion.grid(row = 0, column = 0)

        self.entry_funktion = Tkinter.Entry(self.master, width = 50)
        self.entry_funktion.grid(row = 0, column = 1)

        self.label_startwert = Tkinter.Label(self.master, text = "Startwert der Funktion")
        self.label_startwert.grid(row = 2, column = 0)

        self.entry_startwert = Tkinter.Entry(self.master, width = 15)
        self.entry_startwert.grid(row = 3, column = 0)

        self.label_endwert = Tkinter.Label(self.master, text = "Endwert der Funktion")
        self.label_endwert.grid(row = 4, column = 0)

        self.entry_endwert = Tkinter.Entry(self.master, width = 15)
        self.entry_endwert.grid(row = 5, column = 0)

        self.label_genauigkeit = Tkinter.Label(self.master, text = "Abstand zwischen zu berechnenden Punkten")
        self.label_genauigkeit.grid(row = 6, column = 0)

        self.entry_genauigkeit = Tkinter.Entry(self.master, width = 15)
        self.entry_genauigkeit.grid(row = 7, column = 0)

        self.plot_button = Tkinter.Button(self.master, text = "Funktion Plotten", command = self.plot)
        self.plot_button.grid(row = 0, column = 4)

        fig = plt.figure()
        canvas = FigureCanvasTkAgg(fig, master=self.master)
        toolbar = NavigationToolbar2TkAgg(canvas, self.master)
        canvas.get_tk_widget().grid(row=3, column=1)
        toolbar.grid(row=7, column=1)



    def formel_berechnen(self,):
            self.x = np.arrange(float(entry_startwert.get()),
                                float(entry_endwert.get()),
                                float(entry_genauigkeit.get()))

            x = self.x
            formula_raw = self.formula.get().replace('e^x', 'exp(x)')
            formula_list = re.split('(\W)', formula_raw_exp)
            formula_replace = [REPLACE_DIC.get(item,item) for item in formula_list]
            formula_finish = ''.join(formula_replace)
            form = parser.expr(formula_finish).compile()
            try:
                self.y = eval(form)
                self.legend = self.formula.get()
            except NameError:
                self.y = np.sin(self.x)
                self.legend = 'sin(x)'
            
            return (self.x,self.y,self.legend)
        
    
        

    def plot(self):
            self.formel_berechnen()
            plt.clf()
            plt.plot(self.x,self.y, label=self.legend)
            plt.grid('on')
            plt.legend()
            plt.gcf().canvas.draw()


def main():
     
     root = Tkinter.Tk()
     app = App(root)
     root.mainloop()

if __name__ == '__main__':
    main()

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 08:57
von BlackJack
@Jaga: Das bedeutet, dass das Modul kein Attribut mit dem Namen `arrange` besitzt. Das Modul ist in diesem Fall `numpy`, denn Du bekommst ja mehr als nur diese Zeile, nämlich auch den Traceback der die Quelltextzeile aufzeigt in welcher die Ausnahme ausgelöst wurde. Und das dürfte die erste Zeile von der `formel_berechnen()`-Methode sein.

Schau mal in der Numpy-Dokumentation nach wie die Funktion tatsächlich heisst.

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 09:19
von Jaga
Super danke! arange schreibt man meistens doch nur mit einem r :K (:
Unten nochmal der Quellcode.
Jetzt bleibt nur noch der Runtime Error. Ist mein pc zu schlecht dafür oder liegts an einem Fehler im Programm?

Code: Alles auswählen

import matplotlib.pyplot as plt
import numpy as np
import Tkinter
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import parser
import re

REPLACE_DIC = {'sin' : 'np.sin',
               'arcsin' : 'np.arcsin',
               'sinh' : 'np.sinh',
               'arcsinh' : 'np.arcsinh',
               'cos' : 'np.cos',
               'arccos' : 'np.arccos',
               'cosh' : 'np.cosh',
               'arccosh' : 'np.arccosh',
               'tan' : 'np.tan',
               'arctan' : 'np.arctan',
               'tanh' : 'np.tanh',
               'arctanh' : 'np.arctanh',
               'ln' : 'np.log',
               'log' : 'np.log',
               'log10' : 'np.log10',
               'log2' : 'np.log2',
               'exp' : 'np.exp',
               '^' : '**',
               'sqrt' : 'np.sqrt',
               'pi' : 'np.pi',
               'PI' : 'np.pi',
               }
class App():

    def __init__(self, master):

        self.master = master
        self.initUI()

    def initUI(self):
        

        
        self.master.title("Funktionsplotter")
        
        self.label_funktion = Tkinter.Label(self.master, text = "Funktion")
        self.label_funktion.grid(row = 0, column = 0)

        self.entry_funktion = Tkinter.Entry(self.master, width = 50)
        self.entry_funktion.grid(row = 0, column = 1)

        self.label_startwert = Tkinter.Label(self.master, text = "Startwert der Funktion")
        self.label_startwert.grid(row = 2, column = 0)

        self.entry_startwert = Tkinter.Entry(self.master, width = 15)
        self.entry_startwert.grid(row = 3, column = 0)

        self.label_endwert = Tkinter.Label(self.master, text = "Endwert der Funktion")
        self.label_endwert.grid(row = 4, column = 0)

        self.entry_endwert = Tkinter.Entry(self.master, width = 15)
        self.entry_endwert.grid(row = 5, column = 0)

        self.label_genauigkeit = Tkinter.Label(self.master, text = "Abstand zwischen zu berechnenden Punkten")
        self.label_genauigkeit.grid(row = 6, column = 0)

        self.entry_genauigkeit = Tkinter.Entry(self.master, width = 15)
        self.entry_genauigkeit.grid(row = 7, column = 0)

        self.plot_button = Tkinter.Button(self.master, text = "Funktion Plotten", command = self.plot)
        self.plot_button.grid(row = 0, column = 4)

        fig = plt.figure()
        canvas = FigureCanvasTkAgg(fig, master=self.master)
        toolbar = NavigationToolbar2TkAgg(canvas, self.master)
        canvas.get_tk_widget().grid(row=3, column=1)
        toolbar.grid(row=7, column=1)



    def formel_berechnen(self,):
            self.x = np.arange(float(self.entry_startwert.get()),
                                float(self.entry_endwert.get()),
                                float(self.entry_genauigkeit.get()))

            x = self.x
            formula_raw = self.entry_funktion.get().replace('e^x', 'exp(x)')
            formula_raw_exp = formula_raw.replace('e^', 'exp')
            formula_list = re.split('(\W)', formula_raw_exp)
            formula_replace = [REPLACE_DIC.get(item,item) for item in formula_list]
            formula_finish = ''.join(formula_replace)
            form = parser.expr(formula_finish).compile()
            try:
                self.y = eval(form)
                self.legend = self.entry_funktion.get()
            except NameError:
                self.y = np.sin(self.x)
                self.legend = 'sin(x)'
            
            return (self.x,self.y,self.legend)
        
    
        

    def plot(self):
            self.formel_berechnen()
            plt.clf()
            plt.plot(self.x,self.y, label=self.legend)
            plt.grid('on')
            plt.legend()
            plt.gcf().canvas.draw()


def main():
     
     root = Tkinter.Tk()
     app = App(root)
     root.mainloop()

if __name__ == '__main__':
    main()

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 09:55
von BlackJack
@Jaga: Ist nur geraten, aber ich würde das Canvas- und das Toolbar-Objekt von `matplotlib` an das `App`-Exemplar binden. Wer weiss was sonst an Objekten freigegeben wird, die eigentlich noch benötigt werden.

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 10:03
von Jaga
@ BlackJack Sorry für meine Begriffsstutzigkeit aber könntest du deinen Vorschlag bitte nochmal für sagen wir unerfahrenere beschreiben?

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 11:32
von BlackJack
@Jaga: Na an das Objekt binden, damit es keine lokale Namen sind, die am Ende der Ausführung der Methode wieder verschwinden. Also ``self.name = …`` statt nur ``name = …``.

Re: Button funktioniert nicht; Windows Runtime Error

Verfasst: Dienstag 10. September 2013, 11:38
von Jaga
ist erledigt
danke für den tip