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

Hallo Community.
Ich bin momentan dabei mir eine Art Katalog zu bauen. Am Anfang versuchte ich das ganze in einer Excel Tabelle zu speichern was leider nach hinten los ging. Dann kam mir die glorreiche Idee es mit pickle zu versuchen. Ich habe sehr lange nichts mehr geschrieben. Ich hoffe ihr könnt mir meinen katastrophalen Stil verzeihen. Das Problem ist momentan folgendes. Das ganze ist mit hilfe einer Liste aufgebaut. Diese hat pro "Datensatz" die Form
Hersteller,Artikelnummer,Artikelbeschreibung,preisEK,preisVK.
Nun ja das hinzufügen und entfernen von der Liste funktioniert soweit. Auch speichert mir das script das ganze per pickle und lädt es auch wieder korrekt. nur beim Aufruf von find() schmeißt er mir willkürlichen Wirrwarr auf den Bildschirm. Gewollt ist allerdings nur Einträge auszugeben die auch der gewünschten Form entsprechen so das quasi eine Auflistung aller Artikel von einem Hersteller oder alle Artikel mit der Beschreibung "bliblablub".

Ich hoffe ihr könnt einige Fehler finden und mich darauf hinweisen. Wie gesagt es ist das erste mal seit langem. Solltet ihr eine Idee für einen besseren Aufbau der Datensätze haben wäre ich froh darüber wenn ihr es mir mitteilt.

Hier nun der Code oder besser gesagt Kot

Code: Alles auswählen

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

import cPickle as pickle
import tkinter


################################################################################################
def addtodatabase(Hersteller, Artikelnummer, Artikelbezeichnung, PreisEK, PreisVK, data):
    if Artikelnummer in data:
        print ("Element bereits vorhanden")
        temp1 = data.index(Artikelnummer)
        print (data[temp1-1], "   ", data[temp1], "    ",data[temp1+1], "    ", data[temp1+2], "    ",  data[temp1+3])

    else:
        data += (Hersteller, Artikelnummer, Artikelbezeichnung, PreisEK, PreisVK)
        

    return(data)

###############################################################################################

###############################################################################################
def delfromdatabase(Artikelnummer,data):
    if Artikelnummer not in data:
        print ("Element nicht gefunden")

    else:
        temp1 = data.index(Artikelnummer)
        del data[(temp1-1):(temp1+4)]
    return (data)
###############################################################################################


def find(Suchwort,Typ, data):               #TYP DER ANGABE 1=Hersteller 2=Artikelnummer 3=Artikelbezeichnung
    if Suchwort in data:
        if Typ == "1":
            for Suchwort in data:
                print ("Element vorhanden")
                temp1 = data.index(Suchwort)
                print (data[temp1], "|", data[temp1+1], "|",data[temp1+2], "|", data[temp1+3], "|",  data[temp1+4])
            return 
        elif Typ =="2":
            for Suchwort in data:
                print ("Element vorhanden")
                temp1 = data.index(Suchwort)
                print (data[temp1-1], "|", data[temp1], "|",data[temp1+1], "|", data[temp1+2], "|",  data[temp1+3])
            return
        elif Typ =="3":
            for Suchwort in data:
                print ("Element vorhanden")
                temp1 = data.index(Suchwort)
                print (data[temp1-2], "|", data[temp1-1], "|",data[temp1], "|", data[temp1+1], "|",  data[temp1+2])
            return

    elif Suchwort not in data:
        return("Keine Ergebnisse")

    else:
        print ("Fehler im Programmablauf")


################################################################################################ 
def loadit(pfad):
    try:
        file1 = open(pfad, 'rb')
        daten = pickle.load(file1)
        file1.close()
        return(daten)
    except IOError:
        print("Datei nicht vorhanden")
        return ([])
################################################################################################

################################################################################################ 
def createfile(pfad):
    file1 = open(pfad, 'wb')
    temp1 = []
    pickle.dump(temp1, file1)
    file1.close()
################################################################################################

################################################################################################    
def save(pfad,daten):
    file1 = open(pfad, 'wb')
    pickle.dump(daten, file1)
    file1.close()
################################################################################################ 



