pickleの空ファイルを作ろうと思ってうっかりテキストエディタで何も書いてないファイルを作ったらエラーが出て、原因を特定するのに随分と時間がかかってしまった。 まあ、後から考えてみればあたりまえなんだけど、簡単には気付けなかった。
で、空ファイルを作るツールを作成した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import pickle ls = [] dic = {'':['']} with open('random.pkl', 'wb') as fw: pickle.dump(ls, fw) with open('pattern.pkl', 'wb') as fw: pickle.dump(dic, fw) with open('random.pkl', 'rb') as fr: rls = pickle.load(fr) print(rls) with open('pattern.pkl', 'rb') as fr: rdic = pickle.load(fr) print(rdic) |
辞書はデータ型が特定できるようにしておかないとエラーになる。 C#だとあらかじめ型を明示しておくのでエラーにはなり難いけど、Pythonになれていないとうっかりエラーになる。
で、最新のChatoBotのソース。 ちょこちょこ変更しているので、全部アップしておく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import tkinter as tk import tkinter.scrolledtext as tkst import chatbotC as chat def prompt(unmo): unname = proto.name respname = proto.resp_name() return f'{unname}:{respname} >' def press_ent(event): in_txt = ent.get() txt.insert(tk.END, '> ' + in_txt + '\n') respose = proto.dialog(in_txt) proto.study(in_txt) txt.insert(tk.END, prompt(proto) + respose + '\n') txt.see('end') ent.delete(0, tk.END) def show_txt(tt): txt.insert(tk.END, tt + '\n') def click_close(): proto.savedic() root.destroy() root = tk.Tk() root.title('和文ボット') root.config(width=500, height=400) txt = tkst.ScrolledText(relief='sunken', bg='lightgreen', font=('', 18), bd=5) txt.place(x=10, y=10, width=480, height=300) ent = tk.Entry(relief='sunken', font=('', 18), bd=5) ent.place(x=10, y=340, width=460) ent.bind('<Return>', press_ent) ent.focus_set() proto = chat.ChatBot('Unmo') show_txt('Unmo System') root.protocol('WM_DELETE_WINDOW', click_close) root.mainloop() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import responderC as res import dicsC as dictsc import random class ChatBot(): def __init__(self, name): self.name = name self.dicts = dictsc.Dicts() self.resp_what = res.WhatResponder('ナニ') rnddic = self.dicts.getradomdic() self.resp_rand = res.RandomResponder('ランダム', rnddic) patdic = self.dicts.getpatterndic() self.resp_pattern = res.PatternResponder('パターン', patdic) self.responder = res.Responder('') self.nn = 0 def dialog(self, txt): self.nn = random.randint(0,2) if self.nn == 0: self.responder = self.resp_what elif self.nn == 1: self.responder = self.resp_rand elif self.nn == 2: self.responder = self.resp_pattern return self.responder.response(txt) def study(self, tt): self.dicts.study(tt) def savedic(self): self.dicts.save() def resp_name(self): return self.responder.name |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import random import morphC as Mp class Responder(): def __init__(self, name): self.name = name def response(self, input_text): return '' class WhatResponder(Responder): def __init__(self, name): super().__init__(name) def response(self, input_text): return input_text + 'って何?' class RandomResponder(Responder): def __init__(self, name, dic): super().__init__(name) self.dic = dic def response(self, input_text): outtxt ='' if len(self.dic) > 0: outtxt = self.dic[random.randint(0, len(self.dic)-1)] return outtxt class PatternResponder(Responder): def __init__(self, name, dic): super().__init__(name) self.dic = dic self.mp = Mp.Morph() def response(self, input_text): outtxt ='' nouns = self.mp.analy_noun(input_text) if len(nouns) > 0: noun = nouns[random.randint(0, len(nouns)-1)] if noun in self.dic.keys(): texts = self.dic[noun] if len(texts) > 0: outtxt = texts[random.randint(0, len(texts)-1)] return outtxt |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
import pickle import morphC as Mp class Dicts(): def __init__(self): self.dic_random = [] self.fileload('random.pkl', self.dic_random) self.dic_pattern = {} self.fileload('pattern.pkl', self.dic_pattern) self.mp = Mp.Morph() def filesave(self, filename, dic): try: with open(filename, 'wb') as fw: pickle.dump(dic, fw) except OSError as e: print(e) def fileload(self, filename, dic): try: with open(filename, 'rb') as fr: dic = pickle.load(fr) except OSError as e: print(e) def study_random(self, tt): if tt not in self.dic_random: self.dic_random.append(tt) def study_pattern(self, intt): nouns = self.mp.analy_noun(intt) for noun in nouns: if noun in self.dic_pattern.keys(): if intt not in self.dic_pattern[noun]: self.dic_pattern[noun].append(intt) else: ls = [intt] self.dic_pattern[noun] = ls def study(self, txt): self.study_random(txt) self.study_pattern(txt) def save(self): self.filesave('random.pkl', self.dic_random) self.filesave('pattern.pkl', self.dic_pattern) def getradomdic(self): return self.dic_random def getpatterndic(self): return self.dic_pattern if __name__ == '__main__': dic = Dicts() rnddic = dic.getradomdic() print(rnddic) dic.save() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import MeCab import unidic class Morph(): def analy_noun(self, tt): nouns = [] tagger = MeCab.Tagger() lines = tagger.parse(tt).split('\n') for line in lines: words = line.split('\t') if len(words) == 2: word = words[1].split(',') if word[0] == '名詞': nouns.append(words[0]) return nouns |