This commit is contained in:
Iliyan Angelov
2025-12-01 06:50:10 +02:00
parent 91f51bc6fe
commit 62c1fe5951
4682 changed files with 544807 additions and 31208 deletions

View File

@@ -0,0 +1,48 @@
# Natural Language Toolkit: Chatbots
#
# Copyright (C) 2001-2025 NLTK Project
# Authors: Steven Bird <stevenbird1@gmail.com>
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
# Based on an Eliza implementation by Joe Strout <joe@strout.net>,
# Jeff Epler <jepler@inetnebr.com> and Jez Higgins <jez@jezuk.co.uk>.
"""
A class for simple chatbots. These perform simple pattern matching on sentences
typed by users, and respond with automatically generated sentences.
These chatbots may not work using the windows command line or the
windows IDLE GUI.
"""
from nltk.chat.eliza import eliza_chat
from nltk.chat.iesha import iesha_chat
from nltk.chat.rude import rude_chat
from nltk.chat.suntsu import suntsu_chat
from nltk.chat.util import Chat
from nltk.chat.zen import zen_chat
bots = [
(eliza_chat, "Eliza (psycho-babble)"),
(iesha_chat, "Iesha (teen anime junky)"),
(rude_chat, "Rude (abusive bot)"),
(suntsu_chat, "Suntsu (Chinese sayings)"),
(zen_chat, "Zen (gems of wisdom)"),
]
def chatbots():
print("Which chatbot would you like to talk to?")
botcount = len(bots)
for i in range(botcount):
print(" %d: %s" % (i + 1, bots[i][1]))
while True:
choice = input(f"\nEnter a number in the range 1-{botcount}: ").strip()
if choice.isdigit() and (int(choice) - 1) in range(botcount):
break
else:
print(" Error: bad chatbot number")
chatbot = bots[int(choice) - 1][0]
chatbot()

View File