pfad=raw_input("Bitte geben sie den pfad zur Datenbank an. Sollte die Datei nicht vorhanden sein so wird sie erstellt:   ")
data=loadit(pfad)
if data == []:
    createfile(pfad)
    data=loadit(pfad)
while True:
    menupunkt2=raw_input("Was wollen sie tun:\n1   Nach einem Datensatz suchen\n2   Einen Datensatz hinzufügen\n3   Einen Datensatz löschen\n>>>:  ")
    if menupunkt2=="1":
        menu3=raw_input("Nach was suchen sie? \n1   Hersteller\n2   Artikelnummer\n3   Artikelbezeichnung\n>>>:   ")
        
        if menu3 == "1":
            menu31=raw_input("Geben sie den Suchbegriff ein:   ")
            find(menu31, "1", data)

        elif menu3 == "2":
            menu31=raw_input("Geben sie den Suchbegriff ein:   ")
            find(menu31, "2", data)

        elif menu3 == "3":
            menu31=raw_input("Geben sie den Suchbegriff ein:   ")
            find(menu31, "3", data)

        elif menu3 != "1" and menu3 != "2" and menu3 != "3":
            print("Bitte geben sie eine gültige Ziffer ein!")
    elif menupunkt2=="2":
        data=addtodatabase(raw_input("Hersteller:   "),raw_input("Artikelnummer:   "),raw_input("Artikelbezeichnung"),raw_input("PreisEK:   "),raw_input("PreisVK:   "),data)
        save(pfad, data)
    elif menupunkt2== "3":
        data=delfromdatabase(raw_input("Geben sie die Artikelnummer des gewünschten Artikels ein:   "), data)
        save(pfad, data)
    elif menupunkt2!="1" and menupunkt2 !="2" and menupunkt2 !="3":
        print("Bitte geben sie eine gültige Ziffer ein!")
        
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: Du hast keine Datensätze, sondern eine lange Liste mit einzelnen Werten, die Du nachträglich versuchst wieder zusammenzufinden. Dass da nur Wirrwar rauskommt, ist kein Wunder. Benutzt Du Python2, dann gibt es kein Modul tkinter (das Du auch gar nicht benutzt) und »print« ist keine Funktion, oder Python3, dann gibt es kein cPickle und kein raw_input.

Die Rautenzeilen zur Abtrennung sind überflüssig, weil schon durch die Einrückung sichtbar wird, was zusammengehört. »return« ist keine Funktion, die Klammern gehören also allesamt weg; wie auch die »return«s an sich wegfallen könnten, da die Rückgabewerte nicht benutzt werden. Die Funktion »createfile« und die Zeilen 93ff sind unnötig, weil wenn die Datei nicht existiert, muß man sie auch erst anlegen, wenn Daten vorliegen, und das passiert dann beim »save«-Aufruf sowieso.
Du solltest Dir die Funktionsweise von »else« nochmal anschauen.

Programmierer sind faul, und Zeilen kopieren und ändern ist mühsam, vor allem, wenn man später etwas ändern will. In »find« und ab Zeile 100 sind jeweils die selben Zeilen drei mal kopiert. Für gleichartige Funktionalität schreibt man Funktionen und ruft sie mit entsprechenden Parametern auf.

»Pickle« ist kein Datenformat zum langfristigen Speichern von Daten. Was hat denn bei csv-, bzw. Excel-Dateien nicht funktioniert?
In Deinem Fall böte sich auch eine Datenbank wie SQLite an.

Was Dein »find« betrifft, lies in einer ruhigen Minute noch einmal Wort für Wort, was Du programmiert hast.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Das Tkinter sollte natürlich groß geschrieben werden. Dann ist es existent und soll später auch verwendet werden. Um das genaue Ziel einmal darzustellen. Es gibt sicherlich viele fertig Lösungen doch gerade der Eigenbau ist das was mich fasziniert und Spaß macht. Es soll mehr oder weniger folgendes dabei entstehen:
Eine Software mit Gui welche mir die Möglichkeit bietet aus nach und nach entstehenden Datensätzen der oben genannten Form eine Aufstellung zu erzeugen welche dann als txt Datei exportiert und gedruckt werden kann. Auch sollen neue Einträge hinzugefügt werden können oder andere Einträge gelöscht werden können. Bei Eingabe eines neuen Eintrags welcher bereits vorhanden ist soll automatisch geprüft werden ob sich andere Eigenschaften wie z.B. Preis unterscheiden und gegebenen falls gefragt werden und der Datensatz überschrieben.

