Desktop Assistant

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Friday_Assistant
User
Beiträge: 1
Registriert: Donnerstag 25. April 2019, 11:05

Donnerstag 25. April 2019, 11:09

Hallo zusammen,
bin gerade dabei einen sprachgesteuerten Desktop Assistenten zu programmieren.
Da ich noch recht neu in der Python Umgebung tätig bin stoße ich hier auf einige Probleme
Ich habe eine Reihe von Befehlen programmiert,wobei er nur die ersten 3 ausführen kann, alle danach aufgeführten Befehle führt er nicht aus, stattdessen immer den dritten.
Hier der dazugehörige Code:

import sys
import string
string.ascii_letters
'abcde'
import random
from gtts import gTTS
from playsound import playsound
import pyaudio
import speech_recognition as sr
import os
import webbrowser
import smtplib

#Über die Initialize Funktionen können die Antwortsätze des Bots definiert und gespeichert werden
def Initialize(bot):
exists = os.path.isfile("Audios/"+bot+".mp3")#Wenn die Datei bereits existiert wird man darauf hingewiesen
if exists:
playsound("Audios/The File already exists.mp3")
else:
print(bot)
tts = gTTS(text=bot, lang='en')
path="Audios/"+bot+".mp3"
tts.save(path)

#läuft in Schleife,kann momentan aber nur 3 Befehle verarbeiten, alle die danach kommen macht er Befehl Nr. 3
def Recognize():
playsound("Audios/Greetings.mp3")
r = sr.Recognizer()
mic = sr.Microphone(device_index=1)
with mic as source:
while True:
print("Say Something");
audio = r.listen(source)
record=r.recognize_google(audio)
print(record)

if "what's your name" in record:
playsound("Audios/I'm Friday.mp3")
#Befehle
elif "open YouTube" in record:
url="https://www.youtube.com/"
webbrowser.open_new(url)
playsound("Audios/Anything Else.mp3")
elif "play music" or "play some music" in record:
list=[
"https://www.youtube.com/watch?v=mEljZKCo5Hc",
"https://www.youtube.com/watch?v=hgokPOo8PD0",
"https://www.youtube.com/watch?v=AhiIZKaRixs",
"https://www.youtube.com/watch?v=8wQKNLWRkhs",
"https://www.youtube.com/watch?v=SBjQ9tuuTJQ",
"https://www.youtube.com/watch?v=K73-hmaHPHY",
"https://www.youtube.com/watch?v=GM8VWNMThnQ"
]
song=random.choice(list)
playsound("Audios/No problem.mp3")
webbrowser.open_new(song)
playsound("Audios/Anything Else.mp3")
elif "read news" or "read the news" in record:
playsound("Audios/News Question.mp3")
playsound("Audios/Anything Else.mp3")
elif "no that's it" or "no thank you" or "no Friday" in record:
playsound("Audios/Goodbye.mp3")
break


Danke schonmal für eure Hilfe

Grüße
Benutzeravatar
__blackjack__
User
Beiträge: 4010
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 25. April 2019, 11:58

@Friday_Assistant: ``or`` funktioniert nichts so wie Du denkst. Das ist ein binärer Operator wie ``+`` oder ``*`` und hat einen rechten und einen linken Operanden. So etwas wie ``"play music" or "play some music" in record`` ist immer wahr weil "play_music" wahr ist und damit damit der rechte Operand (``"play some music" in record``) gar nicht erst ausgewertet wird. "play_music" ist wahr weil jede nicht-leere Zeichenkette als Wahrheitswert betrachtet wahr ist. Oder umgekehrt: die leere Zeichenkette ist die einzige Zeichenkette die als Wahrheitswert betrachtet unwahr ist. Der rechte Operand vom ``or`` muss halt auch unwahr werden können in abhängigkeit davon ob "play music" in `record` enthalten ist oder nicht: ``"play music" in record or "play some music" in record``
“Programmieren ist ein Hobby, bei dem es einen riesigen Baumarkt mit quasi jedem Bauteil und Werkzeug und fast immer kostenlos gibt. Ob man deswegen in der Lage ist einen Kölner Dom zu bauen ist eine andere Frage. Arbeit steckt auf jeden Fall drin ;).” — Greebo, forum.ubuntuusers.de
Benutzeravatar
ThomasL
User
Beiträge: 763
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Donnerstag 25. April 2019, 11:59

und wieder einmal war Jacky schneller:
"In dem Thema wurde in der Zwischenzeit mindestens ein neuer Beitrag erstellt. Du kannst deinen Beitrag überprüfen und ihn gegebenenfalls anpassen."

Code: Alles auswählen

elif "play music" or "play some music" in record:
Dies ist immer True weil "play music" True liefert.
Korrekt müsstest du prüfen:

Code: Alles auswählen

