Problem funktion "find(Hersteller,Art.......)" in Teilekatalog

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.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Sirius3 hat geschrieben:@dannyboy385: eine Liste ist der falsche Datentyp für einen Eintrag, nimm Namedtuple, Wörterbücher oder ähnliches. Wenn artikelnummer, preisEK oder preisVK Zahlen sind, dann speicherst Du sie intern auch als Zahlen. Übrigens, preisVK = preisEK * (1 + gewinn) * mwst oder preisVK = preisEK * (1 + gewinn * mwst), je nachdem ob preisEK mit oder ohne Verbrauchssteuern ist. Wenn Du dann an anderer Stelle Probleme bekommst (search, readfile, etc) dann mußt Du die dort lösen und nicht durch eine unsinnige Datenhaltung. `new` bekommt die Liste datenbank als Argument und gibt sie auch wieder als Rückgabewert zurück. Das ist in manchen Sprachen üblich (chaining) in Python aber verpönt, weil es falsche Erwartungen an die Funktion erzeugt, nämlich, dass das Übergebene datenbank NICHT verändert wird. `for index ...` ist ein Anti-Pattern, heißt, soll man nicht machen; man kann direkt über die Listenelemente iterieren. `search` liefert unter Umständen ungewollte Ergebnisse.
Der Preis/artikelnummer habe ich als str gespeichert dar mir search sonst eine exception schmeist dar ich ja nach einem teilstring in den einträgen der listen Suche aber ein string nicht teil einer integer oder float sein kann.

Was genau meinst du mit direkt über die Listen Elemente iterieren. Wie wäre hier ein passender Lösungsansatz? Die Problematik bei einigen anderen versuchen war ja immer das die liste listen enthält und der zugriff über den index reichlicher denksport war. Artikelnummer ist denke ich als string sinnvoll..den preis könnte man aus der Suche ausschöießen, dar sicher keiner nach "3.72" suchen wird.
Dictionaries brachten mich in eine anderen versuch halb zur verzweiflung. Sie sind ja immer eine zuordnung von key:value. Aber in wie fern wird diese zuordnung nützlich oder interessant? Habe soeben feierabend gemacht und werde mich noch einmal an einen versuch waagen.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: genau das habe ich ja bereits geschrieben: die Datenhaltung soll sich nicht an irgendeine Suche anpassen müssen, sondern umgekehrt, verwende sinnvolle Datentypen, denn sobald Du den Gesamtpreis oder ähnliches Ausrechnen willst, was machst Du dann mit Deinen Strings?
Das iterieren meine ich, so wie Du es ja in readfile und savefile breits machst. Warum also nicht auch in search oder new?
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Nabend Sirius. Also auf dein anraten habe ich es einmal mit SQLite versucht. leider scheitere ich schon bei den ersten zweilen

Code: Alles auswählen

import sqlite3

connection = sqlite3.connect("Katalog.db")
cursor= connection.cursor()
sql_command = """
CREATE TABLE materialliste (
Artikelnummer INTEGER(15),
Hersteller VARCHAR(20),
Artikelbezeichnung VARCHAR(30),
PreisEK REAL,
PreisVK REAL
);"""

#cursor.execute(sql_command)



def new (datensatz):
    cursor.execute("""INSERT INTO materialliste (Artikelnummer,Hersteller,Artikelbezeichnung,PreisEK,PreisVK) VALUES (datensatz)""")
    connection.commit()
Ich baue eine verbindung zur datenbank "Katalog.db" auf erstelle einen Cursor und versuche per cursor.execute(???) SQL Befehle auszuführen.

Nun folgendes Problem dar sich SQL quer stellte eine Liste(welche ja eine feste Reihenfulge hat) der tabelle hinzuzufügen habe ich etwas gegoogelt und bin darauf gestoßen das man doch tuple übergeben solle..Nun ja. dann baute ich mir das unter new stehende Konstrukt zusammen.

Wenn ich das Programm ausführe und dann:

Code: Alles auswählen

