Code läuft extrem langsam frage zur Verbesserung

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
jens_lastname
User
Beiträge: 2
Registriert: Mittwoch 4. November 2015, 09:35

Hallo zusammen,

ich bin Python und hätte eine frage warum dieser Code hier extrem langsam läuft.
Das Programm läuft sehr langsam, ich denke es liegt daran, dass ich verschiedene Fenster geöffnet werden jenachdem welche Aktion gewählt wird, gibt es hier verbesserungspotenzial

Code: Alles auswählen

# -*- coding: utf-8 -*-



''' Import der Module '''
import sys, smtplib
from PyQt4 import QtGui, uic
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

''' Definitionen der Funktionen '''
# Allgemein Gueltige Funktionen
def abbruch():
    pat_verschieben.close()
    pat_loeschen.close()
    normal.close()
    fehler.close()
    
def ende(): 
    abbruch()
    sys.exit(0)

def email(fenster, vorname, nachname, betreff_pat1, datum='', pat2=''):
    def check_leerzeichen(name_alt):
    # Funktion um aus der E-Mail Adressen die Leerzeichen zu entfernen
        char=' '
        umlaut={"ä" : "ae",
                "ö" : "oe",
                "ü" : "ue",
                "ß" : "ss",
                "é" : "e",
                "á" : "a"}
        name_neu=' '
        for character in name_alt:
            if character not in char:
                name_neu= name_neu + character 
        name_neu1=(name_neu.translate(str.maketrans(umlaut)))
        return name_neu1
       
    
    # Werte für die E-Mail vorbereiten  
    vorname_neu=check_leerzeichen(vorname) 
    nachname_neu=check_leerzeichen(nachname)
    empfaenger='test@test.de'
    absender=(vorname_neu + '.' + nachname_neu + '@test.de')
    
    if vorname != '' and nachname != ''  and betreff_pat1 != '' : 
        # Prüfen ob Pflichtfelder angegeben sind
        
        if fenster == 'normal':  
            msg=MIMEText(betreff_pat1.encode("utf-8"), _charset="utf-8")
            msg=MIMEMultipart()
            msg['Subject'] = betreff_pat1
            msg['From'] = absender
            msg['To'] = empfaenger
            text=normal.ui.plain1.toPlainText()
            msg.attach(MIMEText(text,'plain')) 
           
        elif fenster == 'patloeschen':
            betreff_neu=('Bitte die Daten von Patient: '  + betreff_pat1 + ' vom: ' + datum + ' löschen')
            msg=MIMEText(betreff_neu.encode("utf-8"), _charset="utf-8")
            msg=MIMEMultipart()
            msg['Subject'] = betreff_neu
            msg['From'] = absender
            msg['To'] = empfaenger
            text=pat_loeschen.ui.plain1.toPlainText()
            msg.attach(MIMEText(text,'plain'))
        
        elif fenster == 'patverschieben':
            if pat2 != '': 
                betreff_neu=('Bitte die Daten von Patient: '  + betreff_pat1 + ' vom: ' + datum +  ' auf Patienten: ' + pat2 + '  verschieben')
                msg=MIMEText(betreff_neu.encode("utf-8"), _charset="utf-8")
                msg=MIMEMultipart()
                msg['Subject'] = betreff_neu
                msg['From'] = absender
                msg['To'] = empfaenger
                text=pat_verschieben.ui.plain1.toPlainText()
                msg.attach(MIMEText(text,'plain'))
            else:
                fehler.show()  
    else:
        fehler.show() 
       
    # Eigentliches Versenden der E-Mail 
    mail=smtplib.SMTP('mail-srv.ocm.local')
    mail.login('Benutzer', 'Kennwort')
    mail.sendmail(absender, empfaenger, msg.as_string("utf-8") )
    mail.quit()  
         
# Funktion Hauptfenster
def start_nt():
    normal.show()
    
def start_patL():
    pat_loeschen.show()

def start_patV():
    pat_verschieben.show()

# Funktion Normales Ticket   
def nt_senden():
    email('normal', normal.ui.line1.text() , normal.ui.line2.text(), normal.ui.line3.text())
    abbruch()

# Funktion Patientendaten Loeschen
def patL_senden():
    email('patloeschen', pat_loeschen.ui.line1.text(), pat_loeschen.ui.line2.text(), 
          pat_loeschen.ui.line3.text(), pat_loeschen.ui.date1.date().toString("dd.MM.yyyy"))
    abbruch()

# Funktion Patientendaten verschieben
# Funktion fehler

def patV_senden():
    email('patverschieben', pat_verschieben.ui.line1.text(), pat_verschieben.ui.line2.text(),  
          pat_verschieben.ui.line3.text(), pat_verschieben.date1.date().toString("yy.MM.yyyy"), pat_verschieben.line4.text())
    abbruch()

def abbruch_fehler():
    fehler.close()
 
''' Bereitstellung der Fenster '''
# Hauptfenster
class Hauptfenster(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.ui = uic.loadUi("Hauptfenster.ui", self)
        self.ui.b1.clicked.connect(start_nt)
        self.ui.b2.clicked.connect(start_patL)
        self.ui.b3.clicked.connect(start_patV)
        self.ui.b4.clicked.connect(ende)
# Ende Hauptfenster

# Normales Ticket
class Normalesticket(QtGui.QMainWindow):    
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.ui = uic.loadUi("normalesticket.ui", self)
        self.ui.button1.clicked.connect(nt_senden)
        self.ui.button2.clicked.connect(abbruch)
        self.ui.button3.clicked.connect(ende)
        #self.ui.button4.clicked.connect(ende)
                
        
             
app1 = QtGui.QApplication(sys.argv)
normal = Normalesticket()
# Ende Normales Ticket

# Patientenloeschen Fenster
class PatientenL(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.ui = uic.loadUi("patienten_loeschen.ui", self)    
        self.ui.button1.clicked.connect(patL_senden)
        self.ui.button2.clicked.connect(abbruch)
        self.ui.button3.clicked.connect(ende)
        
app2 = QtGui.QApplication(sys.argv)
pat_loeschen = PatientenL()
# Ende Patientenloeschen Fenster

# Patientenverschieben Fenster
class PatientenV(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.ui = uic.loadUi("patienten_verschieben.ui", self) 
        self.ui.button1.clicked.connect(patV_senden)
        self.ui.button2.clicked.connect(abbruch)
        self.ui.button3.clicked.connect(ende)
        
app3 = QtGui.QApplication(sys.argv)
pat_verschieben = PatientenV()
# Ende Patientenverschieben Fenster

# Fehler Fenster   
class Fehler(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.ui = uic.loadUi("fehler.ui", self)
        self.ui.b_ok.clicked.connect(abbruch_fehler)
        
app4 = QtGui.QApplication(sys.argv)
fehler = Fehler()
# Ende Fehler Fenster              

''' Erzeugung des Hauptfensters'''
app = QtGui.QApplication(sys.argv)
haupt = Hauptfenster()
haupt.show()
sys.exit(app.exec_())




Danke schon mal im Voraus
BlackJack

@jens_lastname: Ich glaube nicht das sich den Wust tatsächlich jemand antun möchte. Wenn ich raten müsste, dann könnte es vielleicht daran liegen das dort mehrere `QApplication`-Exemplare erstellt werden — das ist ein Objekt das für *die* Anwendung steht, davon sollte es nur eines geben.

Aber so ganz grundsätzlich greifst Du da aus Funktionen wild auf globale Variablen zu und auf Modulebene sind Definitionen und Code vom Hauptprogramm vermischt. Unübersichtlicher geht's kaum. Das solltest Du als erstes mal in den Griff bekommen. Auf Modulebene nur Definitionen von Konstanten, Funktionen, und Klassen. Das Hauptprogramm gehört in einer Funktion, üblicherweise `main()` genannt. Dann kann man nicht mehr so einfach auf globales zugreifen, das heisst Du musst den Code anders, nämlich objektorientiert organisieren. Faustregel: Werte ausser Konstanten betreten Funktionen und Methoden als Argumente und verlassen sie als Rückgabewerte.

Docstrings können nicht an beliebigen Stellen stehen sondern nur am Anfang von Modulen und direkt nach ``class``- und ``def``-Anweisungen. An anderen Stellen sind es einfach nur sinnfreie Ausdrücke die nichts bewirken.

Weder in Docstrings noch in Kommentare gehören offensichtliche Dinge wie das importe gemacht werden direkt bevor die importe gemacht werden. Ein Kommentar soll dem Leser einen Mehrwert über den Code geben und nicht etwas wiederholen was man eh am Code sieht. Gute Kommentare sollten nicht erklären *was* der Code macht, denn das sieht man ja am Code, sondern *warum* er das so macht. Sofern das nicht offensichtlich ist. Die Kommentare welche Funktion für welches Fenster ist, bräuchte man nicht wenn man das in entsprechende Klassen stecken würde.

Die `email()`-Funktion hantiert mit viel zu vielen Variablen die teilweise auch noch global sind und auch noch GUI-Elemente. Dann auch noch verschiene ”Sätze” von Variablen in den ``if``/``elif``-Zweigen, was ein Zeichen dafür ist das hier eigentlich mehrere Funktionen zu einer vermantscht wurde. Versuch die Funktion mal isoliert zu testen, das ist nahezu unmöglich.

Die Namen der GUI-Elemente sind teilweise nichtssagend. `line1`, `line2`, `line3` — da weiss doch kein Leser das sich hinter so etwas Betreff und Vor- und Nachname verbergen. Das sollte man an der Stelle aber aus dem Code ersehen können.
jens_lastname
User
Beiträge: 2
Registriert: Mittwoch 4. November 2015, 09:35

Hallo Black Jack,

danke für die schnelle Info. Wie gesagt ich bin noch Anfänger und hab das mal schnell in ein paar Stunden gebastelt. Ich werde den Code nochmal überarbeiten und dann Testen.

Danke
Antworten