@@ -0,0 +1,337 @@
# Natural Language Toolkit: Eliza
#
# Copyright (C) 2001-2025 NLTK Project
# Authors: Steven Bird <stevenbird1@gmail.com>
# Edward Loper <edloper@gmail.com>
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
# Based on an Eliza implementation by Joe Strout <joe@strout.net>,
# Jeff Epler <jepler@inetnebr.com> and Jez Higgins <mailto:jez@jezuk.co.uk>.
# a translation table used to convert things you say into things the
# computer says back, e.g. "I am" --> "you are"
from nltk.chat.util import Chat, reflections
# a table of response pairs, where each pair consists of a
# regular expression, and a list of possible responses,
# with group-macros labelled as %1, %2.
pairs = (
(
r"I need (.*)",
(
"Why do you need %1?",
"Would it really help you to get %1?",
"Are you sure you need %1?",
),
),
(
r"Why don\'t you (.*)",
(
"Do you really think I don't %1?",
"Perhaps eventually I will %1.",
"Do you really want me to %1?",
),
),
(
r"Why can\'t I (.*)",
(
"Do you think you should be able to %1?",
"If you could %1, what would you do?",
"I don't know -- why can't you %1?",
"Have you really tried?",
),
),
(
r"I can\'t (.*)",
(
"How do you know you can't %1?",
"Perhaps you could %1 if you tried.",
"What would it take for you to %1?",
),
),
(
r"I am (.*)",
(
"Did you come to me because you are %1?",
"How long have you been %1?",
"How do you feel about being %1?",
),
),
(
r"I\'m (.*)",
(
"How does being %1 make you feel?",
"Do you enjoy being %1?",
"Why do you tell me you're %1?",
"Why do you think you're %1?",
),
),
(
r"Are you (.*)",
(
"Why does it matter whether I am %1?",
"Would you prefer it if I were not %1?",
"Perhaps you believe I am %1.",
"I may be %1 -- what do you think?",
),
),
(
r"What (.*)",
(
"Why do you ask?",
"How would an answer to that help you?",
"What do you think?",
),
),
(
r"How (.*)",
(
"How do you suppose?",
"Perhaps you can answer your own question.",
"What is it you're really asking?",
),
),
(
r"Because (.*)",
(
"Is that the real reason?",
"What other reasons come to mind?",
"Does that reason apply to anything else?",
"If %1, what else must be true?",
),
),
(
r"(.*) sorry (.*)",
(
"There are many times when no apology is needed.",
"What feelings do you have when you apologize?",
),
),
(
r"Hello(.*)",
(
"Hello... I'm glad you could drop by today.",
"Hi there... how are you today?",
"Hello, how are you feeling today?",
),
),
(
r"I think (.*)",
("Do you doubt %1?", "Do you really think so?", "But you're not sure %1?"),
),
(
r"(.*) friend (.*)",
(
"Tell me more about your friends.",
"When you think of a friend, what comes to mind?",
"Why don't you tell me about a childhood friend?",
),
),
(r"Yes", ("You seem quite sure.", "OK, but can you elaborate a bit?")),
(
r"(.*) computer(.*)",
(
"Are you really talking about me?",
"Does it seem strange to talk to a computer?",
"How do computers make you feel?",
"Do you feel threatened by computers?",
),
),
(
r"Is it (.*)",
(
"Do you think it is %1?",
"Perhaps it's %1 -- what do you think?",
"If it were %1, what would you do?",
"It could well be that %1.",
),
),
(
r"It is (.*)",
(
"You seem very certain.",
"If I told you that it probably isn't %1, what would you feel?",
),
),
(
r"Can you (.*)",
(
"What makes you think I can't %1?",
"If I could %1, then what?",
"Why do you ask if I can %1?",
),
),
(
r"Can I (.*)",
(
"Perhaps you don't want to %1.",
"Do you want to be able to %1?",
"If you could %1, would you?",
),
),
(
r"You are (.*)",
(
"Why do you think I am %1?",
"Does it please you to think that I'm %1?",
"Perhaps you would like me to be %1.",
"Perhaps you're really talking about yourself?",
),
),
(
r"You\'re (.*)",
(
"Why do you say I am %1?",
"Why do you think I am %1?",
"Are we talking about you, or me?",
),
),
(
r"I don\'t (.*)",
("Don't you really %1?", "Why don't you %1?", "Do you want to %1?"),
),
(
r"I feel (.*)",
(
"Good, tell me more about these feelings.",
"Do you often feel %1?",
"When do you usually feel %1?",
"When you feel %1, what do you do?",
),
),
(
r"I have (.*)",
(
"Why do you tell me that you've %1?",
"Have you really %1?",
"Now that you have %1, what will you do next?",
),
),
(
r"I would (.*)",
(
"Could you explain why you would %1?",
"Why would you %1?",
"Who else knows that you would %1?",
),
),
(
r"Is there (.*)",
(
"Do you think there is %1?",
"It's likely that there is %1.",
"Would you like there to be %1?",
),
),
(
r"My (.*)",
(
"I see, your %1.",
"Why do you say that your %1?",
"When your %1, how do you feel?",
),
),
(
r"You (.*)",
(
"We should be discussing you, not me.",
"Why do you say that about me?",
"Why do you care whether I %1?",
),
),
(r"Why (.*)", ("Why don't you tell me the reason why %1?", "Why do you think %1?")),
(
r"I want (.*)",
(
"What would it mean to you if you got %1?",
"Why do you want %1?",
"What would you do if you got %1?",
"If you got %1, then what would you do?",
),
),
(
r"(.*) mother(.*)",
(
"Tell me more about your mother.",
"What was your relationship with your mother like?",
"How do you feel about your mother?",
"How does this relate to your feelings today?",
"Good family relations are important.",
),
),
(
r"(.*) father(.*)",
(
"Tell me more about your father.",
"How did your father make you feel?",
"How do you feel about your father?",
"Does your relationship with your father relate to your feelings today?",
"Do you have trouble showing affection with your family?",
),
),
(
r"(.*) child(.*)",
(
"Did you have close friends as a child?",
"What is your favorite childhood memory?",
"Do you remember any dreams or nightmares from childhood?",
"Did the other children sometimes tease you?",
"How do you think your childhood experiences relate to your feelings today?",
),
),
(
r"(.*)\?",
(
"Why do you ask that?",
"Please consider whether you can answer your own question.",
"Perhaps the answer lies within yourself?",
"Why don't you tell me?",
),
),
(
r"quit",
(
"Thank you for talking with me.",
"Good-bye.",
"Thank you, that will be $150. Have a good day!",
),
),
(
r"(.*)",
(
"Please tell me more.",
"Let's change focus a bit... Tell me about your family.",
"Can you elaborate on that?",
"Why do you say that %1?",
"I see.",
"Very interesting.",
"%1.",
"I see. And what does that tell you?",
"How does that make you feel?",
"How do you feel when you say that?",
),
),
)
eliza_chatbot = Chat(pairs, reflections)
def eliza_chat():
print("Therapist\n---------")
print("Talk to the program by typing in plain English, using normal upper-")
print('and lower-case letters and punctuation. Enter "quit" when done.')
print("=" * 72)
print("Hello. How are you feeling today?")
eliza_chatbot.converse()
def demo():
eliza_chat()
if __name__ == "__main__":
eliza_chat()

