Button funktioniert nicht; Windows Runtime Error

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Jaga
User
Beiträge: 64
Registriert: Mittwoch 21. August 2013, 13:18

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 (:
FASTER! HARDER! LOUDER!
BlackJack

@Jaga: Schau Dir noch mal die Einrückung von dem Quelltext an, dann sollte klar sein warum `App` keine `plot()`-Methode besitzt.
Jaga
User
Beiträge: 64
Registriert: Mittwoch 21. August 2013, 13:18

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()
FASTER! HARDER! LOUDER!
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.
Jaga
User
Beiträge: 64
Registriert: Mittwoch 21. August 2013, 13:18

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()
FASTER! HARDER! LOUDER!
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.
Jaga
User
Beiträge: 64
Registriert: Mittwoch 21. August 2013, 13:18

@ BlackJack Sorry für meine Begriffsstutzigkeit aber könntest du deinen Vorschlag bitte nochmal für sagen wir unerfahrenere beschreiben?
FASTER! HARDER! LOUDER!
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 = …``.
Jaga
User
Beiträge: 64
Registriert: Mittwoch 21. August 2013, 13:18

ist erledigt
danke für den tip
FASTER! HARDER! LOUDER!
Antworten