Seite 1 von 1

If wirrwarr

Verfasst: Freitag 8. Februar 2008, 10:49
von nordlocke
Hallo Forum,

ich möchte gerne Daten auslesen, was auch alles klappt.
Zu beginn der Daten stehen Zuweisung, z.B.

Lieferung-1=kirschen
Lieferung-2=birnen
Lieferung-3=orangen
Lieferung-4=kiwi
Diese Zuweisung ändert sich jedes mal.

Ich schaue erstmal ob im Feld TEXT überhaupt was drinnen steht, dann splitte ich das ganze auf in
'Lieferung-x' und 'FRUCHT'
beim 'Lieferung-x' splitte ich dann die Zahl ab.

Nun will ich den Zahlen die Frucht zu ordnen.
Dazu mache ich das mit den If Anweisungen.
so das ich am ende 4 Variablen 'frucht1-4' habe

Ich finde das sehr unschön, habe auch schon auf der Pythonseite geschaut, aber nichts richtig passendes gefunden. Für ein paar Tips wäre ich Dankbar


Danke schon mal und der Codeschnipsel.

Code: Alles auswählen

while not oRS.EOF:
   .
   .
   .
   .
   text = str(oRS.Fields.Item('TEXT'))
      if not text == 'None':
         text = text.split('=')
         try:
           testnr = text[0].split('-')
           testnr = testnr[1]
           if testnr == 0:
             frucht0 = text[1]
           elif testnr == 1:
             frucht1 = text[1]
           elif testnr == 2:
             frucht2 = text[2]
           elif testnr == 3:
             frucht3 = text[3]  
           elif testnr == 4:
             frucht4 = text[4]         
         except IndexError:
           pass
   .
   .
   .
   .
oRS.MoveNext()
[/code]

Verfasst: Freitag 8. Februar 2008, 11:55
von Nikolas

Code: Alles auswählen

if not text == 'None':
if testnr = 0:
Findest du den Unterschied :D

// Ach ja: Einfach nur ein pass beim IndexError ist ziemlich schlechter Stil. Vor allem während des Codens wäre hier ein kleiner print-Aufruf wirklich sinnvoll.

Verfasst: Freitag 8. Februar 2008, 11:56
von EyDu
Hausaufgaben: Fehlersuche? Das Programm läuft nämlich unter Garantie nicht korrekt in den if-Statements.

Verfasst: Freitag 8. Februar 2008, 12:26
von nordlocke
Nikolas hat geschrieben:

Code: Alles auswählen

if not text == 'None':
if testnr = 0:
Findest du den Unterschied :D

// Ach ja: Einfach nur ein pass beim IndexError ist ziemlich schlechter Stil. Vor allem während des Codens wäre hier ein kleiner print-Aufruf wirklich sinnvoll.
Der unterschied ist das im text feld auch noch andere Daten drinne stehen, nicht immer nur die test geschichte.

Die Fehlerbehandlung sieht im Endprodukt anders aus, ist ja nur ein Auszug, da es um die IF Verschachtelung geht.

Verfasst: Freitag 8. Februar 2008, 12:30
von nordlocke
EyDu hat geschrieben:Hausaufgaben: Fehlersuche? Das Programm läuft nämlich unter Garantie nicht korrekt in den if-Statements.
Sorry habe das schnell rein getippt das Codebeispiel, habe es mal korrigiert.
Vorausgesetzt das du auf die == abgezielt hast.

Verfasst: Freitag 8. Februar 2008, 12:43
von Rebecca
Wenn du beeinflussen kannst, wie die Daten aussehen, wuerde ich mir ueberlegen, die Daten in einem Format zu speichern, die man z.B. mit ConigParser parsen kann.

Ansonsten: Warum willst du die Namen fruechte1 bis fruechte4 erzeugen, hier ware doch einer Liste oder ein Dictionary viel angebrachter.

Hier koennte man auch ueberlegen, Regular Expressions zu benutzen:

Code: Alles auswählen

In [34]: data = """test-1=kirschen
   ...: test-2=birnen
   ...: test-3=orangen
   ...: test-4=kiwi"""

In [38]: matches = re.findall(r"test-(\d)=(.*)", data)

In [39]: print matches
[('1', 'kirschen'), ('2', 'birnen'), ('3', 'orangen'), ('4', 'kiwi')]

In [40]: fruechte = dict(matches)

In [41]: print fruechte
{'1': 'kirschen', '3': 'orangen', '2': 'birnen', '4': 'kiwi'}
Das Dict hat auch den Vorteil, dass, wenn in den Daten ein Datensatz fehlt, du beim Zugriff auf das Dict eine leicht verstaendliche Fehlermeldung bekommst und sofort weisst, was fehlt oder du einfach Defaultwerte vorgeben kannst. Oder moechtest du das beim Einlesen der Daten schon abfangen?