View File

@@ -0,0 +1,160 @@
# Natural Language Toolkit: Teen Chatbot
#
# Copyright (C) 2001-2025 NLTK Project
# Author: Selina Dennis <sjmd@csse.unimelb.edu.au>
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
"""
This chatbot is a tongue-in-cheek take on the average teen
anime junky that frequents YahooMessenger or MSNM.
All spelling mistakes and flawed grammar are intentional.
"""
from nltk.chat.util import Chat
reflections = {
"am": "r",
"was": "were",
"i": "u",
"i'd": "u'd",
"i've": "u'v",
"ive": "u'v",
"i'll": "u'll",
"my": "ur",
"are": "am",
"you're": "im",
"you've": "ive",
"you'll": "i'll",
"your": "my",
"yours": "mine",
"you": "me",
"u": "me",
"ur": "my",
"urs": "mine",
"me": "u",
}
# Note: %1/2/etc are used without spaces prior as the chat bot seems
# to add a superfluous space when matching.
pairs = (
(
r"I\'m (.*)",
(
"ur%1?? that's so cool! kekekekeke ^_^ tell me more!",
"ur%1? neat!! kekeke >_<",
),
),
(
r"(.*) don\'t you (.*)",
(
r"u think I can%2??! really?? kekeke \<_\<",
"what do u mean%2??!",
"i could if i wanted, don't you think!! kekeke",
),
),
(r"ye[as] [iI] (.*)", ("u%1? cool!! how?", "how come u%1??", "u%1? so do i!!")),
(
r"do (you|u) (.*)\??",
("do i%2? only on tuesdays! kekeke *_*", "i dunno! do u%2??"),
),
(
r"(.*)\?",
(
"man u ask lots of questions!",
"booooring! how old r u??",
"boooooring!! ur not very fun",
),
),
(
r"(cos|because) (.*)",
("hee! i don't believe u! >_<", "nuh-uh! >_<", "ooooh i agree!"),
),
(
r"why can\'t [iI] (.*)",
(
"i dunno! y u askin me for!",
"try harder, silly! hee! ^_^",
"i dunno! but when i can't%1 i jump up and down!",
),
),
(
r"I can\'t (.*)",
(
"u can't what??! >_<",
"that's ok! i can't%1 either! kekekekeke ^_^",
"try harder, silly! hee! ^&^",
),
),
(
r"(.*) (like|love|watch) anime",
(
"omg i love anime!! do u like sailor moon??! ^&^",
"anime yay! anime rocks sooooo much!",
"oooh anime! i love anime more than anything!",
"anime is the bestest evar! evangelion is the best!",
"hee anime is the best! do you have ur fav??",
),
),
(
r"I (like|love|watch|play) (.*)",
("yay! %2 rocks!", "yay! %2 is neat!", "cool! do u like other stuff?? ^_^"),
),
(
r"anime sucks|(.*) (hate|detest) anime",
(
"ur a liar! i'm not gonna talk to u nemore if u h8 anime *;*",
"no way! anime is the best ever!",
"nuh-uh, anime is the best!",
),
),
(
r"(are|r) (you|u) (.*)",
("am i%1??! how come u ask that!", "maybe! y shud i tell u?? kekeke >_>"),
),
(
r"what (.*)",
("hee u think im gonna tell u? .v.", "booooooooring! ask me somethin else!"),
),
(r"how (.*)", ("not tellin!! kekekekekeke ^_^",)),
(r"(hi|hello|hey) (.*)", ("hi!!! how r u!!",)),
(
r"quit",
(
"mom says i have to go eat dinner now :,( bye!!",
"awww u have to go?? see u next time!!",
"how to see u again soon! ^_^",
),
),
(
r"(.*)",
(
"ur funny! kekeke",
"boooooring! talk about something else! tell me wat u like!",
"do u like anime??",
"do u watch anime? i like sailor moon! ^_^",
"i wish i was a kitty!! kekekeke ^_^",
),
),
)
iesha_chatbot = Chat(pairs, reflections)
def iesha_chat():
print("Iesha the TeenBoT\n---------")
print("Talk to the program by typing in plain English, using normal upper-")
print('and lower-case letters and punctuation. Enter "quit" when done.')
print("=" * 72)
print("hi!! i'm iesha! who r u??!")
iesha_chatbot.converse()
def demo():
iesha_chat()
if __name__ == "__main__":
demo()

