Zum Inhalt springen

Programmierung eines Chatbots


Mefisto

Empfohlene Beiträge

Dankeschön, dass ist sehr nett :)

Eine Beispieldatei, in welcher das, was ich heute neu dazu zu machen versucht habe zu sehen ist (also das mit SETTOPIC und IFTOPIC), ist in "language/de/gimp.mod"...

Bevor ich heute dran weitergemacht habe hat alles wunderbar kompilliert und funktioniert. Das heißt die züfällige Ausgabe bei (möglichkeit1|möglichkeit2|möglichkeit3) und alles andere funktioniert.

Hallo,

In diesem Falle hilft der Debugger nicht alleine. Was genau machst du mit diesem "|||||"?

GNU gdb 6.8-debian

Copyright © 2008 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

and "show warranty" for details.

This GDB was configured as "x86_64-linux-gnu"...

(gdb) run

Starting program: /home/tobias/temp/cina2009

[Thread debugging using libthread_db enabled]

[New Thread 0x7fb97dd8e700 (LWP 9680)]

Program received signal SIGSEGV, Segmentation fault.

[switching to Thread 0x7fb97dd8e700 (LWP 9680)]

0x00007fb97ccbcb43 in QString::append () from /usr/lib/libQtCore.so.4

(gdb) bt

#0 0x00007fb97ccbcb43 in QString::append () from /usr/lib/libQtCore.so.4

#1 0x0000000000405cd9 in mainwindow::sendString (this=0xd12e00) at /usr/include/qt4/QtCore/qstring.h:255

#2 0x000000000040a89d in mainwindow::qt_metacall (this=0xd12e00, _c=QMetaObject::InvokeMetaMethod, _id=16, _a=<value optimized out>) at moc_mainwindow.cpp:68

#3 0x00007fb97cd78134 in QMetaObject::activate () from /usr/lib/libQtCore.so.4

#4 0x00007fb97d79e797 in QAbstractButton::clicked () from /usr/lib/libQtGui.so.4

#5 0x00007fb97d5228db in ?? () from /usr/lib/libQtGui.so.4

#6 0x00007fb97d5244a2 in ?? () from /usr/lib/libQtGui.so.4

#7 0x00007fb97d5246f5 in QAbstractButton::mouseReleaseEvent () from /usr/lib/libQtGui.so.4

#8 0x00007fb97d26a329 in QWidget::event () from /usr/lib/libQtGui.so.4

#9 0x00007fb97d217c3d in QApplicationPrivate::notify_helper () from /usr/lib/libQtGui.so.4

#10 0x00007fb97d22022a in QApplication::notify () from /usr/lib/libQtGui.so.4

#11 0x00007fb97cd63d61 in QCoreApplication::notifyInternal () from /usr/lib/libQtCore.so.4

#12 0x00007fb97d21f5c8 in QApplicationPrivate::sendMouseEvent () from /usr/lib/libQtGui.so.4

#13 0x00007fb97d283be9 in ?? () from /usr/lib/libQtGui.so.4

#14 0x00007fb97d282607 in QApplication::x11ProcessEvent () from /usr/lib/libQtGui.so.4

#15 0x00007fb97d2aa2c4 in ?? () from /usr/lib/libQtGui.so.4

#16 0x00007fb97b1cfd3b in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0

#17 0x00007fb97b1d350d in ?? () from /usr/lib/libglib-2.0.so.0

#18 0x00007fb97b1d36cb in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0

#19 0x00007fb97cd8c15f in QEventDispatcherGlib::processEvents () from /usr/lib/libQtCore.so.4

#20 0x00007fb97d2a9a6f in ?? () from /usr/lib/libQtGui.so.4

#21 0x00007fb97cd62682 in QEventLoop::processEvents () from /usr/lib/libQtCore.so.4

#22 0x00007fb97cd6280d in QEventLoop::exec () from /usr/lib/libQtCore.so.4

#23 0x00007fb97cd64cbd in QCoreApplication::exec () from /usr/lib/libQtCore.so.4

#24 0x000000000040531c in main (argc=1, argv=<value optimized out>) at main.cpp:11

