Berechnen von glob.+lok. Maxima & Minima [Programm]

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.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ich bin mir nicht sicher, ob ich dich richtig verstanden habe, aber hier... :

Code: Alles auswählen

try:#lokale Max&Min
            for value in y_val_abl2_list:
                if value < 0:
                    lok_maxima_list.append(value)
                else:
                    lok_minima_list.append(value)
        except:
            lok_maxima_list.append("/")
            lok_minima_list.append("/")
...der Vergleich.

Das Programm soll auch die Komplexe "2 - 2*sqrt(3)*I/9" (siehe Fehlercode) vergleichen, um diese Minima bzw. Maxima zu zuordnen.
Also demnach sollte diese Komplexe der Minimaliste zugeordnet (hinzugefügt) werden.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Also mal konkret, ist nun 2-3i < 0 oder größer 0?

Keine nakten Excepts, vor allem, wenn man den Fehler ignoriert.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Das ist kein "I", sondern eine "1".

Und es ist >0.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Was ist eine 1? Hast Du nun komplexe Zahlen oder nicht?
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

1. Ja, es ist eine komplexe Zahl.
2. Naja, scheint wohl doch ein "I" zu sein, aber woher kommt das "I" - denn ich habe es ja garnicht mit eingegeben, als Funktion?

Da muss ich mir Mal kurz die Doku anschauen.

EDIT: reicht es die "0" als Vergleich in eine Komplexe Zahl umzuwandeln - mit "complex()"?
Bin nämlich gerade nicht am PC, sondern erst morgen wieder.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Das `I` kommt daher, dass Du mathematische Operationen angewendet hast, die als Ergebnis komplexe Zahlen liefern.

Weißt Du überhaupt was komplexe Zahlen sind? Hast Du mal ein Mathematikbuch dazu durchgearbeitet? Ein Vergleich auf größer oder kleiner ist mathematisch nicht definiert. Es macht einfach keinen Sinn.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Naja, eine komplexe Zahl ist ja eine Variable, die in einer Operation eine weitere, unbekannte Variable enthält, z.B. a = 2000 + b.

Und wie kann ich dann das Ergebnis mit der 0 vergleichen, denn ich muss ja rausfinden, ob Minima oder Maxima und ob lokal oder global.
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@xXSkyWalkerXx1: Da ist keine Operation und keine unbekannte Variable. Das `i` ist ja bekannt, man kann es nur nicht mit einer ”normalen” Zahl verrechnen. Bei Deinem ``a = 2000 + b`` könnte man `a` ja als normale Zahl ausrechnen wenn `b` bekannt wäre. Eine komplexe Zahl besteht aber immer aus einem realen und einem imaginären Teil und das man die nicht mit dem ``+`` zusammenrechnen kann, dafür sorgt die Multiplikation mit der imaginären Einheit `i`. (Die bei Physikern `j` heisst und in Python auch.)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

@SW Kann es sein, dass du eine Gleichung mit zwei Unbekannten fälschlicherweise als Komplexe Zahl siehst und es hier schlicht um Kurvendiskussion geht?
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

__blackjack__ hat geschrieben: Sonntag 9. Juni 2019, 13:00 @xXSkyWalkerXx1: Da ist keine Operation und keine unbekannte Variable. Das `i` ist ja bekannt, man kann es nur nicht mit einer ”normalen” Zahl verrechnen. Bei Deinem ``a = 2000 + b`` könnte man `a` ja als normale Zahl ausrechnen wenn `b` bekannt wäre. Eine komplexe Zahl besteht aber immer aus einem realen und einem imaginären Teil und das man die nicht mit dem ``+`` zusammenrechnen kann, dafür sorgt die Multiplikation mit der imaginären Einheit `i`. (Die bei Physikern `j` heisst und in Python auch.)
Okay, also eine komplexe Zahl besteht u.a. aus einem imaginären Teil, wo der Wert beliebig sein kann (?)...Doch wie vergleiche ich diese dann?
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Gar nicht? Eine komplexe Zahl ist im Grunde ein Punkt in der Ebene. Wie vergleichst du denn Punkte in der Ebene? Dafuer gibt es keine sinnvolle Vorgehensweise. Wenn du nicht weisst, was komplexe Zahlen sind, dann habt ihr die auch nicht in der Schule gehabt (oder wofuer das auch immer ist), und dann wird das auch nicht Teil der Loesung sein.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Code: Alles auswählen

