Loop

Fragen zu Tkinter.
Antworten
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bio Salami: Anmerkungen zum `Bibliothek`-Modul: Der Name ist nicht gut.

`error` aus `os`, `sleep` aus `time`, und `new_info` werden importiert, aber nirgends verwendet.

`ChatBot` wird weit unten, tief in einer Funktion versteckt importiert.

Die ``if``-Bedingungen gegen `voice_data` haben alle das gleiche Muster bei dem `voice_data` immer mehrfach in der Bedingung steht – das kann man in eine eigene Funktion herausziehen.

`trash` ist kein so guter Name und den sollte man auch nicht vorbelegen mit einem Wert der nirgends verwendet wird. Üblich ist es `_` als Namen für Werte zu verwenden, die nicht verwendet werden.

Es wiederholt sich sehr oft ein Muster mit `split()`-Aufrufen in einem ``try``/``except``-Block was auch noch mal Zeichenkettenwiederholungen enthält, und dem immer die gleiche ``while``-Schleife folgt.

Zeichenkettenliterale sind kein Ersatz für ``pass``.

Wenn man JSON-Dateien im Binärmodus öffnet, kümmert sich das JSON-Modul um die Zeichenkodierung.

``try``-Blöcke sollten möglichst klein sein, damit nicht die Gefahr besteht, dass die behandelten Ausnahmen von Code kommen von dem man sie nicht erwartet hat.

Der Teil mit dem `ChatBot` sieht komisch aus. Entweder ist das keine Klasse oder der Code ist falsch wenn er das Ergebnis einfach als Zeichenkette behandelt‽

Was soll die Umbennenung von `voice_data` in `sentence`? Das wäre aber vielleicht generell ein besserer Name für `voice_data`.

In dem ``try``-Block sollte kein `TypeError` auftreten können‽

Je nachdem ob `sentence` "## " enthält ist es danach eine Zeichenkette oder eine Liste mit Zeichenkette, was nicht sein sollte, weil sehr verwirrend.

`exit()` gibt es nicht wirklich wenn man das nicht aus `sys` importiert.

Die URL-Parameter kann man bei `requests` als Wörterbuch übergeben. Das ist übersichtlicher und sicherer als die Werte selbst in eine URL hinein zu formatieren.

`data` ist kein guter Name für ein `Response`-Objekt.

Man sollte prüfen ob die HTTP-Antwort Ok-Status hat.

Die `format()`-Funktion mit nur einem Argument aufrufen macht bei Zeichenketten keinen Sinn.

`tmp` ist eine übliche Abkürzung für `temporary`. Wenn man `temparature` meint, sollte man nicht `tmp` schreiben.

Gleitkommazahlen in Zeichenketten umwandeln um dann die Nachkommastellen zu entfernen ist umständlich. Man formatiert einfach die Zahl mit 0 Nachkommastellen. Oder, falls man immer abrunden möchte, wandelt man die Gleitkommazahl einfach in eine ganze Zahl um.

Die Funktion ist insgesamt zu lang.

Ungetestet:

Code: Alles auswählen

import json
import sys
import webbrowser
from datetime import datetime as DateTime

import pywhatkit
import requests
import wikipediaapi
from chat import ChatBot
from speak import listen, say
from stbw import standby


def contains_any(haystack, needles):
    return any(needle in haystack for needle in needles)


def listen_til_answer(prompt):
    while True:
        answer = listen(prompt)
        if answer:
            return answer


def get_subject(text, prefixes, prompt):
    for prefix in prefixes:
        _, prefix, subject = text.partition(prefix)
        if subject:
            return subject

    return listen_til_answer(prompt)


