1 TODO (DONE)
-
重构代码,易扩展性
-
加入数据库存储
-
爬虫优化:尝试scrapy框架
-
推荐算法设计
2 问题以及解决
2.1 字体显示问题
- linux中的python无法正常显示中文。
$ cp *.ttf /usr/share/fonts/TTF
$ fc-list | grep |
$ fc-cache -fv # 刷新,f表示force, v表示view
- 查看python安装路径
python交互环境下:
$ import sys
$ sys.path
catfish搜索 从anaconda入手搜索
一步步$ ls $ subl3 查看源码文件
-
包可能存在的目录
/opt/anaconda/lib
~/.conda/envs/python36/lib/python3.6/site-packages
/home/jktian/.conda/envs/python36/lib/python3.6/tkinter/font.py
# 查看tkinter支持的字体
from tkinter import *
import tkinter.font as tkFont
root = Tk()
print(tkFont.families())
- 给linux系统安装中文字体,并找到字体文件的具体位置
- 希望在python-tkinter的库函数中直接按照文件名调用字体;未找到代码实现,即使找到了tkinter的源代码
- 通过tkinter提供的函数,找到支持的系统字体(即当前平台可用的字体),并筛选出支持中文的字体
font_list = ['sampige','likhan','orya','akrutimal2','droid naskh shift alt','gurbanibolilite','pothana2000','tscu_comic','malotf','tscu_times','sagar','padmaa','akaash'] # 不完全
summary
- 不同的图形函数库对跨平台的支持性不同,要选择合适的库进行图形界面的开发。 - 可选项:python:tkinter, pyqt
- 对于字体的支持。不仅要操作系统支持,还要图形函数库的支持,所以只有.ttf文件是不够的
扩展
类比tkinter:css中引入外部字体,使用任意外部字体文件。通过@font-face. 字体文件后缀.TTF/EOT/SVG
css支持引入外部字体文件,但tkinter函数库不支持 在“现代”Linux上 ,有2级字体支持: 第一种是 “native”X支持, 第二个是由图形工具包提供的使用(Qt与KDE,但我认为OpenOffice和FireFox使用Gtk)。 不幸的是,tk - 因此Tkinter - 只看到X处的字体水平,而不是Qt / Gtk水平。
2.2 几个批量操作(自动化)
- 批量创建函数(无问题,每一个函数确实是不同的)
- 批量将按钮和函数关联(由于执行顺序问题,所有按钮都关联到最后一个函数,因为改变了self, 动态类型就是这样)
解决方案: - 不要在一个消息类中创建所有联系人。要创建一个联系人类,每个联系人作为一个实例。 - 本质:类和对象的关系,选择使用要谨慎
-
抽象出联系人类,继承类有Bolt,People,Translator,MovieRecomm类 问题:按钮的转换有问题,由于联系人类是Msg类的成员变量,无法访问并修改Msg类的其他成员变量,所以按钮的对应函数无法正常工作,即无法完成切换联系人功能
- 矛盾点:想要批量操作,逻辑清晰。但作用域存在问题
- 解决方案:将Msg类的实例(即self)传入Msg的成员变量Connector类中,则Connector类可以对Msg实例进行修改
summary
- 面向接口编程。先定义接口,假设底层函数已经写好
2.3 数据库 & 智能回复算法设计
jieba概览
- 分词模式。精确,全、搜索引擎
- 关键词以及其权重提取
- 词性标注-基于分词
目标
- 数据库预处理。得到对应输入和输出,以及其分词以及词性标注
输入 | 输出 | 输入分词 | 输出分词 |
---|---|---|---|
你是谁 | 我是你 | [(你,n),] | [(我,n),] |
- 用户输入数据。分词
- 方案一(已实现):对输入分词,找到和先验输入的距离,根据距离前几的输出以及词性,进行混合输出(每个词性中随机挑选某个输入)。
- 难点:灵活度很大,一句话的组成成分很复杂,可以是动宾短语,可以是整句。词性的组合是难点。
- 理论依据:根据现实中对方的应答,做出回复
- 此处对所有词性的顺序打乱,是否输出按照概率,输出哪一个词按照概率。没有考虑具体如何成句(考虑到网上聊天的随意性,好像此处假设合理)
- 方案二(不合适):数据库预处理,得到新表。对得到的输出句子的重复数目进行统计,挑选前几名,根据词性进行混合
- 方案三(已实现):直接根据输入,和对方的所有输出进行距离计算,算出距离最小的。理论依据:对话的内容相关即可。之后可以根据词性进行混合
- 只能在原有的输出中原样输出
- 方案一(已实现):对输入分词,找到和先验输入的距离,根据距离前几的输出以及词性,进行混合输出(每个词性中随机挑选某个输入)。
(词语,词性) | 可能的输出句子 |
问题:真实的聊天记录不是问答式的,不是单向的,在整个上下文中,问答角色的确立是模糊的。所以很难根据输入确定输出。直接按照名字和话语列表为一行,然后按照周围的其他角色当做回复 |姓名|输入|输入分词|
summary
- 按照框架,搭脚手架
- 根据不同的方案,比对结果
- 理论依据:对话的内容相关即可。之后可以根据词性进行混合
后续研究方向
一个句子的构成是多种多样的,可以由不同类型以及不同顺序的词性构成,但又存在顺序规律,不是完全随机的。需要在几个固定模式下进行随机,效果会更好。未考虑相邻词的联系
数据库选择 & 基本使用
- SQLite: 适合桌面端和移动端,轻量级,可嵌入
- MySQL: 服务器端,支持高并发访问,占用的内存大
- 登录
- 选择数据库
$ show databases $ use database_name
- 选择查看表
desc table_name 查看表结构 在Python中操作数据库时,要先导入数据库对应的驱动,然后,通过Connection对象和Cursor对象操作数据。数据以.db形式存储,读取文件用建立连接的方式。最后conn要提交,关闭
python字符串和列表的转换
数据库中,需要保存分词结果,是一个内部为元组的列表,只能先转换为字符串,然后取出后转换为列表,普通的分隔符无效,需要设置特殊的分隔符。
- 字符串==》list: str.split(‘’) , 直接用list()是按单个字符划分
- 列表==》字符串: ““.join(list), 直接用str()会把[]包含进去
3 最终改动
消息记录的存储
在class_msg.py中的sendmsg函数中,即和发送按钮关联的命令函数中,添加数据库的插入操作,紧跟两个窗口显示消息的操作之后。
智能回复
- 之前是随机数输出,文件操作
- 现在把文件中的内容存储在数据库中。以xiaochen_and_me数据表为例,改动class_conn_people.py中的auto_reply()函数,对fin_msg进行赋值操作
此处并未修改,仍然为随机数输出,但在database_about/intell_reply.py中,做了详细的说明,代码已跑通,有三种算法模式供选择