from PySide2.QtWidgets import QMainWindow,QApplication,QLabel,QLineEdit,QPushButton,QSplitter,QVBoxLayout,QFrame,QAction,QGroupBox,QGridLayout,QMessageBox
from PySide2.QtGui import QIcon,QPixmap
from PySide2.QtCore import Qt
from sympy import *
import math,sys,winsound


class Calculator(QMainWindow):
    def main(self):
        self.setWindowTitle("Analysierungstool für Funktionen")
        self.setWindowIcon(QIcon("maths.png"))
        self.setGeometry(400,300,370,380)
        self.x = Symbol('x')

        self.menuleiste = self.menuBar()
        help_ = self.menuleiste.addMenu("Hilfe")
        exit_ = self.menuleiste.addMenu("Beenden")
        h = QAction(QIcon("programmer.png"),"Benutzerhandbuch",self)
        h.triggered.connect(self.show_help)
        help_.addAction(h) 
        e = QAction(QIcon("exit.png"),"Beenden",self)
        e.triggered.connect(self.exit)
        exit_.addAction(e)
        
        self.central_widget = QFrame()
        self.entry  = QLineEdit()
        self.button = QPushButton("Analysiere Funktion")
        self.layout   = QVBoxLayout()
        self.gridlayout = QGridLayout()
        self.groupbox_results = QGroupBox("Ergebnisse")
        self.splitter = QSplitter(Qt.Vertical)
        self.layout.addWidget(self.splitter)
        self.groupbox_results.setLayout(self.gridlayout)

        self.title = QLabel("<b><u>Berechnen des Minimum's und Maximum's einer Funktion</u></b>")
        self.abl1 = QLabel("")
        self.abl2 = QLabel("")
        self.extrems = QLabel("")
        self.lok_min = QLabel("")
        self.glob_min = QLabel("")
        self.lok_max = QLabel("")
        self.glob_max = QLabel("")
            
        self.gridlayout.addWidget(QLabel("1. Ableitung: "),0,0)
        self.gridlayout.addWidget(self.abl1,0,1)
        self.gridlayout.addWidget(QLabel("2. Ableitung: "),0,2)
        self.gridlayout.addWidget(self.abl2,0,3)
        self.gridlayout.addWidget(QLabel("Extrempunkte: "),1,0)
        self.gridlayout.addWidget(self.extrems,1,1)
        self.gridlayout.addWidget(QLabel("Lokale Minima/s:"),2,0)
        self.gridlayout.addWidget(self.lok_min,2,1)
        self.gridlayout.addWidget(QLabel("Globale Minima/s:"),2,2)
        self.gridlayout.addWidget(self.glob_min,2,3)
        self.gridlayout.addWidget(QLabel("Lokale Maxima/s:"),3,0)
        self.gridlayout.addWidget(self.lok_max,3,1)
        self.gridlayout.addWidget(QLabel("Globale Maxima/s:"),3,2)
        self.gridlayout.addWidget(self.glob_max,3,3)
        
        for w in [self.title,QLabel("\n"),self.entry,QLabel(""),self.button,self.groupbox_results]:
            self.splitter.addWidget(w)
        
        self.entry.setPlaceholderText("z.B: 2*x**3 + 2*x + 21")
        self.button.clicked.connect(lambda: self.calculation(self.x))
        self.title.setAlignment(Qt.AlignCenter)

        self.central_widget.setLayout(self.layout)
        self.setCentralWidget(self.central_widget)
        self.show()
        winsound.PlaySound('SystemExclamation', winsound.SND_ASYNC)

    def show_help(self):
        self.mb = QMessageBox()
        self.mb.setWindowTitle("Kurzes Benutzerhandbuch")
        self.mb.setWindowIcon(QIcon("programmer.png"))
        self.mb.setText('Ergebnisse:\n-------------\n- "EmptySet()" - d.h. nicht vorhanden\n\n- Es werden keine Extremas angegeben,obwohl sie vorhanden sind?\nDann haben sie eine andere Variable anstatt "x" eingetragen.\nNur Funktionen mit "x" sind zulässig. ')
        self.mb.setStandardButtons(QMessageBox.Ok)
        self.mb.setIconPixmap(QPixmap("programmer.png").scaledToHeight(55))
        self.mb.exec_()

    def exit(self):
        winsound.PlaySound('SystemExit',1)
        self.destroy()
        app.quit()
    
    def calculation(self,x):
            self.f(x)
            self.erste_ableitung(x)
            self.find_extremas(x)
            self.result(x)

        
    def f(self,x):#Funktion erstellen
        return sympify(self.entry.text())#Konvertiere String zu Ausdruck

    def erste_ableitung(self,x):#1.Ableitung bilden
        return diff(self.f(x))

    def zweite_ableitung(self,x):#2.Ableitung bilden
        return diff(self.erste_ableitung(x))

    def find_extremas(self,x):#Extremas berechnen
        extr = list()
        y_val_list = list()
        lok_maxima_list = list()
        lok_minima_list = list()
        glob_maxima_list = list()
        glob_minima_list = list()
        
        x_val = solveset(self.erste_ableitung(x),x)

        for i in x_val: #berechne alle Y-Werte
            y_val = self.f(x).subs({x:i}) 
            y_val_list.append(y_val)

        for i in x_val,y_val_list: #adde zu Liste
            extr.append(i)

        #Erkennen von lok. Maxima&Minima
        y_val_abl2_list = list()
        
        for i in y_val_list:
            y_val_abl2 = self.zweite_ableitung(x).subs({x:i})
            y_val_abl2_list.append(i)
            
        try:#lokale Max&Min
            for value in y_val_abl2_list:
                if value < 0:
                    lok_maxima_list.append(value)
                else:
                    lok_minima_list.append(value)
        except:
            lok_maxima_list.append("/")
            lok_minima_list.append("/")

        try:#globale Max&Min
            max_y_val = max(y_val_list)
            min_y_val = min(y_val_list)
            
            if max_y_val < 0:
                glob_maxima_list.append(max_y_val)
            else:
                glob_minima_list.append(min_y_val) 
        except:
            glob_maxima_list.append("/")
            glob_minima_list.append("/")

                
        return extr,lok_minima_list,lok_maxima_list,glob_minima_list,glob_maxima_list
        

    def result(self,x):
        #Lasse alle Ergebnisse ausgeben
        self.abl1.setText("f'(x) = "+str(self.erste_ableitung(x)))
        self.abl2.setText("f''(x) = "+str(self.zweite_ableitung(x)))
        self.extrems.setText(str(self.find_extremas(x)[0]))
        self.lok_min.setText(str(self.find_extremas(x)[1]))
        self.lok_max.setText(str(self.find_extremas(x)[2]))
        self.glob_min.setText(str(self.find_extremas(x)[3]))
        self.glob_max.setText(str(self.find_extremas(x)[4]))

        
    

app = QApplication(sys.argv)
c = Calculator()
c.main()
sys.exit(app.exec_())
Aber es muss doch möglich sein nicht nur mit lin. oder quadr. Funktion arbeiten zu können, sondern auch mit Funktion n'ten Grades.
Bzw ist dafür sympy etwa nicht geeignet? Weil es nur mit Funktionen 2. Grades richtig arbeitet.

Außerdem reagiert das Programm garnicht mehr, sobald ich was mit Winkelfunktionen eingebe.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@xXSkyWalkerXx1: Das Programm schreibt bei einer fehlerhaften Eingabe (z.B. 2x statt 2*x) nur den SyntaxError in die Konsole. Ich würde da eine Fehlermeldung in der GUI erwarten. Auch könnte man das returnPressed-Signal des Eingabefeldes mit der Berechnung verbinden, sodass man nicht immer den Button anklicken muss.

Nebenbei bemerkt möchtest du dich vielleicht mal mit dem Qt-Designer beschäftigen. Da kannst du deine gesamte grafische Oberfläche erzeugen und siehst auch sofort das Ergebnis. Mithilfe der QUiLoader-Klasse aus dem QtUiTools-Modul lässt sich die im Designer erstellte *.ui-Datei dann in dein Python-Programm einbinden. Du musst dann nur noch die Logik für die Benutzerinteraktion schreiben (also die zusätzlichen Slots und Verbindungen) und hast damit deutlich weniger Python-Code. Auch geht der Gestaltungsprozess im Designer viel leichter von der Hand.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