Das ganze spielt sich unter Python2 ab.
Die Rautenzeichen sind nur kleine Hilfsmittel für mich. Ich habe Funktion für Funktion einzeln erstellt und mit Hilfe der interaktiven Shell unter idle auf Funktion überprüft.
Manche returns denke ich sind schon sinnvoll (nämlich die welche eine variable zurückgeben) andere können natürlich entfallen.

createfile muss ich nun bei einem genaueren Blick gestehen ist sinnfrei.

Auch sitze ich nun schon wieder 2 std hier und bekomme langsam das Gefühl das das ganze mit pickle doch nicht die optimale Lösung zu sein scheint und erst recht nicht diese ungeordnete Aneinanderreihung von Informationen in einer Liste.

Meine nächste idee wäre eine Liste mit unter listen. Hier ist dann aber alles was mit index zu tun hat für mich um einiges undurchsichtiger. Was wäre deine Empfehlung um das ganze zu organisieren. Auch kommt mir soeben der Gedanke das eine Liste natürlich mit wachsendem Umfang mehr speicher belegt und das ganze eventuell dann zu einem RAM Fiasko führen könnte...

Das ganze Excel experiment scheiterte daran das ich es einfach nicht hinbekommen habe nach einem Eintrag X in spalte 0 zu suchen und dann diese Spalte auszugeben.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bis deine Daten deinen Hauptspeicher sprengen bist du bei händischer Eingabe in der Rente.

Aber Listen von Listen sind aus anderen Gründen nicht zu empfehlen. Für viele Daten ist eine Liste von Wörterbüchern ein guter Anfang. Du eigentlich kannst du dann auch gleich das Problem der Speicherung lösen & SQLite verwenden. Damit sollten sich auch die abfragen gut erstellen lassen.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

__deets__ hat geschrieben:Bis deine Daten deinen Hauptspeicher sprengen bist du bei händischer Eingabe in der Rente.

Aber Listen von Listen sind aus anderen Gründen nicht zu empfehlen. Für viele Daten ist eine Liste von Wörterbüchern ein guter Anfang. Du eigentlich kannst du dann auch gleich das Problem der Speicherung lösen & SQLite verwenden. Damit sollten sich auch die abfragen gut erstellen lassen.
Aber ist SQLite nicht an eine SQl Datenbankj also folglich an einen SQL Server gebunden? So etwas würde ich gern umgehen. Die Excel Liste wäre ja z.B eine klare zuordnung von den 5 Werten aber (ich habe es gerade noch einmal versucht) bekomme ich keine vernünftige funktion zusammen welche mit übergabe von Pfad und Suchbegriff einen String erstestellt welcher durch \n in Zeilen unterteilt wird. Die Idee eines Dict war mein allererster gedanke. eine klare zuordnung von Schüssel und Wert..Doch das brachte mich auch nicht an das gewünschte ergebnis. Auch hatte ich die Idee eine Art Suchindex mit zu erstellen. Also ein Dict:

Artikelnummer:index in der Liste



welchen ich dann durch die unelegante Lösung ala:
for Suchwort in data:
print ("Element vorhanden")
temp1 = data.index(Suchwort)
print (data[temp1-1], "|", data[temp1], "|",data[temp1+1], "|", data[temp1+2], "|", data[temp1+3])

ausgeben lassen könnte. Auch scheint mir dieser Lösungsansatz sehr umständlich. Auch ist es dann nicht so einfach möglich z.B nach einem Hersteller zu suchen, dar ich ja dann wieder 3 dicts hätte und dann noch iwie klären müsste anhand der eingabe nach was gesucht wird..
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein, SQLite ist eine datei-basierte Datenbank, also ohne Server. Und darauf kannst du dann uA auch indizes drauf anlegen.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: es ist wichtig, eine klare Trennung der Datenstrukturen zu haben. Ein Datensatz kann als Wörterbuch, Namedtuple oder Klasse dargestellt werden. Dazu braucht es Funktionen zum Erstellen, Ändern, Darstellen und Vergleichen. Dazu Parallel gibt es Listen, um viele dieser Daten zu speichern, das Darstellen, Suchen, Speichern, etc. besteht dann nur daraus die Liste durchzugehen und den einzelnen Datensatz Darzustellen, zu Vergleichen, zu Speichern.

Folgende Ideen solltest Du vergessen: alles nacheinander ein einer Liste speichern; ein Wörterbuch Spalte->Index; Dir Gedanken um Speicherbedarf oder Geschwindigkeit machen; jetzt schon mit GUI anfangen.

Das einfachste dürfte Sein, alle Daten einer Liste mit Wörterbüchern zu speichern {'Artikelnummer': 3434, 'Hersteller': 'ABC', ...}. Speichern und Lesen mit csv.DictReader bzw. DictWriter.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Habe mich nun einmal mit SQlite befasst. dafür müsste man sich aber erst einmal die SQL Befehle näher ansehen.
Ein weiterer Versuch mit Excel scheitert.

durch

Code: Alles auswählen

zeilen=[]
for row_number in xrange(tabelle.nrows):
    zeilen.append(tabelle.row_values(row_number))
erhalte ich eine Liste mit Listen in welcher jede unterliste ein Zeile der Tabelle repräsentiert

nun an solch eine liste via append eine weitere Liste anzuhängen ist nicht das Problem.
Was mir allerdings Probleme bereitet ist folgendes.
Meine Testtabelle besteht im Endeffekt nur aus Zellen in denen ihr eigener Name steht also z.B. "Zelle A1"

Code: Alles auswählen

"Zelle A1" in zeilen
liefert mir "False" zurück. Was nach 1 min denksport auch sinn ergibt dar die Liste den String nicht enthällt.

Wie komme ich jetzt aber an den String der in einer unterliste enthalten ist....

Code: Alles auswählen

>>> u"Zelle A1" in zeilen[0]
True
Dieses ergebniss scheint schon logischer. Zumindest gelange ich an den Eintrag der Unterliste. nun könnte man ja sagen:

Code: Alles auswählen

for suchbegriff in liste[range(0,tabelle.nrows)]:
aber dann komme ich gedanklich nicht mehr weiter wie ich damit einen rückschluss auf die Tabellen Zeile bekomme und nicht nur auf den String in der unterliste

Edit:

Code: Alles auswählen

>>> for row_number in xrange(tabelle.nrows):
	if "Zelle A3" in tabelle.row_values(row_number):
		print tabelle.row_values(row_number)

		
[u'Zelle A3', u'Zelle B3', u'Zelle C3', u'Zelle D3']
>>> 
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Man kann das mit Excel machen. Wenn es aber keinen Grund gibt wie zB das der Abteilungsleiter das nunmal von einem verlangt, dann ist das eine wirklich schlechte Idee.

Ja, du wirst etwas lernen muessen, wenn du sqlite oder csv benutzt. Wo ist das Problem? Ich dachte lernen ist Sinn und Zweck der ganzen Nummer.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

__deets__ hat geschrieben:Man kann das mit Excel machen. Wenn es aber keinen Grund gibt wie zB das der Abteilungsleiter das nunmal von einem verlangt, dann ist das eine wirklich schlechte Idee.

Ja, du wirst etwas lernen muessen, wenn du sqlite oder csv benutzt. Wo ist das Problem? Ich dachte lernen ist Sinn und Zweck der ganzen Nummer.
wobei ich ja immernoch damit beschäftigt bin mir so manche python syntax oder befehl zu merken und trotzdem immer wieder auf mein Buch angewiesen bin. Excel wäre in der hinsicht keine schlechte idee, dar es eben auch zum testen (schnell mal ne tabelle mit fuuu inhalt erstellen) recht einfach ist.

Code: Alles auswählen

# -*- coding: utf-8 -*-
import xlrd
import xlwt
#Variable zu testzwecken festgelegt
pfad="Materialliste.xls"

def openfile(pfad):
    datei = xlrd.open_workbook(pfad)
    tabelle = datei.sheet_by_index(0)
    return (tabelle)

