Zählung in Python ergibt immer null

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
informatik_neuling
User
Beiträge: 4
Registriert: Samstag 6. September 2014, 13:56

Hallo zusammen,

ich muss für ein Seminar an der Uni einen Python-Code fertig schreiben und komme gerade überhaupt nicht weiter... :(
Der Text, auf den sich das Ganze bezieht, sind die gesammelten Briefe von Martin Luther. Ich soll jetzt anhand eines Dictionaries, dass alle Jahre enthält, in denen Briefe geschrieben wurden, herausfinden, wie viele Briefe Luther pro Jahr geschrieben hat und wie viele er anfangen hat. Bei der Zählung kommt allerdings immer null raus und ich verstehe einfach nicht, warum...

Code: Alles auswählen

import json

with open('data.json', 'rb') as fp:
    data = json.load(fp,encoding="utf-8")

list_of_years = []

for datas in data:
    list_of_years.append(data[datas]['year'])

print set(list_of_years)

for years in set(list_of_years):
    print years
    n = 0
    number_of_sent_letters =0
    number_of_received_letters =0
    for datas in data:
        if (data[datas]['year'] in list_of_years):
            if ' Luther, Martin' in data [datas] ['sender']:
                number_of_sent_letters+=1
    print "The number of sent letters:" +str(n)

    for datas in data:
        if (data[datas]['year'] == years):
            if ' Luther, Martin' in data [datas] ['receiver']:
                number_of_received_letters+=1
    print "The number of received letters:" +str(n)

sorted (set(list_of_years))
Kann mir irgendjemand sagen, wo hier der Fehler liegt? Am Schluss soll übrigens noch ein Ranking der Jahre (nach Anzahl der geschriebenen und der empfangenen Briefe) erstellt werden. Ist die sorted-Funktion dafür überhaupt die richtige?

Vielen Dank schon mal für eure Hilfe!

P.S. Tut mir Leid, dass ich den Code einfach nur hier rein kopiert habe. Ich bin erst seit heute in diesem Forum und weiß nicht, wie man einen Code einfügt (im FAQ stehts leider auch nicht... :cry: ). Wär super, wenn mir das auch gleich jemand erklären könnte! Nochmal danke!
Zuletzt geändert von Anonymous am Samstag 6. September 2014, 14:49, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Dein Code definiert n=0, zählt Werte in anderen Variablen hoch und gibt dann "n" aus, was nach wie vor beim Wert "0" ist. Du solltest also schon das ausgeben, was du tatsächlich verändert hast.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@informatik_neuling: Statt alle Briefe immer wieder durchzugehen, um sie nach Jahr oder Empfänger auszufiltern, solltest Du die gelesenen Daten zuerst einmal in eine für Deine Anforderungen geeignete Datenstruktur packen:

Code: Alles auswählen

import json
from collections import defaultdict

with open('data.json', 'rb') as fp:
    data = json.load(fp)

year2letters = defaultdict(list)
for letter in data.iteritems():
    year2letters[letter['year']].append(letter)
 
statistics = [(year,
    sum('Luther, Martin' in letter['sender'] for letter in letters),
    sum('Luther, Martin' in letter['receiver'] for letter in letters),
    ) for year, letters in year2letters]

for year, sent, received in sorted(statistics):
    print year
    print "The number of sent letters:", sent
    print "The number of received letters:", received
 
BlackJack

@informatik_neuling: Ein paar Anmerkungen zum Quelltext:

Utf-8 ist die Standardkodierung von JSON-Dateien, das muss man nicht explizit angeben.

Abkürzungen bei Namen sollte man vermeiden wenn es keine allgemein bekannten Abkürzungen sind. `fp` ist ziemlich nichtssagend wenn man nicht gerade Erfahrung mit einer Programmiersprache hat wo das üblicherweise als Abkürzung für „file pointer” verwendet wird. Selbst dann ist es in Python falsch weil es Zeiger als Datentyp hier nicht gibt.

Ebenfalls vermeiden sollte man konkrete Typen in Namen wie `list`. Wenn man den Typ dann später mal ändern möchte, und das kommt in dynamischen Programmiersprachen mit „duck typing” durchaus vor, muss man überall den Namen ändern oder man hat irreführende Namen im Programm. Namen sollten die Bedeutung des Wertes im Kontext des Programms reflektieren. Für Containertypen nimmt man üblicherweise die Mehrzahl von dem was ein einzelnes Element bedeutet. Also `years` statt `list_of_years`. Dann muss man natürlich den bereits vorhandenen Namen `years` umbenenen. Der steht für *ein* Jahr und sollte deshalb sowieso `year` heissen.

Die Liste mit den Jahreszahlen wird *dreimal* in ein `set()` umgewandelt und selbst nur einmal für einen ``in``-Test verwendet. Was man eigentlich nicht mit Listen sondern mit `set()`\s macht. Da hätten wir also schon den Fall wo man die Liste eigentlich komplett durch ein `set()` ersetzen sollte und damit der Name `list_of_years` falsch würde.

Was zum Henker ist `datas`? Der Name gibt keinen Hinweis was der Schlüssel von dem Wörterbuch bedeutet. Andererseits wird der Wert auch nirgends wirklich verwendet, immer nur als Schlüssel in das Wörterbuch in Schleifen über *alle* Werte. Die Schlüssel sind also völlig irrelevant und man kann jeweils direkt über die Werte iterieren.

Um Bedingungen bei ``if`` braucht man in Python keine Klammern.

Die Bedingung im ersten ``if`` in der Schleife für versandte Briefe ist unsinnig. Die ist *immer* wahr. `years` besteht aus allen Jahren in allen Briefen, als ist auch jedes Jahr aus einem Brief in `years`.

Wie Sirius3 schon schrieb müsstest Du die Daten aber auch in eine passende Datenstruktur überführen wenn Du die Jahre irgendwie nach den aggregierten Daten sortieren möchtest. Momentan hast Du ja nach dem zählen die Information gar nicht mehr wieviele Briefe in welchem Jahr ausgetauscht wurden.
Antworten