*-Importe sind auch bei sympy schlecht, da damit fast 1000 Namen in den eigenen Namensraum geschaufelt werden.
Du layoutest wirklich mit leeren Labels??
`exit` nutzt die globale Variable `app`. Das sollte nicht sein.
`calculation` macht nichts sinnvolles und kann weg.
In `results` rufst Du 5 mal find_extremas auf, nur um eines der 5 Ergebnisse weiter zu benutzen. `find_extremas` ruft etliche male `zweite_ableitung` auf, das wiederum jedes mal `erste_ableitung` aufruft, das jeweils `f` aufruft, was `sympify` aufruft. Statt also im Zweifel hunderte Male die gleiche Funktion zu parsen, solltest Du das jeweils nur EINMAL machen und die Ergebnisse speichern.
`find_extremas` benutzt nackte Excepts. Es wird eine for-Schleife über ein explizietes Zwei-Tuple benutzt, um damit eine Liste zu füllen, statt die Liste direkt zu erzeugen.
Die Variablennamen sollten nicht das Wort list enthalten und auch keine Abkürzungen.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Die Alternative zu app.quit() ist übrigens der close-Slot, den jedes QWidget mitbringt. Das mündet letztlich auch in einem Beenden der Anwendung, nachdem alle Fenster erfolgreich geschlossen wurden (oder eben das einzig vorhandene). Dabei haben Fenster noch die Möglichkeit, dass sie evtl eine Sicherheitsabfrage vor dem Schließen durchführen. Ich finde diesen Ansatz eleganter.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ja, hab die Funktion von 'exit' zu 'exit_app' umbenannt und die vielen Funktionsaufrufe jeweils in eine Variable gespeichert.

Aber dennoch ist mir nicht klar wie bzw. womit ich nun auch Funktionen ab 3. Grades verwenden kann und warum bei 'sin(x)' das Programm nicht mehr reagiert.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum solltest Du keine Polynome dritten Grades verwenden können?

Was glaubst Du, wie viele Nullstellen hat `sin`?
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Naja, verwenden geht schon, aber ich meinte dies im Sinne, dass ich da auch mit der "0" vergleichen kann, um Minima oder Maxima zu ermitteln.

Stimmt... :facepalm: Hm, theoretisch hätte ich also dafür noch was schreiben müssen, dass den x-Wertebereich eingrenzt.
Und du meinst eher Minimas und Maximas, aber da merk ich wie es dumm ist eine Winkelfunktion einzubringen, da sie ja unendl. Minimas und Maximas hat. ^^
Dabei hat sie glaube nicht einmal Relevanz bei meiner Belegarbeit, fällt mir gerade ein.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Polynome der Ordnung n haben 0 bis n für gerades n und 1 bis n reelle Nullstellen für ungerades n.
Der Rest der bis zu n Nullstellen sind komplex.
Ähnlich verhält es sich mit den Minima und Maxima. Für Dich sind wahrscheinlich nur die reelen Werte interessant, die Du halt ausfiltern mußt.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Oha, danke! Hab das Mal mit meinem Programm versucht und tatsächlich funktioniert es, sobald wenigstens 1 Exponent gerade ist.
Antworten