Wetterdaten aus Internet in Python

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.
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Im Terminal hat alles so geklappt wie ich mir erhofft habe.
Was klappt micht so wie Du Dir das dachtest? Regnet es die ganze Zeit, obwohl die Anzeige auf sonnig steht? Gibt es eine Fehlermeldung? Wenn ja, welche?
Nunja eine Fehlermeldung gibt es nicht. Das mit dem den ganzen Tag regnen trifft es schon ehr. Es ist so, dass sich die Temperatur... nicht aktualisiert, d.h es ist dauerhaft die gleiche Temperatur. Wenn ich alles neu starte, erst dann hat sich die Temperatur … auch wieder aktualisiert. Das ist das problem, welches noch gelöst werden muss, wie ich es schaffe das sich alles nach meinetwegen einer Minute neu aktualisiert.


@sirius3 Was hat der Code, den du gepostet hast für eine "bessere Funktion" bzw ist das bloß meiner in übersichtlicher Weise?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Ohne das gesamte Programm zu kennen, kann man da wenig sagen.

Ich wollte nur zeigen, wie viele Parameter man braucht, weil die Funktion so viel Input braucht, dass es wenig Sinn macht, das ohne Klassen zu implementieren.
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Nunja ich denke es macht wenig Sinn, das komplette Programm zu zeige ohne das ich vorher mal die "offensichtlichen" Fehler ausgemerzt habe. Wie gesagt, ich versuche das ganze nochmal neu zu machen mit dem OOP und diesen Klssen etc. Wenn jemand noch gute Tutorials dazu kennt, die man nicht direkt bei Google findet, dann ruhig her damit :-)
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

so ich habe mal ein bissel rumgebastelt

Code: Alles auswählen

class wetter_vorhersage:
    def __init__(self, temperatur, wind):
        self.aktuelle_temperatur = temperatur
        self.maximale_temperatur = temperatur
        self.minimale_temperatur = temperatur
        self.windgeschwindigkeit = wind
        self.windrichtung = wind
        print("erstellt")
    def print(self):
        print("Temperatur aktuell {}".format(self.aktuelle_temperatur.get("temp")))
        print("maximal {}".format(self.maximale_temperatur.get("temp_max")))
        print("minimal {}".format(self.minimale_temperatur.get("temp_min")))
        print("Wind {}" .format(self.windgeschwindigkeit.get("speed")))
        print("Windrichtung {}".format(self.windrichtung.get("deg")))
        
        
        
vorhersage = wetter_vorhersage(w.get_temperature("celsius"), w.get_wind())
vorhersage.print()
so siehts jetzt aus. Kann mal jemdand sagen, ob das so erstmal ordentlich ist, bevor ich weiter mache.

LG
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Da temperatur ein Objekt zu sein schient, dass sowohl die aktuelle als auch max und min Temperaturen enthält, macht es wenig Sinn, das selbe Objekt in aktuelle_tempertur, maximale_temperatur und minimale_temperatur zu speichern. Das gleiche gilt für den Wind.
Klassen schreibt man GrossKlein: WetterVorhersage.
Insgesamt macht die Klasse keinen Sinn, wenn sie nur aus einer Methode besteht. Das könnte man auch als einfache Funktion schreiben.

Code: Alles auswählen

def print_wetter(temperatur, wind):
    print("Temperatur aktuell {}".format(temperatur.get("temp")))
    print("maximal {}".format(temperatur.get("temp_max")))
    print("minimal {}".format(temperatur.get("temp_min")))
    print("Wind {}" .format(wind.get("speed")))
    print("Windrichtung {}".format(wind.get("deg")))
oder falls man nur ein Argument möchte:

Code: Alles auswählen

def print_wetter(wetter, einheit="celsius"):
    temperatur = wetter.get_temperature(einheit)
    wind = wetter.w.get_wind()
    print("Temperatur aktuell {}".format(temperatur.get("temp")))
    print("maximal {}".format(temperatur.get("temp_max")))
    print("minimal {}".format(temperatur.get("temp_min")))
    print("Wind {}" .format(wind.get("speed")))
    print("Windrichtung {}".format(wind.get("deg")))
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

ok verstehe
dennoch wollte ich jetzt gerne, das die Daten in einem Label angezeigt werden.

Code: Alles auswählen

observation = owm.weather_at_place('MEINE STADT, de')
w = observation.get_weather()
class WetterVorhersage:

    def __init__(self, temperatur, wind):
        self.temperatur = temperatur
        self.wind = wind
        print("erstellt")
    def print_wetter(self):
        print("Temperatur aktuell {}".format(self.temperatur.get("temp")))
        print("maximal {}".format(self.temperatur.get("temp_max")))
        print("minimal {}".format(self.temperatur.get("temp_min")))
        print("Wind {}" .format(self.wind.get("speed")))
        print("Windrichtung {}".format(self.wind.get("deg")))

    def label_aktualisieren(self):
        Temperatur.config(text="Temperatur aktuell {}".format(self.temperatur.get("temp")))
        Temperatur_max.config(text="maximal {}".format(self.temperatur.get("temp_max")))
        Temperatur_min.config(text="mainimal {}".format(self.temperatur.get("temp_min")))
        Status_Label.config(text=self.wind)

        
        
        
vorhersage = WetterVorhersage(w.get_temperature("celsius"), w.get_wind())
vorhersage.print_wetter()

def main():
    vorhersage.label_aktualisieren()
    vorhersage.print_wetter()
    print ("*******************************")
    fenster.after(10000, main)
Eigentlich habe ich gehofft, das die Wetterdaten jetzt aktualisiert werden und somit ständig aktuell sind. Leider ist das nicht der Fall. Wie kann ich das jetzt lösen, das die Daten ständig neu geladen werden?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

wieso willst du denn *main* alle 10 Sekunden starten? Wenn fenster.label_akualisieren.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@No17: Na welche Zeile/Anweisung holt denn die Daten vom Server? Und wie oft/wann wird die ausgeführt? Wie oft/wann müsste die ausgeführt werden?

Und wenn Du schon Klassen verwendest, dann gibt es keinen Grund mehr mit globalen Variablen zu arbeiten. Funktionen und Methoden sollten alles was sie benötigen (ausser Konstanten) als Argumente übergeben bekommen. Das `label_aktualisieren()` also auf ”magische” Weise einfach so auf die vier Label-Objekte zugreifen kann, ist nicht okay.

Eine sinnvolle Klasse ist das IMHO immer noch nicht. Wenn Du einfach nur Werte zu einem Objekt zusammenfassen möchtest, dann schau Dir mal `collections.namedtuple` an. Oder falls die Attribute veränderbar sein sollen finde ich https://www.attrs.org/ ganz praktisch, selbst dann wenn man die Klasse als „frozen“ markiert und `attr.evolve()` für “Veränderungen“ verwendet.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

So weit ich weiß holt man die Daten mit

Code: Alles auswählen

observation = owm.weather_at_place('MEINE STADT, de')
w = observation.get_weather()
Eine sinnvolle Klasse ist das IMHO immer noch nicht. Wenn Du einfach nur Werte zu einem Objekt zusammenfassen möchtest, dann schau Dir mal `collections.namedtuple` an. Oder falls die Attribute veränderbar sein sollen finde ich https://www.attrs.org/ ganz praktisch, selbst dann wenn man die Klasse als „frozen“ markiert und `attr.evolve()` für “Veränderungen“ verwendet.
werde ich mir gleich mal angucken. Hat das nur den Vorteil, dass das zugreifen auf die Label "richtig" erfolgt?
Das `label_aktualisieren()` also auf ”magische” Weise einfach so auf die vier Label-Objekte zugreifen kann, ist nicht okay.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@No17: Das hat mit den Labeln nix zu tun, das war als Vorschlag um Deine Klasse zu ersetzen deren Methoden eigentlich einfach nur Funktionen sein sollten. Oder im Falle der Labels eine Methode auf einer anderen Klasse, nämlich die wo die GUI mit modelliert wird.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn man das Wetter in ein eigenes Datenobjekt umverpacken möchte, zum Beispiel um bessere Namen und eine ”Attribut-API” zu haben, könnte man das beispielsweise so machen:

Code: Alles auswählen

#!/usr/bin/env python3
from addict import Dict
from attr import attrib, attrs
from pyowm import OWM

API_KEY = '<API KEY>'
PLACE = 'Berlin,DE'


@attrs
class Weather:
    
    temperatures = attrib()
    wind = attrib()
    
    @classmethod
    def from_owm(cls, owm, place):
        weather = owm.weather_at_place(place).get_weather()
        temperature = weather.get_temperature('celsius')
        return cls(
            Dict(
                current=temperature['temp'],
                min=temperature['temp_min'],
                max=temperature['temp_max'],
            ),
            Dict(weather.get_wind()),
        )


def print_weather(weather):
    print(f' Temperatur aktuell: {weather.temperatures.current}°C')
    print(f'            maximal: {weather.temperatures.max}°C')
    print(f'            minimal: {weather.temperatures.min}°C')
    print(f'Windgeschwindigkeit: {weather.wind.speed} m/s')
    print(f'       Windrichtung: {weather.wind.deg}°')


def main():
    owm = OWM(API_KEY)
    weather = Weather.from_owm(owm, PLACE)
    print_weather(weather)


if __name__ == '__main__':
    main()
`addict` und `attr` sind beides externe, aber sehr praktische Module.

´print_weather()` ist weiterhin eine einfache Funktion und das aktualisieren von Labels würde in einer entsprechenden Methode auf einem GUI-Objekt Sinn machen, aber nicht als Methode auf dem Wetterdatenobjekt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

OK verstehe, das dass noch nicht so "sauber" ist, allerdings habe ich es jetzt geschafft, das es so funktioniert wie ich wollte 8) .
Ich glaube ich lasse das jetzt so wie es ist und verändere nicht wieder alles.
Eine Frage die aber weniger damit zutun hat habe ich trotzdem noch. Wenn jetzt z.B das Internet vom PC weg ist, dann gibt es ja einen Fehler in der Shell. Gibt es eine Möglichkeit, das Python das mitbekommt und ich daraufhin eine Aktion ausführen lasse?

LG
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was du suchst nennt sich Ausnahme oder Exception, und wie man die behandelt wird in jedem Grundlagentutorial besprochen.
Antworten