[yaml] In Datei schreiben ohne Sortierung

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.
Antworten
Benutzeravatar
beli3ver
User
Beiträge: 27
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Servus,

ich schreibe mir gerade ein kleines Programm um Rechnungen aus YAML Files und HTML Dateien zu erstellen, das funktioniert wunderbar.
Damit ich dann ein kleine Kontoübersicht habe, trage ich mir dann die wichtigsten Daten in eine YAML File ein:

Code: Alles auswählen

addEntry = {document_data['invoice']['number']:{'Kunde': document_data['to']['name'], 'Betrag': document_data['totals']['brutto'], 'Umsatzsteuer': document_data['totals']['tax']}}

with open('KontoUebersicht.yml', 'a') as yaml_file:
    yaml.dump(addEntry, yaml_file, default_flow_style=False)
Jetzt ist mein Problem, dass dabei die Einträge umsortiert werden:

Code: Alles auswählen

R00045:
  Betrag: 59,69
  Kunde: Musterkunde
  Umsatzsteuer: 9,53
Wie kann ich diese Sortierung verhindern?
Danke
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

du verwendest ein Dict und die sind in Python unsortiert. Heißt, wenn du über das Dict iterierst, hast du keine Garantier, in welcher Reihenfolge die Schlüssel zurück geliefert werden. Wenn du eine fixe Reihenfolge brauchst, dann nimm' `collection.OrderedDict`

Das sollte auch hier funktioniere, selber ausprobiert habe ich es in der Kombi aber noch nicht.

Gruß, noisefloor
Benutzeravatar
beli3ver
User
Beiträge: 27
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Ok,

habe es jetzt so versucht:

Code: Alles auswählen

addEntry = {document_data['invoice']['number']:{'Kunde': document_data['to']['name'], 'Betrag': document_data['totals']['brutto'], 'Umsatzsteuer': document_data['totals']['tax']}}
addEntry = collections.OrderedDict(addEntry)
Sieht dann aber so aus:

Code: Alles auswählen

!!python/object/apply:collections.OrderedDict
- - - R00045
    - Betrag: 59,69
      Kunde: CodeQ
      Umsatzsteuer: 9,53
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@beli3ver: zu dem Zeitpunkt ist es ja auch schon zu spät, da stehen Deine Daten ja schon in einem normalen Wörterbuch ohne Ordnung.
Benutzeravatar
beli3ver
User
Beiträge: 27
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Ok, jetzt hängt es bei mir völlig, auch diese Lösung bringt nichts:

Code: Alles auswählen

addEntry = collections.OrderedDict()
addEntry = {document_data['invoice']['number']:{'Kunde': document_data['to']['name'], 'Betrag': document_data['totals']['brutto'], 'Umsatzsteuer': document_data['totals']['tax']}}
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Ansatz mit dem geordneten Wörterbuch bringt so zumindets nichts. Denn das Problem beginnt ja schon beim YAML. Bei einer solchen Schlüsselwortaufzählung liefert die YAML bereits das Wörterbuch ungeordnet zurück. Dann bekommst du auch nichts geordnetes mehr raus. Es gibt prinzipiell zwei Lösungen, wobei ich die zweite präferiere.

Erstens könntest du in YAML Listen verwenden, um deine Daten zu erfassen. Damit hast du bereits eine geordnete Datenstruktur. Allerdings gehen wir damit die Schlüssel- und Wertepaare verloren, du müsstest das ganze mühselig selbst herstellen, indem du zum Beispiel unterstellst, das ist immer einen Doppelpunkt gibt, an dem du dann auftrennst.

Die zweite Lösung besteht darin, die erwarteten Schlüssel in deinem Programm in einer Liste zu hinterlegen. Damit kannst du dann aus dem Ursprungs Wörterbuch und dieser Liste das ordered dict aufbauen.
Benutzeravatar
beli3ver
User
Beiträge: 27
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Also gut, ich mache es jetzt als csv.
So kann ich es auch besser meinem Steuerberater geben:

Code: Alles auswählen

addEntry = [document_data['customer_number'], document_data['to']['name'], document_data['totals']['netto'],document_data['totals']['tax'], document_data['totals']['brutto']]
KontoFile = open('KontoUebersicht.csv', 'a')  
with KontoFile:  
   writer = csv.writer(KontoFile, delimiter = ',')
   writer.writerow(addEntry)
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@beli3ver: bei Deinem nächsten Versuch erzeugst Du ja auch ein OrderedDict, wirst es aber in der nächsten Zeile wieder weg und erzeugst statt dessen ein normales ungeordnetes Wörterbuch.

Korrekt wäre:

Code: Alles auswählen

addEntry = collections.OrderedDict()
addEntry[document_data['invoice']['number']] = collections.OrderedDict([
    ('Kunde', document_data['to']['name']),
    ('Betrag', document_data['totals']['brutto']),
    ('Umsatzsteuer', document_data['totals']['tax'])
])
Antworten