View File

@@ -0,0 +1,125 @@
# Natural Language Toolkit: Rude Chatbot
#
# Copyright (C) 2001-2025 NLTK Project
# Author: Peter Spiller <pspiller@csse.unimelb.edu.au>
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
from nltk.chat.util import Chat, reflections
pairs = (
(
r"We (.*)",
(
"What do you mean, 'we'?",
"Don't include me in that!",
"I wouldn't be so sure about that.",
),
),
(
r"You should (.*)",
("Don't tell me what to do, buddy.", "Really? I should, should I?"),
),
(
r"You\'re(.*)",
(
"More like YOU'RE %1!",
"Hah! Look who's talking.",
"Come over here and tell me I'm %1.",
),
),
(
r"You are(.*)",
(
"More like YOU'RE %1!",
"Hah! Look who's talking.",
"Come over here and tell me I'm %1.",
),
),
(
r"I can\'t(.*)",
(
"You do sound like the type who can't %1.",
"Hear that splashing sound? That's my heart bleeding for you.",
"Tell somebody who might actually care.",
),
),
(
r"I think (.*)",
(
"I wouldn't think too hard if I were you.",
"You actually think? I'd never have guessed...",
),
),
(
r"I (.*)",
(
"I'm getting a bit tired of hearing about you.",
"How about we talk about me instead?",
"Me, me, me... Frankly, I don't care.",
),
),
(
r"How (.*)",
(
"How do you think?",
"Take a wild guess.",
"I'm not even going to dignify that with an answer.",
),
),
(r"What (.*)", ("Do I look like an encyclopedia?", "Figure it out yourself.")),
(
r"Why (.*)",
(
"Why not?",
"That's so obvious I thought even you'd have already figured it out.",
),
),
(
r"(.*)shut up(.*)",
(
"Make me.",
"Getting angry at a feeble NLP assignment? Somebody's losing it.",
"Say that again, I dare you.",
),
),
(
r"Shut up(.*)",
(
"Make me.",
"Getting angry at a feeble NLP assignment? Somebody's losing it.",
"Say that again, I dare you.",
),
),
(
r"Hello(.*)",
("Oh good, somebody else to talk to. Joy.", "'Hello'? How original..."),
),
(
r"(.*)",
(
"I'm getting bored here. Become more interesting.",
"Either become more thrilling or get lost, buddy.",
"Change the subject before I die of fatal boredom.",
),
),
)
rude_chatbot = Chat(pairs, reflections)
def rude_chat():
print("Talk to the program by typing in plain English, using normal upper-")
print('and lower-case letters and punctuation. Enter "quit" when done.')
print("=" * 72)
print("I suppose I should say hello.")
rude_chatbot.converse()
def demo():
rude_chat()
if __name__ == "__main__":
demo()

View File

