PyQt / .input() Daten einfügen und umwandeln in ein Dictionary

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

Hi,
ich bin neu hier und auch neu im Python Universum.
Versuche auch soweit wie möglich selber eine Lösung bei meinen auftretenden Problemen zu finden, aber hier hänge ich etwas fest.

Das Ziel meines Programms ist, eine Mehrzeilige Datenansammlung über .input() oder ein Text Edit Widget in PyQt über Copy & Paset einzufügen.
Mit daten = open(Dateiname, 'r') funktioniert es einwandfrei nur will ich es gerne direkt einfügen, aufarbeiten lasen um es dann abzuspeichern.

So schaut mein amateurhaft zusammengetragener Code Schnipsel aus.

Code: Alles auswählen

def ItemPreislisteBerechnen(daten):
    for d in daten:
        E, Z = d.strip().split('*	',1)
        X, Y = Z.strip().split('*			')
        X, Y = Y.strip().split('	')
        Z = X + ' ' + Y
        X = Z.strip().split(' ')
        Z = X[0] + ' ' + X[2]

        zahl_ohne_komma = []
        for e in Z:
            if '.' not in e:
                if ',' == e:
                    zahl_ohne_komma.append('.')
                else:
                    zahl_ohne_komma.append(e)

        Z = str(''.join(zahl_ohne_komma))
        X = Z.strip().split(' ')
        Item_Preis[E] = [X[0], X[1]]
    return(Item_Preis)



Item_Preis = {}                                         #Dictionary wird erstehlt
datum = "01.01.2000"

#PreisListe = open('Item_Preisliste.txt', 'r')          #Datei wird geöffnet und übergeben
PreisListe = input('Bitte Daten eingeben:',)

Item_Preis = ItemPreislisteBerechnen(PreisListe)        #definition "Item_Preisliste" wird ausgeführt und in "Item_Preis" abgelegt
print(Item_Preis)

#self.ui.textEdit.setText(Item_Preis)                   #im zentralem Textfenster wird "Item_Preis" ausgegeben

PreisListe.close()                                      #Datei wird geschlossen
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie sehen denn die Daten aus? Aus den vielen split und sonstigen Verrenkungen kann ich nicht erkennen, ob das zufällig funktioniert oder wirklich auf komische Art gewollt ist.
Einbuchstabige Variablennamen sind schlecht, weil sie das Lesen erschweren. Wie geschrieben kann ich auch deshalb nichts mit dem Code anfangen.
input liest jeweils eine Zeile, wenn Du mehrere Zeilen eingeben willst, brauchst du eine Schleife.
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

So sehen die Daten aus, abgespeichert in einer Textdatei.

Code: Alles auswählen

Item eins*	1	eins*			0,35 m3	54,15 xyz
Item zwei*	1	zwei*			10 m3	648,69 xyz
Item drei*	1	drei*			5 m3	914,12 xyz
Item vier*	1	vier*			10 m3	684,52 xyz
Item fünf*	1	fünf*			10 m3	1.103,99 xyz
Da .input() und jeder andere Weg die Daten auch über ein Text Edit Widget als ein zusammenhängender Text weitergeleitet werden.
Dann versuche ich mir eine Schleife zusammen zusammenbasteln.
Die split Ansammlung ist so gewohnt, es funktioniere auch wie gewünscht und bestimmt bekomme ich es auch noch eleganter.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das sieht nach einer einfachen csv Datei aus. Gibt es einen Grund, die nicht mir dem csv Modul zu öffnen?
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@cR0N0s: Ich glaube nicht das die `split()`/`join()`-Orgie tatsächlich so sein sollte. Insbesondere würde ich Tabulatorzeichen so nicht in literalen Zeichenketten verwenden. Das sieht doch so keiner dass das Tabs sind und nicht Leerzeichen und das geht auch sehr schnell mal kaputt wenn man das mit einem anderen Editor oder mit anderen Einstellungen speichert.

In der ``for e in Z:``-Schleife ist das ``if '.' not in e`` sehr irreführend weil `e` nur ein einzelnes Zeichen ist. Insgesamt ist das alles sehr undurchsichtig formuliert.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

__blackjack__ hat geschrieben: Sonntag 15. März 2020, 21:22 @cR0N0s: Ich glaube nicht das die `split()`/`join()`-Orgie tatsächlich so sein sollte. Insbesondere würde ich Tabulatorzeichen so nicht in literalen Zeichenketten verwenden. Das sieht doch so keiner dass das Tabs sind und nicht Leerzeichen und das geht auch sehr schnell mal kaputt wenn man das mit einem anderen Editor oder mit anderen Einstellungen speichert.

In der ``for e in Z:``-Schleife ist das ``if '.' not in e`` sehr irreführend weil `e` nur ein einzelnes Zeichen ist. Insgesamt ist das alles sehr undurchsichtig formuliert.
Das gesamte Gebilde der Definition, funktioniert soweit, es hat schon einen Sinn wieso auch das ``if '.' not in e`` mit dabei ist.
Die Funktion Spielt nur eine Rolle, beim Aufrufen einer Datei.
Mein Problem ist, der Aufbau einer Schleife, welche die Daten über Input() oder ein TextWidget empfangen und aufbereitet werden, damit diese zeilenweise gelesen werden und nicht als Bock.
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

__deets__ hat geschrieben: Sonntag 15. März 2020, 20:55 Das sieht nach einer einfachen csv Datei aus. Gibt es einen Grund, die nicht mir dem csv Modul zu öffnen?
Es ist ein Log aus einem Spiel, welche mit Str+C entnommen wird. Den Aufwendigen Weg, der Erstellung und anschließenden Ablegung der Daten in die Datei, würde ich gerne umgehen und die Daten direkt in das Programm einfügen, welche aufgearbeitet und vom Programm automatisch abgespeichert werden sollen.
CSV Modul? Diesem Hinweis versuche ich nachzugehen, vielleicht ist es auch eine mögliche Lösung.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn das im clipboard ist, dann solltest du das mit Qt abgreifen können.
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

[Benutze keine globalen Variablen. return ist keine Funktion, die Klammern daher verwirrend.
Das Ganze etwas aufgeräumt, obwohl noch die magischen Indizes stören:

Code: Alles auswählen

def parse_prices(lines):            
    item_price = {}            
    for line in lines:
        item, _, data = line.partition("*\t")
        data = data.split()
        amount = data[-4].replace(",", ".")
        price = data[-2].replace(".", "").replace(",", ".")
        item_price[item] = (amount, price)
    return item_price
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@cR0N0s: Es kann ja sein dass das funktioniert, und auch wenn ``if '.' not in e`` zur Funktion beiträgt ist es völlig unsinnig das *so* dermassen *unverständlich* und *irreführend* auszudrücken. ``in`` oder ``not in`` suggeriert das `e` mehr ist als nur ein Zeichen. „Ich suche ein Zeichen in einem Wort” oder etwas in der Richtung macht Sinn, „ich suche ein Zeichen in einem Zeichen“ ist eine unsinnige Formulierung, auch wenn sie funktioniert. Es verwirrt den Leser und lässt vermuten das der Autor nicht ganz versteht was er da macht. Und der Autor selbst versteht so etwas nach einiger Zeit oft selbst nicht mehr oder eben falsch.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

Sirius3 hat geschrieben: Sonntag 15. März 2020, 22:27 [Benutze keine globalen Variablen. return ist keine Funktion, die Klammern daher verwirrend.
Das Ganze etwas aufgeräumt, obwohl noch die magischen Indizes stören:

Code: Alles auswählen

def parse_prices(lines):            
    item_price = {}            
    for line in lines:
        item, _, data = line.partition("*\t")
        data = data.split()
        amount = data[-4].replace(",", ".")
        price = data[-2].replace(".", "").replace(",", ".")
        item_price[item] = (amount, price)
    return item_price
Vielen dank für den Tip mit return, bin halt noch ein Anfänger und am lernen.
Danke auch für das neu aufsetzen des Inhalts der Definition.
An replace() hatte ich tatsächlich auch dran gedacht, dass das austauschen damit eleganter wäre.
Das schaut besser aus und funktioniert genauso gut.

Trotzdem ist damit mein eigentliches Problem nicht gelöst.
Mein Vorhaben ist, ein Zeichenblock an den Zeilenumbrüchen zu zerlegen, um es dann weiter verarbeiten zu können.

Code: Alles auswählen

def parse_prices(lines):            
    item_price = {}            
    for line in lines:
        item, _, data = line.partition("*\t")
        data = data.split()
        amount = data[-4].replace(",", ".")
        price = data[-2].replace(".", "").replace(",", ".")
        item_price[item] = (amount, price)
    return item_price

PreisListe = input('Bitte Daten eingeben:',)
....................
item_price = parse_prices(PreisListe)
Meine Idee ist, das ganze mit .split() zu zerlegen, aber das will nicht ganz wie ich es gerne Hätte.
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

Bei `input` brauchst Du, wie ich schon geschrieben hatte, eine Schleife.
Oder die `iter`-Funktion:

Code: Alles auswählen

print("Bitte Daten eingeben (Ende mit Leerzeile):")
preis_liste = list(iter(input, ""))
cR0N0s
User
Beiträge: 19
Registriert: Sonntag 15. März 2020, 15:45

Problem gelöst.
So funktioniert es.

Code: Alles auswählen

while True:
            Zeile, n, Block  = Block.partition("\n")
            
            PreisListe.append(Zeile)
            if "\n" not in Block:
                PreisListe.append(Block)
                break
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo auch immer jetzt `Block` herkommt, Du suchst nach

Code: Alles auswählen

preis_liste = block.splitlines()
Antworten