def find(suchbegriff,pfad):
    tabelle=openfile(pfad)
    ergebnisse=[]
    for row_number in xrange(tabelle.nrows):
        if suchbegriff in tabelle.row_values(row_number):
            ergebnisse.append(tabelle.row_values(row_number))
    if ergebnisse == []:
        return()
    return (ergebnisse)
Das wäre der aktuellste Versuch welche auch zu Funktionieren scheint. nur glaube ich das das ziemlich umständlich und ungünstig gebastelt ist. Auch mit der Übergabe einer Variable die übergeben wird. Die Variable wird ja im späteren programmablauf nur noch hin und her gereicht...
Das ergebniss sieht wie folgt aus:

Code: Alles auswählen

>>> print (find("Zelle A1", pfad))
[[u'Zelle A1', u'Zelle B1', u'Zelle C1', u'Zelle D1']]

>>> print (find("Zlle D3", pfad))
()
>>> 
>>> 
Und wie sieht is bei open_workbook aus. Muss das Dateiobjekt nicht auch wieder geschlossen werden?

Beim ergänzen der Tabelle komme ich ebenfalls nicht weiter. Erste Idee wäre gewesen:

Code: Alles auswählen

def add(pfad, hersteller,artikelnummer,artikelbezeichnung,preisEK,preisVK):
    datei = xlwt.Workbook()
    tabelle = datei.add_sheet("sheet1")
    zeilen=openfile(pfad).nrows()
    
    tabelle.write((zeilen+1),0,hersteller)
    tabelle.write((zeilen+1),1,artikelnumme)
    tabelle.write((zeilen+1),2,artikelbezeichnung)
    tabelle.write((zeilen+1),3,preisEK)
    tabelle.write((zeilen+1),4,preisVK)
    datei.save(pfad)
Aber damit füge ich ja nur die werte an der nächsten freien stelle ein. Alte Daten gehen dabei verloren
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: csv-Dateien kann man noch besser anderweitig editieren und sind nicht so aufwändig wie XLS. Das Herumreichen von Parametern ist ganz normal. Du solltest aber nicht den Dateinamen rumreichen, sondern alles einlesen und nur die Liste; dann ist das hinzufügen und ändern von Datensätzen auch kein Problem.

»openfile« ist der falsche Name für die Funktion, da sie ja viel mehr macht, als eine Datei zu öffnen. Die Sonderbehandlung von leeren Ergebnissen in »find« ist seltsam, da Du in dem Fall ein Tuple sonst aber eine Liste zurückgibst.

Insgesamt mußt Du mehr abstrahieren. Wie schon geschrieben, sollte »find« nur auf der Liste arbeiten und nicht wissen, wie ein Datensatz intern aufgebaut ist:

Code: Alles auswählen

def find(datasets, key, value):
    result = []
    for dataset in datasets:
        if matches(dataset, key, value):
            result.append(dataset)
    return result

[...]
result = find(datasets, "Hersteller", "ABC")
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Sirius3 hat geschrieben:@dannyboy385: csv-Dateien kann man noch besser anderweitig editieren und sind nicht so aufwändig wie XLS. Das Herumreichen von Parametern ist ganz normal. Du solltest aber nicht den Dateinamen rumreichen, sondern alles einlesen und nur die Liste; dann ist das hinzufügen und ändern von Datensätzen auch kein Problem.

»openfile« ist der falsche Name für die Funktion, da sie ja viel mehr macht, als eine Datei zu öffnen. Die Sonderbehandlung von leeren Ergebnissen in »find« ist seltsam, da Du in dem Fall ein Tuple sonst aber eine Liste zurückgibst.

Insgesamt mußt Du mehr abstrahieren. Wie schon geschrieben, sollte »find« nur auf der Liste arbeiten und nicht wissen, wie ein Datensatz intern aufgebaut ist:

Code: Alles auswählen

def find(datasets, key, value):
    result = []
    for dataset in datasets:
        if matches(dataset, key, value):
            result.append(dataset)
    return result

[...]
result = find(datasets, "Hersteller", "ABC")
Ich habe mir soeben mal das modul csv angesehen. es scheint wirklich wesentlich einfacher zu sein als das ganze mit excel zu lösen.
Die Liste die mir xxxx.sheet_by_index liefert herum zu reichen würde ebenfalls funktionieren. Allerdings habe ich noch keinen weg gefunden die bearbeitete Liste wieder in eine Datei zu schreiben oO. Das Hinzufügen von unterlisten ist ja mit xxx.append(fuu) möglich..