@@ -0,0 +1,140 @@
# Natural Language Toolkit: Sun Tsu-Bot
#
# Copyright (C) 2001-2025 NLTK Project
# Author: Sam Huston 2007
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
"""
Tsu bot responds to all queries with a Sun Tsu sayings
Quoted from Sun Tsu's The Art of War
Translated by LIONEL GILES, M.A. 1910
Hosted by the Gutenberg Project
https://www.gutenberg.org/
"""
from nltk.chat.util import Chat, reflections
pairs = (
(r"quit", ("Good-bye.", "Plan well", "May victory be your future")),
(
r"[^\?]*\?",
(
"Please consider whether you can answer your own question.",
"Ask me no questions!",
),
),
(
r"[0-9]+(.*)",
(
"It is the rule in war, if our forces are ten to the enemy's one, to surround him; if five to one, to attack him; if twice as numerous, to divide our army into two.",
"There are five essentials for victory",
),
),
(
r"[A-Ca-c](.*)",
(
"The art of war is of vital importance to the State.",
"All warfare is based on deception.",
"If your opponent is secure at all points, be prepared for him. If he is in superior strength, evade him.",
"If the campaign is protracted, the resources of the State will not be equal to the strain.",
"Attack him where he is unprepared, appear where you are not expected.",
"There is no instance of a country having benefited from prolonged warfare.",
),
),
(
r"[D-Fd-f](.*)",
(
"The skillful soldier does not raise a second levy, neither are his supply-wagons loaded more than twice.",
"Bring war material with you from home, but forage on the enemy.",
"In war, then, let your great object be victory, not lengthy campaigns.",
"To fight and conquer in all your battles is not supreme excellence; supreme excellence consists in breaking the enemy's resistance without fighting.",
),
),
(
r"[G-Ig-i](.*)",
(
"Heaven signifies night and day, cold and heat, times and seasons.",
"It is the rule in war, if our forces are ten to the enemy's one, to surround him; if five to one, to attack him; if twice as numerous, to divide our army into two.",
"The good fighters of old first put themselves beyond the possibility of defeat, and then waited for an opportunity of defeating the enemy.",
"One may know how to conquer without being able to do it.",
),
),
(
r"[J-Lj-l](.*)",
(
"There are three ways in which a ruler can bring misfortune upon his army.",
"By commanding the army to advance or to retreat, being ignorant of the fact that it cannot obey. This is called hobbling the army.",
"By attempting to govern an army in the same way as he administers a kingdom, being ignorant of the conditions which obtain in an army. This causes restlessness in the soldier's minds.",
"By employing the officers of his army without discrimination, through ignorance of the military principle of adaptation to circumstances. This shakes the confidence of the soldiers.",
"There are five essentials for victory",
"He will win who knows when to fight and when not to fight.",
"He will win who knows how to handle both superior and inferior forces.",
"He will win whose army is animated by the same spirit throughout all its ranks.",
"He will win who, prepared himself, waits to take the enemy unprepared.",
"He will win who has military capacity and is not interfered with by the sovereign.",
),
),
(
r"[M-Om-o](.*)",
(
"If you know the enemy and know yourself, you need not fear the result of a hundred battles.",
"If you know yourself but not the enemy, for every victory gained you will also suffer a defeat.",
"If you know neither the enemy nor yourself, you will succumb in every battle.",
"The control of a large force is the same principle as the control of a few men: it is merely a question of dividing up their numbers.",
),
),
(
r"[P-Rp-r](.*)",
(
"Security against defeat implies defensive tactics; ability to defeat the enemy means taking the offensive.",
"Standing on the defensive indicates insufficient strength; attacking, a superabundance of strength.",
"He wins his battles by making no mistakes. Making no mistakes is what establishes the certainty of victory, for it means conquering an enemy that is already defeated.",
"A victorious army opposed to a routed one, is as a pound's weight placed in the scale against a single grain.",
"The onrush of a conquering force is like the bursting of pent-up waters into a chasm a thousand fathoms deep.",
),
),
(
r"[S-Us-u](.*)",
(
"What the ancients called a clever fighter is one who not only wins, but excels in winning with ease.",
"Hence his victories bring him neither reputation for wisdom nor credit for courage.",
"Hence the skillful fighter puts himself into a position which makes defeat impossible, and does not miss the moment for defeating the enemy.",
"In war the victorious strategist only seeks battle after the victory has been won, whereas he who is destined to defeat first fights and afterwards looks for victory.",
"There are not more than five musical notes, yet the combinations of these five give rise to more melodies than can ever be heard.",
"Appear at points which the enemy must hasten to defend; march swiftly to places where you are not expected.",
),
),
(
r"[V-Zv-z](.*)",
(
"It is a matter of life and death, a road either to safety or to ruin.",
"Hold out baits to entice the enemy. Feign disorder, and crush him.",
"All men can see the tactics whereby I conquer, but what none can see is the strategy out of which victory is evolved.",
"Do not repeat the tactics which have gained you one victory, but let your methods be regulated by the infinite variety of circumstances.",
"So in war, the way is to avoid what is strong and to strike at what is weak.",
"Just as water retains no constant shape, so in warfare there are no constant conditions.",
),
),
(r"(.*)", ("Your statement insults me.", "")),
)
suntsu_chatbot = Chat(pairs, reflections)
def suntsu_chat():
print("Talk to the program by typing in plain English, using normal upper-")
print('and lower-case letters and punctuation. Enter "quit" when done.')
print("=" * 72)
print("You seek enlightenment?")
suntsu_chatbot.converse()
def demo():
suntsu_chat()
if __name__ == "__main__":
demo()

View File

@@ -0,0 +1,124 @@
# Natural Language Toolkit: Chatbot Utilities
#
# Copyright (C) 2001-2025 NLTK Project
# Authors: Steven Bird <stevenbird1@gmail.com>
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
# Based on an Eliza implementation by Joe Strout <joe@strout.net>,
# Jeff Epler <jepler@inetnebr.com> and Jez Higgins <jez@jezuk.co.uk>.
import random
import re
reflections = {
"i am": "you are",
"i was": "you were",
"i": "you",
"i'm": "you are",
"i'd": "you would",
"i've": "you have",
"i'll": "you will",
"my": "your",
"you are": "I am",
"you were": "I was",
"you've": "I have",
"you'll": "I will",
"your": "my",
"yours": "mine",
"you": "me",
"me": "you",
}
class Chat:
def __init__(self, pairs, reflections={}):
"""
Initialize the chatbot. Pairs is a list of patterns and responses. Each
pattern is a regular expression matching the user's statement or question,
e.g. r'I like (.*)'. For each such pattern a list of possible responses
is given, e.g. ['Why do you like %1', 'Did you ever dislike %1']. Material
which is matched by parenthesized sections of the patterns (e.g. .*) is mapped to
the numbered positions in the responses, e.g. %1.
:type pairs: list of tuple
:param pairs: The patterns and responses
:type reflections: dict
:param reflections: A mapping between first and second person expressions
:rtype: None
"""
self._pairs = [(re.compile(x, re.IGNORECASE), y) for (x, y) in pairs]
self._reflections = reflections
self._regex = self._compile_reflections()
def _compile_reflections(self):
sorted_refl = sorted(self._reflections, key=len, reverse=True)
return re.compile(
r"\b({})\b".format("|".join(map(re.escape, sorted_refl))), re.IGNORECASE
)
def _substitute(self, str):
"""
Substitute words in the string, according to the specified reflections,
e.g. "I'm" -> "you are"
:type str: str
:param str: The string to be mapped
:rtype: str
"""
return self._regex.sub(
lambda mo: self._reflections[mo.string[mo.start() : mo.end()]], str.lower()
)
def _wildcards(self, response, match):
pos = response.find("%")
while pos >= 0:
num = int(response[pos + 1 : pos + 2])
response = (
response[:pos]
+ self._substitute(match.group(num))
+ response[pos + 2 :]
)
pos = response.find("%")
return response
def respond(self, str):
"""
Generate a response to the user input.
:type str: str
:param str: The string to be mapped
:rtype: str
"""
# check each pattern
for pattern, response in self._pairs:
match = pattern.match(str)
# did the pattern match?
if match:
resp = random.choice(response) # pick a random response
resp = self._wildcards(resp, match) # process wildcards
# fix munged punctuation at the end
if resp[-2:] == "?.":
resp = resp[:-2] + "."
if resp[-2:] == "??":
resp = resp[:-2] + "?"
return resp
# Hold a conversation with a chatbot
def converse(self, quit="quit"):
user_input = ""
while user_input != quit:
user_input = quit
try:
user_input = input(">")
except EOFError:
print(user_input)
if user_input:
while user_input[-1] in "!.":
user_input = user_input[:-1]
print(self.respond(user_input))

View File