new(datensatz=(23657236,"ABB","dbksdj",7.45,7.89)
Versuche hängt sich das Programm auf. Das heisst der Cursor blinkt aber es erscheint keine neue Zeile mit >>>
Exception wird aber auch keine geworfen.

Siehst du auf anhieb das Problem? Ich glaube ich stelle mich einfach an wie der Hund zum Eierlegen...
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: da fehlt eine schließende Klammer. Und warum denkst Du, dass das Wort »datensatz« in einem String auf magische Weise mit der Variable `datensatz`ersetzt wird?

Code: Alles auswählen

def new(connection, datensatz):
    cursor = connection.cursor()
    cursor.execute("""INSERT INTO materialliste (Artikelnummer,Hersteller,Artikelbezeichnung,PreisEK,PreisVK) VALUES (?, ?, ?, ?, ?)""", datensatz)
    connection.commit()
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Edit: jetzt funktioniert das hinzufügen zumindest einmal

Code: Alles auswählen


def new (datensatz):        #Funktioniert. Übergabewert muss ein tupel oder eine Liste sein
    if type(datensatz) == 'list':
        datensatz = tuple(datensatz)
    cursor.execute('INSERT INTO materialliste VALUES (?,?,?,?,?)', datensatz)
    connection.commit()
                      
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: es ist völlig egal, welche Sequenztyp als Parameter übergeben wird, Zeile 3 und 4 sind also unnötig.
narpfel
User
Beiträge: 644
Registriert: Freitag 20. Oktober 2017, 16:10

@dannyboy385: Außerdem gibt `type` einen Wert vom Typ `type` zurück, nicht vom Typ `str`. Der Vergleich ergibt also immer `False`.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Code: Alles auswählen

def new (datensatz): 

    cursor.execute('INSERT INTO materialliste VALUES (?,?,?,?,?)', datensatz)
    connection.commit()


def databasesearch(suchbegriff):
    results=[]
    for x in cursor.execute("SELECT * FROM materialliste"):
        if suchbegriff in x:
            results.append(x)
    return results

def listsearch(liste, suchbegriff):
    results=[]
    for x in liste:
        if suchbegriff in x:
            results.append(x)
    return results
Also das erstellen neuer Einträge funktioniert, sowie das durchsuchen der Datenbank nach einem Begriff . Desweiteren habe ich noch eine Funktion mit der ich eventuelle listen noch einmal durchsuchen kann(spart zwar nurj eweils 2 Zeilen aber immer hin.. nĹeider hat das Suchen direkt in SQL nicht so funktioniert wie erwartet. ich wollte ein konstrukt ala
"SELECT * FROM materialliste WHERE Artikelnummer OR Hersteller OR Artickelbezeichnung LIKE (2)",suchgebgriff
bauen, Leider funktioniert das so einfach nicht., . . hat hierzu jemand einen Denkanstoß?.

Desweiteren bin ich noch nicht so weit gekommen wie ich jetzt einen Expliziten Eintrag löschen kann und Doppelte Einträge vermeiden kann..
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: der Tipp wäre ein SQL-Tutorial durchzuarbeiten.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Hallo Leute. Also nachdem ich jetzt etliche Beiträge gelesen habe zur thematik Durchsuchen von Datenbanken und Editieren von Datenbanken steh ich gewaltig auf dem Schlauch. Die SQL Syntax so einfach sie auch aussieht treibt mich in den wahnsinn. Unten Aktueller(schon etwas zerpflückter Code).

Zur Problematik:
Erstens würde ich gerne databasesearch(): so umbauen das die Suche nicht von Python in im Cursor erledigt wird sondern SQL mir die Ergebnisse zurück liefert... dar mir dieses For bla in cursor.execute .... irgendwie missfällt und sehr untypisch vorkommt.

2tens habe ich noch nicht geschafft LIKE zum laufen zu bekommen. Also eine Suche die nicht nach dem genauen Begriff sucht.... Was ich unter databaselike() versucht habe.

Code: Alles auswählen

>>> for row in databaselike("HAGER"):
	print(row)

	
(73476384, 'HAGER', 'Aufputzvertiler Volta48', 42.6, 45.0)
(23657236, 'ABB', 'dbksdj', 7.45, 7.89)
(12839729831, 'ABB', 'jdfkshfd', 4.32, 4.56)
(12839729831, 'ABB', 'jdfkshfd', 4.32, 4.56)
(12839729831, 'ABB', 'jdfkshfd', 4.32, 4.56)
(23657236, 'ABB', 'dbksdj', 7.45, 7.89)
>>> 
Das ist allerdings nicht das erwartete Ergebniss...

Ich stehe wirklich auf dem schlauch.

Das Editieren ist das nächste Thema. Dar das ganze ja später einmal eine GUI bekommen soll die in etwa so aussieht das oben ein Suchfeld ist drunter die Einträge und durch anklicken der Einträge die möglichkeiten des Löschens und Editierens erscheinen. Editieren in einem Popup in dem der Eintrag angezeigt, nach Lust und Liebe editiert und gespeichert werden kann) fehlt mir die Idee wie ich hierbei überhaupt anfangne soll...um die Funktionen später Efektiv nutzen zu können müsste ich den bestehenden Eintrag ja in einer Variable speichern, editieren und dann den alten in einer 2ten variable gesicherten Eintrag mit den neuen Werten an SQL übergeben. Ich habe wirklich keinen Aufriss mehr und das gefühl das das ganze mit SQL wesentlich schwieriger wird als mit csv oder einfach pickle Dateien... :/ :K

Code: Alles auswählen

import sqlite3

connection = sqlite3.connect("Katalog.db")
cursor= connection.cursor()
sql_command = """
CREATE TABLE materialliste (
Artikelnummer INTEGER(15),
Hersteller VARCHAR(20),
Artikelbezeichnung VARCHAR(30),
PreisEK REAL,
PreisVK REAL
);"""

#cursor.execute(sql_command)



def new (datensatz):        #Funktioniert. Übergabewert muss ein tupel oder eine Liste sein
    cursor.execute('INSERT INTO materialliste VALUES (?,?,?,?,?)', datensatz)
    connection.commit()


def databasesearch(suchbegriff):
    results=[]
    for x in cursor.execute("SELECT * FROM materialliste"):
        if suchbegriff in x:
            results.append(x)
    return results

def databaselike(suchbegriff):
    cursor.execute("""SELECT * FROM materialliste WHERE (Artikelnummer OR Hersteller = ?)""",(suchbegriff,))
    	


def listsearch(liste, suchbegriff):		#Durchsucht die unterlisten einer Liste
    results=[]
    for x in liste:
        if suchbegriff in x:
            results.append(x)
    return results

def databasedelete(Artikelnummer):               #Funktioniert Ebenfalls
    cursor.execute("DELETE FROM materialliste WHERE Artikelnummer = ?",(Artikelnummer,))
    connection.commit()

Ich wäre froh darüber wenn mir jemand eventuell Codebeispiele mit Ausführlicher Erklärung liefern könnte...den auch aus den ganzen Tutorials werde ich nicht schlau und egal was ich versuche es ist ein ewiges Syntax gebastel bis es funktioniert.. :?
Ich habe nicht einmal das gefühl dafür wann SQL eine Klammer oder ähnliches erwartet...

Das einzig positive das ich mom sehe ist die Speicherung in der Datenbank. Suche, Löschen und verändern erscheinen mir wesentlich aufwändiger.. und auch komplizierter...
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Hallo Leute nach einigen Kampf bin ich nun soweit das ich Einträge editieren kann welche ich per Artikelnummer identifiziere, Einträge Erstelle und Lösche, Die Datenbank nach einem Suchbegriff Durchsuche eine Neue Datenbank anlege aber vorher prüfe ob sie bereits besteht.

Jetzt würde ich euch bitten noch einmal über das ganze zu schaun und eventuelle Fehler anzusprechen.

Was mir selbst auffältt:
Das global in der Funktion open gefällt mir garnicht

Exceptions von SQLite werden noch nicht behandelt(Hier denke ich an eine folgenden Lösungsansatz:
Dar später das ganze eine GUI haben soll wäre es natürlich schön jede exceotion per try: .....
except(MESSagebox mit FEHLERBESCHREIBUNG)

Was fällt euch noch auf oder wäre einfacher zu lösen?

Code: Alles auswählen

import sqlite3
import os.path






def new (datensatz):        #Funktioniert. Übergabewert muss ein tupel oder eine Liste sein
    cursor.execute('INSERT INTO materialliste VALUES (?,?,?,?,?)', datensatz)
    connection.commit()

def databasesearch(suchbegriff):
    cursor.execute("SELECT * FROM materialliste WHERE Artikelbezeichnung LIKE (?) OR Hersteller LIKE (?) OR Artikelnummer LIKE (?)", (suchbegriff,suchbegriff,suchbegriff))
    	
def listsearch(liste, suchbegriff):		#Durchsucht die unterlisten einer Liste
    results=[]
    for x in liste:
        if suchbegriff in x:
            results.append(x)
    return results

def databasedelete(Artikelnummer):               #Funktioniert Ebenfalls
    cursor.execute("DELETE FROM materialliste WHERE Artikelnummer = ?",(Artikelnummer,))


def save():
    connection.commit()
    connection.close()

def donotsave():
    connection.close()

def createdatabase(name):
    if os.path.isfile(name) is True:
        return(1)
    else:
        connection = sqlite3.connect(name+".db")
        cursor= connection.cursor()
        sql_command = """
        CREATE TABLE IF NOT EXISTS materialliste (
        Artikelnummer INTEGER(15),
        Hersteller VARCHAR(20),
        Artikelbezeichnung VARCHAR(30),
        PreisEK REAL,
        PreisVK REAL
        );"""
        cursor.execute(sql_command)
        save()

def open(name):
    global connection
    connection = sqlite3.connect(name)
    global cursor
    cursor = connection.cursor()
    
    
def editdb(artikelnummer,Artikelbezeichnung=0,Hersteller=0,PreisEK=0,PreisVK=0):
    if Artikelbezeichnung != 0:
        cursor.execute("UPDATE materialliste SET Artikelbezeichnung = ? WHERE Artikelnummer = ?", (Artikelbezeichnung,artikelnummer))
    if Hersteller != 0:
        cursor.execute("UPDATE materialliste SET Hersteller = ? WHERE Artikelnummer = ?", (Hersteller,artikelnummer))
    if PreisEK != 0:
        cursor.execute("UPDATE materialliste SET PreisEK = ? WHERE Artikelnummer = ?", (PreisEK,artikelnummer))
    if PreisVK != 0:
        cursor.execute("UPDATE materialliste SET PreisVK = ? WHERE Artikelnummer = ?", (PreisVK,artikelnummer))

dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

natürlich funktionieren meine ersten Versuche der Gui bereits nicht....ich möchte einen Button Save welcher aber nur erscheint wenn einen Datenabnak geöffnet ist und folglichermassen Open in position und größe ersetzt... allein das funktioniert schon nicht. . .

Code: Alles auswählen

if "connection" not in dir(sqlite3):
    openbt=tkinter.Button(master=fenster, text="Open", command=lambda : tkinter.filedialog.askopenfilename())
    openbt.pack()
    if "connection" in dir(sqlite3):
        openbt.destroy()

if "connection" in dir(sqlite3):
    savebt=tkinter.Button(master=fenster, text="Save", command=save)
    savebt.pack(side="LEFT")

fenster.mainloop()
PS: Warum ist eigentlich die Zeit um Einträge zu editieren so kurz. könnte mnan das nicht einfach solange ermöglichen bis die nächste Antwort geschrieben wurde?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: Du benutzt in allen Deinen „Funktionen“ globale Variablen, nicht nur in »open«. In editdb benutzt Du 0 als Platzhalter für „keinen Wert“. Dafür gibt es aber schon None.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Sirius3 hat geschrieben:@dannyboy385: Du benutzt in allen Deinen „Funktionen“ globale Variablen, nicht nur in »open«. In editdb benutzt Du 0 als Platzhalter für „keinen Wert“. Dafür gibt es aber schon None.
Ok das habe ich im Code einmal geändert. Nur ist die verwendung von globalen Variablen doch eher unschön. Wie könnte man das vermeiden? Ich meinte damit auch die verwendung des befehls global. Das ganze ist ja leider alles andere als OO..
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das es nicht OO ist, ist doch deine Entscheidung. Das lässt sich doch alles problemlos in eine Klasse packen.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

__deets__ hat geschrieben:Das es nicht OO ist, ist doch deine Entscheidung. Das lässt sich doch alles problemlos in eine Klasse packen.
Bei der OOP steh ich mit dem Kopf vor der Wand. Ich habe schon einige tutorials gelesen und Verstehe es einfach nicht. Ich weiss nicht woran es liegt aber ich bekomme es einfach nicht auf die Reihe. Auch könnte man ja dann die GUI so schreiben das sie auf dem object bla arbeitet und man könnte eine möglichkeit erarbeiten um mehrere Datenbanken zu öffnen und Einträge zu kopieren...Ich denke das meine Ideen weit von meiner Programmiertechnischen Fähigkeit abweichen. Aber gerade da packt mich der ergeiz dieses "Projekt" auszubauen und Auszubauen. Immer mehr dazu zu lernen und am Ende etwas wirklich Praktisches in den händen zu halten. Leider denke ich das ich es ohne Hilfe nicht schaffen werde. Gerade im mom Arbeite ich an einer Import Funktion und einer die doppelte Einträge ausmerzt, aber das so offen das man später die möglichkeit hat per checkboxen einen der Einträge zu behalten... Das ganze Artet sichtbar aus :D
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: das was Du in dem Code den Du als GUI bezeichnest, machst, ist noch viel schlimmere globale Variablen-Verwirrung. Ich weiß nicht, woher Du das mit dem »in dir« hast, aber vergiss es genauso schnell wieder. Bei GUIs von der Komplexität, wie Du es Dir vorstellst, kommst Du um OO nicht herum.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Ich hätte hier ienmal das ganze in eine Klasse verpackt. Ich wäre froh wenn ihr mir eure Meinung sagen würdet. Ich habe bis jetzt ausführlich getestet und konnte keine Funktionsfehler festellen. Kann natürlich sein das ich etwas übersehen habe. Auf jeden Fall ist es so möglich gleichzeitig mit 2 Datenbanken zu arbeiten. Allerdings weis ich nicht ob das wirklich sagen wir einmal Klassen"gerecht" konstruiert ist. Die Import anweisungen und die Testfunktionen außerhalb habe ich mir einmal gespart dar der thread sowieso schon so lang ist. auch wird es langsam etwas OT dar es ja eigenlich nicht mehr um find() geht.


Code: Alles auswählen

class database():
    def opendb(self,name):
        self.connection = sqlite3.connect(name)
        self.cursor = self.connection.cursor()


    def savedata(self):
        self.connection.commit()
        self.connection.close()

    def donotsavedata(self):
        self.connection.close()

    def newdata(self,dataset):
        self.cursor.execute('INSERT INTO materialliste VALUES (?,?,?,?,?)', dataset)

    def deletedataset(self, artikelnummer):
        self.cursor.execute("DELETE FROM materialliste WHERE Artikelnummer = ?",(artikelnummer,))

    def createdb(self,name):
        if os.path.isfile(name) is True:
            return(1)
        else:
            self.connection = sqlite3.connect(name+".db")
            self.cursor= self.connection.cursor()
            sql_command = """
            CREATE TABLE IF NOT EXISTS materialliste (
            Artikelnummer INTEGER(15),
            Hersteller VARCHAR(20),
            Artikelbezeichnung VARCHAR(30),
            PreisEK REAL,
            PreisVK REAL
            );"""
            self.cursor.execute(sql_command)
            self.savedata()
            self.opendb(name+".db")
            
    def createtable(self):
        sql_command = """
            CREATE TABLE IF NOT EXISTS materialliste (
            Artikelnummer INTEGER(15),
            Hersteller VARCHAR(20),
            Artikelbezeichnung VARCHAR(30),
            PreisEK REAL,
            PreisVK REAL
            );"""
        self.cursor.execute(sql_command)

    def editdata(self,artikelnummer,Artikelbezeichnung=None,Hersteller=None,PreisEK=None,PreisVK=None):
        if Artikelbezeichnung != None:
             self.cursor.execute("UPDATE materialliste SET Artikelbezeichnung = ? WHERE Artikelnummer = ?", (Artikelbezeichnung,artikelnummer))
        if Hersteller != None:
            self.cursor.execute("UPDATE materialliste SET Hersteller = ? WHERE Artikelnummer = ?", (Hersteller,artikelnummer))
        if PreisEK != None:
            self.cursor.execute("UPDATE materialliste SET PreisEK = ? WHERE Artikelnummer = ?", (PreisEK,artikelnummer))
        if PreisVK != None:
            self.cursor.execute("UPDATE materialliste SET PreisVK = ? WHERE Artikelnummer = ?", (PreisVK,artikelnummer))

    def search(self,suchbegriff):
        self.cursor.execute("SELECT * FROM materialliste WHERE Artikelbezeichnung LIKE (?) OR Hersteller LIKE (?) OR Artikelnummer LIKE (?)", (suchbegriff,suchbegriff,suchbegriff))
        return self.cursor.fetchall()

    def all(self):
        self.cursor.execute("SELECT * FROM materialliste")
        return self.cursor.fetchall()

    def emptydb(self):
        self.cursor.execute("DROP TABLE IF EXISTS materialliste")
        self.createtable()
edit: und noch eine kurze Frage. was bringt es eine GUI in eine Klasse Gui packen? meist hat man doch eh nur 1 instanz bzw ein Fenster in dem sich allesabspielt
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Das wäre nun der erste Versuch etwas sichtbar zu machen. Doch merke ich jetzt schon dass das ganze extrem aus dem Ruder läuft.
Ich denke darüber nach eventuell eine classe zu erstellen mit methoden für die GUI welche die methoden der SQLDatenbankverwaltung nutzt aufwelche ich dann aus einer main.py zugreife und mir somit das ganze etwas aufteile. Nur wird das dann sehr verschachtelt. . . Aber irgendwie müsste ich meines erachtens den SQL Teil class database() von der GUI und dem eigentlichen Programm ablauf etwas abkapseln um den überblick zu behalten.. .

Code: Alles auswählen

def guisave():
    try:
        data.savedata()
        showinfo("Speichern", "Speichervorgang erfolgreich")
    except sqlite3.ProgrammingError:
        showerror("Datei Auswählen","Keine Datenbank geladen")
    except AttributeError:
        showerror("Datei öffnen","Keine Datenbank geladen")
    except TypeError:
        showerror("Datei öffnen","Bitte wählen sie die Datenbank aus, mit welcher sie Arbeiten möchten")
def kill():
    if askyesno("Datenbank leeren", "Sind sie sicher das sie den Inhalt der Datenbank Löschen wollen?"):
        data.emptydb()
        
def guineu():               #Öffnet neues Fenster in dem 5 Entrys abgefragt werden und der Datenbank hinzugefügt
    def getit():
        artnr=e1.get()
        herst=e2.get()
        beschrei=e3.get()
        preisek=e4.get()
        preisvk=e5.get()
        results=[]
        results.append(int(artnr))
        results.append(str(herst))
        results.append(str(beschrei))
        results.append(float(preisek))
        results.append(float(preisvk))
        data.newdata(results)
        popup.destroy()
        
    popup=tkinter.Tk(className="Neuer Datensatz")
    e1=tkinter.Entry(popup)
    e2=tkinter.Entry(popup)
    e3=tkinter.Entry(popup)
    e4=tkinter.Entry(popup)
    e5=tkinter.Entry(popup)
    tkinter.Label(popup, text="Artikelnummer").grid(column=0,row=1)
    tkinter.Label(popup, text="Hersteller").grid(column=2,row=1)
    tkinter.Label(popup, text="Artikelbezeichnung").grid(column=4,row=1)
    tkinter.Label(popup, text="PreisEK").grid(column=6,row=1)
    tkinter.Label(popup, text="PreisVK").grid(column=8,row=1)
    e1.grid(column=0,row=2)
    e2.grid(column=2,row=2)
    e3.grid(column=4,row=2)
    e4.grid(column=6,row=2)
    e5.grid(column=8,row=2)
    tkinter.Button(popup, text="OK", command=getit).grid(column=4, row=3)

    popup.mainloop()

def guisuche():
    try:
        suchbegriff=suchfeld.get()
        results=data.search(suchbegriff)
        counter=10
        for line in results:
            tkinter.Label(root, text=line[0]).grid(column=7,row=counter)
            tkinter.Label(root, text=line[1]).grid(column=8, row=counter)
            tkinter.Label(root, text=line[2]).grid(column=9, row=counter)
            tkinter.Label(root, text=line[3]).grid(column=10, row=counter)
            tkinter.Label(root, text=line[4]).grid(column=11, row=counter)
            counter+=1
    except AttributeError:
        showerror("Datei öffnen","Keine Datenbank geladen")
    
data=database()
root=tkinter.Tk(className="blaaaa")
root.geometry("800x600")
menu = tkinter.Menu(root)
root.config(menu=menu)
filemenu= tkinter.Menu(menu)
menu.add_cascade(label="Datei", menu=filemenu)
filemenu.add_command(label="Datei öffnen", command=lambda:data.opendb(tkinter.filedialog.askopenfilename()))
filemenu.add_command(label="Speichern", command= guisave)
changemenu=tkinter.Menu(menu)
menu.add_cascade(label="Bearbeiten", menu=changemenu)
changemenu.add_command(label="Datenbank leeren", command = kill)
changemenu.add_command(label="Neuer Eintrag", command = guineu)
suchfeld=tkinter.Entry(root)
suchfeld.grid(row=2,column=5)
searchbutton=tkinter.Button(root, text="Suchen", command=guisuche)
searchbutton.grid(row=2, column=6)

root.mainloop()
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: `database` ist eine Klasse und wird deshalb `Database` geschrieben. Eine Klasse sollte immer ein __init__ haben, wo alle Attribute angelegt werden und wo danach die Instanz benutzbar ist. Cursor sind eigentlich etwas kurzzeitiges, was man für jede Transaktion neu erstellt. Transaktion ist etwas, was einen Vorgang bezeichnet und per `COMMIT` abgeschlossen wird. So wie Du jetzt mit `savedata` und `donotsavedata` arbeiten Datenbanken nicht. Man sollte immer die Feldnamen angeben, und sich nicht darauf verlassen, dass die da schon in der richtigen Reihenfolge sind, bei INSERT oder SELECT. »createdb« macht ziemliches Chaos mit Dateinamen. Den Wahrheitswert explizit mit "is True" zu vergleichen, ist unnötig. Was soll der Rückgabewert hier? Die Datenbank zu schließen und gleich wieder zu öffnen, ist umständlich. »createtable« wiederholt nochmal »createdb«. Warum zweimal? Bei »editdata« macht man am besten ein UPDATE. Bei search benutzt Du LIKE wahrscheinlich ohne zu wissen warum. »all« ist ein komischer Methodenname, und um eine Tabelle zu leeren gibt es DELETE. Da muß man nicht gleich die ganze Tabelle löschen.

Der GUI-Code benutzt wieder über und über globale Variablen. Die Exceptions, die Du in `guisave` abfängst sind eher zufällig. Wo soll da ein TypeError auftreten? Einen AttributeError dafür zu verwenden, um eine nicht geöffnete Datei abzufragen ist schlechter Stil. Alle Attribute einer Klasse sollten schon in __init__ angelegt werden, so dass jeder AttributeError ein Programmierfehler ist.

In `guineu` erzeugst Du ein neues Tk-Exemplar, davon darf es aber nur eins im ganzen Programm geben. e1 bis e5 sind schlechte Variablennamen, und statt innerer Funktionen schreibt man besser Klassen.

Alles ab Zeile 66 sollte in eine Funktion wandern, so dass man erst gar nicht in versuchung gerät, globale Variablen zu benutzen.
Antworten