elif "play music" in record or "play some music" in record:
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
__blackjack__
User
Beiträge: 4010
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 25. April 2019, 12:39

@Friday_Assistant: Noch ein paar Anmerkungen zum Code:

`sys`, `pyaudio`, und `smtplib` werden importiert, aber gar nicht verwendet. Das `string`-Modul wird auch nicht wirklich verwendet.

``string.ascii_letters`` und ``'abcde'`` zwischen den Importen haben an der Stelle nichts zu suchen und haben sowieso keinen sinnvollen Effekt. Was sollte das?

Es gibt ein paar sehr verbreitete Module bei denen ist es üblich sie unter einem Namen zum importieren der stark verkürzt ist. Üblicherweise weil dann viele Namen daraus verwendet werden. Das trifft auf `speech_recognition` nicht zu.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Das `bot`-Argument von `initialize()` ist eine Zeichenkette, also sollte man das vielleicht besser `bot_name` nennen.

Pfade sind keine einfachen Zeichenketten, die sollte man also nicht mit ``+`` oder anderen Zeichenkettenoperationen verarbeiten, sondern mit den Funktionen aus `os.path` oder mit dem `pathlib`-Modul.

In der Funktion wird für den Bot-Namen auch zweimal der gleiche Pfad zusammengesetzt. Das sollte man nur einmal machen.

Da alle `playsound()`-Aufrufe etwas im Unterverzeichnis 'Audios/' abspielen, könnte man diesen Teil auch in eine eigene Funktion auslagern.

Einbuchstabige Namen sind selten gute Namen. Ein Name soll dem Leser verraten was der Wert im Kontext des Programms bedeutet, und nicht zum rätseln oder suchen nach der Definition zwingen.

Da ist ein überflüssiges Semikolon in einer Zeile. Semikolons braucht man in Python so gut wie nie.

`record` ist ein unpassender Name. Das ist kein Datensatz und keine Schallplatte und auch keine Funktion die etwas aufnimmt. `recording` ginge vielleicht aber da würde man auch eher Audiodaten hinter vermuten. `text` wäre vielleicht passen, wenn auch etwas generisch.

Für die Tests ob einer von mehreren Texten enthalten ist, könnte man sich eine kleine Funktion schreiben.

`list` ist der Name des eingebauten `list`-Datentyps, den sollte man nicht an einen anderen Wert binden. Der Name ist ja auch ziemlich nichtssagend.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import random
import webbrowser
from pathlib import Path

from gtts import gTTS
from playsound import playsound
from speech_recognition import Microphone, Recognizer

AUDIO_PATH = Path('Audios')
SONG_URLS = [
    'https://www.youtube.com/watch?v=8wQKNLWRkhs',
    'https://www.youtube.com/watch?v=AhiIZKaRixs',
    'https://www.youtube.com/watch?v=GM8VWNMThnQ',
    'https://www.youtube.com/watch?v=hgokPOo8PD0',
    'https://www.youtube.com/watch?v=K73-hmaHPHY',
    'https://www.youtube.com/watch?v=mEljZKCo5Hc',
    'https://www.youtube.com/watch?v=SBjQ9tuuTJQ',
]


def play_mp3(name):
    playsound(str((AUDIO_PATH / name).with_suffix('.mp3')))


def initialize(bot_name):
    mp3_path = (AUDIO_PATH / bot_name).with_suffix('.mp3')
    if mp3_path.is_file():
        play_mp3('The File already exists')
    else:
        print(bot_name)
        gTTS(text=bot_name, lang='en').save(str(mp3_path))


def contains_any(text, commands):
    return any(command in text for command in commands)


def recognize():
    play_mp3('Greetings')
    recognizer = Recognizer()
    with Microphone(device_index=1) as source:
        while True:
            print('Say Something')
            text = recognizer.recognize_google(recognizer.listen(source))
            print(text)
            
            if "what's your name" in text:
                play_mp3("I'm Friday")    
            elif "open YouTube" in text:
                webbrowser.open_new('https://www.youtube.com/')
                play_mp3('Anything Else')
            elif contains_any(text, ['play music', 'play some music']):
                play_mp3('No problem')
                webbrowser.open_new(random.choice(SONG_URLS))
                play_mp3('Anything Else')
            elif contains_any(text, ['read news', 'read the news']):
                play_mp3('News Question')
                play_mp3('Anything Else') 
            elif contains_any(
                text, ["no that's it", 'no thank you', 'no Friday']
            ):
                play_mp3("Goodbye")
                break
“Programmieren ist ein Hobby, bei dem es einen riesigen Baumarkt mit quasi jedem Bauteil und Werkzeug und fast immer kostenlos gibt. Ob man deswegen in der Lage ist einen Kölner Dom zu bauen ist eine andere Frage. Arbeit steckt auf jeden Fall drin ;).” — Greebo, forum.ubuntuusers.de
Antworten