def respond(sentence):
    if contains_any(sentence, ["suche Ort", "suche den Ort", "wo liegt"]):
        location = get_subject(
            sentence, ["suche den Ort", "wo liegt"], "Welchen Ort suchst Du?"
        )
        webbrowser.get().open(f"https://google.nl/maps/place/{location}/&")
        say("Hier ist der Ort " + location)

    elif contains_any(sentence, ["Suche nach", "suche", "Google Suche"]):
        search = get_subject(sentence, ["Suche nach"], "Nach was suchst Du?")
        webbrowser.get().open(f"https://google.com/search?q={search}")
        say("Hier ist mein suchergebnis für " + search)

    elif contains_any(
        sentence,
        [
            "was weißt du über",
            "weißt du was über",
            "was ist",
            "Wer war",
            "Wer ist",
            "Wikipedia Suche",
        ],
    ):
        question = get_subject(
            sentence,
            [
                "was weißt du über",
                "weißt du was über",
                "was ist",
                "Wer war",
                "Wer war",
            ],
            "Was willst Du wissen?",
        )

        wikipedia = wikipediaapi.Wikipedia("de")
        page = wikipedia.page(question)
        article_start = wikipedia.extracts(page, exsentences=4)
        say(article_start)

        if "ja" in listen_til_answer("Willst Du mehr hören?"):
            say(wikipedia.extracts(page)[len(article_start) :])

    elif contains_any(
        sentence, ["sende eine nachricht", "sende eine Nachricht an"]
    ):
        name = get_subject(
            sentence,
            ["sende eine Nachricht an"],
            "An wen geht die Nachricht?",
        )
        nachricht = listen_til_answer(f"Was möchtest Du {name} senden?")
        if contains_any(
            listen_til_answer(
                f"Soll ich die Nachricht: {nachricht} an {name} absenden?"
            ),
            ["ja", "absenden"],
        ):
            vorname, _, name = name.partition(" ")
            if not name:
                name = vorname

            with open("numbers.json", "rb") as json_file:
                numbers = json.load(json_file)

            try:
                number = numbers[name]
            except KeyError:
                say(f"Ich habe {name} nicht gefunden.")
            else:
                print(number)
                say("Nachricht wird gleich versendet.")
                pywhatkit.sendwhatmsg_instantly(
                    number[0], nachricht, tab_close=True
                )
                say("Die Nachricht wurde versendet.")
        else:
            say("Ich habe die Nachricht nicht gesendet.")

    elif contains_any(sentence, ["übersetze", "Übersetze"]):
        text = get_subject(
            sentence, ["übersetze", "Übersetze"], "Was soll ich übersetzen?"
        )
        sprache = listen_til_answer("In welche sprache soll ich übersetzen?")
        try:
            with open(f"language/{sprache}.txt", encoding="utf-8") as file:
                sprach_code = next(file)
        except FileNotFoundError:
            say("In diese Sprache kann ich noch nicht übersetzen")
        else:
            webbrowser.get().open(
                f"https://translate.google.de/"
                f"?sl=auto&tl={sprach_code}&text={text}&op=translate"
            )
            say("Hier ist die übersetzung")

    else:
        sentence = ChatBot(sentence) or "nothing here"

        if "## " in sentence:
            parts = sentence.split("## ")
        else:
            say(sentence)
            parts = [sentence]

        if "time" in parts:
            say(f"Es ist {DateTime.now():%H:%M} Uhr")

        elif "sss" in parts:
            say("Schnik Schnak Schnuk")
            spielzug = listen_til_answer("Was hast du?")
            for zug, gegenzug in [
                ("Schere", "Stein"),
                ("Stein", "Papier"),
                ("Papier", "Schere"),
            ]:
                if zug in spielzug:
                    say(f"Ich habe {gegenzug}.")
                    break

            say("Ich habe gewonnen")

        elif contains_any(parts, ["ausschalten", "reload"]):
            sys.exit()

        elif "wetter" in parts:
            response = requests.get(
                "https://api.openweathermap.org/data/2.5/weather",
                params={
                    "appid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "lang": "de",
                    "q": "willich",
                    "units": "metric",
                },
            )
            response.raise_for_status()
            
            weather_data = response.json()
            
            temperatures = weather_data["main"]
            temperature = int(temperatures["temp"])
            max_temperature = int(temperatures["temp_max"])
            min_temperature = int(temperatures["temp_min"])

            clouds_percentage = weather_data["clouds"]["all"]
            if clouds_percentage <= 10:
                clouds_text = "Es sollten keine Wolken am Himmel sein."
            elif clouds_percentage <= 40:
                clouds_text = "Es ist teilweise Bewölkt."
            elif clouds_percentage <= 100:
                clouds_text = "Es ist gerade sehr Bewölkt."
            else:
                assert False, f"clouds_percentage > 100: {clouds_percentage}"

            say(
                f"Die Temperatur beträgt {temperature}°."
                f" Die maximale Temperatur liegt bei {max_temperature}°"
                f" und die minimale Temperatur liegt bei {min_temperature}°."
                f" {clouds_text}"
            )

        elif "radio" in parts:
            say("Radio Auswahl wird geöffnet")
            webbrowser.get().open(
                "https://www.news894.de/service/radioplayer.html"
                "?radiochannel=live"
            )
            standby()
            sys.exit()

        elif "stb" in parts:
            say("Standby modus Aktiviert")
            standby()
            sys.exit()

        elif "kalender" in parts:
            webbrowser.get().open("https://www.icloud.com/calendar/")
            say("Hier ist dein Kalender")
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten