Berechnung liefert jedes mal anderes Ergebnis

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo,

    ich habe ein Python-Skript im Internet gefunden, womit man für einen gewünschten Tag den Sonnenaufgang und den Sonnenuntergang berechnen kann.

    Da ich aber für eine Woche gerne diese Zeiten hätte, habe ich das Skript erweitert und die jeweiligen Zeiten in ein Dictionary geschrieben.

    Das habe ich dann auf dem Pi umgesetzt und ausgeführt.

    Ich habe keine Fehlermeldung bekommen, nur leider wird jedes mal für unterschiedliche Tage unterschiedliche Zeiten berechnet. Das ist naturlich nicht richtig und ich weiß leider nicht woran das liegt. :(

    Ich habe ein RasPi Model B Rev2, worauf Raspbian 9 läuft.

    Ich habe das Skript auch nochmal mit Visual Studio ausgeführt und dort hat es immer die richtigen Werte ausgegeben.

    Anbei noch Skript und ein Screenshot von ein paar Ausgaben.

    Auf dem Screenshot sieht man auch dass die ersten Ausgaben immer die gleichen Zeiten haben, was mich auch zum Stutzen gebracht hat....

    Vielen Dank für Hilfe

    Gruß

  • Danke, für die schnelle Hilfe!

    Ich habe das mit einem OrderedDict aus dem Modul Collections gelöst

    Wobei ich mich jetzt frage, warum das nicht in genau der Reihenfolge abgespeichert wird, wie man es eingibt...

    Weil man sagt ja Python wäre so anfängerfreundlich :conf:

    Trotzdem Danke!

  • Hallo,

    Zitat

    Wobei ich mich jetzt frage, warum das nicht in genau der Reihenfolge abgespeichert wird, wie man es eingibt...

    Ganz einfach: weil du auf die Werte in einem Dict über den Schlüssel zugreifst - und da ist die Reihenfolge völlig Latte. Wenn du eine garantierte Reihenfolge brauchst nimmt man eine Liste oder ein Tupel oder ein Deque. Oder ein OrderedDict.

    Bei Python 3.6. wird die Reihenfolge im Dict übrigens in der Regel auch beibehalten, ab Python 3.7 garantiert. Zumindest für CPython, die Referenzimplementierung. Das die Reihenfolge beibehalten wird ist übrigens "nur" der Seiteneffekt einer effizienteren Implementierung von Dict, welche in CPython 3.6 Einzug gehalten hat.

    Gruß, noisefloor

  • Hallo,

    noch ein paar Anmerkungen zum Code:

    • Konstanten werden per Konvention am Anfang des Codes definiert und nicht mal hier, mal da.
    • Konstanten werden per Konvention GROSS geschrieben
    • Variablennamen werden per Konvention klein_mit_unterstrich geschrieben - nicht mal klein, mal groß am Anfang, mal CamelCase
    • Variablennamen sollten aussagekräftig sein. So was wie M, L, x, n ist kryptisch und macht den Code schwer bis nicht lesbar / nachvollziehbar.
    • Der Ausdruck hinter `if` in Zeile 30, 47, 49 usw. braucht nicht geklammert werden.
    • In Zeile 124 und 127 reicht es, ein leeres Dict anzulegen. Das vorbelegen der Werte mit 00:00 ist a) überflüssig, b) hättest du einen falschen Wert, wenn der Wert warum-auch-immer nicht überschrieben würde.
    • Das `dict_` Prefix bei Sonnenaufgang und Sonnenuntergang macht wenig Sinn. Man sieht im Code, dass es ein Dict ist.
    • Warum machst du zwei Dicts und nicht eins, wo pro Tag Sonnenauf- und -untergang als Tupel hinterlegt sind?
    • Strings setzt mit nicht per `+` zusammen, sondern mit der format-Methode von Strings (Zeile 154+155)
    • Die definierst in Zeile 138 `value` - es wird aber nirgendwo im Code genutzt. Dann kannst du auch direkt nur über die Schlüssel des Dicts iterieren.
    • Zeile 142-144 ist ziemlich gruslig... `tag` ist ein `datetime` Objekt, was du brauchst bekommst du ganz einfach über `tag.year`, `tag.month`, `tag.day`.
    • Die Zeilen 167-190 kann man eleganter und kürzer (ohne if-elif-else Kaskade) schreiben:

    Gruß, noisefloor

  • Hallo,

    wie bereits geschrieben, habe ich die Berechnung für einen einzelnen Tag aus der Quelle oben. Auch ich muss zugeben, dass der Code teilweise sehr kryptisch ist. Deshalb hab ich mir hier angeschaut wie so etwas geht...

    Ich muss aber gestehen, dass ich froh war, dass der Code funktioniert hat und ich mich nicht noch mit der Mathematik rumschlagen musste:blush:, was ich leider sowieso schon in der Uni zu viel muss ;(

    Danke auf jeden Fall für die einzelnen Tipps und Grundsätze!:bravo2:

    Und natürlich für die Heute/Morgen "Berechnung" :bravo2:

    Ich hätte dazu aber noch ein/zwei Fragen:

    In Zeile 124 und 127 reicht es, ein leeres Dict anzulegen. Das vorbelegen der Werte mit 00:00 ist a) überflüssig, b) hättest du einen falschen Wert, wenn der Wert warum-auch-immer nicht überschrieben würde.

    Ich hatte gedacht, dass zu einem Key jeweils ein Wert zugewiesen werden muss. Was für ein Wert würde denn zu Key gehören, dem noch kein Wert zugewiesen wurde. Ich dachte, dass ich so später überprüfen konnte ob ein "richtiger" Wert zugewiesen wurde, weil 0 Uhr doch sehr unwahrscheinlich ist. Oder wird dann hier sowas wie NaN abgespeichert?:denker:


    Der Ausdruck hinter `if` in Zeile 30, 47, 49 usw. braucht nicht geklammert werden.

    In Python allgemeiner Usus, dass nicht geklammert wird?

    Auch bei evtl. größeren Bedingungen?

    Zeile 142-144 ist ziemlich gruslig... `tag` ist ein `datetime` Objekt, was du brauchst bekommst du ganz einfach über `tag.year`, `tag.month`, `tag.day`

    Der Gedanke von mir war hier einfach, dass ich so immer mit dem Montag anfange, mein Dictionary zu beschreiben. Leider wusste ich nicht wie ich das sonst anstellen sollte, also habe ich vielleicht ein bisschen rumgepfuscht...:blush:


    Danke, und noch schönen Restabend;)

    Einmal editiert, zuletzt von JaGr0 (25. April 2018 um 21:21)

  • Ganz einfach: weil du auf die Werte in einem Dict über den Schlüssel zugreifst - und da ist die Reihenfolge völlig Latte.

    Unintuitiv finde ich es trotzdem, gerade wenn man die Wörterbuchmetapher ernst nimmt. Außerdem fällt mir kein Fall ein, in dem es aus Sicht des Programmierers ein Vorteil wäre, die Reihenfolge einer Iteration über das dictionary nicht vorhersagen zu können. Insofern finde ich die von Dir beschriebene Entwicklung in CPython durchaus begrüßenswert.

  • Hallo,

    Zitat

    Unintuitiv finde ich es trotzdem, gerade wenn man die Wörterbuchmetapher ernst nimmt.

    Die ist ja eigentlich auch suboptimal. Dicts sind ein "assoziativer Array". Warum das in Python Dictionary heißt und nicht Array oder Map müsstest du mal Guido van Rossum fragen ;)

    Grundsätzlich würde ich sagen, dass wenn man über ein Dict itereriert und eine bestimmte Reihenfolge voraussetzt, man sich erst Mal Gedanken über seine Datenstruktrur machen sollte. Der Zugriff auf eine Dict erfolgt bei Schlüssel, nicht per Indexwert. Für eine lexikalische Sortierung funktioniert auch `sorted(dict.keys())`

    Zitat

    In Python allgemeiner Usus, dass nicht geklammert wird?

    Jein. Klammer brauchst du nur, wenn die die Reihenfolge der Evaluierung eines Ausrducks beeinflussen willst. Sonst wird von links nach rechts evaluiert. Bei einfachen Vergleichen wie `a==b` sind Klammer nicht nowendig.

    Zitat


    Ich hatte gedacht, dass zu einem Key jeweils ein Wert zugewiesen werden muss.

    Nein. Überlicher ist bei Python, dass man den Fehler behandelt, wenn ein Schlüssel fehlt (also den KeyError, der dann kommt), als einem Key einen falschen / Phantasiewert zuzuweisen. Was auch weniger Aufwand und klarer ist, als später nochmal zu prüfen, ob der Defaultwert nicht falsch ist.

    Oder du benutzt die `get` Methode von Dicts, um nicht-vorhandene Schlüssel zu handhaben:

    Gruß, noisefloor

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!