利用Python实现桌面小部件——ECDICT与单词查询实现

一、ECDICT简介

        ECDICT是一个免费开源的中英词典数据库,收录了数十万条单词。如果想让桌面小部件在离线状态下方便简介的查询单词,使用自带的词库无疑是最佳选择。

        ECDICT提供了Python的编程接口,可以方便快速的查询单词。此外,ECDICT也提供了单词的词性变化、标签(四六级)等信息,具体可以去github上寻找项目浏览README.md文档。

        由于编程接口的存在,其使用也异常简单,这里以类DictCsv为例:

    def loadWordVisitor(self):
        self.par.isLoading = True
        self.par.wordVisitor = DictCsv('ecdict.csv')
        self.par.vocab = set(words.words())
        self.par.isLoading = False

        注意这里真正有关ECDICT的代码只有第三行,创建一个单词管理器。之所以有其他内容,是因为加载数据库较为耗时,需要放在线程中避免阻塞应用运行,同时在加载期间设置加载标签为True,用于禁止用户的查询操作。vocab用于模糊匹配单词,后面会讲到。

    def query(self):
        # 检查是否有加载操作正在进行,如果有,则不执行查询
        if self.par.isLoading or self.par.isMatchingWord:
            return
        # 获取线编辑框中的文本内容
        self.text = self.lineeditQuery.text()
        # 更新界面中的单词显示区域的文本
        self.showWord.text = self.text
        # 使用查询的文本,将结果设置到单词显示逻辑中
        self.showWord.setWordLogic(self.par.wordVisitor.query(self.text))
        # 确保单词显示区域可见
        self.showWord.show()

        使用时只需要调用DictCsv类实例的query方法,便能查询相应单词,返回一个字典,包含单词序号、汉译、词性变换等众多信息。

二、模糊匹配

        ECDICT提供了模糊匹配单词的功能,但貌似只能匹配开头字母一致的一系列单词,应该是为了防止用户查询时单词形态出现问题。笔者希望能进一步完善这一功能,比如即便用户输入pronouncation,桌面部件也能给出正确的pronunciation。

        为了实现这一目标,这里使用了nltk库,nltk库提供了edit_distance方法计算两个字符串之间的相似度,同时提供了一个英语词库(即上文的vocab,仅有单词,没有其它冗余元素),由于用户输入的不确定性,在直接查询失败时,最好是逐一计算相似度取最大值,经实测,匹配一个单词需要十数秒,这显然是无法接受的。但是如果采取一些前置条件:

    def matchWord(self, word):
        self.par.isMatchingWord = True
        # 初始化最小编辑距离和当前单词
        minDistance = edit_distance('natsuki', word)  # 默认初始化为 'nasuki' 到输入单词的距离
        current_word = ''
        # 遍历词汇表以找到与输入单词编辑距离最小的单词
        for w in self.par.vocab:
            # 如果单词长度差异大于等于3,则跳过
            if abs(len(word) - len(w)) >= 3:
                continue
            # 单词长度大于等于2时,检查首字母或次字母是否匹配
            if len(w) >= 2 and len(word) >= 2:
                if word[0] != w[0] and word[1] != w[0]:
                    continue
                # 单词长度大于等于4时,检查末字母或倒数第二字母是否匹配
                if len(w) >= 4 and len(word) >= 4:
                    if word[-1] != w[-1] and word[-2] != w[-2]:
                        continue
            # 计算当前单词与输入单词的编辑距离
            distance = edit_distance(word, w)
            # 如果当前距离小于最小距离,更新最小距离和当前单词
            if distance < minDistance:
                minDistance = distance
                current_word = w
        # 如果当前单词不为空,写入推测结果,询问用户是否是指定的单词
        if current_word != '':
            self.writeOutput(f'你想找的是不是 <span style="color: #00ff00;">{current_word}</span>?')
        # 调用逻辑处理函数,传递当前单词的查询结果
        self.setWordLogic(self.par.wordVisitor.query(current_word), True)
        self.par.isMatchingWord = False

        通过默认用户希望匹配的单词与输入差异小于3以及首尾两字母是否大致对应,可以将延迟减少到用户难以察觉的程度。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值