Wie nutze ich "oder" bei einem Chatbot in Python?

2 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Ich würde das reaktionsantworten Dictionary um einen Eintrag erweitern. So hast du zwei Einträge, die auf die gleiche Antwort zeigen.

{
  "hallo": "Guten Tag",
  "servus": "Guten Tag",
  ...
}

Eventuell solltest die Antwort in eine variable packen, um die Antwort für beide Fälle ändern zu können.

antwort = "Guten Tag"
{
  "hallo": antwort,
  "servus": antwort,
  ...
}

Du könntest auch alle Antworten ein separates Dictionary packen und ein zweites Dictionary anlegen, welches die möglichen Antworten mit den Schlüsselwörtern aus dem Chat verbindet.


DirkWasser 
Beitragsersteller
 23.11.2021, 09:30

Danke. Zu deinem ersten Beispiel: Wie erreiche ich, dass es mir dann auch noch als zufällige Antwort auf "hallo" und "servus" entweder ein "Hallo", "Guten Tag", "Moin" oder auch "Servus", auf zufälliger Basis, gibt?

0
tide1109  23.11.2021, 14:55
@DirkWasser

Zuerst würde ich eine Funktion anlegen, welche eine zufällige Antwort ausgibt.

def getRandomGreeting():
  greetings = ["hallo", "servus", "Hallo", "Guten Tag", "Moin", "Servus"]
  // hast du bereits benutzt
  return random.choice(greetings)

Wenn du dein Antworten Dictionary wie folgt anlegst, hast du ein kleines Problem:

{
  "hallo": getRandomGreeting(),
  "servus": getRandomGreeting(),
  ...
}

Das Dictionary wird beim Programmstart angelegt und mit zufälligen Antworten befüllt. Wenn allerdings bei einem Start zweimal "hallo" verwendet wird, kommt jeweils die selbe Antwort zurück.

Ich hätte daher das Anlegen vom Antworten Dictionary über eine Funktion gemacht.

Zum Beispiel:

def getReactions():
  return {
    "hallo": getRandomGreeting(),
    "servus": getRandomGreeting(),
    ...
  }

Die Anwendung sollte dann z.B. so aussehen:

# folgende Zeile entfernen/auskommentieren
# reaktionsantworten = { ... 
# ...
while nutzereingabe != "bye":
  # ...
  reaktionsantworten = getReactions() # neu
  
  for einzelwoerter in nutzerwoerter:
    if einzelwoerter in reaktionsantworten:
      print(reaktionsantworten[einzelwoerter])

Damit wird nach jeder Nutzereingabe ein neues Dictionary mit zufälligen Antworten angelegt. Die Antworten sind also auch durchgehender Nutzung zufällig.

Du könntest den Inhalt der "getReactions()" Funtion auch direkt in der "while nutzereingabe" Schleife einbauen. Die Funktion wird nur einmal benutzt und die das Resultat ist identisch. Mit der Funktion ist dein Code allerdings etwas aufgeräumter.

1
DirkWasser 
Beitragsersteller
 27.11.2021, 16:57
@tide1109
Also doch theoretisch so hier, oder? Das funktioniert bei mir nicht :(.

# -*- coding: utf-8 -*-
import random

zufallsantworten = ["Oh, wirklich", "Interessant ...", "Das kann man so sehen", "Ich verstehe ..."]

def getRandomGreeting():
  greetings = ["Hallo", "Guten Tag", "Moin", "Servus"]
  return random.choice(greetings)

def getReactions():
  return {
    "hallo": getRandomGreeting(),
    "servus": getRandomGreeting(),
  }

reaktionsantworten = {"geht": "Was verstehst du darunter?",
                      "essen": "Ich habe leider keinen Geschmackssinn :("
                      }

print("Willkommen beim Chatbot")
print("Worüber würden Sie gerne heute sprechen?")
print("Zum beenden einfach 'bye' eintippen")
print("")

nutzereingabe = ""
while nutzereingabe != "bye":
    nutzereingabe = ""
    while nutzereingabe == "":
        nutzereingabe = input("Ihre Frage/Antwort: ")
        reaktionsantworten = getReactions()

    nutzereingabe = nutzereingabe.lower()
    nutzerwoerter = nutzereingabe.split()

    intelligenteAntworten = False
    for einzelwoerter in nutzerwoerter:
        if einzelwoerter in reaktionsantworten:
            print(reaktionsantworten[einzelwoerter])
            intelligenteAntworten = True
    if intelligenteAntworten == False:
        print(random.choice(zufallsantworten))

    print("")

print("Einen schönen Tag wünsche ich Dir. Bis zum nächsten Mal")
0
tide1109  27.11.2021, 17:44
@DirkWasser

Was soll den nicht funktionieren? Kommt nicht das gewünschte Verhalten? Kommt eine Fehlermeldung?

Habe dein Copy&Paste auf meine Mac (MacOS 12.0.1) mit Python 3.8.9 getestet. Es funktioniert ohne Probleme mit dem erwarteten Verhalten.

Wenn ich es mit Python 2 aufrufe muss ich die Eingabe inkl. Anführungsstriche eintragen. Dann läuft es auch mit Python 2. Das Thema wäre auch schon vorher aufgefallen.

Eine Antwort kann auch z.B. 3 Mal hintereinander gleich sein. Es gibt nur eine 1/4 Wahrscheinlichkeit. Die random Funktion dürfte auch kein echten Zufall darstellen.

0
DirkWasser 
Beitragsersteller
 28.11.2021, 19:36
@tide1109

Danke, ich habe meinen Fehler gefunden. Ich habe bei dem Test mit der Konsole den aktualisierten Code nicht verknüpft, danke :)

0

oder ganz grundlegend in Python:

if condition_1 or condition_2:
  ...

Deine andere Frage:

Dann brauchst du random oder du nutzt einen int; random ist besser:

from random import randrange

if randrange(1) == 1:
  ... Servus
elif:
  ... Guten Tag

kriegst entweder 0 oder 1, dann abfragen und entweder ,,Guten Tag" oder ,,Servus" ausgeben.

Alternative:

from time import time

if int(time()) % 2 == 1:
  ... Servus
elif:
  ... Guten Tag 

Die Zeit läuft ja weiter und pos. ganzzahl ist entweder gerade time mod 2 = 0 oder ungerade time mod 2 = 1

Pseudozufallsgeneratoren basieren auch meist auf der Zeit.

Am Ende sei gesagt: Wenn du mehrere Antworten willst, dann nutzt du die zweite Methode und schieb deine Antwortmögl. in eine List. Statt % 2 schreibst du

int(time()) %länge deiner List

Wenn genau die Länge getroffen wird, ist der mod 0, wenn nicht, höchstens Länge -1

nachricht = deinelist[int(time()) % len(deinelist)]

Statt die Zeit geht hier natürlich auch der andere Pseudozufall in einer Range. Auf die WS-Verteilung in kurzen Abständen kommt es dir hier wohl nicht an.


DirkWasser 
Beitragsersteller
 21.11.2021, 11:55

Und wo würdest du das in meinen Code einbetten? Kannst du die veränderte Form noch einmal posten?

0