Hier sieht man eigentlich schon die Ursache, du hängst einen String an einem anderen an (append) und das löst einen Segmentation fault aus. Das passiert dann, wenn versucht wird, auf eine Speicherstelle zuzugreifen, die dem jeweiligen Programm nicht vom Betriebssystem zugewiesen wurde und ist ein Schutz sowohl für die Stabilität des Gesamtsystems und gegen Auslesen von Daten, die gerade in anderen Programmen verwendet werden.

Die Quellcodedatei der Methode mainwindow::sendString wurde auf den ersten Blick "falsch" angegeben, was aber daran liegt, dass Qt einen Teil deines Quellcodes zuerst (mit "moc") umwandelt, um die Qt-spezifischen Makros aufzulösen.

In mainwindow::sendString verwendest du mehrmals die "append"-Funktion. Was mir dann sofort auffällt, ist dieses Konstrukt:

	QStringList outputtopic = foo.split("|||||");
Vermeide so etwas unbedingt. Ich habe bei FreeHAL auch früher gedacht, dass es praktischer/einfacher/bequemer ist, mehrere String aneinander anzuhängen und später wieder zu trennen, auch weil dadurch die API nicht verändert wird. Am Ende hatte ich dann soetwas (Beispiel):
	QStringList outputtopic = foo.split("|||||");

QStringList hierMussNochMeinUserNameDrinSein = outputtopic[5].split("]][[");

QString username = hierMussNochMeinUserNameDrinSein[0];

QString dasUntergeordneteThema = hierMussNochMeinUserNameDrinSein[2].split("^")[0];

Verwende lieber gleich eine QStringList, oder noch besser, eine eigene Klasse "Answer" oder ähnlich, die diese Attribute enthält. Der Fehler war hier ja, dass du das zweite Element der QStringList abgefragt hast, aber nur eins existierte, weil kein |||| enthalten war.

Gruß

Tobias

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • Antworten 58
  • Erstellt
  • Letzte Antwort

Top-Benutzer in diesem Thema

Wow, vielen Dank für diese ausführliche Antwort... Das mit der Klasse hatte ich mir auch schon überlegt, aber ich würde gerne ein Funktion machen, die Hinterher andere Leute einfach in Ihr Programm einbauen können... Und es gibt ja nichts einfacheres als einen Funktionsaufruf... Dass ich das ganze mit Parametern löse ist ja ansich auch kein Problem, es funktioniert ja. Nur das blöde ist dann halt, dass eine Funktion nur einen Rückgabewert haben kann... An einen StringList als Workaround dafür habe ich auch schon gedacht, und das werde ich wohl auch dann als nächstes probieren. Vielen Dank wie gesagt, jetzt werde ich erstmal tüfteln, dass es soweit wie es jetzt ist läuft... Vereinfacht wird wie in Mathe hinterher :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wow, vielen Dank für diese ausführliche Antwort... Das mit der Klasse hatte ich mir auch schon überlegt, aber ich würde gerne ein Funktion machen, die Hinterher andere Leute einfach in Ihr Programm einbauen können... Und es gibt ja nichts einfacheres als einen Funktionsaufruf... Dass ich das ganze mit Parametern löse ist ja ansich auch kein Problem, es funktioniert ja. Nur das blöde ist dann halt, dass eine Funktion nur einen Rückgabewert haben kann... An einen StringList als Workaround dafür habe ich auch schon gedacht, und das werde ich wohl auch dann als nächstes probieren. Vielen Dank wie gesagt, jetzt werde ich erstmal tüfteln, dass es soweit wie es jetzt ist läuft... Vereinfacht wird wie in Mathe hinterher :)

Wenn du den Parser wirklich auch in andere Programme integrierbar machen willst, ist hier Qt für den Parser eigentlich verkehrt. Denn angenommen, jemand will ihn in ein Gtk- oder rein Shell-basiertes Programm integrieren, dann braucht er trotzdem den "Qt-Klotz". Die Online-Demo von FreeHAL könnte es nicht geben, wenn ich nicht reines C++ verwendet hätte - Qt im CGI-Script, das klingt so, als ob ich einen Bleiakkumulaor für Auto in ein Fahrrad einbauen würde, nur der Beleuchtung wegen - Nein, da reichen ein paar kleine Batterien.

Gruß

Tobias

Link zu diesem Kommentar
Auf anderen Seiten teilen

So, ich habe meine Funktion jetzt vom QString zur QStringList abgeändert und es funktioniert alles soweit ganz gut. Nur jetzt habe ich ein Problem. Meine Funktion soll ja, sofern kein Thema gesetzt war und auch innerhalb der Funktion nicht durch ein [sETTOPIC ...] ein Thema gesetzt wurde, logischerweise kein Thema zurückgeben. Also eine StringList mit nur einem einzigen String, der Antwort des Bots. Nur dann habe ich folgendes Problem: Wie erkenne ich hinterher beim Sortieren von Antwort und Thema, was Antwort und was Thema ist? Angenommen das Thema ist immer das letzte Element der QStringList, dann wäre folgendes Möglich:

1: Mir gehts auch gut.

2: Wie geht es Ihnen denn?

3: Gesundheit

Hier würde der PC zwei Strings ausgeben und das thema auf Gesundheit setzen. Wenn nun aber kein Thema gesetzt wird und der PC auf 3 Eingaben antwortet, sähe das ganze so aus:

1: Mir gehts auch gut.

2: Wie geht es Ihnen denn?

3: Ist heute nicht schönes Wetter?

Natürlich sollte hier der dritte String auch ausgegeben werden, aber logischerweise würde er auch als Thema gesetzt werden.

Ich denke mal, ein leeres Element an die StringList anzuhängen wäre unsinnig, ich weiß nicht mal, ob das überhaupt geht... Auch das ganze mit "Thema: " einzuleiten und hinterher wieder rauszulöschen ist sicher nicht so professionell... Wie löse ich das denn am besten?

Link zu diesem Kommentar
Auf anderen Seiten teilen

So, ich habe meine Funktion jetzt vom QString zur QStringList abgeändert und es funktioniert alles soweit ganz gut. Nur jetzt habe ich ein Problem. Meine Funktion soll ja, sofern kein Thema gesetzt war und auch innerhalb der Funktion nicht durch ein [sETTOPIC ...] ein Thema gesetzt wurde, logischerweise kein Thema zurückgeben. Also eine StringList mit nur einem einzigen String, der Antwort des Bots. Nur dann habe ich folgendes Problem: Wie erkenne ich hinterher beim Sortieren von Antwort und Thema, was Antwort und was Thema ist? Angenommen das Thema ist immer das letzte Element der QStringList, dann wäre folgendes Möglich:

1: Mir gehts auch gut.

2: Wie geht es Ihnen denn?

3: Gesundheit

Hier würde der PC zwei Strings ausgeben und das thema auf Gesundheit setzen. Wenn nun aber kein Thema gesetzt wird und der PC auf 3 Eingaben antwortet, sähe das ganze so aus:

1: Mir gehts auch gut.

2: Wie geht es Ihnen denn?

3: Ist heute nicht schönes Wetter?

Natürlich sollte hier der dritte String auch ausgegeben werden, aber logischerweise würde er auch als Thema gesetzt werden.

Ich denke mal, ein leeres Element an die StringList anzuhängen wäre unsinnig, ich weiß nicht mal, ob das überhaupt geht... Auch das ganze mit "Thema: " einzuleiten und hinterher wieder rauszulöschen ist sicher nicht so professionell... Wie löse ich das denn am besten?

Wie du selbst gesagt hast, mit einem leeren String (einfach ein QString Objekt, dem du nichts zugewiesen hast). Oder mit einer Klasse, die aber dann ebenfalls einen leeren String enthalten würde.

Man muss von dem Gedanken wegkommen, eine perfekte API zu erstellen. Mach es so wie es ohne großen Aufwand machbar ist und so, dass der Code möglichst übersichtlich und logisch bleibt. Und wenn das Thema (der QSTring) leer ist, ist eben kein Thema vorhanden.

Gruß

Tobias

Link zu diesem Kommentar
Auf anderen Seiten teilen

Jup, danke, funktioniert jetzt super. Genau so wie ichs mir die Woche über überlegt habe...

Und ansonsten nochmal vielen Dank so überhaupt für die ganze Hilfe und das Testen! Ist wirklich nett :)

Ich werd jetzt wohl erstmal etwas am Inhalt schreiben und dann vielleicht heute oder die kommende Woche mal eine erste "nutzbare" Version hochladen...

Liebe Grüße,

Jonathan

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...

So, mal wieder etwas weitergeschrieben. Ich habe jetzt meinen kompletten parser umgeschrieben, sodass er mit eienr Datenbank funktionieren sollte. Nur jetzt habe ich damit ein ziemlich großes und blödes Problem:

Ich würde gerne eine Disk-basierte Datenbank verwenden, da bietet sich unter QT ja SQLite an. Soweit so gut. Nur ich muss ja auch das Reg-Exp in der Datenbank verstauen und mit dem Befehl "... REGEXP ..." hinterher wieder aus der Datenbank auslesen. Eigentlich unterstützt SQLite ja auch diesen Vergleich, um einen String mit einer Regular Expression aus der Datenbank zu vergleichen, nur dummerweise tut dies nicht die abgespeckte Version, die QT von Hause aus mitbringt. Was mache ich da jetzt? Weil ohne Regexp ist das ganze ja nicht wirklich realisierbar...

Wäre nett, wenn mir jemand helfen könnte :)

Liebe Grüße und einen guten Abend,

Jonathan

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 7 Monate später...

Hallo!

Ich weiß, das Thema hier ist inzwischen lange veraltet. Aber es hat mich einfach wieder überkommen, etwas an "CINA" weiterzubasteln. Als ich mir hier nochmal den Thread durchgelesen habe, ist mir nach und nach mehr klar geworden, dass ich wahrscheinlich falsch angefangen habe. Also; gestern habe ich nochmal ganz neu angefangen und habe jetzt auch schon wieder ein wenig Code. Veränderungen von alt zu neu:

1. Kein Qt mehr, der "Kern" wird ausschließlich in C++ geschrieben. Hinterher kommt eine hübsches Qt Interface dazu, aber nur zur Steuerung des "Kerns".

2. Weg von Mustern; Einfach nur die Eingabe mit einem Regular-Expression-Muster abzugleichen ist nicht so anspruchsvoll und raubt dem Chatbot irgendwie seine Faszination. Also: Jetzt hat das ganze den selben Ansatz wie FreeHal. Natürlich nicht mit dem Ziel, eine Konkurenz darstellen zu wollen (wenn ich das Programm denn überhaupt jemals soweit schaffe!)

Das sind so die zwei maßgeblichen Dinge, die ich jetzt ändern will. Was bis jetzt an dem Projekt auf zwei Beinen steht ist die Satzanalyse: Erkennung von Sätzen anhand von Satzzeichen, Aufteilung in einzelne Wörter und Speicherung in einen Vektor, um damit weiterarbeiten zu können. Was als nächstes kommt ist die Erkennung der Wörter, also welcher Worttyp (Nomen, Prädikat, Adjektiv, Atribut, etc.). Da dies für jede Sprache unterschiedlich ist, kommt ab jetzt auch die Datenbank ins Spiel. Und natürlich poste ich hier nicht aus Zeitvertreib, ich habe nämlich diesbezüglich auch gleich eine Frage:

Gibt es eventuell eine Wörterdatenbank, die man kostenfrei verwenden darf? Also in der alle Wörter der deutschen Sprache verzeichnet sind und deren Worttyp? Weil auch wenn das Programm später selbstlernend ist, sollte es ja wenigstens über einen groben Basiswortschatz verfügen, den es schon kann. (Beispiel: Ein Baby lernt am Anfang mühsam jedes Wort und kann kaum Sätze bilden. Das wird im Laufe der Zeit besser und ab 6 Jahren sollte einfacher Satzbau kein Problem mehr sein. Ich würde diese 6 Jahre in meinem Programm gerne überspringen :P)

Würde mich über Hilfe natürlich wie immer freuen und hoffe es ist mir niemand böse, dass ich diesen Thread wieder aus der Versenkung geholt habe!

Liebe Grüße,

Jonathan

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...