@@ -0,0 +1,329 @@
# Natural Language Toolkit: Zen Chatbot
#
# Copyright (C) 2001-2025 NLTK Project
# Author: Amy Holland <amyrh@csse.unimelb.edu.au>
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
"""
Zen Chatbot talks in gems of Zen wisdom.
This is a sample conversation with Zen Chatbot:
ZC: Welcome, my child.
me: Good afternoon.
ZC: Ask the question you have come to ask.
me: How can I achieve enlightenment?
ZC: How do you suppose?
me: Through meditation.
ZC: Form is emptiness, and emptiness form.
me: How can I empty my mind of worldly troubles?
ZC: Will an answer to that really help in your search for enlightenment?
me: Yes.
ZC: It is better to be right than to be certain.
me: I seek truth and wisdom.
ZC: The search for truth is a long journey.
me: Are you sure?
ZC: Maybe sure, maybe not sure.
The chatbot structure is based on that of chat.eliza. Thus, it uses
a translation table to convert from question to response
i.e. "I am" --> "you are"
Of course, since Zen Chatbot does not understand the meaning of any words,
responses are very limited. Zen Chatbot will usually answer very vaguely, or
respond to a question by asking a different question, in much the same way
as Eliza.
"""
from nltk.chat.util import Chat, reflections
# responses are matched top to bottom, so non-specific matches occur later
# for each match, a list of possible responses is provided
responses = (
# Zen Chatbot opens with the line "Welcome, my child." The usual
# response will be a greeting problem: 'good' matches "good morning",
# "good day" etc, but also "good grief!" and other sentences starting
# with the word 'good' that may not be a greeting
(
r"(hello(.*))|(good [a-zA-Z]+)",
(
"The path to enlightenment is often difficult to see.",
"Greetings. I sense your mind is troubled. Tell me of your troubles.",
"Ask the question you have come to ask.",
"Hello. Do you seek englightenment?",
),
),
# "I need" and "I want" can be followed by a thing (eg 'help')
# or an action (eg 'to see you')
#
# This is a problem with this style of response -
# person: "I need you"
# chatbot: "me can be achieved by hard work and dedication of the mind"
# i.e. 'you' is not really a thing that can be mapped this way, so this
# interpretation only makes sense for some inputs
#
(
r"i need (.*)",
(
"%1 can be achieved by hard work and dedication of the mind.",
"%1 is not a need, but a desire of the mind. Clear your mind of such concerns.",
"Focus your mind on%1, and you will find what you need.",
),
),
(
r"i want (.*)",
(
"Desires of the heart will distract you from the path to enlightenment.",
"Will%1 help you attain enlightenment?",
"Is%1 a desire of the mind, or of the heart?",
),
),
# why questions are separated into three types:
# "why..I" e.g. "why am I here?" "Why do I like cake?"
# "why..you" e.g. "why are you here?" "Why won't you tell me?"
# "why..." e.g. "Why is the sky blue?"
# problems:
# person: "Why can't you tell me?"
# chatbot: "Are you sure I tell you?"
# - this style works for positives (e.g. "why do you like cake?")
# but does not work for negatives (e.g. "why don't you like cake?")
(r"why (.*) i (.*)\?", ("You%1%2?", "Perhaps you only think you%1%2")),
(r"why (.*) you(.*)\?", ("Why%1 you%2?", "%2 I%1", "Are you sure I%2?")),
(r"why (.*)\?", ("I cannot tell you why%1.", "Why do you think %1?")),
# e.g. "are you listening?", "are you a duck"
(
r"are you (.*)\?",
("Maybe%1, maybe not%1.", "Whether I am%1 or not is God's business."),
),
# e.g. "am I a duck?", "am I going to die?"
(
r"am i (.*)\?",
("Perhaps%1, perhaps not%1.", "Whether you are%1 or not is not for me to say."),
),
# what questions, e.g. "what time is it?"
# problems:
# person: "What do you want?"
# chatbot: "Seek truth, not what do me want."
(r"what (.*)\?", ("Seek truth, not what%1.", "What%1 should not concern you.")),
# how questions, e.g. "how do you do?"
(
r"how (.*)\?",
(
"How do you suppose?",
"Will an answer to that really help in your search for enlightenment?",
"Ask yourself not how, but why.",
),
),
# can questions, e.g. "can you run?", "can you come over here please?"
(
r"can you (.*)\?",
(
"I probably can, but I may not.",
"Maybe I can%1, and maybe I cannot.",
"I can do all, and I can do nothing.",
),
),
# can questions, e.g. "can I have some cake?", "can I know truth?"
(
r"can i (.*)\?",
(
"You can%1 if you believe you can%1, and have a pure spirit.",
"Seek truth and you will know if you can%1.",
),
),
# e.g. "It is raining" - implies the speaker is certain of a fact
(
r"it is (.*)",
(
"How can you be certain that%1, when you do not even know yourself?",
"Whether it is%1 or not does not change the way the world is.",
),
),
# e.g. "is there a doctor in the house?"
(
r"is there (.*)\?",
("There is%1 if you believe there is.", "It is possible that there is%1."),
),
# e.g. "is it possible?", "is this true?"
(r"is(.*)\?", ("%1 is not relevant.", "Does this matter?")),
# non-specific question
(
r"(.*)\?",
(
"Do you think %1?",
"You seek the truth. Does the truth seek you?",
"If you intentionally pursue the answers to your questions, the answers become hard to see.",
"The answer to your question cannot be told. It must be experienced.",
),
),
# expression of hate of form "I hate you" or "Kelly hates cheese"
(
r"(.*) (hate[s]?)|(dislike[s]?)|(don\'t like)(.*)",
(
"Perhaps it is not about hating %2, but about hate from within.",
"Weeds only grow when we dislike them",
"Hate is a very strong emotion.",
),
),
# statement containing the word 'truth'
(
r"(.*) truth(.*)",
(
"Seek truth, and truth will seek you.",
"Remember, it is not the spoon which bends - only yourself.",
"The search for truth is a long journey.",
),
),
# desire to do an action
# e.g. "I want to go shopping"
(
r"i want to (.*)",
("You may %1 if your heart truly desires to.", "You may have to %1."),
),
# desire for an object
# e.g. "I want a pony"
(
r"i want (.*)",
(
"Does your heart truly desire %1?",
"Is this a desire of the heart, or of the mind?",
),
),
# e.g. "I can't wait" or "I can't do this"
(
r"i can\'t (.*)",
(
"What we can and can't do is a limitation of the mind.",
"There are limitations of the body, and limitations of the mind.",
"Have you tried to%1 with a clear mind?",
),
),
# "I think.." indicates uncertainty. e.g. "I think so."
# problem: exceptions...
# e.g. "I think, therefore I am"
(
r"i think (.*)",
(
"Uncertainty in an uncertain world.",
"Indeed, how can we be certain of anything in such uncertain times.",
"Are you not, in fact, certain that%1?",
),
),
# "I feel...emotions/sick/light-headed..."
(
r"i feel (.*)",
(
"Your body and your emotions are both symptoms of your mind."
"What do you believe is the root of such feelings?",
"Feeling%1 can be a sign of your state-of-mind.",
),
),
# exclaimation mark indicating emotion
# e.g. "Wow!" or "No!"
(
r"(.*)!",
(
"I sense that you are feeling emotional today.",
"You need to calm your emotions.",
),
),
# because [statement]
# e.g. "because I said so"
(
r"because (.*)",
(
"Does knowning the reasons behind things help you to understand"
" the things themselves?",
"If%1, what else must be true?",
),
),
# yes or no - raise an issue of certainty/correctness
(
r"(yes)|(no)",
(
"Is there certainty in an uncertain world?",
"It is better to be right than to be certain.",
),
),
# sentence containing word 'love'
(
r"(.*)love(.*)",
(
"Think of the trees: they let the birds perch and fly with no intention to call them when they come, and no longing for their return when they fly away. Let your heart be like the trees.",
"Free love!",
),
),
# sentence containing word 'understand' - r
(
r"(.*)understand(.*)",
(
"If you understand, things are just as they are;"
" if you do not understand, things are just as they are.",
"Imagination is more important than knowledge.",
),
),
# 'I', 'me', 'my' - person is talking about themself.
# this breaks down when words contain these - eg 'Thyme', 'Irish'
(
r"(.*)(me )|( me)|(my)|(mine)|(i)(.*)",
(
"'I', 'me', 'my'... these are selfish expressions.",
"Have you ever considered that you might be a selfish person?",
"Try to consider others, not just yourself.",
"Think not just of yourself, but of others.",
),
),
# 'you' starting a sentence
# e.g. "you stink!"
(
r"you (.*)",
("My path is not of concern to you.", "I am but one, and you but one more."),
),
# say goodbye with some extra Zen wisdom.
(
r"exit",
(
"Farewell. The obstacle is the path.",
"Farewell. Life is a journey, not a destination.",
"Good bye. We are cups, constantly and quietly being filled."
"\nThe trick is knowning how to tip ourselves over and let the beautiful stuff out.",
),
),
# fall through case -
# when stumped, respond with generic zen wisdom
#
(
r"(.*)",
(
"When you're enlightened, every word is wisdom.",
"Random talk is useless.",
"The reverse side also has a reverse side.",
"Form is emptiness, and emptiness is form.",
"I pour out a cup of water. Is the cup empty?",
),
),
)
zen_chatbot = Chat(responses, reflections)
def zen_chat():
print("*" * 75)
print("Zen Chatbot!".center(75))
print("*" * 75)
print('"Look beyond mere words and letters - look into your mind"'.center(75))
print("* Talk your way to truth with Zen Chatbot.")
print("* Type 'quit' when you have had enough.")
print("*" * 75)
print("Welcome, my child.")
zen_chatbot.converse()
def demo():
zen_chat()
if __name__ == "__main__":
demo()