Natuelich kann man die "Indices" auch in Integers umwandeln:

Code: Alles auswählen

In [42]: matches = [(int(i), frucht) for (i, frucht) in matches]

In [43]: print matches
[(1, 'kirschen'), (2, 'birnen'), (3, 'orangen'), (4, 'kiwi')]

Verfasst: Freitag 8. Februar 2008, 13:09
von BlackJack
@nordlocke: Die Beschreibung des Problems passt nicht zum Quelltext. Der würde nur funktionieren, wenn mehrere Werte durch '=' getrennt in `text` stehen würden und wenn Du `testnr` auch an eine Zahl und nicht an ein Zeichen binden würdest.

Und wie schon gesagt wurde: Wenn man durchnummerierte Namen hat, will man in der Regel eigentlich eine Liste oder ein Dictionary verwenden.

Verfasst: Freitag 8. Februar 2008, 13:39
von nordlocke
Ich lese über die COM Schnittstelle Daten aus einem System aus und diese Daten schreibe ich in eine Textdatei, die später in eine MYSQL DB importiert wird.

Es gibt dort mehrere Felder die ich auslesen muss, eines der Felder heißt 'Text' in diesem Feld steht jede menge Kram drinnen den ich nicht brauche, aber ab und an auch die "Testbeschreibung". Diese muss ich mir raus holen. Es gibt auch ein Feld 'ID' und dieses Feld enthält auch die Testnummer.
Die 'Testbeschreibung' ordne ich dann später der 'ID' zu, deshalb nummeriere ich ja auch nur die Frucht da diese später der richtigen 'ID' zugeordnet wird.

Ich weiß nicht ob ich das Problem nun besser erklärt habe oder mehr Verwirrung gestiftet habe, freue mich auf Feedback ;)

Verfasst: Freitag 8. Februar 2008, 13:54
von BlackJack
@nordlocke: Bei mir hat's noch mehr Verwirrung gestiftet. Du zeigst uns Eingabedaten die wahrscheinlich nicht den echten entsprechen, Quelltext der so nicht lauffähig ist und damit wohl auch nicht dem Original entspricht und eine Beschreibung die mit Beispieldaten und Quelltext nicht überein stimmt.

Gib uns doch mal Beispieldaten, zum Beispiel eine Liste mit Texten, die Du aus dem 'TEXT'-Feld nacheinander bekommst und was genau Du daraus dann haben willst.

Und wenn Beispielquelltext, dann bitte welchen der mit so einer Liste arbeitet und den jeder hier im Forum einfach ausprobieren kann.

Verfasst: Freitag 8. Februar 2008, 14:51
von nordlocke
Hier ein Auszug was alles im Feld 'Text' drinnen stand, nach dem ich alle Felder bis zu ende durchlaufen habe:

Lieferungen am 08.02.2008
Lieferung-0=Birnen
Lieferung-1=Kirschen
Lieferung-2=Orangen
Lieferung-3=Kiwi
Lieferung nach Hamburg fällt aus
Hamburg nach Berlin nicht erforderlich
Error
Stau im Bereich Kassel

Hier die Liste für das Feld 'ID'

Lieferung-0
Lieferung-2
Lieferung-0
Lieferung-4
Lieferung-1
Lieferung-0
Lieferung-1
Lieferung-3
Lieferung-2
Lieferung-3

Ich will raus schreiben welche Frucht welcher Lieferung zugehörig ist.
Diese Zuordnung steht in den ersten Textfeldern und diese Information ändert sich täglich, daher muss ich diese Information raus parsen/splitten und kann es nicht vorher Fest deklarieren.
So das nachher die Fruchtnummer zur Lieferungsnummer passt.

Der Codeschnipsel behandelt nur das rausfiltern dieser Informationen.
Desweiteren habe ich im Code test- statt Lieferung- stehen.
Ändere das nochmal im Code.

Verfasst: Freitag 8. Februar 2008, 14:58
von BlackVivi
Vielleicht nicht so schön, aber meiner Meinung nach gut verständlich:

Code: Alles auswählen

In [9]: deliveries = {}

In [10]: text = """Lieferungen am 08.02.2008
   ....: Lieferung-0=Birnen
   ....: Lieferung-1=Kirschen
   ....: Lieferung-2=Orangen
   ....: Lieferung-3=Kiwi
   ....: Lieferung nach Hamburg fällt aus
   ....: Hamburg nach Berlin nicht erforderlich
   ....: Error
   ....: Stau im Bereich Kassel"""

In [11]: for row in text.split("\n"):
   ....:     if "=" in row:
   ....:         delivery_nr, good = row.split("=")
   ....:         delivery_nr = delivery_nr.split("-")[-1]
   ....:         deliveries[int(delivery_nr)] = good
   ....:
   ....:

In [12]: print deliveries
{0: 'Birnen ', 1: 'Kirschen ', 2: 'Orangen ', 3: 'Kiwi '}

Verfasst: Freitag 8. Februar 2008, 15:10
von Rebecca
Was gefaellt euch an meiner Loesung oben nicht? Ich wuerde sie allerdings noch so abaendern:

Code: Alles auswählen

matches = re.findall(r"^Lieferung-(\d)=(.*)$", data, flags=re.MULTILINE)
damit nur komplette Zeilen gematcht werden.

Verfasst: Freitag 8. Februar 2008, 15:21
von BlackVivi
Rebecca hat geschrieben:Was gefaellt euch an meiner Loesung oben nicht? Ich wuerde sie allerdings noch so abaendern:

Code: Alles auswählen

matches = re.findall(r"^Lieferung-(\d)=(.*)$", data, flags=re.MULTILINE)
damit nur komplette Zeilen gematcht werden.
Tut mir leid, falls das so rüberkam! Ich mag deine Lösung gerne, REs sind immer so schön schnell und elegant. Aber viele können damit nicht umgehen, deswegen hab ich ihm eine RE freie Version vorgeschlagen.

Wollte deinen Quelltext nicht schlecht darstellen ._.

Verfasst: Freitag 8. Februar 2008, 15:22
von BlackJack
@Rebecca: An Deiner Lösung passt nicht 100%ig, dass in dem Programm kein gesamter Text mit allen Zeilen zur Verfügung steht, sondern die Zeilen einzeln in einer Schleife rein kommen. Man könnte natürlich erst alle Texte sammeln, zusammenfügen und dann Deinen regulären Ausdruck drauf los lassen.

Verfasst: Freitag 8. Februar 2008, 15:34
von BlackJack
@nordlocke: Noch'n Vorschlag:

Code: Alles auswählen

TEXTS = """\
Lieferungen am 08.02.2008
Lieferung-0=Birnen
Lieferung-1=Kirschen
Lieferung-2=Orangen
Lieferung-3=Kiwi
Lieferung nach Hamburg fällt aus
Hamburg nach Berlin nicht erforderlich
Error
Stau im Bereich Kassel
""".splitlines()

LIEFERUNG_PREFIX = 'Lieferung-'

lieferungen = dict()

for text in TEXTS:
    if text.startswith(LIEFERUNG_PREFIX):
        nr, art = text[len(LIEFERUNG_PREFIX):].split('=', 1)
        lieferungen[int(nr)] = art

print lieferungen
Ausgabe:

Code: Alles auswählen

{0: 'Birnen', 1: 'Kirschen', 2: 'Orangen', 3: 'Kiwi'}

Verfasst: Freitag 8. Februar 2008, 16:03
von Rebecca
BlackVivi hat geschrieben:Ich mag deine Lösung gerne, REs sind immer so schön schnell und elegant. Aber viele können damit nicht umgehen, deswegen hab ich ihm eine RE freie Version vorgeschlagen.
Hehe, vielleicht haette ich noch einen Smiley spendieren sollen. Ich hatte nur gedacht, dass mein Post evtl. uebersehen wurde, sowas passiert ja manchmal.
BlackJack hat geschrieben:@Rebecca: An Deiner Lösung passt nicht 100%ig, dass in dem Programm kein gesamter Text mit allen Zeilen zur Verfügung steht, sondern die Zeilen einzeln in einer Schleife rein kommen.
.
Ach, mist... :D

Verfasst: Freitag 8. Februar 2008, 17:13
von noise
BlackVivi hat geschrieben:
Rebecca hat geschrieben:Was gefaellt euch an meiner Loesung oben nicht? Ich wuerde sie allerdings noch so abaendern:

Code: Alles auswählen

matches = re.findall(r"^Lieferung-(\d)=(.*)$", data, flags=re.MULTILINE)
damit nur komplette Zeilen gematcht werden.
Tut mir leid, falls das so rüberkam! Ich mag deine Lösung gerne, REs sind immer so schön schnell und elegant. Aber viele können damit nicht umgehen, deswegen hab ich ihm eine RE freie Version vorgeschlagen.

Wollte deinen Quelltext nicht schlecht darstellen ._.
Warum zum $TEUFEL entschuldigst du dich dafür das du eine eigenständige Lösung als Hilfe/Zur Diskussion gestellt hast!?

Außerdem "Quelltext nicht schlecht darstellen "? Ich denke doch sehr stark das es hier erlaubt ist auf ein Problem mehrere Vorschläge zu posten, oder?

:roll:

Verfasst: Montag 18. Februar 2008, 15:31
von nordlocke
Etwas spät, aber besser spät als nie.
Danke für die zahlreichen Antworten habe erfolgreich die DICT geschichte umgesetzt.