Python实例题
题目
基于 Python 的简单聊天机器人
要求:
- 使用 Python 构建一个聊天机器人,支持以下功能:
- 基于规则的简单问答系统
- 关键词匹配和意图识别
- 上下文记忆功能
- 支持多轮对话
- 可扩展的知识库
- 使用
tkinter
构建图形用户界面。 - 实现至少 5 个不同领域的问答功能。
解题思路:
- 使用
tkinter
构建界面,包括消息显示区和输入框。 - 设计基于规则的问答引擎,使用关键词匹配和模式识别。
- 实现简单的上下文管理,支持多轮对话。
代码实现:
import tkinter as tk
from tkinter import ttk, scrolledtext
import re
import random
import time
from datetime import datetime
class ChatBot:
def __init__(self, root):
self.root = root
self.root.title("智能聊天机器人")
self.root.geometry("600x700")
# 对话历史
self.chat_history = []
# 上下文记忆
self.context = {}
# 知识库
self.knowledge_base = self._load_knowledge_base()
# 创建主界面
self.create_main_window()
def _load_knowledge_base(self):
"""加载知识库"""
return {
"问候": {
"patterns": ["你好", "hi", "hello", "嗨", "早上好", "中午好", "晚上好"],
"responses": ["你好!有什么我可以帮助你的吗?", "嗨,今天过得怎么样?", "你好呀!", "很高兴见到你!"]
},
"天气": {
"patterns": ["天气", "下雨", "晴天", "温度", "多云"],
"responses": ["我无法实时获取天气信息呢。你可以查看天气预报网站或应用程序。", "天气变化莫测,建议你出门前查看一下天气预报。"]
},
"时间": {
"patterns": ["时间", "几点", "什么时候"],
"responses": ["现在的时间是:{}", "当前时间为:{}"]
},
"姓名": {
"patterns": ["你叫什么", "名字", "称呼"],
"responses": ["我叫智能聊天机器人,你可以叫我小智。", "我是小智,很高兴认识你!"]
},
"爱好": {
"patterns": ["喜欢", "爱好", "兴趣"],
"responses": ["我喜欢和人聊天,了解各种知识!", "我的爱好是回答你的问题,有什么想聊的吗?"]
},
"功能": {
"patterns": ["能做什么", "功能", "可以帮助", "用途"],
"responses": ["我可以回答问题、提供信息、陪你聊天,还可以和你讨论各种话题!", "我是一个多功能聊天机器人,有什么需要我帮忙的吗?"]
},
"再见": {
"patterns": ["再见", "拜拜", "bye", "下次见", "回头见"],
"responses": ["再见!祝你有个愉快的一天!", "期待下次再聊,拜拜!", "bye~"]
},
"感谢": {
"patterns": ["谢谢", "感谢", "感激", "谢谢啦"],
"responses": ["不客气,随时为你服务!", "能帮到你我很开心!", "这是我应该做的!"]
},
"吃饭": {
"patterns": ["吃什么", "推荐食物", "午餐", "晚餐", "早餐"],
"responses": ["今天推荐你尝试一下意大利面,配上红酒和沙拉,非常美味!", "如果你喜欢中餐,可以试试宫保鸡丁和炒饭。", "寿司和刺身也是不错的选择哦!"]
},
"旅游": {
"patterns": ["旅游", "去哪里玩", "推荐景点", "旅行"],
"responses": ["如果你喜欢自然风光,可以考虑去黄山或张家界。", "历史爱好者可以去北京、西安等古都。", "喜欢海滨城市的话,三亚和厦门是不错的选择。"]
},
"学习": {
"patterns": ["学习", "如何学习", "提高成绩", "读书"],
"responses": ["制定合理的学习计划很重要,每天坚持学习一定时间。", "多做练习、总结归纳是提高学习效果的好方法。", "阅读是获取知识的有效途径,建议你多读书。"]
}
}
def create_main_window(self):
"""创建主窗口"""
# 创建顶部标题
ttk.Label(self.root, text="智能聊天机器人", font=('SimHei', 16, 'bold')).pack(pady=10)
# 创建聊天历史显示区域
chat_frame = ttk.LabelFrame(self.root, text="聊天记录")
chat_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
self.chat_display = scrolledtext.ScrolledText(chat_frame, wrap=tk.WORD, state=tk.DISABLED)
self.chat_display.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# 创建输入区域
input_frame = ttk.Frame(self.root)
input_frame.pack(fill=tk.X, padx=10, pady=10)
self.message_var = tk.StringVar()
message_entry = ttk.Entry(input_frame, textvariable=self.message_var, width=50)
message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
message_entry.bind("<Return>", self.send_message)
ttk.Button(input_frame, text="发送", command=self.send_message).pack(side=tk.RIGHT, padx=5)
# 创建状态栏
self.status_var = tk.StringVar(value="就绪")
ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W).pack(side=tk.BOTTOM, fill=tk.X)
# 显示欢迎信息
self._display_message("机器人", "你好!我是智能聊天机器人,有什么可以帮助你的吗?")
def send_message(self, event=None):
"""发送消息"""
message = self.message_var.get().strip()
if not message:
return
# 显示用户消息
self._display_message("你", message)
# 清空输入框
self.message_var.set("")
# 更新状态栏
self.status_var.set("思考中...")
# 在单独的线程中生成回复
threading.Thread(target=self._generate_response, args=(message,)).start()
def _generate_response(self, message):
"""生成回复"""
try:
# 记录对话历史
self.chat_history.append(("你", message))
# 处理消息
response = self._process_message(message)
# 延迟显示,模拟思考
time.sleep(0.5)
# 显示回复
self.root.after(0, lambda: self._display_message("机器人", response))
# 更新状态栏
self.root.after(0, lambda: self.status_var.set("就绪"))
except Exception as e:
self.root.after(0, lambda: self._display_message("机器人", f"抱歉,发生了错误:{str(e)}"))
self.root.after(0, lambda: self.status_var.set("就绪"))
def _process_message(self, message):
"""处理用户消息"""
# 预处理消息
message = message.lower()
# 检查是否有上下文
if 'context' in self.context:
context = self.context['context']
if context == 'time':
# 处理时间相关的上下文
del self.context['context']
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 检查知识库匹配
for category, data in self.knowledge_base.items():
for pattern in data['patterns']:
if re.search(pattern, message):
# 特殊处理时间查询
if category == "时间":
self.context['context'] = 'time'
# 随机选择一个回复
response = random.choice(data['responses'])
# 如果回复中需要填充内容
if "{}" in response:
if category == "时间":
response = response.format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
return response
# 如果没有匹配到任何内容
return "抱歉,我不理解你的问题。你可以换一种表达方式或问我其他问题。"
def _display_message(self, sender, message):
"""显示消息"""
self.chat_display.config(state=tk.NORMAL)
# 添加消息
timestamp = datetime.now().strftime("%H:%M:%S")
self.chat_display.insert(tk.END, f"[{timestamp}] {sender}: {message}\n\n")
# 滚动到底部
self.chat_display.see(tk.END)
# 禁用编辑
self.chat_display.config(state=tk.DISABLED)
if __name__ == "__main__":
root = tk.Tk()
app = ChatBot(root)
root.mainloop()