allerdings muss ich mich nun erst einmal in die csv geschichte einarbeiten. Verständnissproblem besteht im moment bei:
csv.writer(ofile, delimiter='', quotechar='"', quoting=csv.QUOTE_ALL)

diese Zeile stammt aus einm tutorial. allerdings liefert diese Zeile mir absoulutes Kaudawelsch wenn ich mir die datei ansehe. Und auch wenn ich sie lese und mit print ausgebe. Ich arbeite momentan sehr viel damit funktionen zu schreiben und sie einzeln in der interaktiven shell zu testen...Ich weis auch nicht ob ich mir dadurch eventuell teils meine probleme selbst schaffe. Auch besteht noch ein rießiges defizit im bereich Klassen.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: ohne zu wissen, wie Du versucht hast csv.writer zu benutzen, kann man auch nicht sagen, was Du falsch gemacht hast.
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Hi Sirius3. Ich möchte mich schon einmal für das durchhaltevermögen von dir und den anderen bedanken.

CSV writer habe ich nun so verwendet

Code: Alles auswählen

>>> f=open("data.csv", "wb")
>>> writer = csv.writer(f)
>>> for row in liste:
	writer.writerow(row)

	
>>> f.close()
Das funktioniert soweit auch. Nur verstehe ich die Zeile die ich oben gepostet habe nicht. Diese stammt aus einem tutorial, ergibt aber in der Datei totales chaos, sodass es sich nur mit müh und not entziffern lässt.
Dar ich die letzten 2 Tage sehr wenig Zeit hatte werde ich jetzt dann noch etwas weiter tüfteln. Das Ziel rückt zumindest näher und ich habe schon wieder sehr viel dazu gelernt.

Eine kleine zwischenfrage hätte ich dann noch. Ich sehe immer wieder Code Schnipsel in denen zeilen ala print("xxxxx"%d,Y)
vorkommen. Eventuell wäre es möglich die bedeutung dieser %X angaben in einem kurzen Kommentar zu klären. Das ganze erinnert mich doch ein wenig an C...
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: was meinst Du mit totalem Chaos? Was ist an den 3 Zeilen unverständlich? Das läßt sich 1:1 ins Deutsche übersetzen: für jede Zeile `row` in liste schreibe die Zeile `row`.

Noch kompakter:

Code: Alles auswählen

with open("data.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerows(liste)
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Sirius es geht um folgende Zeile aus einem tutorial welche ich nicht verstehe:

csv.writer(ofile, delimiter='', quotechar='"', quoting=csv.QUOTE_ALL)
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@dannyboy385: erstens, warum interessiert Dich diese Zeile und zweitens, was verstehst Du daran nicht?
dannyboy385
User
Beiträge: 39
Registriert: Freitag 27. November 2015, 21:24

Hallo Leute. Das verständniss Problem ist in den hintergrund gerückt sirius3. es gingm mir um die Bedeutunge dieses Kontrukts "delimiter='', quotechar='"', quoting=csv.QUOTE_ALL".
Was bedeutet delimiter, quotechar und QUOTE_ALL?

Meine aktuelle Fassung sieht folgendermasen aus:

Code: Alles auswählen

def new(datenbank, hersteller,artikelnummer,artikelbezeichnung,preisEK,gewinn=1.10,mwst=1.19):
    for index in range(0,len(datenbank)):
        if artikelnummer in datenbank[index]:
            return datenbank
    
    datenbank.append([hersteller,str(artikelnummer),artikelbezeichnung,str(preisEK),str((preisEK*mwst+preisEK*gewinn+preisEK))])
    return datenbank

def search(datenbank, suchbegriff):
    ergebnisse=[]
    for index in range(0,len(datenbank)):
        for index2 in range(0,4):
            if suchbegriff in datenbank[index][index2]:
                ergebnisse.append(datenbank[index])


    return ergebnisse

def delete(datenbank, artikelnummer):
    for index in range(0,len(datenbank)):
        if str(artikelnummer) in datenbank[index]:
            datenbank.pop(index)
            break
        
    return datenbank
    
def readfile(pfad):
        datenbank=[]
        with open(pfad, "r") as f:
            daten = csv.reader(f)
            for row in daten:
                datenbank.append(row)

        return datenbank

def savefile(pfad,datenbank):
        with open(pfad, "w") as f:
            output = csv.writer(f)
            for row in datenbank:
                output.writerow(row)
        return datenbank
Ich habe versucht die Funktionsbeschreibungen möglichst exakt zu halten was mir bis auf new() denke ich auch einigermaßen gelungen ist. new prüft ob ein Eintrag bereits vorhanden ist und fügt ein vorhandenes Element nicht erneut hinzu.
Auch habe ich versucht das speichern und lesen in CSV Dateien zu implementieren was ebenfalls funktioniert.
Nun dar das hinzufügen, löschen, suchen und das speichern und wieder einlesen funktioniert würde ich gerne noch folgende Funktionen hinzufügen:

Ändern von Einträgen:
Hier fehlt mir ein Gedankenansatz wie dies zu lösen wäre. Würde folgendes Funktionieren oder bin ich hier auf dem Holzweg:
Ich möchte die bestehenden Funktionierenden Funktionen ungern wieder zerlegen oder erweitern. Den bis jetzt bin ich durch das ewige erweitern immer wieder an meine Grenzen gestoßen und habe von neuem b begonnen weil ich den Wald vor lauter Bäumen nicht mehr gesehen habe.

Eine Funktion schreiben welche wie del den Eintrag sucht ihn entfernt aber in einer variable zwischenspeichert. Der Funktion wird der zu ändernde Teil mitgeteilt und dessen Ersatz. Dann wird das Element eben entfernt und ersetzt und der Datensatz wieder an die Liste angehängt. Allerdings weis ich nicht wie ich das ganze umsetzen sollte......

Importieren aus Datei:
Eine Funktion welche eine CSV Datei einließt prüft ob das Format passt(5 Zeilen) dann Eintrag für Eintrag hinzufügt mit "new()". Dar new sowieso überprüft ob eine Artikelnummer bereits vorhanden ist gäbe es keine Probleme mit doppelten Einträgen. Allerdings würde eine importierte Tabelle welche mit der geladenen zusammengeführt wird bei nicht Einhaltung der Reihenfolge Hersteller Bezeichnung Artikelnummer zu einem Riesen Chaos führen und alles zerstören... Wie man dem entgegen wirken könnte wäre zu überlegen..

Regelmäßiges Backup:
Ein Gedankenansatz meinerseits wäre hier am Anfang der CSV Datei 1,2 Reihen hinzuzufügen mit dem Erstellungsdatum der Datei(wie finde ich das heraus???Den der csv.writer legt eine Datei ja Automatisch an wenn sie nicht vorhanden ist und überschreibt sie jedes mal komplett) und Änderungsdatum...
wurde die Datei geändert werden die vorhergehenden Datenstände in .....5 Backups gespeichert um eine Art Undo mit zu implementieren welche einem den Aller wertesten rettet sollte eine Fehlbedienung statt finden...

Dar das ganze am Ende eine Gui bekommen soll stellen sich mir noch ein paar fragen:
Ich habe mich bereits in tkinter etwas eingearbeitet.. Wäre es nicht sinnvoll die Datenverarbeitung und Gui in Klassen zu unterteilen? Wie realisiere ich eine Art Autofill Funktion für Hersteller und artikelbezeichnung?

Wie bereits erwähnt besteht bei mir ein erhebliches Defizit in der OOP...
Auch färe Programmiertechnisch eine:

daten.new(bliblablub) natürlich schöner als jedes mal den Returnwert abzufragen ala

daten = new(daten, bliblablub)

Ich danke schon ein mal jedem der sich das ganze hier durchließt und mir seinen Zeit widmet.

mfg Daniel

PS: Dar ich das ganze abschließend im dauereinsatz haben werde und auch ein bekannter interesse an dem Projekt für private Zwecke hat, möchte ich natürlich eine möglichst perfekte Lösung zaubern
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@dannyboy385: Deine Probleme würden sich großteils in Luft auflösen, wenn du, wie schon mehrfach empfohlen, einfach SQLite verwenden würdest.
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
Antworten